1 // RUN: %clang_cc1 -DNO_DTORS -DNO_EXCEPTIONS -fno-c++-static-destructors -verify %s 2 // RUN: %clang_cc1 -DNO_EXCEPTIONS -verify %s 3 // RUN: %clang_cc1 -DNO_DTORS -fexceptions -fno-c++-static-destructors -verify %s 4 // RUN: %clang_cc1 -fexceptions -verify %s 5 6 struct SecretDestructor { 7 #ifndef NO_DTORS 8 // expected-note@+2 4 {{private}} 9 #endif 10 private: ~SecretDestructor(); // expected-note + {{private}} 11 }; 12 13 SecretDestructor sd1; 14 thread_local SecretDestructor sd2; locals()15void locals() { 16 static SecretDestructor sd3; 17 thread_local SecretDestructor sd4; 18 } 19 20 #ifndef NO_DTORS 21 // SecretDestructor sd1; // expected-error@-8 {{private}} 22 // thread_local SecretDestructor sd2; // expected-error@-8 {{private}} 23 // void locals() { 24 // static SecretDestructor sd3; // expected-error@-8 {{private}} 25 // thread_local SecretDestructor sd4; // expected-error@-8 {{private}} 26 // } 27 #endif 28 29 [[clang::always_destroy]] SecretDestructor sd6; // expected-error{{private}} 30 [[clang::always_destroy]] thread_local SecretDestructor sd7; // expected-error{{private}} 31 32 [[clang::no_destroy]] SecretDestructor sd8; 33 main()34int main() { 35 [[clang::no_destroy]] int p; // expected-error{{no_destroy attribute can only be applied to a variable with static or thread storage duration}} 36 [[clang::always_destroy]] int p2; // expected-error{{always_destroy attribute can only be applied to a variable with static or thread storage duration}} 37 [[clang::no_destroy]] static int p3; 38 [[clang::always_destroy]] static int p4; 39 } 40 41 [[clang::always_destroy]] [[clang::no_destroy]] int p; // expected-error{{'no_destroy' and 'always_destroy' attributes are not compatible}} // expected-note{{here}} 42 [[clang::no_destroy]] [[clang::always_destroy]] int p2; // expected-error{{'always_destroy' and 'no_destroy' attributes are not compatible}} // expected-note{{here}} 43 f()44[[clang::always_destroy]] void f() {} // expected-warning{{'always_destroy' attribute only applies to variables}} 45 struct [[clang::no_destroy]] DoesntApply {}; // expected-warning{{'no_destroy' attribute only applies to variables}} 46 47 [[clang::no_destroy(0)]] int no_args; // expected-error{{'no_destroy' attribute takes no arguments}} 48 [[clang::always_destroy(0)]] int no_args2; // expected-error{{'always_destroy' attribute takes no arguments}} 49 50 // expected-error@+1 {{temporary of type 'SecretDestructor' has private destructor}} 51 SecretDestructor arr[10]; 52 local_arrays()53void local_arrays() { 54 // expected-error@+1 {{temporary of type 'SecretDestructor' has private destructor}} 55 static SecretDestructor arr2[10]; 56 // expected-error@+1 {{temporary of type 'SecretDestructor' has private destructor}} 57 thread_local SecretDestructor arr3[10]; 58 } 59 60 struct Base { 61 ~Base(); 62 }; 63 struct Derived1 { 64 Derived1(int); 65 Base b; 66 }; 67 struct Derived2 { 68 Derived1 b; 69 }; 70 dontcrash()71void dontcrash() { 72 [[clang::no_destroy]] static Derived2 d2[] = {0, 0}; 73 } 74 75 [[clang::no_destroy]] Derived2 d2[] = {0, 0}; 76