Author: Chuanqi Xu Date: 2025-02-05T14:13:18+08:00 New Revision: c5a9a72b3cd118a23193d01bf9393fbf1d4b90ae
URL: https://github.com/llvm/llvm-project/commit/c5a9a72b3cd118a23193d01bf9393fbf1d4b90ae DIFF: https://github.com/llvm/llvm-project/commit/c5a9a72b3cd118a23193d01bf9393fbf1d4b90ae.diff LOG: [C++20] [Modules] Don't diagnose duplicated friend declarations between modules incorrectly Close https://github.com/llvm/llvm-project/issues/125521 We shouldn't use the ownership information for friend declarations to do anything. Added: clang/test/Modules/pr125521.cppm Modified: clang/lib/AST/ASTContext.cpp clang/lib/Serialization/ASTReaderDecl.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f3aedbc39d12aeb..de617860b70040b 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1055,7 +1055,8 @@ void ASTContext::PrintStats() const { void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M, bool NotifyListeners) { if (NotifyListeners) - if (auto *Listener = getASTMutationListener()) + if (auto *Listener = getASTMutationListener(); + Listener && !ND->isUnconditionallyVisible()) Listener->RedefinedHiddenDefinition(ND, M); MergedDefModules[cast<NamedDecl>(ND->getCanonicalDecl())].push_back(M); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 8210eb2143acf56..1aa94d5a22abe28 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3746,6 +3746,11 @@ void ASTDeclReader::checkMultipleDefinitionInNamedModules(ASTReader &Reader, Func && Func->getTemplateSpecializationInfo()) return; + // The module ownership of in-class friend declaration is not straightforward. + // Avoid diagnosing such cases. + if (D->getFriendObjectKind() || Previous->getFriendObjectKind()) + return; + Module *M = Previous->getOwningModule(); if (!M) return; diff --git a/clang/test/Modules/pr125521.cppm b/clang/test/Modules/pr125521.cppm new file mode 100644 index 000000000000000..d064cdfe3eb73bb --- /dev/null +++ b/clang/test/Modules/pr125521.cppm @@ -0,0 +1,57 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/mod2.cppm -emit-module-interface -o %t/mod2.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod1.cppm -emit-module-interface -o %t/mod1.pcm \ +// RUN: -fmodule-file=Mod2=%t/mod2.pcm +// RUN: %clang_cc1 -std=c++20 %t/test.cc -fmodule-file=Mod2=%t/mod2.pcm -fmodule-file=Mod=%t/mod1.pcm \ +// RUN: -fsyntax-only -verify + +// RUN: %clang_cc1 -std=c++20 %t/mod2.cppm -emit-module-interface -o %t/mod2.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod1.cppm -emit-module-interface -o %t/mod1.pcm \ +// RUN: -fmodule-file=Mod2=%t/mod2.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod1.pcm -fmodule-file=Mod2=%t/mod2.pcm -emit-llvm -o - \ +// RUN: | FileCheck %t/mod1.cppm + +//--- hello.h +template <typename V> int get() noexcept {return 0;}; + +template <typename T> +class List +{ + template <typename V> friend int get() noexcept; +}; + +//--- mod2.cppm +module; +#include "hello.h" +export module Mod2; +export const char *modFn2() { + List<int> a; + return "hello"; +} + +//--- mod1.cppm +module; +#include "hello.h" +export module Mod; +import Mod2; +export extern "C" const char *modFn() { + List<int> a; + List<double> b; + return modFn2(); +} + +// Fine enough to check it won't crash. +// CHECK: define {{.*}}@modFn + +//--- test.cc +// expected-no-diagnostics +import Mod; +import Mod2; + +void test() { + modFn(); + modFn2(); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits