From 6ceb32a66fb429b1e6880b723c4f0103f00e6dbd Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Tue, 7 Mar 2023 15:16:23 +0800 Subject: [PATCH] [C++20] [Modules] Handle the linkage of defaulted friend function definition correctly Close https://github.com/llvm/llvm-project/issues/61067 Previously we will only handle the defaulted member functions as discardable ODR. But we need to handle defaulted friend function in this way too. Otherwise we may run into the problems the above issue report mentions. --- clang/lib/AST/ASTContext.cpp | 5 ++--- clang/test/Modules/pr61067.cppm | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 clang/test/Modules/pr61067.cppm diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f226832..499009b 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -11625,9 +11625,8 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, // Non-user-provided functions get emitted as weak definitions with every // use, no matter whether they've been explicitly instantiated etc. - if (const auto *MD = dyn_cast(FD)) - if (!MD->isUserProvided()) - return GVA_DiscardableODR; + if (!FD->isUserProvided()) + return GVA_DiscardableODR; GVALinkage External; switch (FD->getTemplateSpecializationKind()) { diff --git a/clang/test/Modules/pr61067.cppm b/clang/test/Modules/pr61067.cppm new file mode 100644 index 0000000..8469a1d --- /dev/null +++ b/clang/test/Modules/pr61067.cppm @@ -0,0 +1,40 @@ +// From https://github.com/llvm/llvm-project/issues/61067 +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.cppm \ +// RUN: -emit-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/b.cppm \ +// RUN: -emit-module-interface -fmodule-file=a=%t/a.pcm -o %t/b.pcm +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/b.pcm -S \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %t/b.cppm +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/c.cpp -fmodule-file=a=%t/a.pcm \ +// RUN: -S -emit-llvm -disable-llvm-passes -o - | FileCheck %t/c.cpp + +//--- a.cppm +export module a; + +export struct a { + friend bool operator==(a, a) = default; +}; + +//--- b.cppm +export module b; + +import a; + +void b() { + (void)(a() == a()); +} + +// CHECK: define{{.*}}linkonce_odr{{.*}}@_ZW1aeqS_1aS0_( + +//--- c.cpp +import a; + +int c() { + (void)(a() == a()); +} + +// CHECK: define{{.*}}linkonce_odr{{.*}}@_ZW1aeqS_1aS0_( -- 2.7.4