1 | // RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++98 %s |
2 | // RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++98 %s |
3 | // RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify -std=c++11 %s |
4 | // RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -std=c++11 %s |
5 | |
6 | typedef __typeof(sizeof(int)) size_t; |
7 | |
8 | // PR7803 |
9 | namespace test0 { |
10 | class A { |
11 | public: |
12 | static void operator delete(void *p) {}; |
13 | virtual ~A(); |
14 | }; |
15 | |
16 | class B : protected A { |
17 | public: |
18 | ~B(); |
19 | }; |
20 | |
21 | class C : protected B { |
22 | public: |
23 | using B::operator delete; |
24 | ~C(); |
25 | }; |
26 | |
27 | // Shouldn't have an error. |
28 | C::~C() {} |
29 | } |
30 | |
31 | namespace test1 { |
32 | class A { |
33 | public: |
34 | static void operator delete(void *p) {}; |
35 | virtual ~A(); |
36 | }; |
37 | |
38 | class B : protected A { |
39 | public: |
40 | static void operator delete(void *, size_t) {}; |
41 | ~B(); |
42 | }; |
43 | |
44 | class C : protected B { |
45 | public: |
46 | using A::operator delete; |
47 | using B::operator delete; |
48 | |
49 | ~C(); |
50 | }; |
51 | |
52 | // We assume that the intent is to treat C::operator delete(void*, size_t) as |
53 | // /not/ being a usual deallocation function, as it would be if it were |
54 | // declared with in C directly. |
55 | C::~C() {} |
56 | |
57 | struct D { |
58 | void operator delete(void*); // expected-note {{member 'operator delete' declared here}} |
59 | void operator delete(void*, ...); // expected-note {{member 'operator delete' declared here}} |
60 | virtual ~D(); |
61 | }; |
62 | // FIXME: The standard doesn't say this is ill-formed, but presumably either |
63 | // it should be or the variadic operator delete should not be a usual |
64 | // deallocation function. |
65 | D::~D() {} // expected-error {{multiple suitable 'operator delete' functions in 'D'}} |
66 | } |
67 | |
68 | // ...at the point of definition of a virtual destructor... |
69 | namespace test2 { |
70 | struct A { |
71 | virtual ~A(); |
72 | static void operator delete(void*, const int &); |
73 | }; |
74 | |
75 | struct B { |
76 | virtual ~B(); |
77 | static void operator delete(void*, const int &); // expected-note {{declared here}} |
78 | }; |
79 | B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}} |
80 | |
81 | #if __cplusplus < 201103L |
82 | struct CBase { virtual ~CBase(); }; |
83 | struct C : CBase { // expected-error {{no suitable member 'operator delete' in 'C'}} |
84 | static void operator delete(void*, const int &); // expected-note {{declared here}} |
85 | }; |
86 | void test() { |
87 | C c; // expected-note {{first required here}} |
88 | } |
89 | #else |
90 | struct CBase { virtual ~CBase(); }; // expected-note {{overridden virtual function is here}} |
91 | struct C : CBase { // expected-error {{deleted function '~C' cannot override a non-deleted function}} expected-note 2{{requires an unambiguous, accessible 'operator delete'}} |
92 | static void operator delete(void*, const int &); |
93 | }; |
94 | void test() { |
95 | C c; // expected-error {{attempt to use a deleted function}} |
96 | } |
97 | #endif |
98 | } |
99 | |
100 | // PR7346 |
101 | namespace test3 { |
102 | struct A { |
103 | #ifdef MSABI |
104 | // expected-error@+2 {{no suitable member 'operator delete' in 'A'}} |
105 | #endif |
106 | virtual ~A(); |
107 | #ifdef MSABI |
108 | // expected-note@+2 {{declared here}} |
109 | #endif |
110 | static void operator delete(void*, const int &); |
111 | }; |
112 | |
113 | struct B : A { |
114 | virtual ~B() {} |
115 | static void operator delete(void*); |
116 | }; |
117 | |
118 | void f() { |
119 | #ifdef MSABI |
120 | // expected-note@+2 {{implicit default constructor for 'test3::B' first required here}} |
121 | #endif |
122 | B use_vtable; |
123 | } |
124 | } |
125 | |