1 // RUN: %clang_cc1 -std=c++23 -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. This is a pure C++98 test. 124 // However we may extend implicit moves into C++98, we must make sure the 125 // result here is not changed. 126 class AutoPtrRef { }; 127 128 class AutoPtr { 129 AutoPtr(AutoPtr &); // cxx98-note {{declared private here}} 130 131 public: 132 AutoPtr(); 133 AutoPtr(AutoPtrRef); 134 135 operator AutoPtrRef(); 136 }; 137 138 AutoPtr make_auto_ptr(); 139 140 AutoPtr test_auto_ptr(bool Cond) { 141 AutoPtr p1( make_auto_ptr() ); 142 143 AutoPtr p; 144 if (Cond) 145 return p; // cxx98-error {{calling a private constructor}} 146 147 return AutoPtr(); 148 } 149 150 struct A1 { 151 A1(const char *); 152 ~A1(); 153 154 private: 155 A1(const A1 &); // cxx98_11-note 2 {{declared private here}} 156 }; 157 158 A1 f() { 159 // FIXME: redundant diagnostics! 160 return "Hello"; // cxx98_11-error {{calling a private constructor}} 161 // cxx98-warning@-1 {{an accessible copy constructor}} 162 // cxx11-warning@-2 {{copying parameter of type 'A1' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}} 163 } 164 165 namespace source_locations { 166 template<typename T> 167 struct sneaky_int { 168 typedef int type; 169 }; 170 171 template<typename T, typename U> 172 struct A { }; 173 174 template<typename T> 175 struct A<T, T> : A<T, int> { }; 176 177 struct E { 178 template<typename T> 179 operator A<T, typename sneaky_int<T>::type>&() const; // expected-note{{candidate function}} 180 }; 181 182 void f() { 183 A<float, float> &af = E(); // expected-error{{no viable conversion}} 184 A<float, int> &af2 = E(); 185 const A<float, int> &caf2 = E(); 186 } 187 188 // Check 189 template<typename T> 190 struct E2 { 191 operator T 192 * // expected-error{{'operator type-parameter-0-0 *' declared as a pointer to a reference of type 'int &'}} 193 () const; 194 }; 195 196 E2<int&> e2i; // expected-note{{in instantiation}} 197 } 198 199 namespace crazy_declarators { 200 struct A { 201 (&operator bool())(); // expected-error {{use a typedef to declare a conversion to 'bool (&)()'}} 202 *operator int(); // expected-error {{put the complete type after 'operator'}} 203 // No suggestion of using a typedef here; that's not possible. 204 template<typename T> (&operator T())(); 205 #if __cplusplus <= 199711L 206 // expected-error-re@-2 {{cannot specify any part of a return type in the declaration of a conversion function{{$}}}} 207 #else 208 // 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 (&)()'{{$}}}} 209 #endif 210 211 }; 212 } 213 214 namespace smart_ptr { 215 class Y { 216 class YRef { }; 217 218 Y(Y&); 219 220 public: 221 Y(); 222 Y(YRef); 223 224 operator YRef(); // expected-note{{candidate function}} 225 }; 226 227 struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}} 228 #if __cplusplus >= 201103L 229 // expected-note@-2 {{candidate constructor (the implicit move constructor) not}} 230 #endif 231 232 explicit X(Y); // expected-note {{not a candidate}} 233 }; 234 235 Y make_Y(); 236 237 X f() { 238 X x = make_Y(); // expected-error{{no viable conversion from 'Y' to 'X'}} 239 X x2(make_Y()); 240 return X(Y()); 241 } 242 } 243 244 struct Any { 245 Any(...); 246 }; 247 248 struct Other { 249 Other(const Other &); 250 Other(); 251 }; 252 253 void test_any() { 254 Any any = Other(); 255 #if __cplusplus <= 199711L 256 // expected-error@-2 {{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}} 257 #else 258 // expected-error@-4 {{cannot pass object of non-trivial type 'Other' through variadic constructor; call will abort at runtime}} 259 #endif 260 } 261 262 namespace PR7055 { 263 // Make sure that we don't allow too many conversions in an 264 // auto_ptr-like template. In particular, we can't create multiple 265 // temporary objects when binding to a reference. 266 struct auto_ptr { 267 struct auto_ptr_ref { }; 268 269 auto_ptr(auto_ptr&); 270 auto_ptr(auto_ptr_ref); 271 explicit auto_ptr(int *); 272 273 operator auto_ptr_ref(); 274 }; 275 276 struct X { 277 X(auto_ptr); 278 }; 279 280 X f() { 281 X x(auto_ptr(new int)); 282 return X(auto_ptr(new int)); 283 } 284 285 auto_ptr foo(); 286 287 X e(foo()); 288 289 struct Y { 290 Y(X); 291 }; 292 293 Y f2(foo()); 294 } 295 296 namespace PR7934 { 297 typedef unsigned char uint8; 298 299 struct MutablePtr { 300 MutablePtr() : ptr(0) {} 301 void *ptr; 302 303 operator void*() { return ptr; } 304 305 private: 306 operator uint8*() { return reinterpret_cast<uint8*>(ptr); } 307 operator const char*() const { return reinterpret_cast<const char*>(ptr); } 308 }; 309 310 void fake_memcpy(const void *); 311 312 void use() { 313 MutablePtr ptr; 314 fake_memcpy(ptr); 315 } 316 } 317 318 namespace rdar8018274 { 319 struct X { }; 320 struct Y { 321 operator const struct X *() const; 322 }; 323 324 struct Z : Y { 325 operator struct X * (); 326 }; 327 328 void test() { 329 Z x; 330 (void) (x != __null); 331 } 332 333 334 struct Base { 335 operator int(); 336 }; 337 338 struct Derived1 : Base { }; 339 340 struct Derived2 : Base { }; 341 342 struct SuperDerived : Derived1, Derived2 { 343 using Derived1::operator int; 344 }; 345 346 struct UeberDerived : SuperDerived { 347 operator long(); 348 }; 349 350 void test2(UeberDerived ud) { 351 int i = ud; // expected-error{{ambiguous conversion from derived class 'UeberDerived' to base class 'rdar8018274::Base'}} 352 } 353 354 struct Base2 { 355 operator int(); 356 }; 357 358 struct Base3 { 359 operator int(); 360 }; 361 362 struct Derived23 : Base2, Base3 { 363 using Base2::operator int; 364 }; 365 366 struct ExtraDerived23 : Derived23 { }; 367 368 void test3(ExtraDerived23 ed) { 369 int i = ed; 370 } 371 } 372 373 namespace PR8065 { 374 template <typename T> struct Iterator; 375 template <typename T> struct Container; 376 377 template<> 378 struct Iterator<int> { 379 typedef Container<int> container_type; 380 }; 381 382 template <typename T> 383 struct Container { 384 typedef typename Iterator<T>::container_type X; 385 operator X(void) { return X(); } 386 }; 387 388 Container<int> test; 389 } 390 391 namespace PR8034 { 392 struct C { 393 operator int(); 394 395 private: 396 template <typename T> operator T(); 397 }; 398 int x = C().operator int(); 399 } 400 401 namespace PR9336 { 402 template<class T> 403 struct generic_list 404 { 405 template<class Container> 406 operator Container() 407 { 408 Container ar; 409 T* i; 410 ar[0]=*i; 411 return ar; 412 } 413 }; 414 415 template<class T> 416 struct array 417 { 418 T& operator[](int); 419 const T& operator[](int)const; 420 }; 421 422 generic_list<generic_list<int> > l; 423 array<array<int> > a = l; 424 } 425 426 namespace PR8800 { 427 struct A; 428 struct C { 429 operator A&(); 430 }; 431 void f() { 432 C c; 433 A& a1(c); 434 A& a2 = c; 435 A& a3 = static_cast<A&>(c); 436 A& a4 = (A&)c; 437 } 438 } 439 440 namespace PR12712 { 441 struct A {}; 442 struct B { 443 operator A(); 444 operator A() const; 445 }; 446 struct C : B {}; 447 448 A f(const C c) { return c; } 449 } 450 451 namespace PR18234 { 452 struct A { 453 operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}} 454 operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}} 455 // expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'struct A' to 'const S &' for 1st argument}} 456 #if __cplusplus >= 201103L 457 // expected-note@-3 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'struct A' to 'S &&' for 1st argument}} 458 #endif 459 } a; 460 A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}} 461 A::E e = a; 462 bool k1 = e == A::e; // expected-error {{no member named 'e'}} 463 bool k2 = e.n == 0; 464 } 465 466 namespace PR30595 { 467 struct S { 468 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'}} 469 const operator int() const; // expected-error {{cannot specify any part of a return type}} 470 volatile const operator int(); // expected-error {{cannot specify any part of a return type}} 471 472 operator const int() const; 473 }; 474 } 475 476 #if __cplusplus >= 201103L 477 namespace dependent_conversion_function_id_lookup { 478 namespace gh77583 { 479 struct A1 { 480 operator int(); 481 }; 482 template<class T> struct C { 483 template <typename U> using Lookup = decltype(T{}.operator U()); 484 }; 485 C<A1> v{}; 486 } 487 template<typename T> struct A2 { 488 operator T(); 489 }; 490 template<typename T> struct B : A2<T> { 491 template<typename U> using Lookup = decltype(&B::operator U); 492 }; 493 using Result = B<int>::Lookup<int>; 494 using Result = int (A2<int>::*)(); 495 } 496 #endif 497 498 namespace GH121706 { 499 struct S { 500 *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'}} 501 **operator char(); // expected-error {{cannot specify any part of a return type in the declaration of a conversion function; put the complete type after 'operator'}} 502 }; 503 } 504