summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/eh-aggregated-inits.cpp
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2015-07-14 07:55:48 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2015-07-14 07:55:48 +0000
commit94436b9e9d3b3fea8166f8917af0792d38e1ee16 (patch)
tree7703f9dea8019a7f9f0ac7263d25ef79b868fcac /test/CodeGenCXX/eh-aggregated-inits.cpp
parente2695b039ea365a935f3983768b620af17ee57c0 (diff)
Fix for clang memcpyizer bugs 23911 and 23924 (patch by Denis Zobnin)
The fix is to remove duplicate copy-initialization of the only memcpy-able struct member and to correct the address of aggregately initialized members in destructors' calls during stack unwinding (in order to obtain address of struct member by using GEP instead of 'bitcast'). Differential Revision: http://reviews.llvm.org/D10990 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242127 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/eh-aggregated-inits.cpp')
-rw-r--r--test/CodeGenCXX/eh-aggregated-inits.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/test/CodeGenCXX/eh-aggregated-inits.cpp b/test/CodeGenCXX/eh-aggregated-inits.cpp
new file mode 100644
index 0000000000..cb34b65dfe
--- /dev/null
+++ b/test/CodeGenCXX/eh-aggregated-inits.cpp
@@ -0,0 +1,46 @@
+// Check that initialization of the only one memcpy-able struct member will not
+// be performed twice after successful non-trivial initializtion of the second
+// member.
+//
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -emit-llvm %s -o - | FileCheck %s
+
+int globId = 0;
+
+struct ImplicitCopy {
+ int id;
+
+ ImplicitCopy() { id = 10; }
+ ~ImplicitCopy() { id = 20; }
+};
+
+struct ExplicitCopy {
+ int id;
+
+ ExplicitCopy() { id = 15; }
+ ExplicitCopy(const ExplicitCopy &x) { id = 25; }
+ ~ExplicitCopy() { id = 35; }
+};
+
+struct Container {
+ ImplicitCopy o1; // memcpy-able member.
+ ExplicitCopy o2; // non-trivial initialization.
+
+ Container() { globId = 1000; }
+ ~Container() { globId = 2000; }
+};
+
+int main() {
+ try {
+ Container c1;
+ // CHECK-DAG: call void @llvm.memcpy
+ // CHECK-DAG: declare void @llvm.memcpy
+ // CHECK-NOT: @llvm.memcpy
+ Container c2(c1);
+
+ return 2;
+ }
+ catch (...) {
+ return 1;
+ }
+ return 0;
+}