Skip to content

Commit 71a827e

Browse files
committed
[clang] fix broken canonicalization of DeducedTemplateSpecializationType
This reverts the functional elements of commit 3e78fa8 and redoes it, by fixing the true root cause of #61317. A TemplateName can be non-canonical; profiling it based on the canonical name would result in inconsistent preservation of as-written information in the AST. The true problem in #61317 is that we would not consider the methods with requirements expression which contain DTSTs as the same in relation to merging of declarations when importing modules. The expressions would never match because they contained DTSTs pointing to different redeclarations of the same class template, but since canonicalization for them was broken, their canonical types would not match either. --- No changelog entry because #61317 was already claimed as fixed in previous release.
1 parent 4748b49 commit 71a827e

File tree

5 files changed

+29
-22
lines changed

5 files changed

+29
-22
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
17701770
QualType getDeducedTemplateSpecializationType(TemplateName Template,
17711771
QualType DeducedType,
17721772
bool IsDependent) const;
1773+
QualType getDeducedTemplateSpecializationTypeInternal(TemplateName Template,
1774+
QualType DeducedType,
1775+
bool IsDependent,
1776+
QualType Canon) const;
17731777

17741778
/// Return the unique reference to the type for the specified TagDecl
17751779
/// (struct/union/class/enum) decl.

clang/include/clang/AST/TemplateName.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,9 @@ class TemplateName {
346346
/// error.
347347
void dump() const;
348348

349-
void Profile(llvm::FoldingSetNodeID &ID);
349+
void Profile(llvm::FoldingSetNodeID &ID) {
350+
ID.AddPointer(Storage.getOpaqueValue());
351+
}
350352

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

clang/include/clang/AST/Type.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6050,14 +6050,13 @@ class DeducedTemplateSpecializationType : public DeducedType,
60506050

60516051
DeducedTemplateSpecializationType(TemplateName Template,
60526052
QualType DeducedAsType,
6053-
bool IsDeducedAsDependent)
6053+
bool IsDeducedAsDependent, QualType Canon)
60546054
: DeducedType(DeducedTemplateSpecialization, DeducedAsType,
60556055
toTypeDependence(Template.getDependence()) |
60566056
(IsDeducedAsDependent
60576057
? TypeDependence::DependentInstantiation
60586058
: TypeDependence::None),
6059-
DeducedAsType.isNull() ? QualType(this, 0)
6060-
: DeducedAsType.getCanonicalType()),
6059+
Canon),
60616060
Template(Template) {}
60626061

60636062
public:
@@ -6071,9 +6070,7 @@ class DeducedTemplateSpecializationType : public DeducedType,
60716070
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
60726071
QualType Deduced, bool IsDependent) {
60736072
Template.Profile(ID);
6074-
QualType CanonicalType =
6075-
Deduced.isNull() ? Deduced : Deduced.getCanonicalType();
6076-
ID.AddPointer(CanonicalType.getAsOpaquePtr());
6073+
Deduced.Profile(ID);
60776074
ID.AddBoolean(IsDependent || Template.isDependent());
60786075
}
60796076

clang/lib/AST/ASTContext.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5925,11 +5925,9 @@ QualType ASTContext::getUnconstrainedType(QualType T) const {
59255925
return T;
59265926
}
59275927

5928-
/// Return the uniqued reference to the deduced template specialization type
5929-
/// which has been deduced to the given type, or to the canonical undeduced
5930-
/// such type, or the canonical deduced-but-dependent such type.
5931-
QualType ASTContext::getDeducedTemplateSpecializationType(
5932-
TemplateName Template, QualType DeducedType, bool IsDependent) const {
5928+
QualType ASTContext::getDeducedTemplateSpecializationTypeInternal(
5929+
TemplateName Template, QualType DeducedType, bool IsDependent,
5930+
QualType Canon) const {
59335931
// Look in the folding set for an existing type.
59345932
void *InsertPos = nullptr;
59355933
llvm::FoldingSetNodeID ID;
@@ -5940,7 +5938,8 @@ QualType ASTContext::getDeducedTemplateSpecializationType(
59405938
return QualType(DTST, 0);
59415939

59425940
auto *DTST = new (*this, alignof(DeducedTemplateSpecializationType))
5943-
DeducedTemplateSpecializationType(Template, DeducedType, IsDependent);
5941+
DeducedTemplateSpecializationType(Template, DeducedType, IsDependent,
5942+
Canon);
59445943
llvm::FoldingSetNodeID TempID;
59455944
DTST->Profile(TempID);
59465945
assert(ID == TempID && "ID does not match");
@@ -5949,6 +5948,20 @@ QualType ASTContext::getDeducedTemplateSpecializationType(
59495948
return QualType(DTST, 0);
59505949
}
59515950

5951+
/// Return the uniqued reference to the deduced template specialization type
5952+
/// which has been deduced to the given type, or to the canonical undeduced
5953+
/// such type, or the canonical deduced-but-dependent such type.
5954+
QualType ASTContext::getDeducedTemplateSpecializationType(
5955+
TemplateName Template, QualType DeducedType, bool IsDependent) const {
5956+
QualType Canon = DeducedType.isNull()
5957+
? getDeducedTemplateSpecializationTypeInternal(
5958+
getCanonicalTemplateName(Template), QualType(),
5959+
IsDependent, QualType())
5960+
: DeducedType.getCanonicalType();
5961+
return getDeducedTemplateSpecializationTypeInternal(Template, DeducedType,
5962+
IsDependent, Canon);
5963+
}
5964+
59525965
/// getAtomicType - Return the uniqued reference to the atomic type for
59535966
/// the given value type.
59545967
QualType ASTContext::getAtomicType(QualType T) const {

clang/lib/AST/TemplateName.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,15 +264,6 @@ bool TemplateName::containsUnexpandedParameterPack() const {
264264
return getDependence() & TemplateNameDependence::UnexpandedPack;
265265
}
266266

267-
void TemplateName::Profile(llvm::FoldingSetNodeID &ID) {
268-
if (const auto* USD = getAsUsingShadowDecl())
269-
ID.AddPointer(USD->getCanonicalDecl());
270-
else if (const auto *TD = getAsTemplateDecl())
271-
ID.AddPointer(TD->getCanonicalDecl());
272-
else
273-
ID.AddPointer(Storage.getOpaqueValue());
274-
}
275-
276267
void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
277268
Qualified Qual) const {
278269
auto handleAnonymousTTP = [](TemplateDecl *TD, raw_ostream &OS) {

0 commit comments

Comments
 (0)