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