r178939 - <rdar://problem/13325066> Destroy std::initializer_list temporaries whose lifetime has been extended by reference binding.
Douglas Gregor
dgregor at apple.com
Fri Apr 5 17:46:21 PDT 2013
Author: dgregor
Date: Fri Apr 5 19:46:20 2013
New Revision: 178939
URL: http://llvm.org/viewvc/llvm-project?rev=178939&view=rev
Log:
<rdar://problem/13325066> Destroy std::initializer_list temporaries whose lifetime has been extended by reference binding.
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=178939&r1=178938&r2=178939&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Apr 5 19:46:20 2013
@@ -201,6 +201,7 @@ static llvm::Value *
EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
llvm::Value *&ReferenceTemporary,
const CXXDestructorDecl *&ReferenceTemporaryDtor,
+ const InitListExpr *&ReferenceInitializerList,
QualType &ObjCARCReferenceLifetimeType,
const NamedDecl *InitializedDecl) {
const MaterializeTemporaryExpr *M = NULL;
@@ -222,6 +223,7 @@ EmitExprForReferenceBinding(CodeGenFunct
return EmitExprForReferenceBinding(CGF, EWC->getSubExpr(),
ReferenceTemporary,
ReferenceTemporaryDtor,
+ ReferenceInitializerList,
ObjCARCReferenceLifetimeType,
InitializedDecl);
}
@@ -314,9 +316,14 @@ EmitExprForReferenceBinding(CodeGenFunct
}
if (InitializedDecl) {
- // Get the destructor for the reference temporary.
- if (const RecordType *RT =
- E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
+ if (const InitListExpr *ILE = dyn_cast<InitListExpr>(E)) {
+ if (ILE->initializesStdInitializerList()) {
+ ReferenceInitializerList = ILE;
+ }
+ }
+ else if (const RecordType *RT =
+ E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()){
+ // Get the destructor for the reference temporary.
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
if (!ClassDecl->hasTrivialDestructor())
ReferenceTemporaryDtor = ClassDecl->getDestructor();
@@ -396,9 +403,11 @@ CodeGenFunction::EmitReferenceBindingToE
const NamedDecl *InitializedDecl) {
llvm::Value *ReferenceTemporary = 0;
const CXXDestructorDecl *ReferenceTemporaryDtor = 0;
+ const InitListExpr *ReferenceInitializerList = 0;
QualType ObjCARCReferenceLifetimeType;
llvm::Value *Value = EmitExprForReferenceBinding(*this, E, ReferenceTemporary,
ReferenceTemporaryDtor,
+ ReferenceInitializerList,
ObjCARCReferenceLifetimeType,
InitializedDecl);
if (SanitizePerformTypeCheck && !E->getType()->isFunctionType()) {
@@ -410,7 +419,8 @@ CodeGenFunction::EmitReferenceBindingToE
QualType Ty = E->getType();
EmitTypeCheck(TCK_ReferenceBinding, E->getExprLoc(), Value, Ty);
}
- if (!ReferenceTemporaryDtor && ObjCARCReferenceLifetimeType.isNull())
+ if (!ReferenceTemporaryDtor && !ReferenceInitializerList &&
+ ObjCARCReferenceLifetimeType.isNull())
return RValue::get(Value);
// Make sure to call the destructor for the reference temporary.
@@ -430,6 +440,9 @@ CodeGenFunction::EmitReferenceBindingToE
CleanupArg = cast<llvm::Constant>(ReferenceTemporary);
}
CGM.getCXXABI().registerGlobalDtor(*this, CleanupFn, CleanupArg);
+ } else if (ReferenceInitializerList) {
+ EmitStdInitializerListCleanup(ReferenceTemporary,
+ ReferenceInitializerList);
} else {
assert(!ObjCARCReferenceLifetimeType.isNull());
// Note: We intentionally do not register a global "destructor" to
@@ -445,6 +458,9 @@ CodeGenFunction::EmitReferenceBindingToE
destroyCXXObject, getLangOpts().Exceptions);
else
PushDestructorCleanup(ReferenceTemporaryDtor, ReferenceTemporary);
+ } else if (ReferenceInitializerList) {
+ EmitStdInitializerListCleanup(ReferenceTemporary,
+ ReferenceInitializerList);
} else {
switch (ObjCARCReferenceLifetimeType.getObjCLifetime()) {
case Qualifiers::OCL_None:
Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=178939&r1=178938&r2=178939&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp Fri Apr 5 19:46:20 2013
@@ -250,3 +250,22 @@ namespace PR12178 {
map m{ {1, 2}, {3, 4} };
}
+
+namespace rdar13325066 {
+ struct X { ~X(); };
+
+ // CHECK: define void @_ZN12rdar133250664loopERNS_1XES1_
+ void loop(X &x1, X &x2) {
+ // CHECK: br label
+ // CHECK: br i1
+ // CHECK: br label
+ // CHECK call void @_ZN12rdar133250661XD1Ev
+ // CHECK: br label
+ // CHECK: br label
+ // CHECK: call void @_ZN12rdar133250661XD1Ev
+ // CHECK: br i1
+ // CHECK: br label
+ // CHECK: ret void
+ for (X x : { x1, x2 }) { }
+ }
+}
More information about the cfe-commits
mailing list