summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2019-05-10 17:52:26 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2019-05-10 17:52:26 +0000
commitf8ccf052935adaf405e581fd31e8bc634cc5bbc7 (patch)
tree9cd6c6c3082628abfbfaed9a9ccc5f4f774f70b4 /clang/test
parentd74b87150448ab9e2e61f1d5c47de0503fca322f (diff)
downloadbcm5719-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.cpp6
-rw-r--r--clang/test/CodeGenCXX/no_destroy.cpp52
-rw-r--r--clang/test/SemaCXX/no_destroy.cpp35
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};
OpenPOWER on IntegriCloud