504 lines · cpp
1// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected -triple %itanium_abi_triple -Wbind-to-temporary-copy %s2// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected -triple %itanium_abi_triple -Wbind-to-temporary-copy %s3// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify=expected,cxx98_11,cxx11 -triple %itanium_abi_triple -Wbind-to-temporary-copy %s4// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify=expected,cxx98_11,cxx98 -triple %itanium_abi_triple -Wbind-to-temporary-copy %s5 6class X {7public: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 22operator int(); // expected-error{{conversion function must be a non-static member function}}23 24operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}}25 26typedef int func_type(int);27typedef int array_type[10];28 29class Y {30public: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 45typedef int INT;46typedef INT* INT_PTR;47 48class 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 57class A { };58 59class B : public A {60public: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 66class BaseA {};67class DerivedA;68 69class BaseB {70 virtual operator BaseA &() = 0;71 virtual operator DerivedA &() = 0;72};73 74class DerivedA : public BaseA, BaseB {75 virtual operator BaseA &(); // OK. Overrides BaseB::operatorBaseA&()76 virtual operator DerivedA &(); // OK. Overrides BaseB::operatorDerivedA&()77};78 79class 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.85struct Flip;86struct Flop {87 Flop();88 Flop(const Flip&); // expected-note{{candidate constructor}}89};90struct Flip {91 operator Flop() const; // expected-note{{candidate function}}92};93Flop 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 conversions96struct C {97 operator const char *() const;98};99 100C::operator const char*() const { return 0; }101 102void f(const C& c) {103 const char* v = c;104}105 106// Test. Conversion in base class is visible in derived class.107class XB {108public:109 operator int(); // expected-note {{candidate function}}110};111 112class Yb : public XB {113public:114 operator char(); // expected-note {{candidate function}}115};116 117void 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 the125// result here is not changed.126class AutoPtrRef { };127 128class AutoPtr {129 AutoPtr(AutoPtr &); // cxx98-note {{declared private here}}130 131public:132 AutoPtr();133 AutoPtr(AutoPtrRef);134 135 operator AutoPtrRef();136};137 138AutoPtr make_auto_ptr();139 140AutoPtr 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 150struct A1 {151 A1(const char *);152 ~A1();153 154private:155 A1(const A1 &); // cxx98_11-note 2 {{declared private here}}156};157 158A1 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 165namespace 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 // Check189 template<typename T>190 struct E2 {191 operator T192 * // 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 199namespace 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 <= 199711L206 // expected-error-re@-2 {{cannot specify any part of a return type in the declaration of a conversion function{{$}}}}207#else208 // 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#endif210 211 };212}213 214namespace 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 >= 201103L229 // expected-note@-2 {{candidate constructor (the implicit move constructor) not}}230#endif231 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 244struct Any {245 Any(...);246};247 248struct Other {249 Other(const Other &);250 Other();251};252 253void test_any() {254 Any any = Other();255#if __cplusplus <= 199711L256 // expected-error@-2 {{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}}257#else258 // expected-error@-4 {{cannot pass object of non-trivial type 'Other' through variadic constructor; call will abort at runtime}}259#endif260}261 262namespace PR7055 {263 // Make sure that we don't allow too many conversions in an264 // auto_ptr-like template. In particular, we can't create multiple265 // 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 296namespace 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 318namespace 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 373namespace 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 391namespace 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 401namespace PR9336 {402 template<class T>403 struct generic_list404 {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 array417 {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 426namespace 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 440namespace 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 451namespace 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 >= 201103L457 // expected-note@-3 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'struct A' to 'S &&' for 1st argument}}458#endif459 } a;460 A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}}461 A::E e = a; // expected-note {{'e' declared here}}462 bool k1 = e == A::e; // expected-error {{no member named 'e'}}463 bool k2 = e.n == 0;464}465 466namespace PR30595 {467struct 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 >= 201103L477namespace dependent_conversion_function_id_lookup {478namespace gh77583 {479struct A1 {480 operator int();481};482template<class T> struct C {483 template <typename U> using Lookup = decltype(T{}.operator U());484};485C<A1> v{};486}487template<typename T> struct A2 {488 operator T();489};490template<typename T> struct B : A2<T> {491 template<typename U> using Lookup = decltype(&B::operator U);492};493using Result = B<int>::Lookup<int>;494using Result = int (A2<int>::*)();495}496#endif497 498namespace GH121706 {499struct 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