forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			193 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 -fsyntax-only -Wnon-virtual-dtor -verify %s
 | |
| class A {
 | |
| public:
 | |
|   ~A();
 | |
| };
 | |
| 
 | |
| class B {
 | |
| public:
 | |
|   ~B() { }
 | |
| };
 | |
| 
 | |
| class C {
 | |
| public:
 | |
|   (~C)() { }
 | |
| };
 | |
| 
 | |
| struct D {
 | |
|   static void ~D(int, ...) const { } //                          \
 | |
|     // expected-error{{type qualifier is not allowed on this function}} \
 | |
|     // expected-error{{destructor cannot be declared 'static'}}  \
 | |
|     // expected-error{{destructor cannot have any parameters}}   \
 | |
|     // expected-error{{destructor cannot be variadic}} \
 | |
|     // expected-error{{destructor cannot have a return type}} \
 | |
|     // expected-error{{'const' qualifier is not allowed on a destructor}}
 | |
| };
 | |
| 
 | |
| struct D2 {
 | |
|   void ~D2() { } //                          \
 | |
|   // expected-error{{destructor cannot have a return type}}  
 | |
| };
 | |
| 
 | |
| 
 | |
| struct E;
 | |
| 
 | |
| typedef E E_typedef;
 | |
| struct E {
 | |
|   ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}}
 | |
| };
 | |
| 
 | |
| struct F {
 | |
|   (~F)(); // expected-note {{previous declaration is here}}
 | |
|   ~F(); // expected-error {{destructor cannot be redeclared}}
 | |
| };
 | |
| 
 | |
| ~; // expected-error {{expected a class name after '~' to name a destructor}}
 | |
| ~undef(); // expected-error {{expected the class name after '~' to name a destructor}}
 | |
| ~operator+(int, int);  // expected-error {{expected a class name after '~' to name a destructor}}
 | |
| ~F(){} // expected-error {{destructor must be a non-static member function}}
 | |
| 
 | |
| struct G {
 | |
|   ~G();
 | |
| };
 | |
| 
 | |
| G::~G() { }
 | |
| 
 | |
| // <rdar://problem/6841210>
 | |
| struct H {
 | |
|   ~H(void) { } 
 | |
| };
 | |
| 
 | |
| struct X {};
 | |
| 
 | |
| struct Y {
 | |
|   ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}}
 | |
| };
 | |
| 
 | |
| namespace PR6421 {
 | |
|   class T; // expected-note{{forward declaration}}
 | |
| 
 | |
|   class QGenericArgument // expected-note{{declared here}}
 | |
|   {
 | |
|     template<typename U>
 | |
|     void foo(T t) // expected-error{{variable has incomplete type}}
 | |
|     { }
 | |
|     
 | |
|     void disconnect()
 | |
|     {
 | |
|       T* t;
 | |
|       bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \
 | |
|       // expected-error{{does not refer to a value}}
 | |
|     }
 | |
|   };
 | |
| }
 | |
| 
 | |
| namespace PR6709 {
 | |
|   template<class T> class X { T v; ~X() { ++*v; } };
 | |
|   void a(X<int> x) {}
 | |
| }
 | |
| 
 | |
| struct X0 { virtual ~X0() throw(); };
 | |
| struct X1 : public X0 { };
 | |
| 
 | |
| // Make sure we instantiate operator deletes when building a virtual
 | |
| // destructor.
 | |
| namespace test6 {
 | |
|   template <class T> class A {
 | |
|   public:
 | |
|     void *operator new(__SIZE_TYPE__);
 | |
|     void operator delete(void *p) {
 | |
|       T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
 | |
|     }
 | |
| 
 | |
|     virtual ~A() {}
 | |
|   };
 | |
| 
 | |
|   class B : A<int> { B(); }; // expected-note {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
 | |
|   B::B() {}
 | |
| }
 | |
| 
 | |
| // Make sure classes are marked invalid when they have invalid
 | |
| // members.  This avoids a crash-on-invalid.
 | |
| namespace test7 {
 | |
|   struct A {
 | |
|     ~A() const; // expected-error {{'const' qualifier is not allowed on a destructor}}
 | |
|   };
 | |
|   struct B : A {};
 | |
| 
 | |
|   void test() {
 | |
|     B *b;
 | |
|     b->~B();
 | |
|   }
 | |
| }
 | |
| 
 | |
| namespace nonvirtualdtor {
 | |
| struct S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
 | |
|   virtual void m();
 | |
| };
 | |
| 
 | |
| struct S2 {
 | |
|   ~S2(); // expected-warning {{has virtual functions but non-virtual destructor}}
 | |
|   virtual void m();
 | |
| };
 | |
| 
 | |
| struct S3 : public S1 {  // expected-warning {{has virtual functions but non-virtual destructor}}
 | |
|   virtual void m();
 | |
| };
 | |
| 
 | |
| struct S4 : public S2 {  // expected-warning {{has virtual functions but non-virtual destructor}}
 | |
|   virtual void m();
 | |
| };
 | |
| 
 | |
| struct B {
 | |
|   virtual ~B();
 | |
|   virtual void m();
 | |
| };
 | |
| 
 | |
| struct S5 : public B {
 | |
|   virtual void m();
 | |
| };
 | |
| 
 | |
| struct S6 {
 | |
|   virtual void m();
 | |
| private:
 | |
|   ~S6();
 | |
| };
 | |
| 
 | |
| struct S7 {
 | |
|   virtual void m();
 | |
| protected:
 | |
|   ~S7();
 | |
| };
 | |
| 
 | |
| template<class T> class TS : public B {
 | |
|   virtual void m();
 | |
| };
 | |
| 
 | |
| TS<int> baz;
 | |
| 
 | |
| template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}}
 | |
|   virtual void m();
 | |
| };
 | |
| 
 | |
| TS2<int> foo; // expected-note {{instantiation}}
 | |
| }
 | |
| 
 | |
| namespace PR9238 {
 | |
|   class B { public: ~B(); };
 | |
|   class C : virtual B { public: ~C() { } };
 | |
| }
 | |
| 
 | |
| namespace PR7900 {
 | |
|   struct A { // expected-note 2{{type 'PR7900::A' is declared here}}
 | |
|   };
 | |
|   struct B : public A {
 | |
|   };
 | |
|   void foo() {
 | |
|     B b;
 | |
|     b.~B();
 | |
|     b.~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
 | |
|     (&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
 | |
|   }
 | |
| }
 |