1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wexit-time-destructors %s -verify=expected,cxx11 2 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -Wexit-time-destructors %s -verify=expected 3 4 namespace test1 { 5 struct A { ~A(); }; 6 A a; // expected-warning {{declaration requires an exit-time destructor}} 7 A b[10]; // expected-warning {{declaration requires an exit-time destructor}} 8 A c[10][10]; // expected-warning {{declaration requires an exit-time destructor}} 9 10 A &d = a; 11 A &e = b[5]; 12 A &f = c[5][7]; 13 } 14 15 namespace test2 { f()16void f() { 17 struct A { ~A() { } }; 18 19 static A a; // expected-warning {{declaration requires an exit-time destructor}} 20 static A b[10]; // expected-warning {{declaration requires an exit-time destructor}} 21 static A c[10][10]; // expected-warning {{declaration requires an exit-time destructor}} 22 23 static A &d = a; 24 static A &e = b[5]; 25 static A &f = c[5][7]; 26 } 27 } 28 29 namespace test3 { 30 struct A { ~A() = default; }; 31 A a; 32 33 struct B { ~B(); }; 34 struct C : B { ~C() = default; }; 35 C c; // expected-warning {{exit-time destructor}} 36 37 class D { 38 friend struct E; 39 ~D() = default; 40 }; 41 struct E : D { 42 D d; 43 ~E() = default; 44 }; 45 E e; 46 } 47 48 namespace test4 { 49 struct A { ~A(); }; 50 [[clang::no_destroy]] A a; // no warning 51 } 52 53 namespace test5 { 54 struct A { ~A(); }; 55 [[clang::always_destroy]] A a; // no warning 56 func()57 void func() { 58 [[clang::always_destroy]] static A a; // no warning 59 } 60 } 61 62 namespace test6 { 63 #if __cplusplus >= 202002L 64 #define CPP20_CONSTEXPR constexpr 65 #else 66 #define CPP20_CONSTEXPR 67 #endif 68 struct S { ~Stest6::S69 CPP20_CONSTEXPR ~S() {} 70 }; 71 S s; // cxx11-warning {{exit-time destructor}} 72 73 struct T { ~Ttest6::T74 CPP20_CONSTEXPR ~T() { if (b) {} } 75 bool b; 76 }; 77 T t; // expected-warning {{exit-time destructor}} 78 #undef CPP20_CONSTEXPR 79 } 80 81