Correctly destroy reference temporaries with global storage. Remove ErrorUnsupported call when binding a global reference to a non-lvalue. Fixes PR7326.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106983 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 0d5369d..2bda5ad 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -308,9 +308,9 @@
           // the object we're binding to.
           QualType T = Adjustment.Field.Field->getType().getNonReferenceType()
                                                         .getUnqualifiedType();
-          Object = CGF.CreateTempAlloca(CGF.ConvertType(T), "lv");
-          LValue TempLV = 
-            LValue::MakeAddr(Object, Qualifiers::fromCVRMask(CVR));
+          Object = CreateReferenceTemporary(CGF, T, InitializedDecl);
+          LValue TempLV = LValue::MakeAddr(Object, 
+                                           Qualifiers::fromCVRMask(CVR));
           CGF.EmitStoreThroughLValue(CGF.EmitLoadOfLValue(LV, T), TempLV, T);
           break;
         }
@@ -348,20 +348,34 @@
                                                    ReferenceTemporaryDtor,
                                                    InitializedDecl);
 
+  if (!ReferenceTemporaryDtor)
+    return RValue::get(Value);
+  
   // Make sure to call the destructor for the reference temporary.
-  if (ReferenceTemporaryDtor) {
+  if (const VarDecl *VD = dyn_cast_or_null<VarDecl>(InitializedDecl)) {
+    if (VD->hasGlobalStorage()) {
+      llvm::Constant *DtorFn = 
+        CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete);
+      CGF.EmitCXXGlobalDtorRegistration(DtorFn, 
+                                      cast<llvm::Constant>(ReferenceTemporary));
+      
+      return RValue::get(Value);
+    }
+  }
+  
+  {
     DelayedCleanupBlock Scope(*this);
     EmitCXXDestructorCall(ReferenceTemporaryDtor, Dtor_Complete, 
                           /*ForVirtualBase=*/false, ReferenceTemporary);
             
     // Make sure to jump to the exit block.
     EmitBranch(Scope.getCleanupExitBlock());
+  }
 
-    if (Exceptions) {
-      EHCleanupBlock Cleanup(*this);
-      EmitCXXDestructorCall(ReferenceTemporaryDtor, Dtor_Complete, 
-                            /*ForVirtualBase=*/false, ReferenceTemporary);
-    }
+  if (Exceptions) {
+    EHCleanupBlock Cleanup(*this);
+    EmitCXXDestructorCall(ReferenceTemporaryDtor, Dtor_Complete, 
+                          /*ForVirtualBase=*/false, ReferenceTemporary);
   }
 
   return RValue::get(Value);