Author: Chuanqi Xu Date: 2025-12-03T10:29:52+08:00 New Revision: 93ebe63f2e7a252038bde01a4399c14e0123cdac
URL: https://github.com/llvm/llvm-project/commit/93ebe63f2e7a252038bde01a4399c14e0123cdac DIFF: https://github.com/llvm/llvm-project/commit/93ebe63f2e7a252038bde01a4399c14e0123cdac.diff LOG: [C++20] [Modules] Fix ADL for friend in modules Close https://github.com/llvm/llvm-project/issues/170235 The cause of the issue is it didn't check friendness for decls in ordinary namespace if it isn't visible. It is fine for code before modules, since everything is visible. But it is not true after modules came in. This patch adjusts this. Note that this doesn't change the control flow for non-modules codes, as the decls in ordinary namespace is always visible then it won't never fall in following friendness check. Added: clang/test/Modules/pr170235.cppm Modified: clang/lib/Sema/SemaLookup.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 5915d6e57d893..b9fac5a4a1153 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3927,7 +3927,8 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc, break; } - if (!getLangOpts().CPlusPlusModules) + if (!D->getOwningModule() || + !D->getOwningModule()->getTopLevelModule()->isNamedModule()) continue; if (D->isInExportDeclContext()) { @@ -3959,7 +3960,9 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc, break; } } - } else if (D->getFriendObjectKind()) { + } + + if (D->getFriendObjectKind()) { auto *RD = cast<CXXRecordDecl>(D->getLexicalDeclContext()); // [basic.lookup.argdep]p4: // Argument-dependent lookup finds all declarations of functions and diff --git a/clang/test/Modules/pr170235.cppm b/clang/test/Modules/pr170235.cppm new file mode 100644 index 0000000000000..614c3abce3d61 --- /dev/null +++ b/clang/test/Modules/pr170235.cppm @@ -0,0 +1,32 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -std=c++20 %t/lib.cppm -emit-module-interface -o %t/lib.pcm +// RUN: %clang_cc1 -std=c++20 %t/main.cpp -fmodule-file=lib=%t/lib.pcm -fsyntax-only -verify +// +// RUN: %clang_cc1 -std=c++20 %t/lib.cppm -emit-reduced-module-interface -o %t/lib.pcm +// RUN: %clang_cc1 -std=c++20 %t/main.cpp -fmodule-file=lib=%t/lib.pcm -fsyntax-only -verify + +//--- lib.cppm +export module lib; +namespace lib { + struct A; + // Definition comes BEFORE the class declaration + int foo(const A &, int) { return 42; } + + struct A { + // Friend declaration inside the class + friend int foo(const A &, int); + }; + + export A a{}; +} +//--- main.cpp +// expected-no-diagnostics +import lib; +int main() { + // Should be found via ADL since lib::a is of type lib::A + auto res1 = foo(lib::a, 1); + return 0; +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
