aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-11-06 04:19:02 +0000
committerAnders Carlsson <andersca@mac.com>2009-11-06 04:19:02 +0000
commit5e1b91875c275f0ec50d3680afbac150d684fdba (patch)
tree43a2e1776f807bcf2f5132198b3fa0fd6d163437
parent1faf67478c6d423880726a327c737db13b8d9f0b (diff)
If a member variable of reference type is bound to a temporary in its member initializer it needs to be destroyed at the end of the constructor.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86230 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp5
-rw-r--r--test/CodeGenCXX/temporaries.cpp17
2 files changed, 22 insertions, 0 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 281aa604fe..9cd44fda95 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -264,6 +264,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD,
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
EmitCtorPrologue(CD, GD.getCtorType());
EmitStmt(S);
+
+ // If any of the member initializers are temporaries bound to references
+ // make sure to emit their destructors.
+ EmitCleanupBlocks(0);
+
} else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) {
llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue");
PushCleanupBlock(DtorEpilogue);
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index 5366612001..87ca9ca7d4 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -131,6 +131,7 @@ struct B {
int a1;
int a2;
B();
+ ~B();
};
B::B()
@@ -147,4 +148,20 @@ B::B()
f();
}
+struct C {
+ C();
+
+ const B& b;
+};
+
+C::C()
+ // CHECK: call void @_ZN6PR50771BC1Ev
+ : b(B()) {
+ // CHECK: call void @_ZN6PR50771fEv
+ f();
+
+ // CHECK: call void @_ZN6PR50771BD1Ev
+}
+
+
}