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>(); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits