1 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected -triple %itanium_abi_triple -Wbind-to-temporary-copy %s 2 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected -triple %itanium_abi_triple -Wbind-to-temporary-copy %s 3 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify=expected,cxx98_11,cxx11 -triple %itanium_abi_triple -Wbind-to-temporary-copy %s 4 // RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify=expected,cxx98_11,cxx98 -triple %itanium_abi_triple -Wbind-to-temporary-copy %s 5 6 class X { 7 public: 8 operator bool(); 9 operator int() const; 10 11 bool f() { 12 return operator bool(); 13 } 14 15 float g() { 16 return operator float(); // expected-error{{use of undeclared 'operator float'}} 17 } 18 19 static operator short(); // expected-error{{conversion function must be a non-static member function}} 20 }; 21 22 operator int(); // expected-error{{conversion function must be a non-static member function}} 23 24 operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}} 25 26 typedef int func_type(int); 27 typedef int array_type[10]; 28 29 class Y { 30 public: 31 void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \ 32 // expected-error{{conversion function cannot have any parameters}} 33 34 operator bool(int a = 4, int b = 6) const; // expected-error{{conversion function cannot have any parameters}} 35 36 37 operator float(...) const; // expected-error{{conversion function cannot be variadic}} 38 39 40 operator func_type(); // expected-error{{conversion function cannot convert to a function type}} 41 operator array_type(); // expected-error{{conversion function cannot convert to an array type}} 42 }; 43 44 45 typedef int INT; 46 typedef INT* INT_PTR; 47 48 class Z { 49 operator int(); // expected-note {{previous declaration is here}} 50 operator int**(); // expected-note {{previous declaration is here}} 51 52 operator INT(); // expected-error{{conversion function cannot be redeclared}} 53 operator INT_PTR*(); // expected-error{{conversion function cannot be redeclared}} 54 }; 55 56 57 class A { }; 58 59 class B : public A { 60 public: 61 operator A&() const; // expected-warning{{conversion function converting 'B' to its base class 'A' will never be used}} 62 operator const void() const; // expected-warning{{conversion function converting 'B' to 'const void' will never be used}} 63 operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}} 64 }; 65 66 class BaseA {}; 67 class DerivedA; 68 69 class BaseB { 70 virtual operator BaseA &() = 0; 71 virtual operator DerivedA &() = 0; 72 }; 73 74 class DerivedA : public BaseA, BaseB { 75 virtual operator BaseA &(); // OK. Overrides BaseB::operatorBaseA&() 76 virtual operator DerivedA &(); // OK. Overrides BaseB::operatorDerivedA&() 77 }; 78 79 class DerivedB : public BaseA { 80 virtual operator DerivedB &(); // expected-warning{{conversion function converting 'DerivedB' to itself will never be used}} 81 virtual operator BaseA &(); // expected-warning{{conversion function converting 'DerivedB' to its base class 'BaseA' will never be used}} 82 }; 83 84 // This used to crash Clang. 85 struct Flip; 86 struct Flop { 87 Flop(); 88 Flop(const Flip&); // expected-note{{candidate constructor}} 89 }; 90 struct Flip { 91 operator Flop() const; // expected-note{{candidate function}} 92 }; 93 Flop flop = Flip(); // expected-error {{conversion from 'Flip' to 'Flop' is ambiguous}} 94 95 // This tests that we don't add the second conversion declaration to the list of user conversions 96 struct C { 97 operator const char *() const; 98 }; 99 100 C::operator const char*() const { return 0; } 101 102 void f(const C& c) { 103 const char* v = c; 104 } 105 106 // Test. Conversion in base class is visible in derived class. 107 class XB { 108 public: 109 operator int(); // expected-note {{candidate function}} 110 }; 111 112 class Yb : public XB { 113 public: 114 operator char(); // expected-note {{candidate function}} 115 }; 116 117 void f(Yb& a) { 118 if (a) { } // expected-error {{conversion from 'Yb' to 'bool' is ambiguous}} 119 int i = a; // OK. calls XB::operator int(); 120 char ch = a; // OK. calls Yb::operator char(); 121 } 122 123 // Test conversion + copy construction. 124 class AutoPtrRef { }; 125 126 class AutoPtr { 127 AutoPtr(AutoPtr &); // cxx98-note {{declared private here}} 128 129 public: 130 AutoPtr(); 131 AutoPtr(AutoPtrRef); 132 133 operator AutoPtrRef(); 134 }; 135 136 AutoPtr make_auto_ptr(); 137 138 AutoPtr test_auto_ptr(bool Cond) { 139 AutoPtr p1( make_auto_ptr() ); 140 141 AutoPtr p; 142 if (Cond) 143 return p; // cxx98-error {{calling a private constructor}} 144 145 return AutoPtr(); 146 } 147 148 struct A1 { 149 A1(const char *); 150 ~A1(); 151 152 private: 153 A1(const A1 &); // cxx98_11-note 2 {{declared private here}} 154 }; 155 156 A1 f() { 157 // FIXME: redundant diagnostics! 158 return "Hello"; // cxx98_11-error {{calling a private constructor}} 159 // cxx98-warning@-1 {{an accessible copy constructor}} 160 // cxx11-warning@-2 {{copying parameter of type 'A1' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}} 161 } 162 163 namespace source_locations { 164 template<typename T> 165 struct sneaky_int { 166 typedef int type; 167 }; 168 169 template<typename T, typename U> 170 struct A { }; 171 172 template<typename T> 173 struct A<T, T> : A<T, int> { }; 174 175 struct E { 176 template<typename T> 177 operator A<T, typename sneaky_int<T>::type>&() const; // expected-note{{candidate function}} 178 }; 179 180 void f() { 181 A<float, float> &af = E(); // expected-error{{no viable conversion}} 182 A<float, int> &af2 = E(); 183 const A<float, int> &caf2 = E(); 184 } 185 186 // Check 187 template<typename T> 188 struct E2 { 189 operator T 190 * // expected-error{{pointer to a reference}} 191 () const; 192 }; 193 194 E2<int&> e2i; // expected-note{{in instantiation}} 195 } 196 197 namespace crazy_declarators { 198 struct A { 199 (&operator bool())(); // expected-error {{use a typedef to declare a conversion to 'bool (&)()'}} 200 *operator int(); // expected-error {{put the complete type after 'operator'}} 201 // No suggestion of using a typedef here; that's not possible. 202 template<typename T> (&operator T())(); 203 #if __cplusplus <= 199711L 204 // expected-error-re@-2 {{cannot specify any part of a return type in the declaration of a conversion function{{$}}}} 205 #else 206 // expected-error-re@-4 {{cannot specify any part of a return type in the declaration of a conversion function; use an alias template to declare a conversion to 'T (&)()'{{$}}}} 207 #endif 208 209 }; 210 } 211 212 namespace smart_ptr { 213 class Y { 214 class YRef { }; 215 216 Y(Y&); 217 218 public: 219 Y(); 220 Y(YRef); 221 222 operator YRef(); // expected-note{{candidate function}} 223 }; 224 225 struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}} 226 #if __cplusplus >= 201103L 227 // expected-note@-2 {{candidate constructor (the implicit move constructor) not}} 228 #endif 229 230 explicit X(Y); // expected-note {{not a candidate}} 231 }; 232 233 Y make_Y(); 234 235 X f() { 236 X x = make_Y(); // expected-error{{no viable conversion from 'smart_ptr::Y' to 'smart_ptr::X'}} 237 X x2(make_Y()); 238 return X(Y()); 239 } 240 } 241 242 struct Any { 243 Any(...); 244 }; 245 246 struct Other { 247 Other(const Other &); 248 Other(); 249 }; 250 251 void test_any() { 252 Any any = Other(); 253 #if __cplusplus <= 199711L 254 // expected-error@-2 {{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}} 255 #else 256 // expected-error@-4 {{cannot pass object of non-trivial type 'Other' through variadic constructor; call will abort at runtime}} 257 #endif 258 } 259 260 namespace PR7055 { 261 // Make sure that we don't allow too many conversions in an 262 // auto_ptr-like template. In particular, we can't create multiple 263 // temporary objects when binding to a reference. 264 struct auto_ptr { 265 struct auto_ptr_ref { }; 266 267 auto_ptr(auto_ptr&); 268 auto_ptr(auto_ptr_ref); 269 explicit auto_ptr(int *); 270 271 operator auto_ptr_ref(); 272 }; 273 274 struct X { 275 X(auto_ptr); 276 }; 277 278 X f() { 279 X x(auto_ptr(new int)); 280 return X(auto_ptr(new int)); 281 } 282 283 auto_ptr foo(); 284 285 X e(foo()); 286 287 struct Y { 288 Y(X); 289 }; 290 291 Y f2(foo()); 292 } 293 294 namespace PR7934 { 295 typedef unsigned char uint8; 296 297 struct MutablePtr { 298 MutablePtr() : ptr(0) {} 299 void *ptr; 300 301 operator void*() { return ptr; } 302 303 private: 304 operator uint8*() { return reinterpret_cast<uint8*>(ptr); } 305 operator const char*() const { return reinterpret_cast<const char*>(ptr); } 306 }; 307 308 void fake_memcpy(const void *); 309 310 void use() { 311 MutablePtr ptr; 312 fake_memcpy(ptr); 313 } 314 } 315 316 namespace rdar8018274 { 317 struct X { }; 318 struct Y { 319 operator const struct X *() const; 320 }; 321 322 struct Z : Y { 323 operator struct X * (); 324 }; 325 326 void test() { 327 Z x; 328 (void) (x != __null); 329 } 330 331 332 struct Base { 333 operator int(); 334 }; 335 336 struct Derived1 : Base { }; 337 338 struct Derived2 : Base { }; 339 340 struct SuperDerived : Derived1, Derived2 { 341 using Derived1::operator int; 342 }; 343 344 struct UeberDerived : SuperDerived { 345 operator long(); 346 }; 347 348 void test2(UeberDerived ud) { 349 int i = ud; // expected-error{{ambiguous conversion from derived class 'rdar8018274::UeberDerived' to base class 'rdar8018274::Base'}} 350 } 351 352 struct Base2 { 353 operator int(); 354 }; 355 356 struct Base3 { 357 operator int(); 358 }; 359 360 struct Derived23 : Base2, Base3 { 361 using Base2::operator int; 362 }; 363 364 struct ExtraDerived23 : Derived23 { }; 365 366 void test3(ExtraDerived23 ed) { 367 int i = ed; 368 } 369 } 370 371 namespace PR8065 { 372 template <typename T> struct Iterator; 373 template <typename T> struct Container; 374 375 template<> 376 struct Iterator<int> { 377 typedef Container<int> container_type; 378 }; 379 380 template <typename T> 381 struct Container { 382 typedef typename Iterator<T>::container_type X; 383 operator X(void) { return X(); } 384 }; 385 386 Container<int> test; 387 } 388 389 namespace PR8034 { 390 struct C { 391 operator int(); 392 393 private: 394 template <typename T> operator T(); 395 }; 396 int x = C().operator int(); 397 } 398 399 namespace PR9336 { 400 template<class T> 401 struct generic_list 402 { 403 template<class Container> 404 operator Container() 405 { 406 Container ar; 407 T* i; 408 ar[0]=*i; 409 return ar; 410 } 411 }; 412 413 template<class T> 414 struct array 415 { 416 T& operator[](int); 417 const T& operator[](int)const; 418 }; 419 420 generic_list<generic_list<int> > l; 421 array<array<int> > a = l; 422 } 423 424 namespace PR8800 { 425 struct A; 426 struct C { 427 operator A&(); 428 }; 429 void f() { 430 C c; 431 A& a1(c); 432 A& a2 = c; 433 A& a3 = static_cast<A&>(c); 434 A& a4 = (A&)c; 435 } 436 } 437 438 namespace PR12712 { 439 struct A {}; 440 struct B { 441 operator A(); 442 operator A() const; 443 }; 444 struct C : B {}; 445 446 A f(const C c) { return c; } 447 } 448 449 namespace PR18234 { 450 struct A { 451 operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}} 452 operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}} 453 // expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'struct A' to 'const PR18234::A::S &' for 1st argument}} 454 #if __cplusplus >= 201103L 455 // expected-note@-3 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'struct A' to 'PR18234::A::S &&' for 1st argument}} 456 #endif 457 } a; 458 A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}} 459 A::E e = a; 460 bool k1 = e == A::e; // expected-error {{no member named 'e'}} 461 bool k2 = e.n == 0; 462 } 463 464 namespace PR30595 { 465 struct S { 466 const operator int(); // expected-error {{cannot specify any part of a return type in the declaration of a conversion function; put the complete type after 'operator'}} 467 const operator int() const; // expected-error {{cannot specify any part of a return type}} 468 volatile const operator int(); // expected-error {{cannot specify any part of a return type}} 469 470 operator const int() const; 471 }; 472 } 473