1 | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -Wsign-conversion %s |
2 | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++17 -Wsign-conversion %s |
3 | |
4 | // C++ rules for ?: are a lot stricter than C rules, and have to take into |
5 | // account more conversion options. |
6 | // This test runs in C++11 mode for the contextual conversion of the condition. |
7 | |
8 | struct ToBool { explicit operator bool(); }; |
9 | |
10 | struct B; |
11 | struct A { |
12 | A(); |
13 | A(const B&); // expected-note 2 {{candidate constructor}} |
14 | }; |
15 | struct B { operator A() const; }; // expected-note 2 {{candidate function}} |
16 | struct I { operator int(); }; |
17 | struct J { operator I(); }; |
18 | struct K { operator double(); }; |
19 | typedef void (*vfn)(); |
20 | struct F { operator vfn(); }; |
21 | struct G { operator vfn(); }; |
22 | |
23 | struct Base { |
24 | int trick(); |
25 | A trick() const; |
26 | void fn1(); |
27 | }; |
28 | struct Derived : Base { |
29 | void fn2(); |
30 | }; |
31 | struct Convertible { operator Base&(); }; |
32 | struct Priv : private Base {}; // expected-note 4 {{declared private here}} |
33 | struct Mid : Base {}; |
34 | struct Fin : Mid, Derived {}; |
35 | typedef void (Derived::*DFnPtr)(); |
36 | struct ToMemPtr { operator DFnPtr(); }; |
37 | |
38 | struct BadDerived; |
39 | struct BadBase { operator BadDerived&(); }; |
40 | struct BadDerived : BadBase {}; |
41 | |
42 | struct Fields { |
43 | int i1, i2, b1 : 3, b2 : 3; |
44 | }; |
45 | struct MixedFields { |
46 | int i; |
47 | volatile int vi; |
48 | const int ci; |
49 | const volatile int cvi; |
50 | }; |
51 | struct MixedFieldsDerived : MixedFields { |
52 | }; |
53 | |
54 | enum Enum { EVal }; |
55 | |
56 | struct Ambig { |
57 | operator short(); // expected-note 2 {{candidate function}} |
58 | operator signed char(); // expected-note 2 {{candidate function}} |
59 | }; |
60 | |
61 | struct Abstract { |
62 | virtual ~Abstract() = 0; // expected-note {{unimplemented pure virtual method '~Abstract' in 'Abstract'}} |
63 | }; |
64 | |
65 | struct Derived1: Abstract { |
66 | }; |
67 | |
68 | struct Derived2: Abstract { |
69 | }; |
70 | |
71 | void test() |
72 | { |
73 | // This function tests C++0x 5.16 |
74 | |
75 | // p1 (contextually convert to bool) |
76 | int i1 = ToBool() ? 0 : 1; |
77 | |
78 | // p2 (one or both void, and throwing) |
79 | Fields flds; |
80 | i1 ? throw 0 : throw 1; |
81 | i1 ? test() : throw 1; |
82 | i1 ? throw 0 : test(); |
83 | i1 ? test() : test(); |
84 | i1 = i1 ? throw 0 : 0; |
85 | i1 = i1 ? 0 : throw 0; |
86 | i1 = i1 ? (throw 0) : 0; |
87 | i1 = i1 ? 0 : (throw 0); |
88 | i1 ? 0 : test(); // expected-error {{right operand to ? is void, but left operand is of type 'int'}} |
89 | i1 ? test() : 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}} |
90 | (i1 ? throw 0 : i1) = 0; |
91 | (i1 ? i1 : throw 0) = 0; |
92 | (i1 ? (throw 0) : i1) = 0; |
93 | (i1 ? i1 : (throw 0)) = 0; |
94 | (i1 ? (void)(throw 0) : i1) = 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}} |
95 | (i1 ? i1 : (void)(throw 0)) = 0; // expected-error {{right operand to ? is void, but left operand is of type 'int'}} |
96 | int &throwRef1 = (i1 ? flds.i1 : throw 0); |
97 | int &throwRef2 = (i1 ? throw 0 : flds.i1); |
98 | int &throwRef3 = (i1 ? flds.b1 : throw 0); // expected-error {{non-const reference cannot bind to bit-field}} |
99 | int &throwRef4 = (i1 ? throw 0 : flds.b1); // expected-error {{non-const reference cannot bind to bit-field}} |
100 | |
101 | // p3 (one or both class type, convert to each other) |
102 | // b1 (lvalues) |
103 | Base base; |
104 | Derived derived; |
105 | Convertible conv; |
106 | Base &bar1 = i1 ? base : derived; |
107 | Base &bar2 = i1 ? derived : base; |
108 | Base &bar3 = i1 ? base : conv; |
109 | Base &bar4 = i1 ? conv : base; |
110 | // these are ambiguous |
111 | BadBase bb; |
112 | BadDerived bd; |
113 | (void)(i1 ? bb : bd); // expected-error {{conditional expression is ambiguous; 'BadBase' can be converted to 'BadDerived' and vice versa}} |
114 | (void)(i1 ? bd : bb); // expected-error {{conditional expression is ambiguous}} |
115 | // curiously enough (and a defect?), these are not |
116 | // for rvalues, hierarchy takes precedence over other conversions |
117 | (void)(i1 ? BadBase() : BadDerived()); |
118 | (void)(i1 ? BadDerived() : BadBase()); |
119 | |
120 | // b2.1 (hierarchy stuff) |
121 | extern const Base constret(); |
122 | extern const Derived constder(); |
123 | // should use const overload |
124 | A a1((i1 ? constret() : Base()).trick()); |
125 | A a2((i1 ? Base() : constret()).trick()); |
126 | A a3((i1 ? constret() : Derived()).trick()); |
127 | A a4((i1 ? Derived() : constret()).trick()); |
128 | // should use non-const overload |
129 | i1 = (i1 ? Base() : Base()).trick(); |
130 | i1 = (i1 ? Base() : Base()).trick(); |
131 | i1 = (i1 ? Base() : Derived()).trick(); |
132 | i1 = (i1 ? Derived() : Base()).trick(); |
133 | // should fail: const lost |
134 | (void)(i1 ? Base() : constder()); // expected-error {{incompatible operand types ('Base' and 'const Derived')}} |
135 | (void)(i1 ? constder() : Base()); // expected-error {{incompatible operand types ('const Derived' and 'Base')}} |
136 | |
137 | Priv priv; |
138 | Fin fin; |
139 | (void)(i1 ? Base() : Priv()); // expected-error{{private base class}} |
140 | (void)(i1 ? Priv() : Base()); // expected-error{{private base class}} |
141 | (void)(i1 ? Base() : Fin()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}} |
142 | (void)(i1 ? Fin() : Base()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}} |
143 | (void)(i1 ? base : priv); // expected-error {{private base class}} |
144 | (void)(i1 ? priv : base); // expected-error {{private base class}} |
145 | (void)(i1 ? base : fin); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}} |
146 | (void)(i1 ? fin : base); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}} |
147 | |
148 | // b2.2 (non-hierarchy) |
149 | i1 = i1 ? I() : i1; |
150 | i1 = i1 ? i1 : I(); |
151 | I i2(i1 ? I() : J()); |
152 | I i3(i1 ? J() : I()); |
153 | // "the type [it] would have if E2 were converted to an rvalue" |
154 | vfn pfn = i1 ? F() : test; |
155 | pfn = i1 ? test : F(); |
156 | (void)(i1 ? A() : B()); // expected-error {{conversion from 'B' to 'A' is ambiguous}} |
157 | (void)(i1 ? B() : A()); // expected-error {{conversion from 'B' to 'A' is ambiguous}} |
158 | (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}} |
159 | (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}} |
160 | // By the way, this isn't an lvalue: |
161 | &(i1 ? i1 : i2); // expected-error {{cannot take the address of an rvalue}} |
162 | |
163 | // p4 (lvalue, same type) |
164 | int &ir1 = i1 ? flds.i1 : flds.i2; |
165 | (i1 ? flds.b1 : flds.i2) = 0; |
166 | (i1 ? flds.i1 : flds.b2) = 0; |
167 | (i1 ? flds.b1 : flds.b2) = 0; |
168 | |
169 | // p5 (conversion to built-in types) |
170 | // GCC 4.3 fails these |
171 | double d1 = i1 ? I() : K(); |
172 | pfn = i1 ? F() : G(); |
173 | DFnPtr pfm; |
174 | pfm = i1 ? DFnPtr() : &Base::fn1; |
175 | pfm = i1 ? &Base::fn1 : DFnPtr(); |
176 | |
177 | // p6 (final conversions) |
178 | i1 = i1 ? i1 : ir1; |
179 | int *pi1 = i1 ? &i1 : 0; |
180 | pi1 = i1 ? 0 : &i1; |
181 | i1 = i1 ? i1 : EVal; |
182 | i1 = i1 ? EVal : i1; |
183 | d1 = i1 ? 'c' : 4.0; |
184 | d1 = i1 ? 4.0 : 'c'; |
185 | Base *pb = i1 ? (Base*)0 : (Derived*)0; |
186 | pb = i1 ? (Derived*)0 : (Base*)0; |
187 | pfm = i1 ? &Base::fn1 : &Derived::fn2; |
188 | pfm = i1 ? &Derived::fn2 : &Base::fn1; |
189 | pfm = i1 ? &Derived::fn2 : 0; |
190 | pfm = i1 ? 0 : &Derived::fn2; |
191 | const int (MixedFieldsDerived::*mp1) = |
192 | i1 ? &MixedFields::ci : &MixedFieldsDerived::i; |
193 | const volatile int (MixedFields::*mp2) = |
194 | i1 ? &MixedFields::ci : &MixedFields::cvi; |
195 | (void)(i1 ? &MixedFields::ci : &MixedFields::vi); |
196 | // Conversion of primitives does not result in an lvalue. |
197 | &(i1 ? i1 : d1); // expected-error {{cannot take the address of an rvalue}} |
198 | |
199 | (void)&(i1 ? flds.b1 : flds.i1); // expected-error {{address of bit-field requested}} |
200 | (void)&(i1 ? flds.i1 : flds.b1); // expected-error {{address of bit-field requested}} |
201 | |
202 | |
203 | unsigned long test0 = 5; |
204 | test0 = test0 ? (long) test0 : test0; // expected-warning {{operand of ? changes signedness: 'long' to 'unsigned long'}} |
205 | test0 = test0 ? (int) test0 : test0; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}} |
206 | test0 = test0 ? (short) test0 : test0; // expected-warning {{operand of ? changes signedness: 'short' to 'unsigned long'}} |
207 | test0 = test0 ? test0 : (long) test0; // expected-warning {{operand of ? changes signedness: 'long' to 'unsigned long'}} |
208 | test0 = test0 ? test0 : (int) test0; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}} |
209 | test0 = test0 ? test0 : (short) test0; // expected-warning {{operand of ? changes signedness: 'short' to 'unsigned long'}} |
210 | test0 = test0 ? test0 : (long) 10; |
211 | test0 = test0 ? test0 : (int) 10; |
212 | test0 = test0 ? test0 : (short) 10; |
213 | test0 = test0 ? (long) 10 : test0; |
214 | test0 = test0 ? (int) 10 : test0; |
215 | test0 = test0 ? (short) 10 : test0; |
216 | |
217 | int test1; |
218 | test0 = test0 ? EVal : test0; |
219 | test1 = test0 ? EVal : (int) test0; |
220 | |
221 | test0 = test0 ? EVal : test1; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}} |
222 | test0 = test0 ? test1 : EVal; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}} |
223 | |
224 | test1 = test0 ? EVal : (int) test0; |
225 | test1 = test0 ? (int) test0 : EVal; |
226 | |
227 | // Note the thing that this does not test: since DR446, various situations |
228 | // *must* create a separate temporary copy of class objects. This can only |
229 | // be properly tested at runtime, though. |
230 | |
231 | const Abstract &abstract1 = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}} |
232 | const Abstract &abstract2 = true ? static_cast<const Abstract&>(Derived1()) : throw 3; |
233 | } |
234 | |
235 | namespace PR6595 { |
236 | struct OtherString { |
237 | OtherString(); |
238 | OtherString(const char*); |
239 | }; |
240 | |
241 | struct String { |
242 | String(const char *); |
243 | String(const OtherString&); |
244 | operator const char*() const; |
245 | }; |
246 | |
247 | void f(bool Cond, String S, OtherString OS) { |
248 | (void)(Cond? S : ""); |
249 | (void)(Cond? "" : S); |
250 | const char a[1] = {'a'}; |
251 | (void)(Cond? S : a); |
252 | (void)(Cond? a : S); |
253 | (void)(Cond? OS : S); |
254 | } |
255 | } |
256 | |
257 | namespace PR6757 { |
258 | struct Foo1 { |
259 | Foo1(); |
260 | Foo1(const Foo1&); |
261 | }; |
262 | |
263 | struct Foo2 { }; |
264 | |
265 | struct Foo3 { |
266 | Foo3(); // expected-note{{requires 0 arguments}} |
267 | Foo3(Foo3&); // expected-note{{would lose const qualifier}} |
268 | }; |
269 | |
270 | struct Bar { |
271 | operator const Foo1&() const; |
272 | operator const Foo2&() const; |
273 | operator const Foo3&() const; |
274 | }; |
275 | |
276 | void f() { |
277 | (void)(true ? Bar() : Foo1()); // okay |
278 | (void)(true ? Bar() : Foo2()); // okay |
279 | (void)(true ? Bar() : Foo3()); // expected-error{{no viable constructor copying temporary}} |
280 | } |
281 | } |
282 | |
283 | // Reduced from selfhost. |
284 | namespace test1 { |
285 | struct A { |
286 | enum Foo { |
287 | fa, fb, fc, fd, fe, ff |
288 | }; |
289 | |
290 | Foo x(); |
291 | }; |
292 | |
293 | void foo(int); |
294 | |
295 | void test(A *a) { |
296 | foo(a ? a->x() : 0); |
297 | } |
298 | } |
299 | |
300 | namespace rdar7998817 { |
301 | class X { |
302 | X(X&); // expected-note{{declared private here}} |
303 | |
304 | struct ref { }; |
305 | |
306 | public: |
307 | X(); |
308 | X(ref); |
309 | |
310 | operator ref(); |
311 | }; |
312 | |
313 | void f(bool B) { |
314 | X x; |
315 | (void)(B? x // expected-error{{calling a private constructor of class 'rdar7998817::X'}} |
316 | : X()); |
317 | } |
318 | } |
319 | |
320 | namespace PR7598 { |
321 | enum Enum { |
322 | v = 1, |
323 | }; |
324 | |
325 | const Enum g() { |
326 | return v; |
327 | } |
328 | |
329 | const volatile Enum g2() { |
330 | return v; |
331 | } |
332 | |
333 | void f() { |
334 | const Enum v2 = v; |
335 | Enum e = false ? g() : v; |
336 | Enum e2 = false ? v2 : v; |
337 | Enum e3 = false ? g2() : v; |
338 | } |
339 | |
340 | } |
341 | |
342 | namespace PR9236 { |
343 | #define NULL 0L |
344 | void f() { |
345 | int i; |
346 | (void)(true ? A() : NULL); // expected-error{{non-pointer operand type 'A' incompatible with NULL}} |
347 | (void)(true ? NULL : A()); // expected-error{{non-pointer operand type 'A' incompatible with NULL}} |
348 | (void)(true ? 0 : A()); // expected-error{{incompatible operand types}} |
349 | (void)(true ? nullptr : A()); // expected-error{{non-pointer operand type 'A' incompatible with nullptr}} |
350 | (void)(true ? nullptr : i); // expected-error{{non-pointer operand type 'int' incompatible with nullptr}} |
351 | (void)(true ? __null : A()); // expected-error{{non-pointer operand type 'A' incompatible with NULL}} |
352 | (void)(true ? (void*)0 : A()); // expected-error{{incompatible operand types}} |
353 | } |
354 | } |
355 | |
356 | namespace DR587 { |
357 | template<typename T> |
358 | const T *f(bool b) { |
359 | static T t1 = T(); |
360 | static const T t2 = T(); |
361 | return &(b ? t1 : t2); |
362 | } |
363 | struct S {}; |
364 | template const int *f(bool); |
365 | template const S *f(bool); |
366 | |
367 | extern bool b; |
368 | int i = 0; |
369 | const int ci = 0; |
370 | volatile int vi = 0; |
371 | const volatile int cvi = 0; |
372 | |
373 | const int &cir = b ? i : ci; |
374 | volatile int &vir = b ? vi : i; |
375 | const volatile int &cvir1 = b ? ci : cvi; |
376 | const volatile int &cvir2 = b ? cvi : vi; |
377 | const volatile int &cvir3 = b ? ci : vi; // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}} |
378 | } |
379 | |
380 | namespace PR17052 { |
381 | struct X { |
382 | int i_; |
383 | bool b_; |
384 | |
385 | int &test() { return b_ ? i_ : throw 1; } |
386 | }; |
387 | } |
388 | |
389 | namespace PR26448 { |
390 | struct Base {}; |
391 | struct Derived : Base {}; |
392 | Base b; |
393 | Derived d; |
394 | typedef decltype(true ? static_cast<Base&&>(b) : static_cast<Derived&&>(d)) x; |
395 | typedef Base &&x; |
396 | } |
397 | |
398 | namespace lifetime_extension { |
399 | struct A {}; |
400 | struct B : A { B(); ~B(); }; |
401 | struct C : A { C(); ~C(); }; |
402 | |
403 | void f(bool b) { |
404 | A &&r = b ? static_cast<A&&>(B()) : static_cast<A&&>(C()); |
405 | } |
406 | |
407 | struct D { A &&a; }; |
408 | void f_indirect(bool b) { |
409 | D d = b ? D{B()} : D{C()}; |
410 | } |
411 | } |
412 | |