summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-10-18 23:09:21 +0000
committerAnders Carlsson <andersca@mac.com>2009-10-18 23:09:21 +0000
commit69c2c4becc7a1b74c2d6a4b621bd9e908f7fd6a8 (patch)
tree8a1baadeb82ba1d9475c1c8b09aebe43b1b6d314 /clang/lib/CodeGen
parent7d2019f9b3dfd49584d4f59bd76ed6a6e117068e (diff)
downloadbcm5719-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.cpp38
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>()) {
OpenPOWER on IntegriCloud