diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-08-21 17:24:06 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-08-21 17:24:06 +0000 |
commit | 5a559e64a919dfdbc9d97af2a3529a2c9f555230 (patch) | |
tree | 6dbe891715fe23defb265c1df486e9f097ada5bb /clang/test | |
parent | 7d1790868f289ca7831c2175463899dbe2bdd5e3 (diff) | |
download | bcm5719-llvm-5a559e64a919dfdbc9d97af2a3529a2c9f555230.tar.gz bcm5719-llvm-5a559e64a919dfdbc9d97af2a3529a2c9f555230.zip |
Add a new flag and attributes to control static destructor registration
This commit adds the flag -fno-c++-static-destructors and the attributes
[[clang::no_destroy]] and [[clang::always_destroy]]. no_destroy specifies that a
specific static or thread duration variable shouldn't have it's destructor
registered, and is the default in -fno-c++-static-destructors mode.
always_destroy is the opposite, and is the default in -fc++-static-destructors
mode.
A variable whose destructor is disabled (either because of
-fno-c++-static-destructors or [[clang::no_destroy]]) doesn't count as a use of
the destructor, so we don't do any access checking or mark it referenced. We
also don't emit -Wexit-time-destructors for these variables.
rdar://21734598
Differential revision: https://reviews.llvm.org/D50994
llvm-svn: 340306
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CodeGenCXX/always_destroy.cpp | 31 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/no_destroy.cpp | 31 | ||||
-rw-r--r-- | clang/test/Misc/pragma-attribute-supported-attributes-list.test | 4 | ||||
-rw-r--r-- | clang/test/SemaCXX/no_destroy.cpp | 40 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-exit-time-destructors.cpp | 5 |
5 files changed, 110 insertions, 1 deletions
diff --git a/clang/test/CodeGenCXX/always_destroy.cpp b/clang/test/CodeGenCXX/always_destroy.cpp new file mode 100644 index 00000000000..e84c4cf02c5 --- /dev/null +++ b/clang/test/CodeGenCXX/always_destroy.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -fno-c++-static-destructors -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s + +struct NonTrivial { + ~NonTrivial(); +}; + +// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev +NonTrivial nt1; +// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev +thread_local NonTrivial nt2; + +struct NonTrivial2 { + ~NonTrivial2(); +}; + +// CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev +[[clang::always_destroy]] NonTrivial2 nt21; +// CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev +[[clang::always_destroy]] thread_local NonTrivial2 nt22; + +void f() { + // CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev + [[clang::always_destroy]] static NonTrivial2 nt21; + // CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev + [[clang::always_destroy]] thread_local NonTrivial2 nt22; +} + +// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev +[[clang::no_destroy]] NonTrivial nt3; +// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev +[[clang::no_destroy]] thread_local NonTrivial nt4; diff --git a/clang/test/CodeGenCXX/no_destroy.cpp b/clang/test/CodeGenCXX/no_destroy.cpp new file mode 100644 index 00000000000..93e6ce17bb6 --- /dev/null +++ b/clang/test/CodeGenCXX/no_destroy.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s + +struct NonTrivial { + ~NonTrivial(); +}; + +// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev +[[clang::no_destroy]] NonTrivial nt1; +// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev +[[clang::no_destroy]] thread_local NonTrivial nt2; + +struct NonTrivial2 { + ~NonTrivial2(); +}; + +// CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev +NonTrivial2 nt21; +// CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev +thread_local NonTrivial2 nt22; + +void f() { + // CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev + static NonTrivial2 nt21; + // CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev + thread_local NonTrivial2 nt22; +} + +// CHECK: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev +[[clang::always_destroy]] NonTrivial nt3; +// CHECK: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev +[[clang::always_destroy]] thread_local NonTrivial nt4; diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 4a3846be8d9..d2c1fe6d27b 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -2,7 +2,7 @@ // The number of supported attributes should never go down! -// CHECK: #pragma clang attribute supports 72 attributes: +// CHECK: #pragma clang attribute supports 74 attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) @@ -11,6 +11,7 @@ // CHECK-NEXT: AbiTag (SubjectMatchRule_record_not_is_union, SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_namespace) // CHECK-NEXT: AlignValue (SubjectMatchRule_variable, SubjectMatchRule_type_alias) // CHECK-NEXT: AllocSize (SubjectMatchRule_function) +// CHECK-NEXT: AlwaysDestroy (SubjectMatchRule_variable) // CHECK-NEXT: Annotate () // CHECK-NEXT: AnyX86NoCfCheck (SubjectMatchRule_hasType_functionType) // CHECK-NEXT: AssumeAligned (SubjectMatchRule_objc_method, SubjectMatchRule_function) @@ -38,6 +39,7 @@ // CHECK-NEXT: MipsLongCall (SubjectMatchRule_function) // CHECK-NEXT: MipsShortCall (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) +// CHECK-NEXT: NoDestroy (SubjectMatchRule_variable) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) // CHECK-NEXT: NoEscape (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) diff --git a/clang/test/SemaCXX/no_destroy.cpp b/clang/test/SemaCXX/no_destroy.cpp new file mode 100644 index 00000000000..bdb8077cb58 --- /dev/null +++ b/clang/test/SemaCXX/no_destroy.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -DNO_DTORS -fno-c++-static-destructors -verify %s +// RUN: %clang_cc1 -verify %s + +struct SecretDestructor { +#ifndef NO_DTORS + // expected-note@+2 4 {{private}} +#endif +private: ~SecretDestructor(); // expected-note 2 {{private}} +}; + +SecretDestructor sd1; +thread_local SecretDestructor sd2; +void locals() { + static SecretDestructor sd3; + thread_local SecretDestructor sd4; +} + +#ifndef NO_DTORS +// SecretDestructor sd1; // expected-error@-8 {{private}} +// thread_local SecretDestructor sd2; // expected-error@-8 {{private}} +// void locals() { +// static SecretDestructor sd3; // expected-error@-8 {{private}} +// thread_local SecretDestructor sd4; // expected-error@-8 {{private}} +// } +#endif + +[[clang::always_destroy]] SecretDestructor sd6; // expected-error{{private}} +[[clang::always_destroy]] thread_local SecretDestructor sd7; // expected-error{{private}} + +[[clang::no_destroy]] SecretDestructor sd8; + +int main() { + [[clang::no_destroy]] int p; // expected-error{{no_destroy attribute can only be applied to a variable with static or thread storage duration}} + [[clang::always_destroy]] int p2; // expected-error{{always_destroy attribute can only be applied to a variable with static or thread storage duration}} + [[clang::no_destroy]] static int p3; + [[clang::always_destroy]] static int p4; +} + +[[clang::always_destroy]] [[clang::no_destroy]] int p; // expected-error{{'no_destroy' and 'always_destroy' attributes are not compatible}} // expected-note{{here}} +[[clang::no_destroy]] [[clang::always_destroy]] int p2; // expected-error{{'always_destroy' and 'no_destroy' attributes are not compatible}} // expected-note{{here}} diff --git a/clang/test/SemaCXX/warn-exit-time-destructors.cpp b/clang/test/SemaCXX/warn-exit-time-destructors.cpp index 124576aa95b..17b3a940636 100644 --- a/clang/test/SemaCXX/warn-exit-time-destructors.cpp +++ b/clang/test/SemaCXX/warn-exit-time-destructors.cpp @@ -43,3 +43,8 @@ namespace test3 { }; E e; } + +namespace test4 { +struct A { ~A(); }; +[[clang::no_destroy]] A a; // no warning +} |