diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/Decl.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 9 | ||||
| -rw-r--r-- | clang/test/CodeGen/ms-declspecs.c | 4 | ||||
| -rw-r--r-- | clang/test/CodeGen/ms-declspecs.cpp | 2 |
4 files changed, 15 insertions, 6 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 1cdc24e65fc..628c9b053ea 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1915,7 +1915,7 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const { if (hasInit()) return Definition; - if (hasAttr<AliasAttr>()) + if (hasAttr<AliasAttr>() || hasAttr<SelectAnyAttr>()) return Definition; // A variable template specialization (other than a static data member @@ -1925,14 +1925,14 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const { getTemplateSpecializationKind() != TSK_ExplicitSpecialization) return DeclarationOnly; - if (!hasAttr<SelectAnyAttr>() && hasExternalStorage()) + if (hasExternalStorage()) return DeclarationOnly; // [dcl.link] p7: // A declaration directly contained in a linkage-specification is treated // as if it contains the extern specifier for the purpose of determining // the linkage of the declared name and whether it is a definition. - if (!hasAttr<SelectAnyAttr>() && isSingleLineLanguageLinkage(*this)) + if (isSingleLineLanguageLinkage(*this)) return DeclarationOnly; // C99 6.9.2p2: diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index f60a68ab011..17b7ddc7683 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2134,7 +2134,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { } static bool isVarDeclStrongDefinition(const ASTContext &Context, - const VarDecl *D, bool NoCommon) { + CodeGenModule &CGM, const VarDecl *D, + bool NoCommon) { // Don't give variables common linkage if -fno-common was specified unless it // was overridden by a NoCommon attribute. if ((NoCommon || D->hasAttr<NoCommonAttr>()) && !D->hasAttr<CommonAttr>()) @@ -2159,6 +2160,10 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context, if (D->hasAttr<WeakImportAttr>()) return true; + // A variable cannot be both common and exist in a comdat. + if (shouldBeInCOMDAT(CGM, *D)) + return true; + // Declarations with a required alignment do not have common linakge in MSVC // mode. if (Context.getLangOpts().MSVCCompat) { @@ -2227,7 +2232,7 @@ llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator( // C++ doesn't have tentative definitions and thus cannot have common // linkage. if (!getLangOpts().CPlusPlus && isa<VarDecl>(D) && - !isVarDeclStrongDefinition(Context, cast<VarDecl>(D), + !isVarDeclStrongDefinition(Context, *this, cast<VarDecl>(D), CodeGenOpts.NoCommon)) return llvm::GlobalVariable::CommonLinkage; diff --git a/clang/test/CodeGen/ms-declspecs.c b/clang/test/CodeGen/ms-declspecs.c index 985c227faa3..c32733e65ff 100644 --- a/clang/test/CodeGen/ms-declspecs.c +++ b/clang/test/CodeGen/ms-declspecs.c @@ -6,8 +6,10 @@ const __declspec(selectany) int x2 = 2; // CHECK: @x2 = weak_odr constant i32 2, comdat, align 4 // selectany turns extern variable declarations into definitions. -extern __declspec(selectany) int x3; +__declspec(selectany) int x3; +extern __declspec(selectany) int x4; // CHECK: @x3 = weak_odr global i32 0, comdat, align 4 +// CHECK: @x4 = weak_odr global i32 0, comdat, align 4 struct __declspec(align(16)) S { char x; diff --git a/clang/test/CodeGen/ms-declspecs.cpp b/clang/test/CodeGen/ms-declspecs.cpp index f77c7cb8916..decf5d6fcb2 100644 --- a/clang/test/CodeGen/ms-declspecs.cpp +++ b/clang/test/CodeGen/ms-declspecs.cpp @@ -7,7 +7,9 @@ extern "C++" __declspec(selectany) int x3; extern "C" { __declspec(selectany) int x4; } +__declspec(selectany) int x5; // CHECK: @"\01?x1@@3HA" = weak_odr global i32 0, comdat, align 4 // CHECK: @x2 = weak_odr global i32 0, comdat, align 4 // CHECK: @"\01?x3@@3HA" = weak_odr global i32 0, comdat, align 4 // CHECK: @x4 = weak_odr global i32 0, comdat, align 4 +// CHECK: @"\01?x5@@3HA" = weak_odr global i32 0, comdat, align 4 |

