summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/temporaries.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CodeGenCXX/temporaries.cpp')
-rw-r--r--clang/test/CodeGenCXX/temporaries.cpp117
1 files changed, 110 insertions, 7 deletions
diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp
index 61b517abeb2..e8b4613a20d 100644
--- a/clang/test/CodeGenCXX/temporaries.cpp
+++ b/clang/test/CodeGenCXX/temporaries.cpp
@@ -584,11 +584,9 @@ namespace BindToSubobject {
// CHECK: call void @_ZN15BindToSubobject1fEv()
// CHECK: call void @_ZN15BindToSubobject1gEv()
// CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE)
- // FIXME: This is wrong. We should emit the call to __cxa_atexit prior to
- // calling h(), in case h() throws.
+ // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE to i8*), i8* @__dso_handle)
// CHECK: call {{.*}} @_ZN15BindToSubobject1hE
// CHECK: getelementptr
- // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE to i8*), i8* @__dso_handle)
// CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1cE, align 8
int &&c = (f(), (g(), A().*h()));
@@ -598,9 +596,9 @@ namespace BindToSubobject {
};
// CHECK: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE)
+ // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE to i8*), i8* @__dso_handle)
// CHECK: call {{.*}} @_ZN15BindToSubobject1hE
// CHECK: getelementptr {{.*}} getelementptr
- // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE to i8*), i8* @__dso_handle)
// CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1dE, align 8
int &&d = (B().a).*h();
}
@@ -611,7 +609,7 @@ namespace Bitfield {
// Do not lifetime extend the S() temporary here.
// CHECK: alloca
// CHECK: call {{.*}}memset
- // CHECK: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE, align 4
+ // CHECK: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE
// CHECK: call void @_ZN8Bitfield1SD1
// CHECK: store i32* @_ZGRN8Bitfield1rE, i32** @_ZN8Bitfield1rE, align 8
int &&r = S().a;
@@ -626,15 +624,120 @@ namespace Vector {
};
// CHECK: alloca
// CHECK: extractelement
- // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1rE,
+ // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1rE
// CHECK: store i32* @_ZGRN6Vector1rE, i32** @_ZN6Vector1rE,
int &&r = S().v[1];
// CHECK: alloca
// CHECK: extractelement
- // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1sE,
+ // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1sE
// CHECK: store i32* @_ZGRN6Vector1sE, i32** @_ZN6Vector1sE,
int &&s = S().w[1];
// FIXME PR16204: The following code leads to an assertion in Sema.
//int &&s = S().w.y;
}
+
+namespace ImplicitTemporaryCleanup {
+ struct A { A(int); ~A(); };
+ void g();
+
+ // CHECK: define void @_ZN24ImplicitTemporaryCleanup1fEv(
+ void f() {
+ // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AC1Ei(
+ A &&a = 0;
+
+ // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1gEv(
+ g();
+
+ // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AD1Ev(
+ }
+}
+
+namespace MultipleExtension {
+ struct A { A(); ~A(); };
+ struct B { B(); ~B(); };
+ struct C { C(); ~C(); };
+ struct D { D(); ~D(); int n; C c; };
+ struct E { const A &a; B b; const C &c; ~E(); };
+
+ E &&e1 = { A(), B(), D().c };
+
+ // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e1E.*]])
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]]
+ // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE:_ZGRN17MultipleExtension2e1E.*]], i32 0, i32 0)
+
+ // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 1))
+
+ // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e1E.*]])
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]]
+ // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 2)
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[TEMPE]]
+ // CHECK: store {{.*}} @[[TEMPE]], %"struct.MultipleExtension::E"** @_ZN17MultipleExtension2e1E, align 8
+
+ E e2 = { A(), B(), D().c };
+
+ // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e2E.*]])
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]]
+ // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[E:_ZN17MultipleExtension2e2E]], i32 0, i32 0)
+
+ // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 1))
+
+ // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e2E.*]])
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]]
+ // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 2)
+ // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[E]]
+
+
+ void g();
+ // CHECK: define void @[[NS:_ZN17MultipleExtension]]1fEv(
+ void f() {
+ E &&e1 = { A(), B(), D().c };
+ // CHECK: %[[TEMPE1_A:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1:.*]], i32 0, i32 0
+ // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA1:.*]])
+ // CHECK: store {{.*}} %[[TEMPA1]], {{.*}} %[[TEMPE1_A]]
+ // CHECK: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 1
+ // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE1_B]])
+ // CHECK: %[[TEMPE1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 2
+ // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD1:.*]])
+ // CHECK: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i32 0, i32 1
+ // CHECK: store {{.*}} %[[TEMPD1_C]], {{.*}} %[[TEMPE1_C]]
+ // CHECK: store {{.*}} %[[TEMPE1]], {{.*}} %[[E1:.*]]
+
+ g();
+ // CHECK: call void @[[NS]]1gEv()
+
+ E e2 = { A(), B(), D().c };
+ // CHECK: %[[TEMPE2_A:.*]] = getelementptr inbounds {{.*}} %[[E2:.*]], i32 0, i32 0
+ // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA2:.*]])
+ // CHECK: store {{.*}} %[[TEMPA2]], {{.*}} %[[TEMPE2_A]]
+ // CHECK: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 1
+ // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE2_B]])
+ // CHECK: %[[TEMPE2_C:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 2
+ // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD2:.*]])
+ // CHECK: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i32 0, i32 1
+ // CHECK: store {{.*}} %[[TEMPD2_C]], {{.*}}* %[[TEMPE2_C]]
+
+ g();
+ // CHECK: call void @[[NS]]1gEv()
+
+ // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[E2]])
+ // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD2]])
+ // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA2]])
+ // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[TEMPE1]])
+ // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD1]])
+ // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA1]])
+ }
+}
+
+namespace Ctor {
+ struct A { A(); ~A(); };
+ void f();
+ struct B {
+ A &&a;
+ B() : a{} { f(); }
+ } b;
+ // CHECK: define {{.*}}void @_ZN4Ctor1BC1Ev(
+ // CHECK: call void @_ZN4Ctor1AC1Ev(
+ // CHECK: call void @_ZN4Ctor1fEv(
+ // CHECK: call void @_ZN4Ctor1AD1Ev(
+}
OpenPOWER on IntegriCloud