Author: Chuanqi Xu Date: 2022-01-26T10:54:52+08:00 New Revision: 5c1f7b296ac0dddeca02891976e6ab5cfc006719
URL: https://github.com/llvm/llvm-project/commit/5c1f7b296ac0dddeca02891976e6ab5cfc006719 DIFF: https://github.com/llvm/llvm-project/commit/5c1f7b296ac0dddeca02891976e6ab5cfc006719.diff LOG: [C++20] [Modules] Only check decls under namespace scope in CheckRedeclarationExported Since only the decls inhabit in a namespace scope could be exported, it is not meaningful to check it in CheckRedeclarationExported, which implements [module.interface]/p6. Reviewed By: urnathan Differential Revision: https://reviews.llvm.org/D118120 Added: Modified: clang/lib/Sema/SemaDecl.cpp clang/test/CXX/module/module.interface/p6.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 673631a12eee0..7c5f6b318e973 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1635,6 +1635,19 @@ bool Sema::CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old) { // A redeclaration of an entity X is implicitly exported if X was introduced by // an exported declaration; otherwise it shall not be exported. bool Sema::CheckRedeclarationExported(NamedDecl *New, NamedDecl *Old) { + // [module.interface]p1: + // An export-declaration shall inhabit a namespace scope. + // + // So it is meaningless to talk about redeclaration which is not at namespace + // scope. + if (!New->getLexicalDeclContext() + ->getNonTransparentContext() + ->isFileContext() || + !Old->getLexicalDeclContext() + ->getNonTransparentContext() + ->isFileContext()) + return false; + bool IsNewExported = New->isInExportDeclContext(); bool IsOldExported = Old->isInExportDeclContext(); diff --git a/clang/test/CXX/module/module.interface/p6.cpp b/clang/test/CXX/module/module.interface/p6.cpp index a696851ccbff4..070aa62f5800a 100644 --- a/clang/test/CXX/module/module.interface/p6.cpp +++ b/clang/test/CXX/module/module.interface/p6.cpp @@ -91,3 +91,24 @@ template <typename T> T TemplVar; // expected-note {{previous declaration is here}} export template <typename T> T TemplVar; // expected-error {{cannot export redeclaration 'TemplVar' here since the previous declaration is not exported}} + +// Test the compiler wouldn't complain about the redeclaration of friend in exported class. +namespace Friend { +template <typename T> +class bar; +class gua; +template <typename T> +void hello(); +void hi(); +export class foo; +bool operator<(const foo &a, const foo &b); +export class foo { + template <typename T> + friend class bar; + friend class gua; + template <typename T> + friend void hello(); + friend void hi(); + friend bool operator<(const foo &a, const foo &b); +}; +} // namespace Friend _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits