diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2019-05-10 17:52:26 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2019-05-10 17:52:26 +0000 |
commit | f8ccf052935adaf405e581fd31e8bc634cc5bbc7 (patch) | |
tree | 9cd6c6c3082628abfbfaed9a9ccc5f4f774f70b4 /clang/test | |
parent | d74b87150448ab9e2e61f1d5c47de0503fca322f (diff) | |
download | bcm5719-llvm-f8ccf052935adaf405e581fd31e8bc634cc5bbc7.tar.gz bcm5719-llvm-f8ccf052935adaf405e581fd31e8bc634cc5bbc7.zip |
[Sema] Mark array element destructors referenced during initialization
This fixes a crash where we would neglect to mark a destructor referenced for an
__attribute__((no_destory)) array. The destructor is needed though, since if an
exception is thrown we need to cleanup the elements.
rdar://48462498
Differential revision: https://reviews.llvm.org/D61165
llvm-svn: 360446
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CXX/expr/expr.unary/expr.new/p17.cpp | 6 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/no_destroy.cpp | 52 | ||||
-rw-r--r-- | clang/test/SemaCXX/no_destroy.cpp | 35 |
3 files changed, 86 insertions, 7 deletions
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp index 0d108eb6a89..9ca2e3d84ee 100644 --- a/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp +++ b/clang/test/CXX/expr/expr.unary/expr.new/p17.cpp @@ -10,7 +10,7 @@ class dtor { void test() { new ctor[0]; // expected-error{{calling a private constructor of class 'ctor'}} - new dtor[0]; // expected-error{{calling a private destructor of class 'dtor'}} - new dtor[3]; // expected-error{{calling a private destructor of class 'dtor'}} - new dtor[3][3]; // expected-error{{calling a private destructor of class 'dtor'}} + new dtor[0]; // expected-error{{temporary of type 'dtor' has private destructor}} + new dtor[3]; // expected-error{{temporary of type 'dtor' has private destructor}} + new dtor[3][3]; // expected-error{{temporary of type 'dtor' has private destructor}} } diff --git a/clang/test/CodeGenCXX/no_destroy.cpp b/clang/test/CodeGenCXX/no_destroy.cpp index 93e6ce17bb6..3400b6080b5 100644 --- a/clang/test/CodeGenCXX/no_destroy.cpp +++ b/clang/test/CodeGenCXX/no_destroy.cpp @@ -1,11 +1,14 @@ -// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s --check-prefixes=CHECK,NO_EXCEPTIONS +// RUN: %clang_cc1 -fexceptions %s -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s --check-prefixes=CHECK,EXCEPTIONS struct NonTrivial { ~NonTrivial(); }; +// CHECK-LABEL: define internal void @__cxx_global_var_init // CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev [[clang::no_destroy]] NonTrivial nt1; +// CHECK-LABEL: define internal void @__cxx_global_var_init // CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev [[clang::no_destroy]] thread_local NonTrivial nt2; @@ -13,11 +16,14 @@ struct NonTrivial2 { ~NonTrivial2(); }; +// CHECK-LABEL: define internal void @__cxx_global_var_init // CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev NonTrivial2 nt21; +// CHECK-LABEL: define internal void @__cxx_global_var_init // CHECK: _tlv_atexit{{.*}}_ZN11NonTrivial2D1Ev thread_local NonTrivial2 nt22; +// CHECK-LABEL: define void @_Z1fv void f() { // CHECK: __cxa_atexit{{.*}}_ZN11NonTrivial2D1Ev static NonTrivial2 nt21; @@ -25,7 +31,51 @@ void f() { thread_local NonTrivial2 nt22; } +// CHECK-LABEL: define void @_Z1gv +void g() { + // CHECK-NOT: __cxa_atexit + [[clang::no_destroy]] static NonTrivial2 nt21; + // CHECK-NOT: _tlv_atexit + [[clang::no_destroy]] thread_local NonTrivial2 nt22; +} + +// CHECK-LABEL: define internal void @__cxx_global_var_init // CHECK: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev [[clang::always_destroy]] NonTrivial nt3; +// CHECK-LABEL: define internal void @__cxx_global_var_init // CHECK: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev [[clang::always_destroy]] thread_local NonTrivial nt4; + + +struct NonTrivial3 { + NonTrivial3(); + ~NonTrivial3(); +}; + +[[clang::no_destroy]] NonTrivial3 arr[10]; + +// CHECK-LABEL: define internal void @__cxx_global_var_init +// CHECK: {{invoke|call}} void @_ZN11NonTrivial3C1Ev +// EXCEPTIONS: call void @_ZN11NonTrivial3D1Ev +// NO_EXCEPTIONS-NOT: call void @_ZN11NonTrivial3D1Ev +// CHECK-NOT: call i32 @__cxa_atexit + +void h() { + [[clang::no_destroy]] static NonTrivial3 slarr[10]; +} + +// CHECK-LABEL: define void @_Z1hv +// CHECK: {{invoke|call}} void @_ZN11NonTrivial3C1Ev +// EXCEPTIONS: call void @_ZN11NonTrivial3D1Ev +// NO_EXCEPTIONS-NOT: call void @_ZN11NonTrivial3D1Ev +// CHECK-NOT: call i32 @__cxa_atexit + +void i() { + [[clang::no_destroy]] thread_local NonTrivial3 tlarr[10]; +} + +// CHECK-LABEL: define void @_Z1iv +// CHECK: {{invoke|call}} void @_ZN11NonTrivial3C1Ev +// EXCEPTIONS: call void @_ZN11NonTrivial3D1Ev +// NO_EXCEPTIONS-NOT: call void @_ZN11NonTrivial3D1Ev +// CHECK-NOT: _tlv_atexit diff --git a/clang/test/SemaCXX/no_destroy.cpp b/clang/test/SemaCXX/no_destroy.cpp index 7afbf999825..5872bcf4b43 100644 --- a/clang/test/SemaCXX/no_destroy.cpp +++ b/clang/test/SemaCXX/no_destroy.cpp @@ -1,11 +1,13 @@ -// RUN: %clang_cc1 -DNO_DTORS -fno-c++-static-destructors -verify %s -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -DNO_DTORS -DNO_EXCEPTIONS -fno-c++-static-destructors -verify %s +// RUN: %clang_cc1 -DNO_EXCEPTIONS -verify %s +// RUN: %clang_cc1 -DNO_DTORS -fexceptions -fno-c++-static-destructors -verify %s +// RUN: %clang_cc1 -fexceptions -verify %s struct SecretDestructor { #ifndef NO_DTORS // expected-note@+2 4 {{private}} #endif -private: ~SecretDestructor(); // expected-note 2 {{private}} +private: ~SecretDestructor(); // expected-note + {{private}} }; SecretDestructor sd1; @@ -44,3 +46,30 @@ struct [[clang::no_destroy]] DoesntApply {}; // expected-warning{{'no_destroy' [[clang::no_destroy(0)]] int no_args; // expected-error{{'no_destroy' attribute takes no arguments}} [[clang::always_destroy(0)]] int no_args2; // expected-error{{'always_destroy' attribute takes no arguments}} + +// expected-error@+1 {{temporary of type 'SecretDestructor' has private destructor}} +SecretDestructor arr[10]; + +void local_arrays() { + // expected-error@+1 {{temporary of type 'SecretDestructor' has private destructor}} + static SecretDestructor arr2[10]; + // expected-error@+1 {{temporary of type 'SecretDestructor' has private destructor}} + thread_local SecretDestructor arr3[10]; +} + +struct Base { + ~Base(); +}; +struct Derived1 { + Derived1(int); + Base b; +}; +struct Derived2 { + Derived1 b; +}; + +void dontcrash() { + [[clang::no_destroy]] static Derived2 d2[] = {0, 0}; +} + +[[clang::no_destroy]] Derived2 d2[] = {0, 0}; |