// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // Test1 struct B { operator char *(); // expected-note {{candidate function}} }; struct D : B { operator int *(); // expected-note {{candidate function}} }; void f (D d) { delete d; // expected-error {{ambiguous conversion of delete expression of type 'D' to a pointer}} } // Test2 struct B1 { operator int *(); }; struct D1 : B1 { operator int *(); }; void f1 (D1 d) { delete d; } // Test3 struct B2 { operator const int *(); // expected-note {{candidate function}} }; struct D2 : B2 { operator int *(); // expected-note {{candidate function}} }; void f2 (D2 d) { delete d; // expected-error {{ambiguous conversion of delete expression of type 'D2' to a pointer}} } // Test4 struct B3 { operator const int *(); // expected-note {{candidate function}} }; struct A3 { operator const int *(); // expected-note {{candidate function}} }; struct D3 : A3, B3 { }; void f3 (D3 d) { delete d; // expected-error {{ambiguous conversion of delete expression of type 'D3' to a pointer}} } // Test5 struct X { operator int(); operator int*(); }; void f4(X x) { delete x; delete x; } // Test6 struct X1 { operator int(); operator int*(); template<typename T> operator T*() const; // converts to any pointer! }; void f5(X1 x) { delete x; } // OK. In selecting a conversion to pointer function, template convesions are skipped. // Test7 struct Base { operator int*(); }; struct Derived : Base { // not the same function as Base's non-const operator int() operator int*() const; }; void foo6(const Derived cd, Derived d) { // overload resolution selects Derived::operator int*() const; delete cd; delete d; } // Test8 struct BB { template<typename T> operator T*() const; }; struct DD : BB { template<typename T> operator T*() const; // hides base conversion operator int *() const; }; void foo7 (DD d) { // OK. In selecting a conversion to pointer function, template convesions are skipped. delete d; }