[clang] [Clang] prevent errors for deduction guides using deduced type aliases (PR #117450)
Oleksandr T. via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 26 14:45:07 PST 2024
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/117450
>From 5212f12874a859a9f7b6c662402aa2171006d011 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Sun, 24 Nov 2024 00:19:06 +0200
Subject: [PATCH 1/6] [Clang] prevent errors for deduction guides using deduced
type aliases
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/lib/Sema/SemaDeclCXX.cpp | 6 +++++-
clang/test/CXX/temp/temp.deduct.guide/p3.cpp | 12 +++++++++++-
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8bd06fadfdc984..2437def6322764 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -583,6 +583,8 @@ Improvements to Clang's diagnostics
- For an rvalue reference bound to a temporary struct with an integer member, Clang will detect constant integer overflow
in the initializer for the integer member (#GH46755).
+- Clang now prevents errors for deduction guides with deduced type aliases (#GH54909).
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 26041e53de5061..9d0eb098841a3a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11451,7 +11451,11 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
bool MightInstantiateToSpecialization = false;
if (auto RetTST =
TSI->getTypeLoc().getAsAdjusted<TemplateSpecializationTypeLoc>()) {
- TemplateName SpecifiedName = RetTST.getTypePtr()->getTemplateName();
+ const TemplateSpecializationType *TST = RetTST.getTypePtr();
+ while (TST->isTypeAlias())
+ TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
+
+ TemplateName SpecifiedName = TST->getTemplateName();
bool TemplateMatches = Context.hasSameTemplateName(
SpecifiedName, GuidedTemplate, /*IgnoreDeduced=*/true);
diff --git a/clang/test/CXX/temp/temp.deduct.guide/p3.cpp b/clang/test/CXX/temp/temp.deduct.guide/p3.cpp
index c5404847beb066..36e0f75ccf9098 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>; // 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)->B<T>;
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,3 +71,13 @@ namespace WrongScope {
Local(int) -> Local<int>; // expected-error {{expected}}
}
}
+
+namespace GH54909 {
+template <typename T> struct A {};
+A(void) -> A<int>;
+
+template <typename T> using B = A<T>;
+template <typename T> using C = B<T>;
+template <typename T> using D = C<T>;
+template <typename T> A(T) -> D<T>;
+}
>From 2bd28afb7743b7279f2cd9ce6e8e43db3a02a8cc Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Mon, 25 Nov 2024 14:48:27 +0200
Subject: [PATCH 2/6] update release notes
---
clang/docs/ReleaseNotes.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2437def6322764..e337729dbd49a3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -583,7 +583,8 @@ Improvements to Clang's diagnostics
- For an rvalue reference bound to a temporary struct with an integer member, Clang will detect constant integer overflow
in the initializer for the integer member (#GH46755).
-- Clang now prevents errors for deduction guides with deduced type aliases (#GH54909).
+- 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).
Improvements to Clang's time-trace
----------------------------------
>From 030630bf379e22a223f7a4c19fcae632be531187 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Mon, 25 Nov 2024 14:49:18 +0200
Subject: [PATCH 3/6] prevent missed template specialization type
---
clang/lib/Sema/SemaDeclCXX.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 9d0eb098841a3a..a51c9c8e9d504b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11452,7 +11452,7 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
if (auto RetTST =
TSI->getTypeLoc().getAsAdjusted<TemplateSpecializationTypeLoc>()) {
const TemplateSpecializationType *TST = RetTST.getTypePtr();
- while (TST->isTypeAlias())
+ while (TST && TST->isTypeAlias())
TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
TemplateName SpecifiedName = TST->getTemplateName();
>From a265118788be55369bc18e2ee822d6f9f77f6f22 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Mon, 25 Nov 2024 14:50:20 +0200
Subject: [PATCH 4/6] remove unnecessary tests
---
clang/test/CXX/temp/temp.deduct.guide/p3.cpp | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/clang/test/CXX/temp/temp.deduct.guide/p3.cpp b/clang/test/CXX/temp/temp.deduct.guide/p3.cpp
index 36e0f75ccf9098..47bacd60585b0d 100644
--- a/clang/test/CXX/temp/temp.deduct.guide/p3.cpp
+++ b/clang/test/CXX/temp/temp.deduct.guide/p3.cpp
@@ -71,13 +71,3 @@ namespace WrongScope {
Local(int) -> Local<int>; // expected-error {{expected}}
}
}
-
-namespace GH54909 {
-template <typename T> struct A {};
-A(void) -> A<int>;
-
-template <typename T> using B = A<T>;
-template <typename T> using C = B<T>;
-template <typename T> using D = C<T>;
-template <typename T> A(T) -> D<T>;
-}
>From d1da83bd1dd7fd3607c01cda7c8912f8a8734caf Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Tue, 26 Nov 2024 18:58:00 +0200
Subject: [PATCH 5/6] add an assertion to handle type alias resolution failure
---
clang/lib/Sema/SemaDeclCXX.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index a51c9c8e9d504b..ff666e41fc3c41 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11454,6 +11454,7 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
const TemplateSpecializationType *TST = RetTST.getTypePtr();
while (TST && TST->isTypeAlias())
TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
+ assert(TST && "failed to resolve type alias");
TemplateName SpecifiedName = TST->getTemplateName();
bool TemplateMatches = Context.hasSameTemplateName(
>From 82799938d6e7abc885f6bf8777daf0a1b622bee7 Mon Sep 17 00:00:00 2001
From: Oleksandr T <oleksandr.tarasiuk at outlook.com>
Date: Wed, 27 Nov 2024 00:44:50 +0200
Subject: [PATCH 6/6] add tests to verify handling of invalid alias resolution
---
clang/lib/Sema/SemaDeclCXX.cpp | 39 ++++++++++----------
clang/test/CXX/temp/temp.deduct.guide/p3.cpp | 8 ++++
2 files changed, 28 insertions(+), 19 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index ff666e41fc3c41..3ff365649c93d2 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11454,25 +11454,26 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
const TemplateSpecializationType *TST = RetTST.getTypePtr();
while (TST && TST->isTypeAlias())
TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
- assert(TST && "failed to resolve type alias");
-
- 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);
+
+ 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);
+ }
}
} 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 47bacd60585b0d..195ba2831439d0 100644
--- a/clang/test/CXX/temp/temp.deduct.guide/p3.cpp
+++ b/clang/test/CXX/temp/temp.deduct.guide/p3.cpp
@@ -71,3 +71,11 @@ 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'}}
+}
More information about the cfe-commits
mailing list