From cb3b8b45b560f4f1e6bcdcacbfc459f1cb0f61ed Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Thu, 9 Apr 2015 22:50:07 +0000 Subject: [PATCH] [CodeGen] Do a more principled fix for PR231653, always use the inner type. 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 | 19 +++++++++---------- .../cxx0x-initializer-references.cpp | 15 ++++++++++++--- .../cxx0x-initializer-stdinitializerlist.cpp | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index dd66f6cc7a..4147317963 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -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); diff --git a/test/CodeGenCXX/cxx0x-initializer-references.cpp b/test/CodeGenCXX/cxx0x-initializer-references.cpp index bdc97b5bd5..318c8ea0d7 100644 --- a/test/CodeGenCXX/cxx0x-initializer-references.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-references.cpp @@ -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 ¶m) { } 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; +} } diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp index 1131ca9fa3..6d5d3971bd 100644 --- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -510,7 +510,7 @@ namespace B19773010 { void PR22940_helper(const pair&) { } void PR22940() { // CHECK-LABEL: @_ZN9B197730107PR22940Ev - // CHECK-NOT: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev( + // CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev( // CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE( PR22940_helper(pair()); } -- 2.50.1