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