diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 760cf7fd805ccc..1bf959a35178a7 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1660,9 +1660,11 @@ bool Sema::CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old) { // 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(); + if (NewM && OldM && + (NewM->isModulePartition() || OldM->isModulePartition()) && + NewM->getPrimaryModuleInterfaceName() == + OldM->getPrimaryModuleInterfaceName()) + return false; bool NewIsModuleInterface = NewM && NewM->isModulePurview(); bool OldIsModuleInterface = OldM && OldM->isModulePurview(); diff --git a/clang/test/Modules/inconsistent-deduction-guide-linkage.cppm b/clang/test/Modules/inconsistent-deduction-guide-linkage.cppm new file mode 100644 index 00000000000000..abcbec07f97de0 --- /dev/null +++ b/clang/test/Modules/inconsistent-deduction-guide-linkage.cppm @@ -0,0 +1,49 @@ +// RUN: rm -fr %t +// RUN: mkdir %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/B.cppm -I%t -emit-module-interface -o %t/B.pcm +// RUN: %clang_cc1 -std=c++20 -fsyntax-only %t/A.cppm -I%t -fprebuilt-module-path=%t -verify +// +// RUN: %clang_cc1 -std=c++20 %t/D.cppm -I%t -emit-module-interface -o %t/D.pcm +// RUN: %clang_cc1 -std=c++20 -fsyntax-only %t/D-part.cppm -I%t -fprebuilt-module-path=%t -verify + +//--- A.cppm +module; +export module baz:A; +import B; +#include "C.h" + +//--- B.cppm +module; + +#include "C.h" +export module B; + +//--- C.h +namespace foo { + template struct bar { // expected-error {{declaration of 'bar' in module baz:A follows declaration in the global module}} // expected-note {{previous declaration is here}} + template bar(T, U); + }; + template bar(T, U) -> bar; // expected-error {{declaration of '' in module baz:A follows declaration in the global module}} // expected-note {{previous declaration is here}} +} + +//--- D.cppm +// Tests that it is still problematic if they are in one module. +module; +#include "E.h" +export module D; + +//--- D-part.cppm +export module D:part; +import D; +#include "E.h" + +//--- E.h +// another file for simpler diagnostics. +namespace foo { + template struct bar { // expected-error {{declaration of 'bar' in module D:part follows declaration in the global module}} // expected-note {{previous declaration is here}} + template bar(T, U); + }; + template bar(T, U) -> bar; // expected-error {{declaration of '' in module D:part follows declaration in the global module}} // expected-note {{previous declaration is here}} +}