From e78b86f3201ae5f09e2cf85bd6558f1d9b34de26 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 5 Aug 2009 05:20:29 +0000 Subject: [PATCH] weak globals that are const should get weak_odr linkage. add a fixme about C++ const. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78159 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 25 +++++++++++++++++++------ test/CodeGen/global-init.c | 16 ++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 95ce3e5d3a..df1781de9e 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -870,7 +870,15 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { } GV->setInitializer(Init); - GV->setConstant(D->getType().isConstant(Context)); + + // 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". + GV->setConstant(true); + } + GV->setAlignment(getContext().getDeclAlignInBytes(D)); // Set the llvm linkage type as appropriate. @@ -880,13 +888,18 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { GV->setLinkage(llvm::Function::DLLImportLinkage); else if (D->hasAttr()) GV->setLinkage(llvm::Function::DLLExportLinkage); - else if (D->hasAttr()) - GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage); - else if (!CompileOpts.NoCommon && + else if (D->hasAttr()) { + if (GV->isConstant()) + GV->setLinkage(llvm::GlobalVariable::WeakODRLinkage); + else + GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage); + } else if (!CompileOpts.NoCommon && !D->hasExternalStorage() && !D->getInit() && - !D->getAttr()) + !D->getAttr()) { GV->setLinkage(llvm::GlobalVariable::CommonLinkage); - else + // common vars aren't constant even if declared const. + GV->setConstant(false); + } else GV->setLinkage(llvm::GlobalVariable::ExternalLinkage); SetCommonAttributes(D, GV); diff --git a/test/CodeGen/global-init.c b/test/CodeGen/global-init.c index 2c4ccce5a6..2a4c77b1da 100644 --- a/test/CodeGen/global-init.c +++ b/test/CodeGen/global-init.c @@ -7,8 +7,24 @@ int a; int a = 242; // CHECK: @a = global i32 242 +// This should get normal weak linkage. +int c __attribute__((weak))= 0; +// CHECK: @c = weak global i32 0 + + + +// Since this is marked const, it should get weak_odr linkage, since all +// definitions have to be the same. +// CHECK: @d = weak_odr constant i32 0 +const int d __attribute__((weak))= 0; + + + +// NOTE: tentative definitions are processed at the end of the translation unit. + // This shouldn't be emitted as common because it has an explicit section. // rdar://7119244 int b __attribute__((section("foo"))); // CHECK: @b = global i32 0, section "foo" +