blob: 5872bcf4b439e2769b2339fe3e5a5eb1e52e7e57 [file] [log] [blame]
Erik Pilkingtonf8ccf052019-05-10 17:52:26 +00001// 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
Erik Pilkington5a559e62018-08-21 17:24:06 +00005
6struct SecretDestructor {
7#ifndef NO_DTORS
8 // expected-note@+2 4 {{private}}
9#endif
Erik Pilkingtonf8ccf052019-05-10 17:52:26 +000010private: ~SecretDestructor(); // expected-note + {{private}}
Erik Pilkington5a559e62018-08-21 17:24:06 +000011};
12
13SecretDestructor sd1;
14thread_local SecretDestructor sd2;
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
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}}
Erik Pilkington63e7ab12018-08-21 17:50:10 +000043
44[[clang::always_destroy]] void f() {} // expected-warning{{'always_destroy' attribute only applies to variables}}
45struct [[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}}
Erik Pilkingtonf8ccf052019-05-10 17:52:26 +000049
50// expected-error@+1 {{temporary of type 'SecretDestructor' has private destructor}}
51SecretDestructor arr[10];
52
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
60struct Base {
61 ~Base();
62};
63struct Derived1 {
64 Derived1(int);
65 Base b;
66};
67struct Derived2 {
68 Derived1 b;
69};
70
71void dontcrash() {
72 [[clang::no_destroy]] static Derived2 d2[] = {0, 0};
73}
74
75[[clang::no_destroy]] Derived2 d2[] = {0, 0};