[clang] 6ceb32a - [C++20] [Modules] Handle the linkage of defaulted friend function

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 6 23:35:00 PST 2023


Author: Chuanqi Xu
Date: 2023-03-07T15:34:33+08:00
New Revision: 6ceb32a66fb429b1e6880b723c4f0103f00e6dbd

URL: https://github.com/llvm/llvm-project/commit/6ceb32a66fb429b1e6880b723c4f0103f00e6dbd
DIFF: https://github.com/llvm/llvm-project/commit/6ceb32a66fb429b1e6880b723c4f0103f00e6dbd.diff

LOG: [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.

Added: 
    clang/test/Modules/pr61067.cppm

Modified: 
    clang/lib/AST/ASTContext.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index f226832966648..499009b54a04e 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<CXXMethodDecl>(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 0000000000000..8469a1db1f1c8
--- /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_(


        


More information about the cfe-commits mailing list