diff options
| author | Anders Carlsson <andersca@mac.com> | 2009-10-18 23:09:21 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2009-10-18 23:09:21 +0000 |
| commit | 69c2c4becc7a1b74c2d6a4b621bd9e908f7fd6a8 (patch) | |
| tree | 8a1baadeb82ba1d9475c1c8b09aebe43b1b6d314 /clang/lib/CodeGen | |
| parent | 7d2019f9b3dfd49584d4f59bd76ed6a6e117068e (diff) | |
| download | bcm5719-llvm-69c2c4becc7a1b74c2d6a4b621bd9e908f7fd6a8.tar.gz bcm5719-llvm-69c2c4becc7a1b74c2d6a4b621bd9e908f7fd6a8.zip | |
When binding a reference to a temporary, it's important that other temporaries created as on the RHS are destroyed before emitting the dtor for the temporary.
llvm-svn: 84451
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 01a057f6745..01fb766dfb0 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -78,24 +78,18 @@ RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E, RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E, QualType DestType, bool IsInitializer) { + bool ShouldDestroyTemporaries = false; + unsigned OldNumLiveTemporaries = 0; + if (const CXXExprWithTemporaries *TE = dyn_cast<CXXExprWithTemporaries>(E)) { - // If we shouldn't destroy the temporaries, just emit the - // child expression. - if (!TE->shouldDestroyTemporaries()) - return EmitReferenceBindingToExpr(TE->getSubExpr(), DestType, - IsInitializer); - - // Keep track of the current cleanup stack depth. - unsigned OldNumLiveTemporaries = LiveTemporaries.size(); - - RValue RV = EmitReferenceBindingToExpr(TE->getSubExpr(), DestType, - IsInitializer); - - // Pop temporaries. - while (LiveTemporaries.size() > OldNumLiveTemporaries) - PopCXXTemporary(); + ShouldDestroyTemporaries = TE->shouldDestroyTemporaries(); + + if (ShouldDestroyTemporaries) { + // Keep track of the current cleanup stack depth. + OldNumLiveTemporaries = LiveTemporaries.size(); + } - return RV; + E = TE->getSubExpr(); } RValue Val; @@ -105,6 +99,12 @@ RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E, if (LV.isSimple()) return RValue::get(LV.getAddress()); Val = EmitLoadOfLValue(LV, E->getType()); + + if (ShouldDestroyTemporaries) { + // Pop temporaries. + while (LiveTemporaries.size() > OldNumLiveTemporaries) + PopCXXTemporary(); + } } else { const CXXRecordDecl *BaseClassDecl = 0; const CXXRecordDecl *DerivedClassDecl = 0; @@ -124,6 +124,12 @@ RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E, Val = EmitAnyExprToTemp(E, /*IsAggLocVolatile=*/false, IsInitializer); + if (ShouldDestroyTemporaries) { + // Pop temporaries. + while (LiveTemporaries.size() > OldNumLiveTemporaries) + PopCXXTemporary(); + } + if (IsInitializer) { // We might have to destroy the temporary variable. if (const RecordType *RT = E->getType()->getAs<RecordType>()) { |

