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