// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected -triple %itanium_abi_triple -Wbind-to-temporary-copy %s // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected -triple %itanium_abi_triple -Wbind-to-temporary-copy %s // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify=expected,cxx98_11,cxx11 -triple %itanium_abi_triple -Wbind-to-temporary-copy %s // RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify=expected,cxx98_11,cxx98 -triple %itanium_abi_triple -Wbind-to-temporary-copy %s class X { public: operator bool(); operator int() const; bool f() { return operator bool(); } float g() { return operator float(); // expected-error{{use of undeclared 'operator float'}} } static operator short(); // expected-error{{conversion function must be a non-static member function}} }; operator int(); // expected-error{{conversion function must be a non-static member function}} operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}} typedef int func_type(int); typedef int array_type[10]; class Y { public: void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \ // expected-error{{conversion function cannot have any parameters}} operator bool(int a = 4, int b = 6) const; // expected-error{{conversion function cannot have any parameters}} operator float(...) const; // expected-error{{conversion function cannot be variadic}} operator func_type(); // expected-error{{conversion function cannot convert to a function type}} operator array_type(); // expected-error{{conversion function cannot convert to an array type}} }; typedef int INT; typedef INT* INT_PTR; class Z { operator int(); // expected-note {{previous declaration is here}} operator int**(); // expected-note {{previous declaration is here}} operator INT(); // expected-error{{conversion function cannot be redeclared}} operator INT_PTR*(); // expected-error{{conversion function cannot be redeclared}} }; class A { }; class B : public A { public: operator A&() const; // expected-warning{{conversion function converting 'B' to its base class 'A' will never be used}} operator const void() const; // expected-warning{{conversion function converting 'B' to 'const void' will never be used}} operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}} }; class BaseA {}; class DerivedA; class BaseB { virtual operator BaseA &() = 0; virtual operator DerivedA &() = 0; }; class DerivedA : public BaseA, BaseB { virtual operator BaseA &(); // OK. Overrides BaseB::operatorBaseA&() virtual operator DerivedA &(); // OK. Overrides BaseB::operatorDerivedA&() }; class DerivedB : public BaseA { virtual operator DerivedB &(); // expected-warning{{conversion function converting 'DerivedB' to itself will never be used}} virtual operator BaseA &(); // expected-warning{{conversion function converting 'DerivedB' to its base class 'BaseA' will never be used}} }; // This used to crash Clang. struct Flip; struct Flop { Flop(); Flop(const Flip&); // expected-note{{candidate constructor}} }; struct Flip { operator Flop() const; // expected-note{{candidate function}} }; Flop flop = Flip(); // expected-error {{conversion from 'Flip' to 'Flop' is ambiguous}} // This tests that we don't add the second conversion declaration to the list of user conversions struct C { operator const char *() const; }; C::operator const char*() const { return 0; } void f(const C& c) { const char* v = c; } // Test. Conversion in base class is visible in derived class. class XB { public: operator int(); // expected-note {{candidate function}} }; class Yb : public XB { public: operator char(); // expected-note {{candidate function}} }; void f(Yb& a) { if (a) { } // expected-error {{conversion from 'Yb' to 'bool' is ambiguous}} int i = a; // OK. calls XB::operator int(); char ch = a; // OK. calls Yb::operator char(); } // Test conversion + copy construction. This is a pure C++98 test. // However we may extend implicit moves into C++98, we must make sure the // result here is not changed. class AutoPtrRef { }; class AutoPtr { AutoPtr(AutoPtr &); // cxx98-note {{declared private here}} public: AutoPtr(); AutoPtr(AutoPtrRef); operator AutoPtrRef(); }; AutoPtr make_auto_ptr(); AutoPtr test_auto_ptr(bool Cond) { AutoPtr p1( make_auto_ptr() ); AutoPtr p; if (Cond) return p; // cxx98-error {{calling a private constructor}} return AutoPtr(); } struct A1 { A1(const char *); ~A1(); private: A1(const A1 &); // cxx98_11-note 2 {{declared private here}} }; A1 f() { // FIXME: redundant diagnostics! return "Hello"; // cxx98_11-error {{calling a private constructor}} // cxx98-warning@-1 {{an accessible copy constructor}} // cxx11-warning@-2 {{copying parameter of type 'A1' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}} } namespace source_locations { template struct sneaky_int { typedef int type; }; template struct A { }; template struct A : A { }; struct E { template operator A::type>&() const; // expected-note{{candidate function}} }; void f() { A &af = E(); // expected-error{{no viable conversion}} A &af2 = E(); const A &caf2 = E(); } // Check template struct E2 { operator T * // expected-error{{'operator type-parameter-0-0 *' declared as a pointer to a reference of type 'int &'}} () const; }; E2 e2i; // expected-note{{in instantiation}} } namespace crazy_declarators { struct A { (&operator bool())(); // expected-error {{use a typedef to declare a conversion to 'bool (&)()'}} *operator int(); // expected-error {{put the complete type after 'operator'}} // No suggestion of using a typedef here; that's not possible. template (&operator T())(); #if __cplusplus <= 199711L // expected-error-re@-2 {{cannot specify any part of a return type in the declaration of a conversion function{{$}}}} #else // 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 (&)()'{{$}}}} #endif }; } namespace smart_ptr { class Y { class YRef { }; Y(Y&); public: Y(); Y(YRef); operator YRef(); // expected-note{{candidate function}} }; struct X { // expected-note{{candidate constructor (the implicit copy constructor) not}} #if __cplusplus >= 201103L // expected-note@-2 {{candidate constructor (the implicit move constructor) not}} #endif explicit X(Y); // expected-note {{not a candidate}} }; Y make_Y(); X f() { X x = make_Y(); // expected-error{{no viable conversion from 'Y' to 'X'}} X x2(make_Y()); return X(Y()); } } struct Any { Any(...); }; struct Other { Other(const Other &); Other(); }; void test_any() { Any any = Other(); #if __cplusplus <= 199711L // expected-error@-2 {{cannot pass object of non-POD type 'Other' through variadic constructor; call will abort at runtime}} #else // expected-error@-4 {{cannot pass object of non-trivial type 'Other' through variadic constructor; call will abort at runtime}} #endif } namespace PR7055 { // Make sure that we don't allow too many conversions in an // auto_ptr-like template. In particular, we can't create multiple // temporary objects when binding to a reference. struct auto_ptr { struct auto_ptr_ref { }; auto_ptr(auto_ptr&); auto_ptr(auto_ptr_ref); explicit auto_ptr(int *); operator auto_ptr_ref(); }; struct X { X(auto_ptr); }; X f() { X x(auto_ptr(new int)); return X(auto_ptr(new int)); } auto_ptr foo(); X e(foo()); struct Y { Y(X); }; Y f2(foo()); } namespace PR7934 { typedef unsigned char uint8; struct MutablePtr { MutablePtr() : ptr(0) {} void *ptr; operator void*() { return ptr; } private: operator uint8*() { return reinterpret_cast(ptr); } operator const char*() const { return reinterpret_cast(ptr); } }; void fake_memcpy(const void *); void use() { MutablePtr ptr; fake_memcpy(ptr); } } namespace rdar8018274 { struct X { }; struct Y { operator const struct X *() const; }; struct Z : Y { operator struct X * (); }; void test() { Z x; (void) (x != __null); } struct Base { operator int(); }; struct Derived1 : Base { }; struct Derived2 : Base { }; struct SuperDerived : Derived1, Derived2 { using Derived1::operator int; }; struct UeberDerived : SuperDerived { operator long(); }; void test2(UeberDerived ud) { int i = ud; // expected-error{{ambiguous conversion from derived class 'UeberDerived' to base class 'rdar8018274::Base'}} } struct Base2 { operator int(); }; struct Base3 { operator int(); }; struct Derived23 : Base2, Base3 { using Base2::operator int; }; struct ExtraDerived23 : Derived23 { }; void test3(ExtraDerived23 ed) { int i = ed; } } namespace PR8065 { template struct Iterator; template struct Container; template<> struct Iterator { typedef Container container_type; }; template struct Container { typedef typename Iterator::container_type X; operator X(void) { return X(); } }; Container test; } namespace PR8034 { struct C { operator int(); private: template operator T(); }; int x = C().operator int(); } namespace PR9336 { template struct generic_list { template operator Container() { Container ar; T* i; ar[0]=*i; return ar; } }; template struct array { T& operator[](int); const T& operator[](int)const; }; generic_list > l; array > a = l; } namespace PR8800 { struct A; struct C { operator A&(); }; void f() { C c; A& a1(c); A& a2 = c; A& a3 = static_cast(c); A& a4 = (A&)c; } } namespace PR12712 { struct A {}; struct B { operator A(); operator A() const; }; struct C : B {}; A f(const C c) { return c; } } namespace PR18234 { struct A { operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}} operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}} // expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'struct A' to 'const S &' for 1st argument}} #if __cplusplus >= 201103L // expected-note@-3 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'struct A' to 'S &&' for 1st argument}} #endif } a; A::S s = a; // expected-error {{no viable conversion from 'struct A' to 'A::S'}} A::E e = a; bool k1 = e == A::e; // expected-error {{no member named 'e'}} bool k2 = e.n == 0; } namespace PR30595 { struct S { 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'}} const operator int() const; // expected-error {{cannot specify any part of a return type}} volatile const operator int(); // expected-error {{cannot specify any part of a return type}} operator const int() const; }; } #if __cplusplus >= 201103L namespace dependent_conversion_function_id_lookup { namespace gh77583 { struct A1 { operator int(); }; template struct C { template using Lookup = decltype(T{}.operator U()); }; C v{}; } template struct A2 { operator T(); }; template struct B : A2 { template using Lookup = decltype(&B::operator U); }; using Result = B::Lookup; using Result = int (A2::*)(); } #endif