[clang] 3e78fa8 - [C++20] [Modules] Profile TemplateName by canonical decl

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 13 23:35:30 PDT 2023


Author: Chuanqi Xu
Date: 2023-03-14T14:34:44+08:00
New Revision: 3e78fa860235431323aaf08c8fa922d75a7cfffa

URL: https://github.com/llvm/llvm-project/commit/3e78fa860235431323aaf08c8fa922d75a7cfffa
DIFF: https://github.com/llvm/llvm-project/commit/3e78fa860235431323aaf08c8fa922d75a7cfffa.diff

LOG: [C++20] [Modules] Profile TemplateName by canonical decl

Close https://github.com/llvm/llvm-project/issues/61317

The root cause of the problem is that we profile TemplateName by the
non-canonical decls so that the compiler thought they are two different
types. But this is not true. We fixed the issue after we profile the
template name by using the same name.

Added: 
    clang/test/Modules/pr61317.cppm

Modified: 
    clang/include/clang/AST/TemplateName.h
    clang/lib/AST/TemplateName.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h
index 2f108ea00726e..d56361b500596 100644
--- a/clang/include/clang/AST/TemplateName.h
+++ b/clang/include/clang/AST/TemplateName.h
@@ -351,9 +351,7 @@ class TemplateName {
   /// error.
   void dump() const;
 
-  void Profile(llvm::FoldingSetNodeID &ID) {
-    ID.AddPointer(Storage.getOpaqueValue());
-  }
+  void Profile(llvm::FoldingSetNodeID &ID);
 
   /// Retrieve the template name as a void pointer.
   void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }

diff  --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp
index a6dd0fad93314..76f507ba26fe4 100644
--- a/clang/lib/AST/TemplateName.cpp
+++ b/clang/lib/AST/TemplateName.cpp
@@ -281,6 +281,13 @@ bool TemplateName::containsUnexpandedParameterPack() const {
   return getDependence() & TemplateNameDependence::UnexpandedPack;
 }
 
+void TemplateName::Profile(llvm::FoldingSetNodeID &ID) {
+  if (auto *TD = getAsTemplateDecl())
+    ID.AddPointer(TD->getCanonicalDecl());
+  else
+    ID.AddPointer(Storage.getOpaqueValue());
+}
+
 void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
                          Qualified Qual) const {
   auto Kind = getKind();

diff  --git a/clang/test/Modules/pr61317.cppm b/clang/test/Modules/pr61317.cppm
new file mode 100644
index 0000000000000..4b9c1a3e97eab
--- /dev/null
+++ b/clang/test/Modules/pr61317.cppm
@@ -0,0 +1,49 @@
+// From https://github.com/llvm/llvm-project/issues/61317
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
+// RUN: %clang_cc1 -std=c++20 %t/B.cppm -emit-module-interface -o %t/B.pcm \
+// RUN:     -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/Use.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
+
+//--- foo.h
+#ifndef _FOO
+#define _FOO
+
+template <typename T> struct Foo {
+  Foo(T) {}
+};
+
+template <typename T> Foo(T&) -> Foo<T>;
+
+struct Bar {
+  template <typename T>
+    requires requires { Foo{T()}; }
+  void baz() const {}
+};
+
+#endif
+
+//--- A.cppm
+module;
+#include "foo.h"
+export module A;
+export using ::Foo;
+export using ::Bar;
+
+//--- B.cppm
+module;
+#include "foo.h"
+export module B;
+export import A;
+
+//--- Use.cpp
+// expected-no-diagnostics
+import A;
+import B;
+void use() {
+  Bar _; 
+  _.baz<int>();
+}


        


More information about the cfe-commits mailing list