1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
18 static void ~D(int, ...) const { } // \
19 // expected-error{{type qualifier is not allowed on this function}} \
20 // expected-error{{destructor cannot be declared 'static'}} \
21 // expected-error{{destructor cannot have any parameters}} \
22 // expected-error{{destructor cannot be variadic}} \
23 // expected-error{{destructor cannot have a return type}} \
24 // expected-error{{'const' qualifier is not allowed on a destructor}}
29 // expected-error{{destructor cannot have a return type}}
37 ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}}
41 (~F)(); // expected-note {{previous declaration is here}}
42 ~F(); // expected-error {{destructor cannot be redeclared}}
45 ~; // expected-error {{expected a class name after '~' to name a destructor}}
46 ~undef(); // expected-error {{expected the class name after '~' to name a destructor}}
47 ~operator+(int, int); // expected-error {{expected a class name after '~' to name a destructor}}
48 ~F(){} // expected-error {{destructor must be a non-static member function}}
56 // <rdar://problem/6841210>
64 ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}}
68 class T; // expected-note{{forward declaration}}
70 class QGenericArgument // expected-note{{declared here}}
73 void foo(T t) // expected-error{{variable has incomplete type}}
79 bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \
80 // expected-error{{does not refer to a value}}
86 template<class T> class X { T v; ~X() { ++*v; } };
90 struct X0 { virtual ~X0() throw(); };
91 struct X1 : public X0 { };
93 // Make sure we instantiate operator deletes when building a virtual
96 template <class T> class A {
98 void *operator new(__SIZE_TYPE__);
99 void operator delete(void *p) {
100 T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
106 class B : A<int> { B(); }; // expected-note {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
110 // Make sure classes are marked invalid when they have invalid
111 // members. This avoids a crash-on-invalid.
114 ~A() const; // expected-error {{'const' qualifier is not allowed on a destructor}}
124 namespace nonvirtualdtor {
125 struct S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
130 ~S2(); // expected-warning {{has virtual functions but non-virtual destructor}}
134 struct S3 : public S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
138 struct S4 : public S2 { // expected-warning {{has virtual functions but non-virtual destructor}}
147 struct S5 : public B {
163 template<class T> class TS : public B {
169 template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}}
173 TS2<int> foo; // expected-note {{instantiation}}
176 namespace dnvd { // delete-non-virtual-dtor warning
179 struct B { // expected-warning {{has virtual functions but non-virtual destructor}}
183 struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
185 struct F final: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
194 struct VF final: VB {};
196 template <typename T>
199 simple_ptr(T* t): _ptr(t) {}
200 ~simple_ptr() { delete _ptr; } // \
201 // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}} \
202 // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
203 T& operator*() const { return *_ptr; }
208 template <typename T>
211 simple_ptr2(T* t): _ptr(t) {}
212 ~simple_ptr2() { delete _ptr; } // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
213 T& operator*() const { return *_ptr; }
230 void nowarnnonpoly() {
260 template <typename T>
261 void nowarntemplate() {
298 delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
302 delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
306 delete d; // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
312 simple_ptr<F> f(new F());
316 simple_ptr<VB> vb(new VB());
320 simple_ptr<VB> vb(new VD());
324 simple_ptr<VD> vd(new VD());
328 simple_ptr<VF> vf(new VF());
335 simple_ptr<B> b(new B()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::B>::~simple_ptr' requested here}}
339 simple_ptr2<B> b(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr2<dnvd::B>::~simple_ptr2' requested here}}
343 simple_ptr<D> d(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::D>::~simple_ptr' requested here}}
350 class B { public: ~B(); };
351 class C : virtual B { public: ~C() { } };
355 struct A { // expected-note 2{{type 'PR7900::A' is declared here}}
357 struct B : public A {
362 b.~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
363 (&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}