Skip to content

Commit

Permalink
[C++20] [Modules] Profile TemplateName by canonical decl
Browse files Browse the repository at this point in the history
Close llvm/llvm-project#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.
  • Loading branch information
ChuanqiXu9 authored and CarlosAlbertoEnciso committed Mar 15, 2023
1 parent 06d687e commit cbdf5b1
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 3 deletions.
4 changes: 1 addition & 3 deletions clang/include/clang/AST/TemplateName.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/AST/TemplateName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
49 changes: 49 additions & 0 deletions clang/test/Modules/pr61317.cppm
Original file line number Diff line number Diff line change
@@ -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>();
}

0 comments on commit cbdf5b1

Please sign in to comment.