PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/clang/test/SemaCXX/destructor.cpp

http://github.com/chapuni/llvm-project
C++ | 405 lines | 321 code | 61 blank | 23 comment | 0 complexity | bc03cf81a3ae82b1bed0d6481fbd2fa3 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, JSON, BSD-3-Clause
  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. struct S8 {} s8;
  144. UnknownType S8::~S8() { // expected-error {{unknown type name 'UnknownType'}}
  145. s8.~S8();
  146. }
  147. template<class T> class TS : public B {
  148. virtual void m();
  149. };
  150. TS<int> baz;
  151. template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}}
  152. virtual void m();
  153. };
  154. TS2<int> foo; // expected-note {{instantiation}}
  155. }
  156. namespace dnvd { // delete-non-virtual-dtor warning
  157. struct NP {};
  158. struct B { // expected-warning {{has virtual functions but non-virtual destructor}}
  159. virtual void foo();
  160. };
  161. struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
  162. struct F final : B {};
  163. struct VB {
  164. virtual void foo();
  165. virtual ~VB();
  166. };
  167. struct VD: VB {};
  168. struct VF final: VB {};
  169. template <typename T>
  170. class simple_ptr {
  171. public:
  172. simple_ptr(T* t): _ptr(t) {}
  173. ~simple_ptr() { delete _ptr; } // \
  174. // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}} \
  175. // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
  176. T& operator*() const { return *_ptr; }
  177. private:
  178. T* _ptr;
  179. };
  180. template <typename T>
  181. class simple_ptr2 {
  182. public:
  183. simple_ptr2(T* t): _ptr(t) {}
  184. ~simple_ptr2() { delete _ptr; } // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
  185. T& operator*() const { return *_ptr; }
  186. private:
  187. T* _ptr;
  188. };
  189. void use(B&);
  190. void use(VB&);
  191. void nowarnstack() {
  192. B b; use(b);
  193. D d; use(d);
  194. F f; use(f);
  195. VB vb; use(vb);
  196. VD vd; use(vd);
  197. VF vf; use(vf);
  198. }
  199. void nowarnnonpoly() {
  200. {
  201. NP* np = new NP();
  202. delete np;
  203. }
  204. {
  205. NP* np = new NP[4];
  206. delete[] np;
  207. }
  208. }
  209. void nowarnarray() {
  210. {
  211. B* b = new B[4];
  212. delete[] b;
  213. }
  214. {
  215. D* d = new D[4];
  216. delete[] d;
  217. }
  218. {
  219. VB* vb = new VB[4];
  220. delete[] vb;
  221. }
  222. {
  223. VD* vd = new VD[4];
  224. delete[] vd;
  225. }
  226. }
  227. template <typename T>
  228. void nowarntemplate() {
  229. {
  230. T* t = new T();
  231. delete t;
  232. }
  233. {
  234. T* t = new T[4];
  235. delete[] t;
  236. }
  237. }
  238. void nowarn0() {
  239. {
  240. F* f = new F();
  241. delete f;
  242. }
  243. {
  244. VB* vb = new VB();
  245. delete vb;
  246. }
  247. {
  248. VB* vb = new VD();
  249. delete vb;
  250. }
  251. {
  252. VD* vd = new VD();
  253. delete vd;
  254. }
  255. {
  256. VF* vf = new VF();
  257. delete vf;
  258. }
  259. }
  260. void warn0() {
  261. {
  262. B* b = new B();
  263. delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
  264. }
  265. {
  266. B* b = new D();
  267. delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}}
  268. }
  269. {
  270. D* d = new D();
  271. delete d; // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}}
  272. }
  273. }
  274. void nowarn1() {
  275. {
  276. simple_ptr<F> f(new F());
  277. use(*f);
  278. }
  279. {
  280. simple_ptr<VB> vb(new VB());
  281. use(*vb);
  282. }
  283. {
  284. simple_ptr<VB> vb(new VD());
  285. use(*vb);
  286. }
  287. {
  288. simple_ptr<VD> vd(new VD());
  289. use(*vd);
  290. }
  291. {
  292. simple_ptr<VF> vf(new VF());
  293. use(*vf);
  294. }
  295. }
  296. void warn1() {
  297. {
  298. simple_ptr<B> b(new B()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::B>::~simple_ptr' requested here}}
  299. use(*b);
  300. }
  301. {
  302. simple_ptr2<B> b(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr2<dnvd::B>::~simple_ptr2' requested here}}
  303. use(*b);
  304. }
  305. {
  306. simple_ptr<D> d(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::D>::~simple_ptr' requested here}}
  307. use(*d);
  308. }
  309. }
  310. }
  311. namespace PR9238 {
  312. class B { public: ~B(); };
  313. class C : virtual B { public: ~C() { } };
  314. }
  315. namespace PR7900 {
  316. struct A { // expected-note 2{{type 'PR7900::A' is declared here}}
  317. };
  318. struct B : public A {
  319. };
  320. void foo() {
  321. B b;
  322. b.~B();
  323. b.~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
  324. (&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}}
  325. }
  326. }
  327. namespace PR16892 {
  328. auto p = &A::~A; // expected-error{{taking the address of a destructor}}
  329. }
  330. namespace PR20238 {
  331. struct S {
  332. volatile ~S() { } // expected-error{{destructor cannot have a return type}}
  333. };
  334. }
  335. namespace PR22668 {
  336. struct S {
  337. };
  338. void f(S s) {
  339. (s.~S)();
  340. }
  341. void g(S s) {
  342. (s.~S); // expected-error{{reference to destructor must be called}}
  343. }
  344. }