PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/test/SemaCXX/destructor.cpp

https://github.com/alex-v-odesk/clang
C++ | 382 lines | 302 code | 57 blank | 23 comment | 0 complexity | 875cad1469b8e3bc0f98bc997964cce7 MD5 | raw file
Possible License(s): JSON
  1. // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
  2. // RUN: %clang_cc1 -std=c++11 -triple %ms_abi_triple -DMSABI -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
  3. class A {
  4. public:
  5. ~A();
  6. };
  7. class B {
  8. public:
  9. ~B() { }
  10. };
  11. class C {
  12. public:
  13. (~C)() { }
  14. };
  15. struct D {
  16. static void ~D(int, ...) const { } // \
  17. // expected-error{{static member function cannot have 'const' qualifier}} \
  18. // expected-error{{destructor cannot be declared 'static'}} \
  19. // expected-error{{destructor cannot have any parameters}} \
  20. // expected-error{{destructor cannot be variadic}} \
  21. // expected-error{{destructor cannot have a return type}} \
  22. // expected-error{{'const' qualifier is not allowed on a destructor}}
  23. };
  24. struct D2 {
  25. void ~D2() { } // \
  26. // expected-error{{destructor cannot have a return type}}
  27. };
  28. struct E;
  29. typedef E E_typedef;
  30. struct E {
  31. ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}}
  32. };
  33. struct F {
  34. (~F)(); // expected-note {{previous declaration is here}}
  35. ~F(); // expected-error {{destructor cannot be redeclared}}
  36. };
  37. ~; // expected-error {{expected a class name after '~' to name a destructor}}
  38. ~undef(); // expected-error {{expected the class name after '~' to name a destructor}}
  39. ~operator+(int, int); // expected-error {{expected a class name after '~' to name a destructor}}
  40. ~F(){} // expected-error {{destructor must be a non-static member function}}
  41. struct G {
  42. ~G();
  43. };
  44. G::~G() { }
  45. // <rdar://problem/6841210>
  46. struct H {
  47. ~H(void) { }
  48. };
  49. struct X {};
  50. struct Y {
  51. ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}}
  52. };
  53. namespace PR6421 {
  54. class T; // expected-note{{forward declaration}}
  55. class QGenericArgument // expected-note{{declared here}}
  56. {
  57. template<typename U>
  58. void foo(T t) // expected-error{{variable has incomplete type}}
  59. { }
  60. void disconnect()
  61. {
  62. T* t;
  63. bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \
  64. // expected-error{{does not refer to a value}}
  65. }
  66. };
  67. }
  68. namespace PR6709 {
  69. #ifdef MSABI
  70. // This bug, "Clang instantiates destructor for function argument" is intended
  71. // behaviour in the Microsoft ABI because the callee needs to destruct the arguments.
  72. // expected-error@+3 {{indirection requires pointer operand ('int' invalid)}}
  73. // expected-note@+3 {{in instantiation of member function 'PR6709::X<int>::~X' requested here}}
  74. #endif
  75. template<class T> class X { T v; ~X() { ++*v; } };
  76. void a(X<int> x) {}
  77. }
  78. struct X0 { virtual ~X0() throw(); };
  79. struct X1 : public X0 { };
  80. // Make sure we instantiate operator deletes when building a virtual
  81. // destructor.
  82. namespace test6 {
  83. template <class T> class A {
  84. public:
  85. void *operator new(__SIZE_TYPE__);
  86. void operator delete(void *p) {
  87. T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
  88. }
  89. #ifdef MSABI
  90. // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
  91. #endif
  92. virtual ~A() {}
  93. };
  94. #ifndef MSABI
  95. // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
  96. #endif
  97. class B : A<int> { B(); };
  98. B::B() {}
  99. }
  100. // Make sure classes are marked invalid when they have invalid
  101. // members. This avoids a crash-on-invalid.
  102. namespace test7 {
  103. struct A {
  104. ~A() const; // expected-error {{'const' qualifier is not allowed on a destructor}}
  105. };
  106. struct B : A {};
  107. void test() {
  108. B *b;
  109. b->~B();
  110. }
  111. }
  112. namespace nonvirtualdtor {
  113. struct S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
  114. virtual void m();
  115. };
  116. struct S2 {
  117. ~S2(); // expected-warning {{has virtual functions but non-virtual destructor}}
  118. virtual void m();
  119. };
  120. struct S3 : public S1 { // expected-warning {{has virtual functions but non-virtual destructor}}
  121. virtual void m();
  122. };
  123. struct S4 : public S2 { // expected-warning {{has virtual functions but non-virtual destructor}}
  124. virtual void m();
  125. };
  126. struct B {
  127. virtual ~B();
  128. virtual void m();
  129. };
  130. struct S5 : public B {
  131. virtual void m();
  132. };
  133. struct S6 {
  134. virtual void m();
  135. private:
  136. ~S6();
  137. };
  138. struct S7 {
  139. virtual void m();
  140. protected:
  141. ~S7();
  142. };
  143. template<class T> class TS : public B {
  144. virtual void m();
  145. };
  146. TS<int> baz;
  147. template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}}
  148. virtual void m();
  149. };
  150. TS2<int> foo; // expected-note {{instantiation}}
  151. }
  152. namespace dnvd { // delete-non-virtual-dtor warning
  153. struct NP {};
  154. struct B { // expected-warning {{has virtual functions but non-virtual destructor}}
  155. virtual void foo();
  156. };
  157. struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
  158. struct F final : B {};
  159. struct VB {
  160. virtual void foo();
  161. virtual ~VB();
  162. };
  163. struct VD: VB {};
  164. struct VF final: VB {};
  165. template <typename T>
  166. class simple_ptr {
  167. public:
  168. simple_ptr(T* t): _ptr(t) {}
  169. ~simple_ptr() { delete _ptr; } // \
  170. // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}} \
  171. // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
  172. T& operator*() const { return *_ptr; }
  173. private:
  174. T* _ptr;
  175. };
  176. template <typename T>
  177. class simple_ptr2 {
  178. public:
  179. simple_ptr2(T* t): _ptr(t) {}
  180. ~simple_ptr2() { delete _ptr; } // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
  181. T& operator*() const { return *_ptr; }
  182. private:
  183. T* _ptr;
  184. };
  185. void use(B&);
  186. void use(VB&);
  187. void nowarnstack() {
  188. B b; use(b);
  189. D d; use(d);
  190. F f; use(f);
  191. VB vb; use(vb);
  192. VD vd; use(vd);
  193. VF vf; use(vf);
  194. }
  195. void nowarnnonpoly() {
  196. {
  197. NP* np = new NP();
  198. delete np;
  199. }
  200. {
  201. NP* np = new NP[4];
  202. delete[] np;
  203. }
  204. }
  205. void nowarnarray() {
  206. {
  207. B* b = new B[4];
  208. delete[] b;
  209. }
  210. {
  211. D* d = new D[4];
  212. delete[] d;
  213. }
  214. {
  215. VB* vb = new VB[4];
  216. delete[] vb;
  217. }
  218. {
  219. VD* vd = new VD[4];
  220. delete[] vd;
  221. }
  222. }
  223. template <typename T>
  224. void nowarntemplate() {
  225. {
  226. T* t = new T();
  227. delete t;
  228. }
  229. {
  230. T* t = new T[4];
  231. delete[] t;
  232. }
  233. }
  234. void nowarn0() {
  235. {
  236. F* f = new F();
  237. delete f;
  238. }
  239. {
  240. VB* vb = new VB();
  241. delete vb;
  242. }
  243. {
  244. VB* vb = new VD();
  245. delete vb;
  246. }
  247. {
  248. VD* vd = new VD();
  249. delete vd;
  250. }
  251. {
  252. VF* vf = new VF();
  253. delete vf;
  254. }
  255. }
  256. void warn0() {
  257. {
  258. B* b = new B();
  259. delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
  260. }
  261. {
  262. B* b = new D();
  263. delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
  264. }
  265. {
  266. D* d = new D();
  267. delete d; // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
  268. }
  269. }
  270. void nowarn1() {
  271. {
  272. simple_ptr<F> f(new F());
  273. use(*f);
  274. }
  275. {
  276. simple_ptr<VB> vb(new VB());
  277. use(*vb);
  278. }
  279. {
  280. simple_ptr<VB> vb(new VD());
  281. use(*vb);
  282. }
  283. {
  284. simple_ptr<VD> vd(new VD());
  285. use(*vd);
  286. }
  287. {
  288. simple_ptr<VF> vf(new VF());
  289. use(*vf);
  290. }
  291. }
  292. void warn1() {
  293. {
  294. simple_ptr<B> b(new B()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::B>::~simple_ptr' requested here}}
  295. use(*b);
  296. }
  297. {
  298. simple_ptr2<B> b(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr2<dnvd::B>::~simple_ptr2' requested here}}
  299. use(*b);
  300. }
  301. {
  302. simple_ptr<D> d(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::D>::~simple_ptr' requested here}}
  303. use(*d);
  304. }
  305. }
  306. }
  307. namespace PR9238 {
  308. class B { public: ~B(); };
  309. class C : virtual B { public: ~C() { } };
  310. }
  311. namespace PR7900 {
  312. struct A { // expected-note 2{{type 'PR7900::A' is declared here}}
  313. };
  314. struct B : public A {
  315. };
  316. void foo() {
  317. B b;
  318. b.~B();
  319. b.~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
  320. (&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
  321. }
  322. }
  323. namespace PR16892 {
  324. auto p = &A::~A; // expected-error{{taking the address of a destructor}}
  325. }