Skip to content

Commit 3e78fa8

Browse files
committed
[C++20] [Modules] Profile TemplateName by canonical decl
Close #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.
1 parent 537e6e7 commit 3e78fa8

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

clang/include/clang/AST/TemplateName.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,9 +351,7 @@ class TemplateName {
351351
/// error.
352352
void dump() const;
353353

354-
void Profile(llvm::FoldingSetNodeID &ID) {
355-
ID.AddPointer(Storage.getOpaqueValue());
356-
}
354+
void Profile(llvm::FoldingSetNodeID &ID);
357355

358356
/// Retrieve the template name as a void pointer.
359357
void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }

clang/lib/AST/TemplateName.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,13 @@ bool TemplateName::containsUnexpandedParameterPack() const {
281281
return getDependence() & TemplateNameDependence::UnexpandedPack;
282282
}
283283

284+
void TemplateName::Profile(llvm::FoldingSetNodeID &ID) {
285+
if (auto *TD = getAsTemplateDecl())
286+
ID.AddPointer(TD->getCanonicalDecl());
287+
else
288+
ID.AddPointer(Storage.getOpaqueValue());
289+
}
290+
284291
void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
285292
Qualified Qual) const {
286293
auto Kind = getKind();

clang/test/Modules/pr61317.cppm

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// From https://github.com/llvm/llvm-project/issues/61317
2+
// RUN: rm -rf %t
3+
// RUN: mkdir -p %t
4+
// RUN: split-file %s %t
5+
//
6+
// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
7+
// RUN: %clang_cc1 -std=c++20 %t/B.cppm -emit-module-interface -o %t/B.pcm \
8+
// RUN: -fprebuilt-module-path=%t
9+
// RUN: %clang_cc1 -std=c++20 %t/Use.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
10+
11+
//--- foo.h
12+
#ifndef _FOO
13+
#define _FOO
14+
15+
template <typename T> struct Foo {
16+
Foo(T) {}
17+
};
18+
19+
template <typename T> Foo(T&) -> Foo<T>;
20+
21+
struct Bar {
22+
template <typename T>
23+
requires requires { Foo{T()}; }
24+
void baz() const {}
25+
};
26+
27+
#endif
28+
29+
//--- A.cppm
30+
module;
31+
#include "foo.h"
32+
export module A;
33+
export using ::Foo;
34+
export using ::Bar;
35+
36+
//--- B.cppm
37+
module;
38+
#include "foo.h"
39+
export module B;
40+
export import A;
41+
42+
//--- Use.cpp
43+
// expected-no-diagnostics
44+
import A;
45+
import B;
46+
void use() {
47+
Bar _;
48+
_.baz<int>();
49+
}

0 commit comments

Comments
 (0)