ChuanqiXu created this revision. ChuanqiXu added reviewers: rsmith, aaron.ballman, urnathan, hubert.reinterpretcast, erichkeane. ChuanqiXu added a project: clang. ChuanqiXu requested review of this revision. Herald added a subscriber: cfe-commits.
According to https://eel.is/c++draft/basic.namespace.general#2, a namespace declaration shouldn't have a module linkage. Further more, without this patch, the compiler would crash for the test in assertion enabled build due to inconsistent linkage for redeclaration for namespaces. Test Plan: check-all Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D115132 Files: clang/lib/AST/Decl.cpp clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.cppm clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.h clang/test/CXX/basic/basic.namespace/basic.namespace.general/p2.cppm Index: clang/test/CXX/basic/basic.namespace/basic.namespace.general/p2.cppm =================================================================== --- /dev/null +++ clang/test/CXX/basic/basic.namespace/basic.namespace.general/p2.cppm @@ -0,0 +1,14 @@ +// Check that the compiler wouldn't crash due to inconsistent namesapce linkage +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: %clang -std=c++20 %S/Inputs/p2.cppm --precompile -o %t/Y.pcm +// RUN: %clang -std=c++20 -fprebuilt-module-path=%t -I%S/Inputs %s -c -Xclang -verify +// expected-no-diagnostics +export module X; +import Y; + +export namespace foo { +namespace bar{ + void baz(); +} +} Index: clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.h =================================================================== --- /dev/null +++ clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.h @@ -0,0 +1,7 @@ +#ifndef P2_H +#define P2_H +namespace foo { +namespace bar { +} +} // namespace foo +#endif Index: clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.cppm =================================================================== --- /dev/null +++ clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.cppm @@ -0,0 +1,7 @@ +module; +#include "p2.h" +export module Y; +export namespace foo { +// We need to export something at least +void print(); +} Index: clang/lib/AST/Decl.cpp =================================================================== --- clang/lib/AST/Decl.cpp +++ clang/lib/AST/Decl.cpp @@ -604,8 +604,14 @@ // - A name declared at namespace scope that does not have internal linkage // by the previous rules and that is introduced by a non-exported // declaration has module linkage. - if (isInModulePurview(D) && !isExportedFromModuleInterfaceUnit( - cast<NamedDecl>(D->getCanonicalDecl()))) + // + // [basic.namespace.general]/p2 + // A namespace is never attached to a named module and never has a name with + // module linkage. + if (isInModulePurview(D) && + !isExportedFromModuleInterfaceUnit( + cast<NamedDecl>(D->getCanonicalDecl())) && + !isa<NamespaceDecl>(D)) return LinkageInfo(ModuleLinkage, DefaultVisibility, false); return LinkageInfo::external();
Index: clang/test/CXX/basic/basic.namespace/basic.namespace.general/p2.cppm =================================================================== --- /dev/null +++ clang/test/CXX/basic/basic.namespace/basic.namespace.general/p2.cppm @@ -0,0 +1,14 @@ +// Check that the compiler wouldn't crash due to inconsistent namesapce linkage +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: %clang -std=c++20 %S/Inputs/p2.cppm --precompile -o %t/Y.pcm +// RUN: %clang -std=c++20 -fprebuilt-module-path=%t -I%S/Inputs %s -c -Xclang -verify +// expected-no-diagnostics +export module X; +import Y; + +export namespace foo { +namespace bar{ + void baz(); +} +} Index: clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.h =================================================================== --- /dev/null +++ clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.h @@ -0,0 +1,7 @@ +#ifndef P2_H +#define P2_H +namespace foo { +namespace bar { +} +} // namespace foo +#endif Index: clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.cppm =================================================================== --- /dev/null +++ clang/test/CXX/basic/basic.namespace/basic.namespace.general/Inputs/p2.cppm @@ -0,0 +1,7 @@ +module; +#include "p2.h" +export module Y; +export namespace foo { +// We need to export something at least +void print(); +} Index: clang/lib/AST/Decl.cpp =================================================================== --- clang/lib/AST/Decl.cpp +++ clang/lib/AST/Decl.cpp @@ -604,8 +604,14 @@ // - A name declared at namespace scope that does not have internal linkage // by the previous rules and that is introduced by a non-exported // declaration has module linkage. - if (isInModulePurview(D) && !isExportedFromModuleInterfaceUnit( - cast<NamedDecl>(D->getCanonicalDecl()))) + // + // [basic.namespace.general]/p2 + // A namespace is never attached to a named module and never has a name with + // module linkage. + if (isInModulePurview(D) && + !isExportedFromModuleInterfaceUnit( + cast<NamedDecl>(D->getCanonicalDecl())) && + !isa<NamespaceDecl>(D)) return LinkageInfo(ModuleLinkage, DefaultVisibility, false); return LinkageInfo::external();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits