<rdar://problem/13325066> Destroy std::initializer_list temporaries whose lifetime has been extended by reference binding.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178939 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 2f5186d..a0dd158 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -201,6 +201,7 @@
 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 @@
     return EmitExprForReferenceBinding(CGF, EWC->getSubExpr(), 
                                        ReferenceTemporary, 
                                        ReferenceTemporaryDtor,
+                                       ReferenceInitializerList,
                                        ObjCARCReferenceLifetimeType,
                                        InitializedDecl);
   }
@@ -314,9 +316,14 @@
     }
     
     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 @@
                                             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 @@
     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 @@
         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 @@
                   destroyCXXObject, getLangOpts().Exceptions);
     else
       PushDestructorCleanup(ReferenceTemporaryDtor, ReferenceTemporary);
+  } else if (ReferenceInitializerList) {
+    EmitStdInitializerListCleanup(ReferenceTemporary,
+                                  ReferenceInitializerList);
   } else {
     switch (ObjCARCReferenceLifetimeType.getObjCLifetime()) {
     case Qualifiers::OCL_None: