1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2 
3 // Test1
4 struct B {
5   operator char *(); // expected-note {{conversion to pointer type}}
6 };
7 
8 struct D : B {
9   operator int *(); // expected-note {{conversion to pointer type}}
10 };
11 
f(D d)12 void f (D d)
13 {
14    delete d; // expected-error {{ambiguous conversion of delete expression of type 'D' to a pointer}}
15 }
16 
17 // Test2
18 struct B1 {
19   operator int *();
20 };
21 
22 struct D1 : B1 {
23   operator int *();
24 };
25 
f1(D1 d)26 void f1 (D1 d)
27 {
28    delete d;
29 }
30 
31 // Test3
32 struct B2 {
33   operator const int *(); // expected-note {{conversion to pointer type}}
34 };
35 
36 struct D2 : B2 {
37   operator int *(); // expected-note {{conversion to pointer type}}
38 };
39 
f2(D2 d)40 void f2 (D2 d)
41 {
42    delete d; // expected-error {{ambiguous conversion of delete expression of type 'D2' to a pointer}}
43 }
44 
45 // Test4
46 struct B3 {
47   operator const int *(); // expected-note {{conversion to pointer type}}
48 };
49 
50 struct A3 {
51   operator const int *(); // expected-note {{conversion to pointer type}}
52 };
53 
54 struct D3 : A3, B3 {
55 };
56 
f3(D3 d)57 void f3 (D3 d)
58 {
59    delete d; // expected-error {{ambiguous conversion of delete expression of type 'D3' to a pointer}}
60 }
61 
62 // Test5
63 struct X {
64    operator int();
65    operator int*();
66 };
67 
f4(X x)68 void f4(X x) { delete x; delete x; }
69 
70 // Test6
71 struct X1 {
72    operator int();
73    operator int*();
74    template<typename T> operator T*() const; // converts to any pointer!
75 };
76 
f5(X1 x)77 void f5(X1 x) { delete x; }  // OK. In selecting a conversion to pointer function, template convesions are skipped.
78 
79 // Test7
80 struct Base {
81    operator int*();
82 };
83 
84 struct Derived : Base {
85    // not the same function as Base's non-const operator int()
86    operator int*() const;
87 };
88 
foo6(const Derived cd,Derived d)89 void foo6(const Derived cd, Derived d) {
90   // overload resolution selects Derived::operator int*() const;
91   delete cd;
92   delete d;
93 }
94 
95 // Test8
96 struct BB {
97    template<typename T> operator T*() const;
98 };
99 
100 struct DD : BB {
101    template<typename T> operator T*() const; // hides base conversion
102    operator int *() const;
103 };
104 
foo7(DD d)105 void foo7 (DD d)
106 {
107   // OK. In selecting a conversion to pointer function, template convesions are skipped.
108   delete d;
109 }
110