[clang] 04a69a1 - [clang] Fix CTAD for aggregates for nested template classes (#78387)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 17 15:03:24 PST 2024
Author: antangelo
Date: 2024-01-17T18:03:20-05:00
New Revision: 04a69a10f63dae3c03cdfa5e199d8ea4458398b5
URL: https://github.com/llvm/llvm-project/commit/04a69a10f63dae3c03cdfa5e199d8ea4458398b5
DIFF: https://github.com/llvm/llvm-project/commit/04a69a10f63dae3c03cdfa5e199d8ea4458398b5.diff
LOG: [clang] Fix CTAD for aggregates for nested template classes (#78387)
Use the template pattern in determining whether to synthesize the
aggregate deduction guide, and update
DeclareImplicitDeductionGuideFromInitList to substitute outer template
arguments.
Fixes #77599
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bff1124889f606c..3d3e78e2889e976 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -942,6 +942,9 @@ Bug Fixes to C++ Support
(`#57410 <https://github.com/llvm/llvm-project/issues/57410>`_) and
(`#76604 <https://github.com/llvm/llvm-project/issues/57410>`_)
+- Fixes CTAD for aggregates on nested template classes. Fixes:
+ (`#77599 <https://github.com/llvm/llvm-project/issues/77599>`_)
+
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 408ee5f775804b6..48235941f62aa23 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -10718,7 +10718,14 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
bool HasAnyDeductionGuide = false;
auto SynthesizeAggrGuide = [&](InitListExpr *ListInit) {
- auto *RD = cast<CXXRecordDecl>(Template->getTemplatedDecl());
+ auto *Pattern = Template;
+ while (Pattern->getInstantiatedFromMemberTemplate()) {
+ if (Pattern->isMemberSpecialization())
+ break;
+ Pattern = Pattern->getInstantiatedFromMemberTemplate();
+ }
+
+ auto *RD = cast<CXXRecordDecl>(Pattern->getTemplatedDecl());
if (!(RD->getDefinition() && RD->isAggregate()))
return;
QualType Ty = Context.getRecordType(RD);
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 0655d3633520676..839d508b911f063 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2418,6 +2418,9 @@ struct ConvertConstructorToDeductionGuideTransform {
QualType Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,
DeductionGuideName, EPI);
TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(Result, Loc);
+ if (NestedPattern)
+ TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
+ DeductionGuideName);
FunctionProtoTypeLoc FPTL =
TSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
@@ -2425,9 +2428,13 @@ struct ConvertConstructorToDeductionGuideTransform {
// Build the parameters, needed during deduction / substitution.
SmallVector<ParmVarDecl*, 4> Params;
for (auto T : ParamTypes) {
- ParmVarDecl *NewParam = ParmVarDecl::Create(
- SemaRef.Context, DC, Loc, Loc, nullptr, T,
- SemaRef.Context.getTrivialTypeSourceInfo(T, Loc), SC_None, nullptr);
+ auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(T, Loc);
+ if (NestedPattern)
+ TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
+ DeclarationName());
+ ParmVarDecl *NewParam =
+ ParmVarDecl::Create(SemaRef.Context, DC, Loc, Loc, nullptr,
+ TSI->getType(), TSI, SC_None, nullptr);
NewParam->setScopeInfo(0, Params.size());
FPTL.setParam(Params.size(), NewParam);
Params.push_back(NewParam);
@@ -2670,8 +2677,14 @@ FunctionTemplateDecl *Sema::DeclareImplicitDeductionGuideFromInitList(
if (BuildingDeductionGuides.isInvalid())
return nullptr;
- return cast<FunctionTemplateDecl>(
+ ClassTemplateDecl *Pattern =
+ Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
+ ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
+
+ auto *DG = cast<FunctionTemplateDecl>(
Transform.buildSimpleDeductionGuide(ParamTypes));
+ SavedContext.pop();
+ return DG;
}
void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
diff --git a/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp b/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
index c44ec6918c7afb1..f3af6e8d6c17da0 100644
--- a/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
+++ b/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -std=c++20 -verify %s
-// expected-no-diagnostics
template<class T> struct S {
template<class U> struct N {
@@ -58,3 +57,21 @@ template<class X> struct requires_clause {
requires_clause<int>::B req(1, 2);
using RC = decltype(req);
using RC = requires_clause<int>::B<int>;
+
+template<typename X> struct nested_init_list {
+ template<C<X> Y>
+ struct B { // #INIT_LIST_INNER
+ X x;
+ Y y;
+ };
+};
+
+nested_init_list<int>::B nil {1, 2};
+using NIL = decltype(nil);
+using NIL = nested_init_list<int>::B<int>;
+
+// expected-error at +1 {{no viable constructor or deduction guide for deduction of template arguments of 'B'}}
+nested_init_list<int>::B nil_invalid {1, ""};
+// expected-note@#INIT_LIST_INNER {{candidate template ignored: substitution failure [with Y = const char *]: constraints not satisfied for class template 'B' [with Y = const char *]}}
+// expected-note@#INIT_LIST_INNER {{candidate function template not viable: requires 1 argument, but 2 were provided}}
+// expected-note@#INIT_LIST_INNER {{candidate function template not viable: requires 0 arguments, but 2 were provided}}
More information about the cfe-commits
mailing list