aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGCXX.cpp7
-rw-r--r--test/CodeGenCXX/temporaries.cpp33
2 files changed, 40 insertions, 0 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 029fdedb50..0e6b5cb143 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -1468,10 +1468,17 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
B != E; ++B) {
CXXBaseOrMemberInitializer *Member = (*B);
+ assert(LiveTemporaries.empty() &&
+ "Should not have any live temporaries at initializer start!");
+
if (Member->isBaseInitializer())
EmitBaseInitializer(*this, ClassDecl, Member, CtorType);
else
EmitMemberInitializer(*this, ClassDecl, Member);
+
+ // Pop any live temporaries that the initializers might have pushed.
+ while (!LiveTemporaries.empty())
+ PopCXXTemporary();
}
if (!CD->getNumBaseOrMemberInitializers() && !CD->isTrivial()) {
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index e9ed0f7690..5366612001 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -115,3 +115,36 @@ void f7() {
// CHECK: call void @_ZN1GD1Ev
a(G());
}
+
+namespace PR5077 {
+
+struct A {
+ A();
+ ~A();
+ int f();
+};
+
+void f();
+int g(const A&);
+
+struct B {
+ int a1;
+ int a2;
+ B();
+};
+
+B::B()
+ // CHECK: call void @_ZN6PR50771AC1Ev
+ // CHECK: call i32 @_ZN6PR50771A1fEv
+ // CHECK: call void @_ZN6PR50771AD1Ev
+ : a1(A().f())
+ // CHECK: call void @_ZN6PR50771AC1Ev
+ // CHECK: call i32 @_ZN6PR50771gERKNS_1AE
+ // CHECK: call void @_ZN6PR50771AD1Ev
+ , a2(g(A()))
+{
+ // CHECK: call void @_ZN6PR50771fEv
+ f();
+}
+
+}