summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/lambda-expressions.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2016-07-20 21:02:43 +0000
committerJohn McCall <rjmccall@apple.com>2016-07-20 21:02:43 +0000
commit4c7718d51b743b621d7c215eff78004c5ea40cd8 (patch)
tree966770cb1473b82ee0cbdfd2e7776884d7d58375 /clang/test/CodeGenCXX/lambda-expressions.cpp
parent0e4cf2f6b3e54f29d6eaf5b49b2e3235881a8ece (diff)
downloadbcm5719-llvm-4c7718d51b743b621d7c215eff78004c5ea40cd8.tar.gz
bcm5719-llvm-4c7718d51b743b621d7c215eff78004c5ea40cd8.zip
When copying an array into a lambda, destroy temporaries from
the copy-constructor immediately and enter a partial array cleanup for previously-copied elements. Fixes PR28595. llvm-svn: 276180
Diffstat (limited to 'clang/test/CodeGenCXX/lambda-expressions.cpp')
-rw-r--r--clang/test/CodeGenCXX/lambda-expressions.cpp54
1 files changed, 52 insertions, 2 deletions
diff --git a/clang/test/CodeGenCXX/lambda-expressions.cpp b/clang/test/CodeGenCXX/lambda-expressions.cpp
index f59d360314e..2006f0f81ef 100644
--- a/clang/test/CodeGenCXX/lambda-expressions.cpp
+++ b/clang/test/CodeGenCXX/lambda-expressions.cpp
@@ -116,6 +116,56 @@ int *PR22071_fun() {
return [&] { return &y; }();
}
+namespace pr28595 {
+ struct Temp {
+ Temp();
+ ~Temp() noexcept(false);
+ };
+ struct A {
+ A();
+ A(const A &a, const Temp &temp = Temp());
+ ~A();
+ };
+
+ // CHECK-LABEL: define void @_ZN7pr285954testEv()
+ void test() {
+ // CHECK: [[ARRAY:%.*]] = alloca [3 x [5 x [[A:%.*]]]], align 1
+ // CHECK: [[DESTIDX:%.*]] = alloca i64, align 8
+ // CHECK: [[I0:%.*]] = alloca i64, align 8
+ // CHECK: [[I1:%.*]] = alloca i64, align 8
+ A array[3][5];
+
+ // CHECK: [[DESTBASE:%.*]] = bitcast [3 x [5 x [[A]]]]* {{.*}} to [[A]]*
+ // CHECK: store i64 0, i64* [[DESTIDX]], align 8
+ // CHECK: store i64 0, i64* [[I0]], align 8
+ // CHECK: br label
+ // CHECK: icmp ult
+ // CHECK: store i64 0, i64* [[I1]], align 8
+ // CHECK: br label
+ // CHECK: icmp ult
+ // CHECK: [[T0:%.*]] = load i64, i64* [[DESTIDX]], align 8
+ // CHECK: [[DEST:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DESTBASE]], i64 [[T0]]
+ // CHECK: invoke void @_ZN7pr285954TempC1Ev
+ // CHECK: invoke void @_ZN7pr285951AC1ERKS0_RKNS_4TempE
+ // CHECK: invoke void @_ZN7pr285954TempD1Ev
+ // CHECK: landingpad
+ // CHECK: landingpad
+ // CHECK: br label [[CLEANUP:%.*]]{{$}}
+ // CHECK: landingpad
+ // CHECK: invoke void @_ZN7pr285954TempD1Ev
+ // CHECK: br label [[CLEANUP]]
+ // CHECK: icmp eq [[A]]* [[DESTBASE]], [[DEST]]
+ // CHECK: [[T0:%.*]] = phi [[A]]*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i64 -1
+ // CHECK: call void @_ZN7pr285951AD1Ev([[A]]* [[T1]])
+ // CHECK: icmp eq [[A]]* [[T1]], [[DESTBASE]]
+ (void) [array]{};
+
+ // Skip over the initialization loop.
+ // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [5 x [[A]]]], [3 x [5 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
+ }
+}
+
// CHECK-LABEL: define internal void @"_ZZ1e1ES_bEN3$_5D2Ev"
// CHECK-LABEL: define internal i32 @"_ZZ1fvEN3$_68__invokeEii"
@@ -126,9 +176,9 @@ int *PR22071_fun() {
// CHECK-NEXT: call i32 @"_ZZ1fvENK3$_6clEii"
// CHECK-NEXT: ret i32
-// CHECK-LABEL: define internal void @"_ZZ1hvEN4$_108__invokeEv"(%struct.A* noalias sret %agg.result) {{.*}} {
+// CHECK-LABEL: define internal void @"_ZZ1hvEN4$_118__invokeEv"(%struct.A* noalias sret %agg.result) {{.*}} {
// CHECK-NOT: =
-// CHECK: call void @"_ZZ1hvENK4$_10clEv"(%struct.A* sret %agg.result,
+// CHECK: call void @"_ZZ1hvENK4$_11clEv"(%struct.A* sret %agg.result,
// CHECK-NEXT: ret void
struct A { ~A(); };
void h() {
OpenPOWER on IntegriCloud