diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 006063e21eb3d..0f4decc14579b 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -3043,7 +3043,7 @@ class ASTContext : public RefCountedBase { } GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const; - GVALinkage GetGVALinkageForVariable(const VarDecl *VD); + GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const; /// Determines if the decl can be CodeGen'ed or deserialized from PCH /// lazily, only when used; this is only relevant for function or file scoped diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a188837d4144c..a5f7f6a019f87 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -11764,7 +11764,7 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, llvm_unreachable("Invalid Linkage!"); } -GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { +GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) const { return adjustGVALinkageForExternalDefinitionKind(*this, VD, adjustGVALinkageForAttributes(*this, VD, basicGVALinkageForVariable(*this, VD))); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 9e1e58a7fa7e2..69d192612bccf 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1068,7 +1068,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { if (D->getStorageDuration() == SD_Static) { bool ModulesCodegen = false; if (Writer.WritingModule && - !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo()) { + !D->getDescribedVarTemplate()) { // When building a C++20 module interface unit or a partition unit, a // strong definition in the module interface is provided by the // compilation of that unit, not by its users. (Inline variables are still @@ -1077,7 +1077,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { (Writer.WritingModule->isInterfaceOrPartition() || (D->hasAttr() && Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) && - Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal; + Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal; } Record.push_back(ModulesCodegen); if (ModulesCodegen) @@ -2550,7 +2550,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { // compilation of that unit, not by its users. (Inline functions are still // emitted in module users.) Linkage = Writer->Context->GetGVALinkageForFunction(FD); - ModulesCodegen = *Linkage == GVA_StrongExternal; + ModulesCodegen = *Linkage >= GVA_StrongExternal; } if (Writer->Context->getLangOpts().ModulesCodegen || (FD->hasAttr() && diff --git a/clang/test/Modules/pr59780.cppm b/clang/test/Modules/pr59780.cppm index 9578325b976ba..d4bbd52c13f1a 100644 --- a/clang/test/Modules/pr59780.cppm +++ b/clang/test/Modules/pr59780.cppm @@ -33,8 +33,8 @@ struct Y { int Y::value = 0; -// CHECK-NOT: @_ZW1a1xIiE = {{.*}}available_externally{{.*}}global -// CHECK-NOT: @_ZNW1a1YIiE5valueE = {{.*}}available_externally{{.*}}global +// CHECK-NOT: @_ZW1a1xIiE = {{.*}}external{{.*}}global +// CHECK-NOT: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global //--- use.cpp import a; @@ -42,5 +42,5 @@ int foo() { return x + Y::value; } -// CHECK: @_ZW1a1xIiE = {{.*}}available_externally{{.*}}global -// CHECK: @_ZNW1a1YIiE5valueE = {{.*}}available_externally{{.*}}global +// CHECK: @_ZW1a1xIiE = {{.*}}external{{.*}}global +// CHECK: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global diff --git a/clang/test/Modules/pr60693.cppm b/clang/test/Modules/pr60693.cppm new file mode 100644 index 0000000000000..117a0f2753d0a --- /dev/null +++ b/clang/test/Modules/pr60693.cppm @@ -0,0 +1,54 @@ +// Address: https://github.com/llvm/llvm-project/issues/60693 +// +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.cppm -emit-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple -fmodule-file=a=%t/a.pcm %t/c.cpp -S -emit-llvm -disable-llvm-passes -o - | FileCheck %t/c.cpp + +//--- a.cppm +export module a; + +constexpr bool f() { + for (unsigned n = 0; n != 10; ++n) { + } + return true; +} + +export template +struct s { + static constexpr auto a = f(); + static constexpr auto b = f(); + static constexpr auto c = f(); + static constexpr auto d = f(); + int foo() { + return 43; + } + int bar() { + return 44; + } +}; + +template struct s; +template struct s; + +//--- c.cpp +import a; + +extern "C" int use() { + s _; + return _.a + _.b + _.c + _.d; +} + +extern "C" long use2() { + s _; + return _.foo(); +} + +// CHECK: define{{.*}}@use( +// CHECK-NOT: } +// CHECK: ret{{.*}} 4 + +// CHECK: declare{{.*}}@_ZNW1a1sIlE3fooEv +// CHECK-NOT: _ZNW1a1sIlE3barEv