1 | // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only %s |
2 | // RUN: %clang_cc1 -std=c++1y %s -verify -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: |
10 | zero_init() : val(static_cast<T>(0)) {} |
11 | zero_init(T val) : val(val) {} |
12 | |
13 | operator T &() { return val; } //@13 |
14 | operator T() const { return val; } //@14 |
15 | |
16 | private: |
17 | T val; |
18 | }; |
19 | |
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 | |
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 | |
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 | |
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 Foo { |
162 | operator size_t(); // @162 |
163 | operator unsigned short(); // @163 |
164 | }; |
165 | |
166 | void bar() { |
167 | Foo x; |
168 | int *p = new int[x]; // @168 |
169 | } |
170 | } |
171 | |
172 | #ifdef CXX1Y |
173 | #else |
174 | //expected-error@168 {{ambiguous conversion of array size expression of type 'extended_examples_array_bounds::Foo' to an integral or enumeration type}} |
175 | //expected-note@162 {{conversion to integral type 'extended_examples_array_bounds::size_t'}} |
176 | //expected-note@163 {{conversion to integral type 'unsigned short' declared here}} |
177 | #endif |
178 | |