-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Revert [Clang] prevent errors for deduction guides using deduced type aliases #118165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Oleksandr T. (a-tarasyuk) ChangesReverts #117450 #54909 (comment) Full diff: https://github.com/llvm/llvm-project/pull/118165.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e44aefa90ab386..d867f2ea3e8e2e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -624,9 +624,6 @@ Improvements to Clang's diagnostics
- Fixed a false negative ``-Wunused-private-field`` diagnostic when a defaulted comparison operator is defined out of class (#GH116961).
-- Clang now supports using alias templates in deduction guides, aligning with the C++ standard,
- which treats alias templates as synonyms for their underlying types (#GH54909).
-
- Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957).
Improvements to Clang's time-trace
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index c2ae9a9d5e1a0c..7e8e321c4b90e6 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11451,29 +11451,23 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
bool MightInstantiateToSpecialization = false;
if (auto RetTST =
TSI->getTypeLoc().getAsAdjusted<TemplateSpecializationTypeLoc>()) {
- const TemplateSpecializationType *TST = RetTST.getTypePtr();
- while (TST && TST->isTypeAlias())
- TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
-
- if (TST) {
- TemplateName SpecifiedName = TST->getTemplateName();
- bool TemplateMatches = Context.hasSameTemplateName(
- SpecifiedName, GuidedTemplate, /*IgnoreDeduced=*/true);
-
- const QualifiedTemplateName *Qualifiers =
- SpecifiedName.getAsQualifiedTemplateName();
- assert(Qualifiers && "expected QualifiedTemplate");
- bool SimplyWritten = !Qualifiers->hasTemplateKeyword() &&
- Qualifiers->getQualifier() == nullptr;
- if (SimplyWritten && TemplateMatches)
- AcceptableReturnType = true;
- else {
- // This could still instantiate to the right type, unless we know it
- // names the wrong class template.
- auto *TD = SpecifiedName.getAsTemplateDecl();
- MightInstantiateToSpecialization =
- !(TD && isa<ClassTemplateDecl>(TD) && !TemplateMatches);
- }
+ TemplateName SpecifiedName = RetTST.getTypePtr()->getTemplateName();
+ bool TemplateMatches = Context.hasSameTemplateName(
+ SpecifiedName, GuidedTemplate, /*IgnoreDeduced=*/true);
+
+ const QualifiedTemplateName *Qualifiers =
+ SpecifiedName.getAsQualifiedTemplateName();
+ assert(Qualifiers && "expected QualifiedTemplate");
+ bool SimplyWritten = !Qualifiers->hasTemplateKeyword() &&
+ Qualifiers->getQualifier() == nullptr;
+ if (SimplyWritten && TemplateMatches)
+ AcceptableReturnType = true;
+ else {
+ // This could still instantiate to the right type, unless we know it
+ // names the wrong class template.
+ auto *TD = SpecifiedName.getAsTemplateDecl();
+ MightInstantiateToSpecialization =
+ !(TD && isa<ClassTemplateDecl>(TD) && !TemplateMatches);
}
} else if (!RetTy.hasQualifiers() && RetTy->isDependentType()) {
MightInstantiateToSpecialization = true;
diff --git a/clang/test/CXX/temp/temp.deduct.guide/p3.cpp b/clang/test/CXX/temp/temp.deduct.guide/p3.cpp
index 195ba2831439d0..c5404847beb066 100644
--- a/clang/test/CXX/temp/temp.deduct.guide/p3.cpp
+++ b/clang/test/CXX/temp/temp.deduct.guide/p3.cpp
@@ -33,7 +33,7 @@ template<template<typename> typename TT> struct E { // expected-note 2{{template
};
A(int) -> int; // expected-error {{deduced type 'int' of deduction guide is not a specialization of template 'A'}}
-template <typename T> A(T)->B<T>;
+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'}}
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'}}
// A deduction-guide shall be declared in the same scope as the corresponding
@@ -71,11 +71,3 @@ namespace WrongScope {
Local(int) -> Local<int>; // expected-error {{expected}}
}
}
-
-namespace GH54909 {
-template <class T> struct A {};
-struct B {};
-
-template <typename T> using C = B;
-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'}}
-}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change looks good to me (please wait for @erichkeane review before landing). I’d suggest adding a brief rationale in the commit message instead of just including links, to make it more self-contained.
@hokein thanks. I've updated the PR description. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for working so quickly on this! LGTM.
Reverts #117450
Revert #117450 because the prior behavior aligns with the standard -
template-name
in thesimple-template-id
in the return type shall be the actual name of a class template rather than some equivalent alias template. Details #54909 (comment).