Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -1915,7 +1915,7 @@ if (hasInit()) return Definition; - if (hasAttr()) + if (hasAttr() || hasAttr()) return Definition; // A variable template specialization (other than a static data member @@ -1925,14 +1925,14 @@ getTemplateSpecializationKind() != TSK_ExplicitSpecialization) return DeclarationOnly; - if (!hasAttr() && 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() && isSingleLineLanguageLinkage(*this)) + if (isSingleLineLanguageLinkage(*this)) return DeclarationOnly; // C99 6.9.2p2: Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -2134,7 +2134,8 @@ } 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()) && !D->hasAttr()) @@ -2159,6 +2160,10 @@ if (D->hasAttr()) 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 @@ // C++ doesn't have tentative definitions and thus cannot have common // linkage. if (!getLangOpts().CPlusPlus && isa(D) && - !isVarDeclStrongDefinition(Context, cast(D), + !isVarDeclStrongDefinition(Context, *this, cast(D), CodeGenOpts.NoCommon)) return llvm::GlobalVariable::CommonLinkage; Index: test/CodeGen/ms-declspecs.c =================================================================== --- test/CodeGen/ms-declspecs.c +++ test/CodeGen/ms-declspecs.c @@ -6,8 +6,10 @@ // 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; Index: test/CodeGen/ms-declspecs.cpp =================================================================== --- test/CodeGen/ms-declspecs.cpp +++ test/CodeGen/ms-declspecs.cpp @@ -7,7 +7,9 @@ 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