summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGTemporaries.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGTemporaries.cpp')
-rw-r--r--lib/CodeGen/CGTemporaries.cpp42
1 files changed, 31 insertions, 11 deletions
diff --git a/lib/CodeGen/CGTemporaries.cpp b/lib/CodeGen/CGTemporaries.cpp
index 5cfc7efade42..bed843966e62 100644
--- a/lib/CodeGen/CGTemporaries.cpp
+++ b/lib/CodeGen/CGTemporaries.cpp
@@ -17,6 +17,10 @@ using namespace CodeGen;
void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
llvm::Value *Ptr) {
+ assert((LiveTemporaries.empty() ||
+ LiveTemporaries.back().ThisPtr != Ptr ||
+ ConditionalBranchLevel) &&
+ "Pushed the same temporary twice; AST is likely wrong");
llvm::BasicBlock *DtorBlock = createBasicBlock("temp.dtor");
llvm::Value *CondPtr = 0;
@@ -41,6 +45,33 @@ void CodeGenFunction::PushCXXTemporary(const CXXTemporary *Temporary,
CondPtr));
PushCleanupBlock(DtorBlock);
+
+ if (Exceptions) {
+ const CXXLiveTemporaryInfo& Info = LiveTemporaries.back();
+ llvm::BasicBlock *CondEnd = 0;
+
+ EHCleanupBlock Cleanup(*this);
+
+ // If this is a conditional temporary, we need to check the condition
+ // boolean and only call the destructor if it's true.
+ if (Info.CondPtr) {
+ llvm::BasicBlock *CondBlock = createBasicBlock("cond.dtor.call");
+ CondEnd = createBasicBlock("cond.dtor.end");
+
+ llvm::Value *Cond = Builder.CreateLoad(Info.CondPtr);
+ Builder.CreateCondBr(Cond, CondBlock, CondEnd);
+ EmitBlock(CondBlock);
+ }
+
+ EmitCXXDestructorCall(Info.Temporary->getDestructor(),
+ Dtor_Complete, Info.ThisPtr);
+
+ if (CondEnd) {
+ // Reset the condition. to false.
+ Builder.CreateStore(llvm::ConstantInt::getFalse(VMContext), Info.CondPtr);
+ EmitBlock(CondEnd);
+ }
+ }
}
void CodeGenFunction::PopCXXTemporary() {
@@ -92,12 +123,6 @@ CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
llvm::Value *AggLoc,
bool IsAggLocVolatile,
bool IsInitializer) {
- // If we shouldn't destroy the temporaries, just emit the
- // child expression.
- if (!E->shouldDestroyTemporaries())
- return EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
- /*IgnoreResult=*/false, IsInitializer);
-
// Keep track of the current cleanup stack depth.
size_t CleanupStackDepth = CleanupEntries.size();
(void) CleanupStackDepth;
@@ -119,11 +144,6 @@ CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
LValue CodeGenFunction::EmitCXXExprWithTemporariesLValue(
const CXXExprWithTemporaries *E) {
- // If we shouldn't destroy the temporaries, just emit the
- // child expression.
- if (!E->shouldDestroyTemporaries())
- return EmitLValue(E->getSubExpr());
-
// Keep track of the current cleanup stack depth.
size_t CleanupStackDepth = CleanupEntries.size();
(void) CleanupStackDepth;