diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1625,22 +1625,20 @@ Module *NewM = New->getOwningModule(); Module *OldM = Old->getOwningModule(); - if (NewM && NewM->Kind == Module::PrivateModuleFragment) + if (NewM && NewM->isPrivateModule()) NewM = NewM->Parent; - if (OldM && OldM->Kind == Module::PrivateModuleFragment) + if (OldM && OldM->isPrivateModule()) OldM = OldM->Parent; - // If we have a decl in a module partition, it is part of the containing - // module (which is the only thing that can be importing it). - if (NewM && OldM && - (OldM->Kind == Module::ModulePartitionInterface || - OldM->Kind == Module::ModulePartitionImplementation)) { - return false; - } - if (NewM == OldM) return false; + // Partitions are part of the module, but a partition could import another + // module, so verify that the PMIs agree. + if (NewM && OldM && (NewM->isModulePartition() || OldM->isModulePartition())) + return NewM->getPrimaryModuleInterfaceName() == + OldM->getPrimaryModuleInterfaceName(); + bool NewIsModuleInterface = NewM && NewM->isModulePurview(); bool OldIsModuleInterface = OldM && OldM->isModulePurview(); if (NewIsModuleInterface || OldIsModuleInterface) { diff --git a/clang/test/Modules/cxx20-partition-redeclarations.cpp b/clang/test/Modules/cxx20-partition-redeclarations.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Modules/cxx20-partition-redeclarations.cpp @@ -0,0 +1,55 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: cd %t + +// RUN: %clang_cc1 -std=c++20 A-intf-part.cpp -emit-module-interface \ +// RUN: -o A-PubPart.pcm +// RUN: %clang_cc1 -std=c++20 A-interface.cpp -emit-module-interface \ +// RUN: -fmodule-file=A-PubPart.pcm -o A.pcm + +// RUN: %clang_cc1 -std=c++20 A-impl-top.cpp -fsyntax-only -fmodule-file=A.pcm +// RUN: %clang_cc1 -std=c++20 A-impl-part.cpp -fsyntax-only -fmodule-file=A.pcm +// RUN: %clang_cc1 -std=c++20 A-impl-1.cpp -fsyntax-only -fmodule-file=A.pcm +// RUN: %clang_cc1 -std=c++20 A-impl-2.cpp -fsyntax-only -fmodule-file=A.pcm + +//--- A-interface.cpp +export module A; + +export import :PubPart; + +export void do_something(); + +void helper1(); +void helper3(); + +//--- A-intf-part.cpp +export module A:PubPart; + +void helper2(); + +//--- A-impl-top.cpp + +module A; + +void do_something() { + helper1(); + helper2(); + helper3(); +} + +//--- A-impl-part.cpp +module A:Secret; + +import A; + +void helper3() {} + +//--- A-impl-1.cpp +module A; + +void helper1() {} + +//--- A-impl-2.cpp +module A; + +void helper2() {}