destructor.cpp revision f4b793ceb60418b64d3593ba3c8240e3594bff8f
1// RUN: %clang_cc1 -fsyntax-only -Wnon-virtual-dtor -verify %s
2class A {
3public:
4  ~A();
5};
6
7class B {
8public:
9  ~B() { }
10};
11
12class C {
13public:
14  (~C)() { }
15};
16
17struct D {
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}}
25};
26
27struct D2 {
28  void ~D2() { } //                          \
29  // expected-error{{destructor cannot have a return type}}
30};
31
32
33struct E;
34
35typedef E E_typedef;
36struct E {
37  ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}}
38};
39
40struct F {
41  (~F)(); // expected-note {{previous declaration is here}}
42  ~F(); // expected-error {{destructor cannot be redeclared}}
43};
44
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}}
49
50struct G {
51  ~G();
52};
53
54G::~G() { }
55
56// <rdar://problem/6841210>
57struct H {
58  ~H(void) { }
59};
60
61struct X {};
62
63struct Y {
64  ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}}
65};
66
67namespace PR6421 {
68  class T; // expected-note{{forward declaration}}
69
70  class QGenericArgument // expected-note{{declared here}}
71  {
72    template<typename U>
73    void foo(T t) // expected-error{{variable has incomplete type}}
74    { }
75
76    void disconnect()
77    {
78      T* t;
79      bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \
80      // expected-error{{does not refer to a value}}
81    }
82  };
83}
84
85namespace PR6709 {
86  template<class T> class X { T v; ~X() { ++*v; } };
87  void a(X<int> x) {}
88}
89
90struct X0 { virtual ~X0() throw(); };
91struct X1 : public X0 { };
92
93// Make sure we instantiate operator deletes when building a virtual
94// destructor.
95namespace test6 {
96  template <class T> class A {
97  public:
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 '::'}}
101    }
102
103    virtual ~A() {}
104  };
105
106  class B : A<int> { B(); }; // expected-note {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
107  B::B() {}
108}
109
110// Make sure classes are marked invalid when they have invalid
111// members.  This avoids a crash-on-invalid.
112namespace test7 {
113  struct A {
114    ~A() const; // expected-error {{'const' qualifier is not allowed on a destructor}}
115  };
116  struct B : A {};
117
118  void test() {
119    B *b;
120    b->~B();
121  }
122}
123
124namespace nonvirtualdtor {
125struct S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
126  virtual void m();
127};
128
129struct S2 {
130  ~S2(); // expected-warning {{has virtual functions but non-virtual destructor}}
131  virtual void m();
132};
133
134struct S3 : public S1 {  // expected-warning {{has virtual functions but non-virtual destructor}}
135  virtual void m();
136};
137
138struct S4 : public S2 {  // expected-warning {{has virtual functions but non-virtual destructor}}
139  virtual void m();
140};
141
142struct B {
143  virtual ~B();
144  virtual void m();
145};
146
147struct S5 : public B {
148  virtual void m();
149};
150
151struct S6 {
152  virtual void m();
153private:
154  ~S6();
155};
156
157struct S7 {
158  virtual void m();
159protected:
160  ~S7();
161};
162
163template<class T> class TS : public B {
164  virtual void m();
165};
166
167TS<int> baz;
168
169template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}}
170  virtual void m();
171};
172
173TS2<int> foo; // expected-note {{instantiation}}
174}
175
176namespace PR9238 {
177  class B { public: ~B(); };
178  class C : virtual B { public: ~C() { } };
179}
180