From: Eli Friedman Date: Fri, 11 Dec 2009 21:23:03 +0000 (+0000) Subject: Fix for PR5714: make sure globals that will be modified aren't marked const. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=20e098b7e7fda6bed1d67441b56cce77cd3aa918;p=clang Fix for PR5714: make sure globals that will be modified aren't marked const. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91156 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 660dd6cc3e..1cfcfb1ab1 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -760,6 +760,17 @@ CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy, return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl()); } +static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D) { + if (!D->getType().isConstant(Context)) + return false; + if (Context.getLangOptions().CPlusPlus && + Context.getBaseElementType(D->getType())->getAs()) { + // FIXME: We should do something fancier here! + return false; + } + return true; +} + /// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module, /// create and return an llvm GlobalVariable with the specified type. If there /// is something in the module with the specified name, return it potentially @@ -803,7 +814,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName, if (D) { // FIXME: This code is overly simple and should be merged with other global // handling. - GV->setConstant(D->getType().isConstant(Context)); + GV->setConstant(DeclIsConstantGlobal(Context, D)); // FIXME: Merge with other attribute handling code. if (D->getStorageClass() == VarDecl::PrivateExtern) @@ -978,11 +989,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { // If it is safe to mark the global 'constant', do so now. GV->setConstant(false); - if (D->getType().isConstant(Context)) { - // FIXME: In C++, if the variable has a non-trivial ctor/dtor or any mutable - // members, it cannot be declared "LLVM const". + if (DeclIsConstantGlobal(Context, D)) GV->setConstant(true); - } GV->setAlignment(getContext().getDeclAlignInBytes(D)); diff --git a/test/CodeGenCXX/global-llvm-constant.cpp b/test/CodeGenCXX/global-llvm-constant.cpp new file mode 100644 index 0000000000..bd4319667e --- /dev/null +++ b/test/CodeGenCXX/global-llvm-constant.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm -o - %s | FileCheck %s + +struct A { + A() { x = 10; } + int x; +}; + +const A x; + +// CHECK: @x = internal global