1 // RUN: %clang_cc1 -std=c++11 -verify=expected,cxx11 -fsyntax-only -pedantic-errors %s
2 // RUN: %clang_cc1 -std=c++14 -verify=expected,cxx14 -fsyntax-only -pedantic-errors %s -DCXX1Y
3 
4 // Explicit member declarations behave as in C++11.
5 
6 namespace n3323_example {
7 
8   template <class T> class zero_init {
9   public:
zero_init()10     zero_init() : val(static_cast<T>(0)) {}
zero_init(T val)11     zero_init(T val) : val(val) {}
12 
operator T&()13     operator T &() { return val; }     //@13
operator T() const14     operator T() const { return val; } //@14
15 
16   private:
17     T val;
18   };
19 
Delete()20   void Delete() {
21     zero_init<int *> p;
22     p = new int(7);
23     delete p; //@23
24     delete (p + 0);
25     delete + p;
26   }
27 
Switch()28   void Switch() {
29     zero_init<int> i;
30     i = 7;
31     switch (i) {} // @31
32     switch (i + 0) {}
33     switch (+i) {}
34   }
35 }
36 
37 #ifdef CXX1Y
38 #else
39 //expected-error@23 {{ambiguous conversion of delete expression of type 'zero_init<int *>' to a pointer}}
40 //expected-note@13 {{conversion to pointer type 'int *'}}
41 //expected-note@14 {{conversion to pointer type 'int *'}}
42 //expected-error@31 {{multiple conversions from switch condition type 'zero_init<int>' to an integral or enumeration type}}
43 //expected-note@13 {{conversion to integral type 'int'}}
44 //expected-note@14 {{conversion to integral type 'int'}}
45 #endif
46 
47 namespace extended_examples {
48 
49   struct A0 {
50     operator int();      // matching and viable
51   };
52 
53   struct A1 {
54     operator int() &&;   // matching and not viable
55   };
56 
57   struct A2 {
58     operator float();    // not matching
59   };
60 
61   struct A3 {
62     template<typename T> operator T();  // not matching (ambiguous anyway)
63   };
64 
65   struct A4 {
66     template<typename T> operator int();  // not matching (ambiguous anyway)
67   };
68 
69   struct B1 {
70     operator int() &&;  // @70
71     operator int();     // @71  -- duplicate declaration with different qualifier is not allowed
72   };
73 
74   struct B2 {
75     operator int() &&;  // matching but not viable
76     operator float();   // not matching
77   };
78 
foo(A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,B2 b2)79   void foo(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, B2 b2) {
80     switch (a0) {}
81     switch (a1) {}     // @81 -- fails for different reasons
82     switch (a2) {}     // @82
83     switch (a3) {}     // @83
84     switch (a4) {}     // @84
85     switch (b2) {}     // @85 -- fails for different reasons
86   }
87 }
88 
89 //expected-error@71 {{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&&'}}
90 //expected-note@70 {{previous declaration is here}}
91 //expected-error@82 {{statement requires expression of integer type ('extended_examples::A2' invalid)}}
92 //expected-error@83 {{statement requires expression of integer type ('extended_examples::A3' invalid)}}
93 //expected-error@84 {{statement requires expression of integer type ('extended_examples::A4' invalid)}}
94 
95 #ifdef CXX1Y
96 //expected-error@81 {{statement requires expression of integer type ('extended_examples::A1' invalid)}}
97 //expected-error@85 {{statement requires expression of integer type ('extended_examples::B2' invalid)}}
98 #else
99 //expected-error@81 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@54 {{'operator int' declared here}}
100 //expected-error@85 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@75 {{'operator int' declared here}}
101 #endif
102 
103 namespace extended_examples_cxx1y {
104 
105   struct A1 {   // leads to viable match in C++1y, and no viable match in C++11
106     operator int() &&;                  // matching but not viable
107     template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.100
108   };
109 
110   struct A2 {   // leads to ambiguity in C++1y, and no viable match in C++11
111     operator int() &&;                    // matching but not viable
112     template <typename T> operator int(); // In C++1y: matching but ambiguous (disambiguated by L.105).
113   };
114 
115   struct B1 {    // leads to one viable match in both cases
116     operator int();                  // matching and viable
117     template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.110
118   };
119 
120   struct B2 {    // leads to one viable match in both cases
121     operator int();                  // matching and viable
122     template <typename T> operator int(); // In C++1y: matching but ambiguous, since disambiguated by L.115
123   };
124 
125   struct C {    // leads to no match in both cases
126     operator float();                  // not matching
127     template <typename T> operator T(); // In C++1y: not matching, nor viable.
128   };
129 
130   struct D {   // leads to viable match in C++1y, and no viable match in C++11
131     operator int() &&;                  // matching but not viable
132     operator float();                   // not matching
133     template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.125
134   };
135 
136 
foo(A1 a1,A2 a2,B1 b1,B2 b2,C c,D d)137   void foo(A1 a1, A2 a2, B1 b1, B2 b2, C c, D d) {
138     switch (a1) {} // @138 --  should presumably call templated conversion operator to convert to int.
139     switch (a2) {} // @139
140     switch (b1) {}
141     switch (b2) {}
142     switch (c) {}  // @142
143     switch (d) {}  // @143
144   }
145 }
146 
147 //expected-error@142 {{statement requires expression of integer type ('extended_examples_cxx1y::C' invalid)}}
148 
149 #ifdef CXX1Y
150 //expected-error@139 {{statement requires expression of integer type ('extended_examples_cxx1y::A2' invalid)}}
151 #else
152 //expected-error@138 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@106 {{'operator int' declared here}}
153 //expected-error@139 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@111 {{'operator int' declared here}}
154 //expected-error@143 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@131 {{'operator int' declared here}}
155 #endif
156 
157 namespace extended_examples_array_bounds {
158 
159   typedef decltype(sizeof(int)) size_t;
160 
161   struct X {
operator size_textended_examples_array_bounds::X162     constexpr operator size_t() const { return 1; } // cxx11-note 3{{conversion}}
operator unsigned shortextended_examples_array_bounds::X163     constexpr operator unsigned short() const { return 0; } // cxx11-note 3{{conversion}}
164   };
165 
f()166   void f() {
167     X x;
168     int *p = new int[x]; // cxx11-error {{ambiguous}}
169 
170     int arr[x]; // cxx11-error {{ambiguous}}
171     int (*q)[1] = new int[1][x]; // cxx11-error {{ambiguous}}
172   }
173 
174   struct Y {
operator floatextended_examples_array_bounds::Y175     constexpr operator float() const { return 0.0f; } // cxx14-note 3{{candidate}}
operator intextended_examples_array_bounds::Y176     constexpr operator int() const { return 1; } // cxx14-note 3{{candidate}}
177   };
178 
g()179   void g() {
180     Y y;
181     int *p = new int[y]; // cxx14-error {{ambiguous}}
182 
183     int arr[y]; // cxx14-error {{ambiguous}}
184     int (*q)[1] = new int[1][y]; // cxx14-error {{ambiguous}}
185   }
186 
187   template<int N> struct Z {
operator intextended_examples_array_bounds::Z188     constexpr operator int() const { return N; }
189   };
h()190   void h() {
191     int arrA[Z<1>()];
192     int arrB[Z<0>()]; // expected-error {{zero size array}}
193     int arrC[Z<-1>()]; // expected-error {{'arrC' declared as an array with a negative size}}
194   }
195 }
196