[cfe-commits] r84451 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp test/CodeGenCXX/references.cpp
Anders Carlsson
andersca at mac.com
Sun Oct 18 16:09:22 PDT 2009
Author: andersca
Date: Sun Oct 18 18:09:21 2009
New Revision: 84451
URL: http://llvm.org/viewvc/llvm-project?rev=84451&view=rev
Log:
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.
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/test/CodeGenCXX/references.cpp
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=84451&r1=84450&r2=84451&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Oct 18 18:09:21 2009
@@ -78,24 +78,18 @@
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 @@
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 @@
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>()) {
Modified: cfe/trunk/test/CodeGenCXX/references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/references.cpp?rev=84451&r1=84450&r2=84451&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/references.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/references.cpp Sun Oct 18 18:09:21 2009
@@ -107,3 +107,26 @@
const C& c = D();
}
+namespace T {
+ struct A {
+ A();
+ ~A();
+ };
+
+ struct B {
+ B();
+ ~B();
+ A f();
+ };
+
+ void f() {
+ // CHECK: call void @_ZN1T1BC1Ev
+ // CHECK: call void @_ZN1T1B1fEv
+ // CHECK: call void @_ZN1T1BD1Ev
+ const A& a = B().f();
+ // CHECK: call void @_ZN1T1fEv
+ f();
+ // CHECK: call void @_ZN1T1AD1Ev
+ }
+}
+
More information about the cfe-commits
mailing list