https://github.com/cjc0013 updated https://github.com/llvm/llvm-project/pull/219238
>From 26800608844f90546741ee69c9b1461ac87aed59 Mon Sep 17 00:00:00 2001 From: cjc0013 <[email protected]> Date: Thu, 27 Aug 2026 12:26:09 -0400 Subject: [PATCH 1/4] [clang] Disambiguate GMF internal functions across partitions --- clang/lib/AST/ItaniumMangle.cpp | 27 ++++++++++- ...lobal-module-fragment-internal-linkage.cpp | 46 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 clang/test/Modules/global-module-fragment-internal-linkage.cpp diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 7fb162a68fe88..b172f1a302f0a 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1110,9 +1110,34 @@ void CXXNameMangler::mangleNameWithAbiTags( } void CXXNameMangler::mangleModuleName(const NamedDecl *ND) { - if (ND->isExternallyVisible()) + if (ND->isExternallyVisible()) { if (Module *M = ND->getOwningModuleForLinkage()) mangleModuleNamePrefix(M->getPrimaryModuleInterfaceName()); + return; + } + + // A function with internal linkage in a global module fragment denotes a + // different entity in every module unit. When definitions from multiple + // imported units are emitted into one translation unit, their ordinary + // internal-linkage names would otherwise collide. + const auto *FD = dyn_cast<FunctionDecl>(ND); + Module *M = ND->getOwningModule(); + if (!FD || FD->getFormalLinkage() != Linkage::Internal || !M || + !M->isGlobalModule() || !M->Parent || + !M->Parent->isNamedModuleUnit()) + return; + + M = M->Parent; + if (!M->isModulePartition()) { + mangleModuleNamePrefix(M->Name); + return; + } + + auto [PrimaryName, PartitionName] = StringRef(M->Name).rsplit(':'); + assert(!PrimaryName.empty() && !PartitionName.empty() && + "invalid module partition name"); + mangleModuleNamePrefix(PrimaryName); + mangleModuleNamePrefix(PartitionName, /*IsPartition=*/true); } // <module-name> ::= <module-subname> diff --git a/clang/test/Modules/global-module-fragment-internal-linkage.cpp b/clang/test/Modules/global-module-fragment-internal-linkage.cpp new file mode 100644 index 0000000000000..5298015d92abe --- /dev/null +++ b/clang/test/Modules/global-module-fragment-internal-linkage.cpp @@ -0,0 +1,46 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ +// RUN: -emit-module-interface %t/part1.cppm -o %t/A-Part1.pcm +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ +// RUN: -emit-module-interface %t/part2.cppm -o %t/A-Part2.pcm +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ +// RUN: -emit-module-interface %t/A.cppm \ +// RUN: -fmodule-file=%t/A-Part1.pcm -fmodule-file=%t/A-Part2.pcm \ +// RUN: -o %t/A.pcm +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-llvm -o - \ +// RUN: %t/use.cpp -fmodule-file=%t/A.pcm \ +// RUN: -fmodule-file=%t/A-Part1.pcm -fmodule-file=%t/A-Part2.pcm \ +// RUN: | FileCheck %s +// +// Two internal functions with the same ordinary mangled name must remain +// distinct when their global module fragments are imported together. +// CHECK-DAG: define internal {{.*}} @_ZLW1AWP5Part16helperv() +// CHECK-DAG: define internal {{.*}} @_ZLW1AWP5Part26helperv() +// CHECK-DAG: call {{.*}} @_ZLW1AWP5Part16helperv() +// CHECK-DAG: call {{.*}} @_ZLW1AWP5Part26helperv() +// CHECK-DAG: ret i32 1 +// CHECK-DAG: ret i32 2 + +//--- part1.cppm +module; +static inline __attribute__((noinline)) int helper() { return 1; } +export module A:Part1; +export inline int part1() { return helper(); } + +//--- part2.cppm +module; +static inline __attribute__((noinline)) int helper() { return 2; } +export module A:Part2; +export inline int part2() { return helper(); } + +//--- A.cppm +export module A; +export import :Part1; +export import :Part2; + +//--- use.cpp +import A; +int use() { return part1() + part2(); } >From 0571efbe9495ecfc070b5aab9d75e9d8d0e9c034 Mon Sep 17 00:00:00 2001 From: cjc0013 <[email protected]> Date: Thu, 27 Aug 2026 19:45:26 -0400 Subject: [PATCH 2/4] [clang] Distinguish GMF internal functions across module units --- clang/lib/Serialization/ASTReaderDecl.cpp | 27 ++++++++++++++++--- ...lobal-module-fragment-internal-linkage.cpp | 22 ++++++++------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 74e0106520011..0ff0472aacccb 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3584,12 +3584,31 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { } ASTContext &C = Reader.getContext(); + auto IsSameEntity = [&](NamedDecl *Existing) { + if (!C.isSameEntity(Existing, D)) + return false; + + auto *FD = dyn_cast<FunctionDecl>(D); + auto *ExistingFD = dyn_cast<FunctionDecl>(Existing); + if (!FD || !ExistingFD || + FD->getFormalLinkage() != Linkage::Internal || + ExistingFD->getFormalLinkage() != Linkage::Internal) + return true; + + Module *M = FD->getOwningModule(); + Module *ExistingM = ExistingFD->getOwningModule(); + if (!M || !ExistingM || !M->isGlobalModule() || + !ExistingM->isGlobalModule()) + return true; + + return M->getTopLevelModule() == ExistingM->getTopLevelModule(); + }; DeclContext *DC = D->getDeclContext()->getRedeclContext(); if (TypedefNameForLinkage) { auto It = Reader.ImportedTypedefNamesForLinkage.find( std::make_pair(DC, TypedefNameForLinkage)); if (It != Reader.ImportedTypedefNamesForLinkage.end()) - if (C.isSameEntity(It->second, D)) + if (IsSameEntity(It->second)) return FindExistingResult(Reader, D, It->second, AnonymousDeclNumber, TypedefNameForLinkage); // Go on to check in other places in case an existing typedef name @@ -3601,7 +3620,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { // in its context by number. if (auto *Existing = getAnonymousDeclForMerging( Reader, D->getLexicalDeclContext(), AnonymousDeclNumber)) - if (C.isSameEntity(Existing, D)) + if (IsSameEntity(Existing)) return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, TypedefNameForLinkage); } else if (DC->isTranslationUnit() && @@ -3635,7 +3654,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage, /*FilteringUsingShadowDecl=*/false)) - if (C.isSameEntity(Existing, D)) + if (IsSameEntity(Existing)) return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, TypedefNameForLinkage); } @@ -3644,7 +3663,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) { if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage, !isa<UsingShadowDecl>(D))) - if (C.isSameEntity(Existing, D)) { + if (IsSameEntity(Existing)) { return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, TypedefNameForLinkage); } diff --git a/clang/test/Modules/global-module-fragment-internal-linkage.cpp b/clang/test/Modules/global-module-fragment-internal-linkage.cpp index 5298015d92abe..c9fa548ddf6dd 100644 --- a/clang/test/Modules/global-module-fragment-internal-linkage.cpp +++ b/clang/test/Modules/global-module-fragment-internal-linkage.cpp @@ -8,21 +8,23 @@ // RUN: -emit-module-interface %t/part2.cppm -o %t/A-Part2.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ // RUN: -emit-module-interface %t/A.cppm \ -// RUN: -fmodule-file=%t/A-Part1.pcm -fmodule-file=%t/A-Part2.pcm \ +// RUN: -fmodule-file=A:Part1=%t/A-Part1.pcm \ +// RUN: -fmodule-file=A:Part2=%t/A-Part2.pcm \ // RUN: -o %t/A.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-llvm -o - \ // RUN: %t/use.cpp -fmodule-file=%t/A.pcm \ -// RUN: -fmodule-file=%t/A-Part1.pcm -fmodule-file=%t/A-Part2.pcm \ +// RUN: -fmodule-file=A:Part1=%t/A-Part1.pcm \ +// RUN: -fmodule-file=A:Part2=%t/A-Part2.pcm \ // RUN: | FileCheck %s // -// Two internal functions with the same ordinary mangled name must remain -// distinct when their global module fragments are imported together. -// CHECK-DAG: define internal {{.*}} @_ZLW1AWP5Part16helperv() -// CHECK-DAG: define internal {{.*}} @_ZLW1AWP5Part26helperv() -// CHECK-DAG: call {{.*}} @_ZLW1AWP5Part16helperv() -// CHECK-DAG: call {{.*}} @_ZLW1AWP5Part26helperv() +// Identical internal functions from the same textual header must remain +// distinct when separate global module fragments are imported together. +// CHECK-DAG: define internal {{.*}} @_ZW1AWP5Part1L6helperv() +// CHECK-DAG: define internal {{.*}} @_ZW1AWP5Part2L6helperv() +// CHECK-DAG: call {{.*}} @_ZW1AWP5Part1L6helperv() +// CHECK-DAG: call {{.*}} @_ZW1AWP5Part2L6helperv() +// CHECK-DAG: ret i32 1 // CHECK-DAG: ret i32 1 -// CHECK-DAG: ret i32 2 //--- part1.cppm module; @@ -32,7 +34,7 @@ export inline int part1() { return helper(); } //--- part2.cppm module; -static inline __attribute__((noinline)) int helper() { return 2; } +static inline __attribute__((noinline)) int helper() { return 1; } export module A:Part2; export inline int part2() { return helper(); } >From 6e2137b2fa175dc25aa52ac635d260fa061870c3 Mon Sep 17 00:00:00 2001 From: cjc0013 <[email protected]> Date: Mon, 31 Aug 2026 13:15:13 -0400 Subject: [PATCH 3/4] [clang] Address GMF disambiguation review feedback --- clang/docs/StandardCPlusPlusModules.md | 7 +++++ clang/lib/AST/ItaniumMangle.cpp | 7 +++++ clang/lib/Serialization/ASTReaderDecl.cpp | 3 +++ ...lobal-module-fragment-internal-linkage.cpp | 26 +++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/clang/docs/StandardCPlusPlusModules.md b/clang/docs/StandardCPlusPlusModules.md index e9a1c332fe8a2..99df4b6416dc0 100644 --- a/clang/docs/StandardCPlusPlusModules.md +++ b/clang/docs/StandardCPlusPlusModules.md @@ -498,6 +498,13 @@ fragment is disabled by default. These checks can be enabled by specifying and you encounter incorrect or missing diagnostics, please report them via the [community issue tracker](https://github.com/llvm/llvm-project/issues/). +When global module fragment ODR checking is skipped, Clang also keeps +internal-linkage functions from different named module units distinct and +includes the module-unit owner in their mangled names. This is a practical, +non-conforming strategy for C-style `static inline` functions in real-world +headers. `-Xclang -fno-skip-odr-check-in-gmf` restores the ordinary +internal-linkage identity and mangling. + ### Privacy Issue BMIs are not and should not be treated as an information hiding mechanism. diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index b172f1a302f0a..58fd1c339fc9b 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1116,6 +1116,13 @@ void CXXNameMangler::mangleModuleName(const NamedDecl *ND) { return; } + // FIXME: Giving a TU-local entity a module-qualified name is not + // standard-conforming. This is Clang's practical strategy for real-world + // headers when GMF ODR checking is skipped; users can restore the ordinary + // internal-linkage mangling with -fno-skip-odr-check-in-gmf. + if (!getASTContext().getLangOpts().SkipODRCheckInGMF) + return; + // A function with internal linkage in a global module fragment denotes a // different entity in every module unit. When definitions from multiple // imported units are emitted into one translation unit, their ordinary diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 0ff0472aacccb..f1012c2cb0154 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3588,6 +3588,9 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { if (!C.isSameEntity(Existing, D)) return false; + if (!C.getLangOpts().SkipODRCheckInGMF) + return true; + auto *FD = dyn_cast<FunctionDecl>(D); auto *ExistingFD = dyn_cast<FunctionDecl>(Existing); if (!FD || !ExistingFD || diff --git a/clang/test/Modules/global-module-fragment-internal-linkage.cpp b/clang/test/Modules/global-module-fragment-internal-linkage.cpp index c9fa548ddf6dd..a06106a49b191 100644 --- a/clang/test/Modules/global-module-fragment-internal-linkage.cpp +++ b/clang/test/Modules/global-module-fragment-internal-linkage.cpp @@ -3,20 +3,43 @@ // RUN: split-file %s %t // // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ +// RUN: -fskip-odr-check-in-gmf \ // RUN: -emit-module-interface %t/part1.cppm -o %t/A-Part1.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ +// RUN: -fskip-odr-check-in-gmf \ // RUN: -emit-module-interface %t/part2.cppm -o %t/A-Part2.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ +// RUN: -fskip-odr-check-in-gmf \ // RUN: -emit-module-interface %t/A.cppm \ // RUN: -fmodule-file=A:Part1=%t/A-Part1.pcm \ // RUN: -fmodule-file=A:Part2=%t/A-Part2.pcm \ // RUN: -o %t/A.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-llvm -o - \ +// RUN: -fskip-odr-check-in-gmf \ // RUN: %t/use.cpp -fmodule-file=%t/A.pcm \ // RUN: -fmodule-file=A:Part1=%t/A-Part1.pcm \ // RUN: -fmodule-file=A:Part2=%t/A-Part2.pcm \ // RUN: | FileCheck %s // +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ +// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -emit-module-interface %t/part1.cppm -o %t/no-A-Part1.pcm +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ +// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -emit-module-interface %t/part2.cppm -o %t/no-A-Part2.pcm +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ +// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -emit-module-interface %t/A.cppm \ +// RUN: -fmodule-file=A:Part1=%t/no-A-Part1.pcm \ +// RUN: -fmodule-file=A:Part2=%t/no-A-Part2.pcm \ +// RUN: -o %t/no-A.pcm +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-llvm -o - \ +// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: %t/use.cpp -fmodule-file=%t/no-A.pcm \ +// RUN: -fmodule-file=A:Part1=%t/no-A-Part1.pcm \ +// RUN: -fmodule-file=A:Part2=%t/no-A-Part2.pcm \ +// RUN: | FileCheck %s --check-prefix=NO-DISAMBIGUATION +// // Identical internal functions from the same textual header must remain // distinct when separate global module fragments are imported together. // CHECK-DAG: define internal {{.*}} @_ZW1AWP5Part1L6helperv() @@ -26,6 +49,9 @@ // CHECK-DAG: ret i32 1 // CHECK-DAG: ret i32 1 +// NO-DISAMBIGUATION: define internal {{.*}} @_ZL6helperv() +// NO-DISAMBIGUATION-NOT: @_ZW1AWP5Part + //--- part1.cppm module; static inline __attribute__((noinline)) int helper() { return 1; } >From a7c1f633477822bf8b2e278a0ec0e66aa59ef755 Mon Sep 17 00:00:00 2001 From: cjc0013 <[email protected]> Date: Tue, 1 Sep 2026 11:01:39 -0400 Subject: [PATCH 4/4] [clang] Separate GMF identity from ODR checking --- clang/docs/StandardCPlusPlusModules.md | 15 ++++++------ clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Options/Options.td | 11 +++++++++ clang/lib/AST/ItaniumMangle.cpp | 6 ++--- clang/lib/Serialization/ASTReaderDecl.cpp | 4 ++-- ...lobal-module-fragment-internal-linkage.cpp | 24 ++++++++++++------- 6 files changed, 41 insertions(+), 20 deletions(-) diff --git a/clang/docs/StandardCPlusPlusModules.md b/clang/docs/StandardCPlusPlusModules.md index 99df4b6416dc0..f3741e42a3955 100644 --- a/clang/docs/StandardCPlusPlusModules.md +++ b/clang/docs/StandardCPlusPlusModules.md @@ -498,13 +498,6 @@ fragment is disabled by default. These checks can be enabled by specifying and you encounter incorrect or missing diagnostics, please report them via the [community issue tracker](https://github.com/llvm/llvm-project/issues/). -When global module fragment ODR checking is skipped, Clang also keeps -internal-linkage functions from different named module units distinct and -includes the module-unit owner in their mangled names. This is a practical, -non-conforming strategy for C-style `static inline` functions in real-world -headers. `-Xclang -fno-skip-odr-check-in-gmf` restores the ordinary -internal-linkage identity and mangling. - ### Privacy Issue BMIs are not and should not be treated as an information hiding mechanism. @@ -521,6 +514,14 @@ the Itanium C++ ABI are covered. The declarations in a module unit which are not in the global module fragment have new linkage names. +By default, Clang also keeps internal-linkage functions from global module +fragments in different named module units distinct and includes the +module-unit owner in their mangled names. This is a practical, non-conforming +strategy for C-style `static inline` functions in real-world headers. Specify +`-Xclang -fno-modules-unique-gmf-internal-linkage` to restore the ordinary +internal-linkage identity and mangling. This behavior is independent of +whether global module fragment ODR checking is enabled. + For example, ```c++ diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index ad993ce7e5d95..a6db47518eb92 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -158,6 +158,7 @@ LANGOPT(Modules , 1, 0, NotCompatible, "modules semantics") LANGOPT(ClangModules , 1, 0, Compatible, "Clang header modules") LANGOPT(CPlusPlusModules , 1, 0, Compatible, "C++ modules syntax") LANGOPT(SkipODRCheckInGMF , 1, 0, NotCompatible, "Skip ODR checks for decls in the global module fragment") +LANGOPT(ModulesUniqueGMFInternalLinkage, 1, 1, NotCompatible, "Use unique internal linkage for functions in global module fragments") LANGOPT(BuiltinHeadersInSystemModules, 1, 0, NotCompatible, "builtin headers belong to system modules, and _Builtin_ modules are ignored for cstdlib headers") ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 3, CMK_None, Benign, "compiling a module interface") diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 3b88dce9c822b..b08e3099f8ccd 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -3733,6 +3733,17 @@ defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf", "Perform ODR checks for decls in the global module fragment.">>, Group<f_Group>; +defm modules_unique_gmf_internal_linkage : BoolOption<"f", + "modules-unique-gmf-internal-linkage", + LangOpts<"ModulesUniqueGMFInternalLinkage">, DefaultTrue, + PosFlag<SetTrue, [], [CC1Option], + "Use distinct internal-linkage identities for functions in global " + "module fragments.">, + NegFlag<SetFalse, [], [CC1Option], + "Use ordinary internal-linkage identities for functions in global " + "module fragments.">>, + Group<f_Group>; + defm modules_reduced_bmi : BoolOption<"f", "modules-reduced-bmi", FrontendOpts<"GenReducedBMI">, DefaultFalse, NegFlag<SetFalse>, diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index fb725dac727ef..cea17f6b82b6d 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1119,9 +1119,9 @@ void CXXNameMangler::mangleModuleName(const NamedDecl *ND) { // FIXME: Giving a TU-local entity a module-qualified name is not // standard-conforming. This is Clang's practical strategy for real-world - // headers when GMF ODR checking is skipped; users can restore the ordinary - // internal-linkage mangling with -fno-skip-odr-check-in-gmf. - if (!getASTContext().getLangOpts().SkipODRCheckInGMF) + // headers; users can restore the ordinary internal-linkage mangling with + // -fno-modules-unique-gmf-internal-linkage. + if (!getASTContext().getLangOpts().ModulesUniqueGMFInternalLinkage) return; // A function with internal linkage in a global module fragment denotes a diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 82a2837e8b30d..9d05ebd465edd 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3590,7 +3590,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { if (!C.isSameEntity(Existing, D)) return false; - if (!C.getLangOpts().SkipODRCheckInGMF) + if (!C.getLangOpts().ModulesUniqueGMFInternalLinkage) return true; auto *FD = dyn_cast<FunctionDecl>(D); @@ -3606,7 +3606,7 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { !ExistingM->isGlobalModule()) return true; - return M->getTopLevelModule() == ExistingM->getTopLevelModule(); + return false; }; DeclContext *DC = D->getDeclContext()->getRedeclContext(); if (TypedefNameForLinkage) { diff --git a/clang/test/Modules/global-module-fragment-internal-linkage.cpp b/clang/test/Modules/global-module-fragment-internal-linkage.cpp index a06106a49b191..0c90f4c7288e2 100644 --- a/clang/test/Modules/global-module-fragment-internal-linkage.cpp +++ b/clang/test/Modules/global-module-fragment-internal-linkage.cpp @@ -3,38 +3,46 @@ // RUN: split-file %s %t // // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ -// RUN: -fskip-odr-check-in-gmf \ +// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -fmodules-unique-gmf-internal-linkage \ // RUN: -emit-module-interface %t/part1.cppm -o %t/A-Part1.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ -// RUN: -fskip-odr-check-in-gmf \ +// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -fmodules-unique-gmf-internal-linkage \ // RUN: -emit-module-interface %t/part2.cppm -o %t/A-Part2.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ -// RUN: -fskip-odr-check-in-gmf \ +// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -fmodules-unique-gmf-internal-linkage \ // RUN: -emit-module-interface %t/A.cppm \ // RUN: -fmodule-file=A:Part1=%t/A-Part1.pcm \ // RUN: -fmodule-file=A:Part2=%t/A-Part2.pcm \ // RUN: -o %t/A.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-llvm -o - \ -// RUN: -fskip-odr-check-in-gmf \ +// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -fmodules-unique-gmf-internal-linkage \ // RUN: %t/use.cpp -fmodule-file=%t/A.pcm \ // RUN: -fmodule-file=A:Part1=%t/A-Part1.pcm \ // RUN: -fmodule-file=A:Part2=%t/A-Part2.pcm \ // RUN: | FileCheck %s // // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ -// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -fskip-odr-check-in-gmf \ +// RUN: -fno-modules-unique-gmf-internal-linkage \ // RUN: -emit-module-interface %t/part1.cppm -o %t/no-A-Part1.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ -// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -fskip-odr-check-in-gmf \ +// RUN: -fno-modules-unique-gmf-internal-linkage \ // RUN: -emit-module-interface %t/part2.cppm -o %t/no-A-Part2.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \ -// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -fskip-odr-check-in-gmf \ +// RUN: -fno-modules-unique-gmf-internal-linkage \ // RUN: -emit-module-interface %t/A.cppm \ // RUN: -fmodule-file=A:Part1=%t/no-A-Part1.pcm \ // RUN: -fmodule-file=A:Part2=%t/no-A-Part2.pcm \ // RUN: -o %t/no-A.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-llvm -o - \ -// RUN: -fno-skip-odr-check-in-gmf \ +// RUN: -fskip-odr-check-in-gmf \ +// RUN: -fno-modules-unique-gmf-internal-linkage \ // RUN: %t/use.cpp -fmodule-file=%t/no-A.pcm \ // RUN: -fmodule-file=A:Part1=%t/no-A-Part1.pcm \ // RUN: -fmodule-file=A:Part2=%t/no-A-Part2.pcm \ _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
