ChuanqiXu updated this revision to Diff 500046.
ChuanqiXu added a comment.

Address comments:

- Don't store the original trailing require clause. Trying to get the trailing 
require clause of the primary template function when ODR checking instead.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144626/new/

https://reviews.llvm.org/D144626

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/Modules/pr60890.cppm

Index: clang/test/Modules/pr60890.cppm
===================================================================
--- /dev/null
+++ clang/test/Modules/pr60890.cppm
@@ -0,0 +1,82 @@
+// https://github.com/llvm/llvm-project/issues/60890
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/a.cppm -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/b.cppm -fprebuilt-module-path=%t -o %t/b.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/c.cppm -fprebuilt-module-path=%t -o %t/c.pcm
+// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -S -emit-llvm -o -
+
+//--- a.cppm
+export module a;
+ 
+export template<typename T>
+struct a {
+	friend void aa(a x) requires(true) {}
+	void aaa() requires(true) {}
+};
+
+export template struct a<double>;
+
+export template<typename T>
+void foo(T) requires(true) {}
+
+export template void foo<double>(double);
+
+export template <typename T>
+class A {
+	friend void foo<>(A);
+};
+
+//--- b.cppm
+export module b;
+
+import a;
+
+void b() {
+    a<int> _;
+	a<double> __;
+}
+
+//--- c.cppm
+export module c;
+
+import a;
+
+struct c {
+	void f() const {
+		a<int> _;
+		aa(_);
+		_.aaa();
+
+		a<double> __;
+		aa(__);
+		__.aaa();
+
+		foo<int>(5);
+		foo<double>(3.0);
+		foo(A<int>());
+	}
+};
+
+//--- d.cpp
+// expected-no-diagnostics
+import a;
+import b;
+import c;
+
+void d() {
+	a<int> _;
+	aa(_);
+	_.aaa();
+
+	a<double> __;
+	aa(__);
+	__.aaa();
+
+	foo<int>(5);
+	foo<double>(3.0);
+	foo(A<int>());
+}
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -6683,8 +6683,28 @@
         return false;
     }
 
-    if (!isSameConstraintExpr(FuncX->getTrailingRequiresClause(),
-                              FuncY->getTrailingRequiresClause()))
+    // The trailing require clause of instantiated function may change during
+    // the semantic analysis. Trying to get the primary template function (if
+    // exists) to compare the primary trailing require clause.
+    auto TryToGetPrimaryTemplatedFunction =
+        [](const FunctionDecl *FD) -> const FunctionDecl * {
+      switch (FD->getTemplatedKind()) {
+      case FunctionDecl::TK_DependentNonTemplate:
+        return FD->getInstantiatedFromDecl();
+      case FunctionDecl::TK_FunctionTemplate:
+        return FD->getDescribedFunctionTemplate()->getTemplatedDecl();
+      case FunctionDecl::TK_MemberSpecialization:
+        return FD->getInstantiatedFromMemberFunction();
+      case FunctionDecl::TK_FunctionTemplateSpecialization:
+        return FD->getPrimaryTemplate()->getTemplatedDecl();
+      default:
+        return FD;
+      }
+    };
+    const FunctionDecl *PrimaryX = TryToGetPrimaryTemplatedFunction(FuncX);
+    const FunctionDecl *PrimaryY = TryToGetPrimaryTemplatedFunction(FuncY);
+    if (!isSameConstraintExpr(PrimaryX->getTrailingRequiresClause(),
+                              PrimaryY->getTrailingRequiresClause()))
       return false;
 
     auto GetTypeAsWritten = [](const FunctionDecl *FD) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to