Skip to content

Commit 4ad4d34

Browse files
authored
Revert [Clang] prevent errors for deduction guides using deduced type aliases (#118165)
Reverts #117450 --- Revert #117450 because the prior behavior aligns with the standard - _`template-name`_ in the _`simple-template-id`_ in the return type shall be the actual name of a class template rather than some equivalent alias template. Details #54909 (comment).
1 parent aa7fe1c commit 4ad4d34

File tree

3 files changed

+18
-35
lines changed

3 files changed

+18
-35
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,6 @@ Improvements to Clang's diagnostics
626626

627627
- Fixed a false negative ``-Wunused-private-field`` diagnostic when a defaulted comparison operator is defined out of class (#GH116961).
628628

629-
- Clang now supports using alias templates in deduction guides, aligning with the C++ standard,
630-
which treats alias templates as synonyms for their underlying types (#GH54909).
631-
632629
- Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957).
633630

634631
Improvements to Clang's time-trace

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11451,29 +11451,23 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
1145111451
bool MightInstantiateToSpecialization = false;
1145211452
if (auto RetTST =
1145311453
TSI->getTypeLoc().getAsAdjusted<TemplateSpecializationTypeLoc>()) {
11454-
const TemplateSpecializationType *TST = RetTST.getTypePtr();
11455-
while (TST && TST->isTypeAlias())
11456-
TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
11457-
11458-
if (TST) {
11459-
TemplateName SpecifiedName = TST->getTemplateName();
11460-
bool TemplateMatches = Context.hasSameTemplateName(
11461-
SpecifiedName, GuidedTemplate, /*IgnoreDeduced=*/true);
11462-
11463-
const QualifiedTemplateName *Qualifiers =
11464-
SpecifiedName.getAsQualifiedTemplateName();
11465-
assert(Qualifiers && "expected QualifiedTemplate");
11466-
bool SimplyWritten = !Qualifiers->hasTemplateKeyword() &&
11467-
Qualifiers->getQualifier() == nullptr;
11468-
if (SimplyWritten && TemplateMatches)
11469-
AcceptableReturnType = true;
11470-
else {
11471-
// This could still instantiate to the right type, unless we know it
11472-
// names the wrong class template.
11473-
auto *TD = SpecifiedName.getAsTemplateDecl();
11474-
MightInstantiateToSpecialization =
11475-
!(TD && isa<ClassTemplateDecl>(TD) && !TemplateMatches);
11476-
}
11454+
TemplateName SpecifiedName = RetTST.getTypePtr()->getTemplateName();
11455+
bool TemplateMatches = Context.hasSameTemplateName(
11456+
SpecifiedName, GuidedTemplate, /*IgnoreDeduced=*/true);
11457+
11458+
const QualifiedTemplateName *Qualifiers =
11459+
SpecifiedName.getAsQualifiedTemplateName();
11460+
assert(Qualifiers && "expected QualifiedTemplate");
11461+
bool SimplyWritten = !Qualifiers->hasTemplateKeyword() &&
11462+
Qualifiers->getQualifier() == nullptr;
11463+
if (SimplyWritten && TemplateMatches)
11464+
AcceptableReturnType = true;
11465+
else {
11466+
// This could still instantiate to the right type, unless we know it
11467+
// names the wrong class template.
11468+
auto *TD = SpecifiedName.getAsTemplateDecl();
11469+
MightInstantiateToSpecialization =
11470+
!(TD && isa<ClassTemplateDecl>(TD) && !TemplateMatches);
1147711471
}
1147811472
} else if (!RetTy.hasQualifiers() && RetTy->isDependentType()) {
1147911473
MightInstantiateToSpecialization = true;

clang/test/CXX/temp/temp.deduct.guide/p3.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ template<template<typename> typename TT> struct E { // expected-note 2{{template
3333
};
3434

3535
A(int) -> int; // expected-error {{deduced type 'int' of deduction guide is not a specialization of template 'A'}}
36-
template <typename T> A(T)->B<T>;
36+
template <typename T> A(T)->B<T>; // expected-error {{deduced type 'B<T>' (aka 'A<T>') of deduction guide is not written as a specialization of template 'A'}}
3737
template<typename T> A(T*) -> const A<T>; // expected-error {{deduced type 'const A<T>' of deduction guide is not a specialization of template 'A'}}
3838

3939
// A deduction-guide shall be declared in the same scope as the corresponding
@@ -71,11 +71,3 @@ namespace WrongScope {
7171
Local(int) -> Local<int>; // expected-error {{expected}}
7272
}
7373
}
74-
75-
namespace GH54909 {
76-
template <class T> struct A {};
77-
struct B {};
78-
79-
template <typename T> using C = B;
80-
template <typename T> A() -> C<T>; // expected-error {{deduced type 'C<T>' (aka 'GH54909::B') of deduction guide is not a specialization of template 'A'}}
81-
}

0 commit comments

Comments
 (0)