From: Richard Smith Date: Tue, 22 Nov 2011 22:48:32 +0000 (+0000) Subject: Use static storage duration for file-scope compound literals, even when they X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7401cf524cdb7aad4951d8727d280f8b271af5a2;p=clang Use static storage duration for file-scope compound literals, even when they appear in non-constant initializers in C++. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145087 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index a35bb5f711..e4f81b7a3f 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1947,6 +1947,11 @@ CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value *BaseValue, } LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){ + if (E->isFileScope()) { + llvm::Value *GlobalPtr = CGM.GetAddrOfConstantCompoundLiteral(E); + return MakeAddrLValue(GlobalPtr, E->getType()); + } + llvm::Value *DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral"); const Expr *InitExpr = E->getInitializer(); LValue Result = MakeAddrLValue(DeclPtr, E->getType()); diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 7485c71d7d..5d436619d7 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -1087,6 +1087,12 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E, return C; } +llvm::Constant * +CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) { + assert(E->isFileScope() && "not a file-scope compound literal expr"); + return ConstExprEmitter(*this, 0).EmitLValue(E); +} + static uint64_t getFieldOffset(ASTContext &C, const FieldDecl *field) { const ASTRecordLayout &layout = C.getASTRecordLayout(field->getParent()); return layout.getFieldOffset(field->getFieldIndex()); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 7b82819af3..4c31737b29 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -599,6 +599,10 @@ public: llvm::Constant *GetAddrOfConstantCString(const std::string &str, const char *GlobalName=0, unsigned Alignment=1); + + /// GetAddrOfConstantCompoundLiteral - Returns a pointer to a constant global + /// variable for the given file-scope compound literal expression. + llvm::Constant *GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E); /// \brief Retrieve the record type that describes the state of an /// Objective-C fast enumeration loop (for..in). diff --git a/test/CodeGenCXX/compound-literals.cpp b/test/CodeGenCXX/compound-literals.cpp index f520ff9951..aa9ae3cacf 100644 --- a/test/CodeGenCXX/compound-literals.cpp +++ b/test/CodeGenCXX/compound-literals.cpp @@ -37,3 +37,8 @@ int g() { // CHECK-NEXT: ret i32 [[A0]] return v[0]; } + +struct Z { int i[3]; }; +int *p = (Z){ {1, 2, 3} }.i; +// CHECK: define {{.*}}__cxx_global_var_init() +// CHECK: store i32* getelementptr inbounds (%struct.Z* @.compoundliteral, i32 0, i32 0, i32 0), i32** @p, align 8