Author: nico Date: Wed Apr 15 18:04:24 2015 New Revision: 235053 URL: http://llvm.org/viewvc/llvm-project?rev=235053&view=rev Log: Don't crash when a selectany symbol would get common linkage
Things can't both be in comdats and have common linkage, so never give things in comdats common linkage. Common linkage is only used in .c files, and the only thing that can trigger a comdat in c is selectany from what I can tell. Fixes PR23243. Also address an over-the-shoulder review comment from rnk by moving the hasAttr<SelectAnyAttr>() in Decl.cpp around a bit. It only makes a minor difference for selectany on global variables, so it goes well with the rest of this patch. http://reviews.llvm.org/D9042 Modified: cfe/trunk/lib/AST/Decl.cpp cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/test/CodeGen/ms-declspecs.c cfe/trunk/test/CodeGen/ms-declspecs.cpp Modified: cfe/trunk/lib/AST/Decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=235053&r1=235052&r2=235053&view=diff ============================================================================== --- cfe/trunk/lib/AST/Decl.cpp (original) +++ cfe/trunk/lib/AST/Decl.cpp Wed Apr 15 18:04:24 2015 @@ -1915,7 +1915,7 @@ VarDecl::isThisDeclarationADefinition(AS 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(AS 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: Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=235053&r1=235052&r2=235053&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Apr 15 18:04:24 2015 @@ -2134,7 +2134,8 @@ void CodeGenModule::EmitGlobalVarDefinit } 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(co 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 CodeGenM // 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; Modified: cfe/trunk/test/CodeGen/ms-declspecs.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-declspecs.c?rev=235053&r1=235052&r2=235053&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/ms-declspecs.c (original) +++ cfe/trunk/test/CodeGen/ms-declspecs.c Wed Apr 15 18:04:24 2015 @@ -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; Modified: cfe/trunk/test/CodeGen/ms-declspecs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-declspecs.cpp?rev=235053&r1=235052&r2=235053&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/ms-declspecs.cpp (original) +++ cfe/trunk/test/CodeGen/ms-declspecs.cpp Wed Apr 15 18:04:24 2015 @@ -7,7 +7,9 @@ extern "C++" __declspec(selectany) int x 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 _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
