]> granicus.if.org Git - clang/commitdiff
[CodeGen] Do a more principled fix for PR231653, always use the inner type.
authorBenjamin Kramer <benny.kra@googlemail.com>
Thu, 9 Apr 2015 22:50:07 +0000 (22:50 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Thu, 9 Apr 2015 22:50:07 +0000 (22:50 +0000)
We were still using the MaterializeTemporaryExpr's type to check if the
transform is legal. Always use the inner Expr type.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234543 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
test/CodeGenCXX/cxx0x-initializer-references.cpp
test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp

index dd66f6cc7a103ff7b1837664c5188db32e40810e..4147317963b13153c049183804ef82b66ddde1a5 100644 (file)
@@ -300,27 +300,26 @@ createReferenceTemporary(CodeGenFunction &CGF,
                          const MaterializeTemporaryExpr *M, const Expr *Inner) {
   switch (M->getStorageDuration()) {
   case SD_FullExpression:
-  case SD_Automatic:
+  case SD_Automatic: {
     // If we have a constant temporary array or record try to promote it into a
     // constant global under the same rules a normal constant would've been
     // promoted. This is easier on the optimizer and generally emits fewer
     // instructions.
+    QualType Ty = Inner->getType();
     if (CGF.CGM.getCodeGenOpts().MergeAllConstants &&
-        (M->getType()->isArrayType() || M->getType()->isRecordType()) &&
-        CGF.CGM.isTypeConstant(M->getType(), true))
-      if (llvm::Constant *Init =
-              CGF.CGM.EmitConstantExpr(Inner, Inner->getType(), &CGF)) {
+        (Ty->isArrayType() || Ty->isRecordType()) &&
+        CGF.CGM.isTypeConstant(Ty, true))
+      if (llvm::Constant *Init = CGF.CGM.EmitConstantExpr(Inner, Ty, &CGF)) {
         auto *GV = new llvm::GlobalVariable(
             CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
             llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp");
-        GV->setAlignment(CGF.getContext()
-                             .getTypeAlignInChars(Inner->getType())
-                             .getQuantity());
+        GV->setAlignment(
+            CGF.getContext().getTypeAlignInChars(Ty).getQuantity());
         // FIXME: Should we put the new global into a COMDAT?
         return GV;
       }
-    return CGF.CreateMemTemp(Inner->getType(), "ref.tmp");
-
+    return CGF.CreateMemTemp(Ty, "ref.tmp");
+  }
   case SD_Thread:
   case SD_Static:
     return CGF.CGM.GetAddrOfGlobalTemporary(M, Inner);
index bdc97b5bd5018fbc8bdb498512234996c93a4440..318c8ea0d77039fdffcd230e852fdb87a5c7c80e 100644 (file)
@@ -1,7 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: private constant { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN7PR2316510ChildClassE, i64 0, i64 2) }, align 4
-
 namespace reference {
   struct A {
     int i1, i2;
@@ -96,7 +94,18 @@ void helper(const AbstractClass &param) {
 }
 
 void foo() {
-// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE(%{{.*}} bitcast ({ i8** }* @{{.*}} to %{{.*}}*))
+// CHECK-LABEL: @_ZN7PR231653fooEv
+// CHECK: call {{.*}} @_ZN7PR2316510ChildClassC1Ev
+// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE
   helper(ChildClass());
 }
+
+struct S { struct T { int a; } t; mutable int b; };
+void f() {
+// CHECK-LABEL: _ZN7PR231651fEv
+// CHECK: alloca
+// CHECK: alloca
+// CHECK: store
+  const S::T &r = S().t;
+}
 }
index 1131ca9fa31c67705563ea59bf937d57bba7f836..6d5d3971bd7434d4d9064bde9b0a9d6f647ddedd 100644 (file)
@@ -510,7 +510,7 @@ namespace B19773010 {
   void PR22940_helper(const pair<void*, int>&) { }
   void PR22940() {
     // CHECK-LABEL: @_ZN9B197730107PR22940Ev
-    // CHECK-NOT: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev(
+    // CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev(
     // CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE(
     PR22940_helper(pair<void*, int>());
   }