-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] CTAD: build aggregate deduction guides for alias templates. #85904
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: Haojian Wu (hokein) ChangesFixes #85767. Full diff: https://github.com/llvm/llvm-project/pull/85904.diff 3 Files Affected:
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index aa470adb30b47f..a2d5bad1300d1f 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -10918,32 +10918,15 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
Context.getLValueReferenceType(ElementTypes[I].withConst());
}
- llvm::FoldingSetNodeID ID;
- ID.AddPointer(Template);
- for (auto &T : ElementTypes)
- T.getCanonicalType().Profile(ID);
- unsigned Hash = ID.ComputeHash();
- if (AggregateDeductionCandidates.count(Hash) == 0) {
- if (FunctionTemplateDecl *TD =
- DeclareImplicitDeductionGuideFromInitList(
- Template, ElementTypes,
- TSInfo->getTypeLoc().getEndLoc())) {
- auto *GD = cast<CXXDeductionGuideDecl>(TD->getTemplatedDecl());
- GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
- AggregateDeductionCandidates[Hash] = GD;
- addDeductionCandidate(TD, GD, DeclAccessPair::make(TD, AS_public),
- OnlyListConstructors,
- /*AllowAggregateDeductionCandidate=*/true);
- }
- } else {
- CXXDeductionGuideDecl *GD = AggregateDeductionCandidates[Hash];
- FunctionTemplateDecl *TD = GD->getDescribedFunctionTemplate();
- assert(TD && "aggregate deduction candidate is function template");
+ if (FunctionTemplateDecl *TD =
+ DeclareImplicitDeductionGuideFromInitList(
+ LookupTemplateDecl, ElementTypes, TSInfo->getTypeLoc().getEndLoc())) {
+ auto *GD = cast<CXXDeductionGuideDecl>(TD->getTemplatedDecl());
addDeductionCandidate(TD, GD, DeclAccessPair::make(TD, AS_public),
OnlyListConstructors,
/*AllowAggregateDeductionCandidate=*/true);
+ HasAnyDeductionGuide = true;
}
- HasAnyDeductionGuide = true;
}
};
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 51e8db2dfbaac8..86d07dd3a2187a 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2725,21 +2725,43 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
return false;
}
-// Build deduction guides for a type alias template.
-void DeclareImplicitDeductionGuidesForTypeAlias(
- Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) {
- auto &Context = SemaRef.Context;
- // FIXME: if there is an explicit deduction guide after the first use of the
- // type alias usage, we will not cover this explicit deduction guide. fix this
- // case.
- if (hasDeclaredDeductionGuides(
- Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate),
- AliasTemplate->getDeclContext()))
- return;
+NamedDecl *TransformTemplateParameter(Sema &SemaRef, DeclContext *DC,
+ NamedDecl *TemplateParam,
+ MultiLevelTemplateArgumentList &Args,
+ unsigned NewIndex) {
+ if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
+ return transformTemplateTypeParam(SemaRef, DC, TTP, Args, TTP->getDepth(),
+ NewIndex);
+ if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
+ return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex,
+ TTP->getDepth());
+ if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
+ return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex,
+ NTTP->getDepth());
+ return nullptr;
+}
+
+Expr *TransformRequireClause(Sema &SemaRef, FunctionTemplateDecl *FTD,
+ llvm::ArrayRef<TemplateArgument> TransformedArgs) {
+ Expr *RC =
+ FTD->getTemplateParameters()->getRequiresClause();
+ if (!RC)
+ return nullptr;
+ MultiLevelTemplateArgumentList Args;
+ Args.setKind(TemplateSubstitutionKind::Rewrite);
+ Args.addOuterTemplateArguments(TransformedArgs);
+ ExprResult E = SemaRef.SubstExpr(RC, Args);
+ if (E.isInvalid())
+ return nullptr;
+ return E.getAs<Expr>();
+}
+
+std::pair<TemplateDecl *, llvm::ArrayRef<TemplateArgument>>
+GetRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
// Unwrap the sugared ElaboratedType.
auto RhsType = AliasTemplate->getTemplatedDecl()
->getUnderlyingType()
- .getSingleStepDesugaredType(Context);
+ .getSingleStepDesugaredType(SemaRef.Context);
TemplateDecl *Template = nullptr;
llvm::ArrayRef<TemplateArgument> AliasRhsTemplateArgs;
if (const auto *TST = RhsType->getAs<TemplateSpecializationType>()) {
@@ -2760,6 +2782,22 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
} else {
assert(false && "unhandled RHS type of the alias");
}
+ return {Template, AliasRhsTemplateArgs};
+}
+
+// Build deduction guides for a type alias template.
+void DeclareImplicitDeductionGuidesForTypeAlias(
+ Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) {
+ auto &Context = SemaRef.Context;
+ // FIXME: if there is an explicit deduction guide after the first use of the
+ // type alias usage, we will not cover this explicit deduction guide. fix this
+ // case.
+ if (hasDeclaredDeductionGuides(
+ Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate),
+ AliasTemplate->getDeclContext()))
+ return;
+ auto [Template, AliasRhsTemplateArgs] =
+ GetRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
if (!Template)
return;
DeclarationNameInfo NameInfo(
@@ -2854,21 +2892,6 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
// parameters, used for building `TemplateArgsForBuildingFPrime`.
SmallVector<TemplateArgument, 16> TransformedDeducedAliasArgs(
AliasTemplate->getTemplateParameters()->size());
- auto TransformTemplateParameter =
- [&SemaRef](DeclContext *DC, NamedDecl *TemplateParam,
- MultiLevelTemplateArgumentList &Args,
- unsigned NewIndex) -> NamedDecl * {
- if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
- return transformTemplateTypeParam(SemaRef, DC, TTP, Args,
- TTP->getDepth(), NewIndex);
- if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
- return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex,
- TTP->getDepth());
- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
- return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex,
- NTTP->getDepth());
- return nullptr;
- };
for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
auto *TP = AliasTemplate->getTemplateParameters()->getParam(
@@ -2878,9 +2901,9 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
MultiLevelTemplateArgumentList Args;
Args.setKind(TemplateSubstitutionKind::Rewrite);
Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
- NamedDecl *NewParam =
- TransformTemplateParameter(AliasTemplate->getDeclContext(), TP, Args,
- /*NewIndex*/ FPrimeTemplateParams.size());
+ NamedDecl *NewParam = TransformTemplateParameter(
+ SemaRef, AliasTemplate->getDeclContext(), TP, Args,
+ /*NewIndex*/ FPrimeTemplateParams.size());
FPrimeTemplateParams.push_back(NewParam);
auto NewTemplateArgument = Context.getCanonicalTemplateArgument(
@@ -2897,7 +2920,7 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
// TemplateArgsForBuildingFPrime.
Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime);
NamedDecl *NewParam = TransformTemplateParameter(
- F->getDeclContext(), TP, Args, FPrimeTemplateParams.size());
+ SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size());
FPrimeTemplateParams.push_back(NewParam);
assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
@@ -2907,16 +2930,8 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
Context.getInjectedTemplateArg(NewParam));
}
// Substitute new template parameters into requires-clause if present.
- Expr *RequiresClause = nullptr;
- if (Expr *InnerRC = F->getTemplateParameters()->getRequiresClause()) {
- MultiLevelTemplateArgumentList Args;
- Args.setKind(TemplateSubstitutionKind::Rewrite);
- Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime);
- ExprResult E = SemaRef.SubstExpr(InnerRC, Args);
- if (E.isInvalid())
- return;
- RequiresClause = E.getAs<Expr>();
- }
+ Expr *RequiresClause =
+ TransformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime);
// FIXME: implement the is_deducible constraint per C++
// [over.match.class.deduct]p3.3:
// ... and a constraint that is satisfied if and only if the arguments
@@ -2982,11 +2997,104 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
}
}
+// Build an aggregate deduction guide for a type alias template.
+FunctionTemplateDecl *DeclareAggrecateDeductionGuideForTypeAlias(
+ Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
+ MutableArrayRef<QualType> ParamTypes, SourceLocation Loc) {
+ TemplateDecl *RHSTemplate =
+ GetRHSTemplateDeclAndArgs(SemaRef, AliasTemplate).first;
+ if (!RHSTemplate)
+ return nullptr;
+ auto *RHSDeductionGuide =
+ SemaRef.DeclareImplicitDeductionGuideFromInitList(RHSTemplate, ParamTypes,
+ Loc);
+ if (!RHSDeductionGuide)
+ return nullptr;
+
+ LocalInstantiationScope Scope(SemaRef);
+
+ // Build a new template parameter list for the synthesized aggregate deduction
+ // guide by transforming the one from RHSDeductionGuide.
+ SmallVector<NamedDecl *> TransformedTemplateParams;
+ // Template args that refers to the rebuilt template parameters.
+ // All template arguments must be initialized in advance.
+ SmallVector<TemplateArgument> TransformedTemplateArgs(
+ RHSDeductionGuide->getTemplateParameters()->size());
+ for (auto *TP : *RHSDeductionGuide->getTemplateParameters()) {
+ // Rebuild any internal references to earlier parameters and reindex as
+ // we go.
+ MultiLevelTemplateArgumentList Args;
+ Args.setKind(TemplateSubstitutionKind::Rewrite);
+ Args.addOuterTemplateArguments(TransformedTemplateArgs);
+ NamedDecl *NewParam = TransformTemplateParameter(
+ SemaRef, AliasTemplate->getDeclContext(), TP, Args,
+ /*NewIndex=*/ TransformedTemplateParams.size());
+
+ TransformedTemplateArgs[TransformedTemplateParams.size()] =
+ SemaRef.Context.getCanonicalTemplateArgument(
+ SemaRef.Context.getInjectedTemplateArg(NewParam));
+ TransformedTemplateParams.push_back(NewParam);
+ }
+ // FIXME: implement the is_deducible constraint per C++
+ // [over.match.class.deduct]p3.3.
+ Expr *TransformedRequiresClause = TransformRequireClause(
+ SemaRef, RHSDeductionGuide, TransformedTemplateArgs);
+ auto *TransformedTemplateParameterList = TemplateParameterList::Create(
+ SemaRef.Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
+ AliasTemplate->getTemplateParameters()->getLAngleLoc(),
+ TransformedTemplateParams,
+ AliasTemplate->getTemplateParameters()->getRAngleLoc(),
+ TransformedRequiresClause);
+ auto *TransformedTemplateArgList = TemplateArgumentList::CreateCopy(
+ SemaRef.Context, TransformedTemplateArgs);
+
+ if (auto *TransformedDeductionGuide = SemaRef.InstantiateFunctionDeclaration(
+ RHSDeductionGuide, TransformedTemplateArgList,
+ AliasTemplate->getLocation(),
+ Sema::CodeSynthesisContext::BuildingDeductionGuides)) {
+ auto *GD =
+ llvm::dyn_cast<clang::CXXDeductionGuideDecl>(TransformedDeductionGuide);
+ FunctionTemplateDecl *Result = buildDeductionGuide(
+ SemaRef, AliasTemplate, TransformedTemplateParameterList,
+ GD->getCorrespondingConstructor(), GD->getExplicitSpecifier(),
+ GD->getTypeSourceInfo(), AliasTemplate->getBeginLoc(),
+ AliasTemplate->getLocation(), AliasTemplate->getEndLoc(),
+ GD->isImplicit());
+ cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl())
+ ->setDeductionCandidateKind(DeductionCandidate::Aggregate);
+ return Result;
+ }
+ return nullptr;
+}
+
} // namespace
+// FIXME: rename to DeclareAggrecateDeductionGuide.
FunctionTemplateDecl *Sema::DeclareImplicitDeductionGuideFromInitList(
TemplateDecl *Template, MutableArrayRef<QualType> ParamTypes,
SourceLocation Loc) {
+ llvm::FoldingSetNodeID ID;
+ ID.AddPointer(Template);
+ for (auto &T : ParamTypes)
+ T.getCanonicalType().Profile(ID);
+ unsigned Hash = ID.ComputeHash();
+
+ auto Found = AggregateDeductionCandidates.find(Hash);
+ if (Found != AggregateDeductionCandidates.end()) {
+ CXXDeductionGuideDecl *GD = Found->getSecond();
+ return GD->getDescribedFunctionTemplate();
+ }
+
+ if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
+ if (auto *FTD = DeclareAggrecateDeductionGuideForTypeAlias(
+ *this, AliasTemplate, ParamTypes, Loc)) {
+ auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
+ GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
+ AggregateDeductionCandidates[Hash] = GD;
+ return FTD;
+ }
+ }
+
if (CXXRecordDecl *DefRecord =
cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
if (TemplateDecl *DescribedTemplate =
@@ -3019,10 +3127,13 @@ FunctionTemplateDecl *Sema::DeclareImplicitDeductionGuideFromInitList(
Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
- auto *DG = cast<FunctionTemplateDecl>(
+ auto *FTD = cast<FunctionTemplateDecl>(
Transform.buildSimpleDeductionGuide(ParamTypes));
SavedContext.pop();
- return DG;
+ auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
+ GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
+ AggregateDeductionCandidates[Hash] = GD;
+ return FTD;
}
void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp
index 16c7083df29d0c..bf1a6939203f4e 100644
--- a/clang/test/SemaTemplate/deduction-guide.cpp
+++ b/clang/test/SemaTemplate/deduction-guide.cpp
@@ -239,3 +239,18 @@ F s(0);
// CHECK: |-InjectedClassNameType {{.*}} 'F<>' dependent
// CHECK: | `-CXXRecord {{.*}} 'F'
// CHECK: `-TemplateTypeParmType {{.*}} 'type-parameter-0-1' dependent depth 0 index 1
+
+template <typename T>
+struct G { T t1; };
+template<typename X>
+using AG = G<X>;
+
+AG ag = {1};
+// Verify that the aggregate deduction guide for alias templates is built.
+// CHECK-LABEL: Dumping <deduction guide for AG>
+// CHECK: FunctionTemplateDecl
+// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (type-parameter-0-0) -> G<type-parameter-0-0>'
+// CHECK: `-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G<int>' implicit_instantiation
+// CHECK: |-TemplateArgument type 'int'
+// CHECK: | `-BuiltinType {{.*}} 'int'
+// CHECK: `-ParmVarDecl {{.*}} 'int'
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
f11b878
to
1aefbc9
Compare
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.
Thanks for the ping, I didn't see this one in my list from having been away.
clang/lib/Sema/SemaTemplate.cpp
Outdated
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam)) | ||
return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, | ||
NTTP->getDepth()); | ||
return nullptr; |
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.
Is this ever a valid case? Should we be asserting here instead?
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.
No. Switched to llvm_unreachable
.
if (AliasTemplate->isInvalidDecl()) | ||
return; | ||
auto &Context = SemaRef.Context; | ||
// FIXME: if there is an explicit deduction guide after the first use of the |
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.
What needs to happen to fix this? This is a decent sized issue. Is this covered under UB (of so, can we diagnose that?), or does it have well defined rules?
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 behavior depends on where we see the first usage that triggers alias CTAD in the TU. The basic rule is "well-defined":
- when we encounter the first usage (let's say alias
Bar
), we will generate all deduction guides for theBar
. - for all the following usages of the
Bar
, we reuse these generated deduction guides above;
If there are some explicit deduction guides after the first usage, they are not covered and are not added to the overload candidate sets.
Regarding the fix, I haven't put much thought into it yet. A naive solution would be that we cache these results (underlying deduction guides -> alias deduction guides), and check that if we have generated the alias deduction guides.
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.
What about a diagnostic on an explicit deduction guide used after first use? If they are not covered/added to the candidate set, we should diagnose that it isn't valid (then, anything AFTER the error where we generate them 'wrong' is irrelevant anyway).
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.
Emitting a diagnostic is an option, but I think it's suboptimal, and it is not trivial to detect such cases. I prefer to fix the issue directly rather than implementing a diagnostic that would eventually be removed.
Do you consider this case to be critical for the clang trunk at the moment? I believe we should fix it before the next clang release, and we still have some time to do so.
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.
WOULD we remove said diagnostic? It seems that:
If there are some explicit deduction guides after the first usage, they are not covered and are not added to the overload candidate sets.
means that adding an explicit deduction guide after first use effectively 'does nothing'.
That said, I'm ok having us do it (or whatever we do next) in a followup patch.
@@ -2886,21 +2930,6 @@ void DeclareImplicitDeductionGuidesForTypeAlias( | |||
// parameters, used for building `TemplateArgsForBuildingFPrime`. | |||
SmallVector<TemplateArgument, 16> TransformedDeducedAliasArgs( | |||
AliasTemplate->getTemplateParameters()->size()); |
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.
I see this was just moved... I'd still love to see us figure out WHEN this could be nullptr. I fear this is a case where we are going to 'miss' something if we add a new template param type.
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.
It is reasonable that some of it elements will be nullptr, because not all template parameters of the alias template will be rewritten.
I fear this is a case where we are going to 'miss' something if we add a new template param type.
For this particular case, we have covered it in transformTemplateParameter
by adding the llvm_unreachable
as per your other comment.
clang/lib/Sema/SemaTemplate.cpp
Outdated
} // namespace | ||
|
||
// FIXME: rename to DeclareAggrecateDeductionGuide. |
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.
any issues just doing this now? Also, perhaps should be Aggregate
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.
oops, a typo. This FIXME was added at the last minute. Performed the rename change in this PR.
(happy to separate some refactoring changes to a separate change if the PR is too much).
1aefbc9
to
5834754
Compare
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.
Thanks for the review.
if (AliasTemplate->isInvalidDecl()) | ||
return; | ||
auto &Context = SemaRef.Context; | ||
// FIXME: if there is an explicit deduction guide after the first use of the |
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 behavior depends on where we see the first usage that triggers alias CTAD in the TU. The basic rule is "well-defined":
- when we encounter the first usage (let's say alias
Bar
), we will generate all deduction guides for theBar
. - for all the following usages of the
Bar
, we reuse these generated deduction guides above;
If there are some explicit deduction guides after the first usage, they are not covered and are not added to the overload candidate sets.
Regarding the fix, I haven't put much thought into it yet. A naive solution would be that we cache these results (underlying deduction guides -> alias deduction guides), and check that if we have generated the alias deduction guides.
clang/lib/Sema/SemaTemplate.cpp
Outdated
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam)) | ||
return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, | ||
NTTP->getDepth()); | ||
return nullptr; |
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.
No. Switched to llvm_unreachable
.
@@ -2886,21 +2930,6 @@ void DeclareImplicitDeductionGuidesForTypeAlias( | |||
// parameters, used for building `TemplateArgsForBuildingFPrime`. | |||
SmallVector<TemplateArgument, 16> TransformedDeducedAliasArgs( | |||
AliasTemplate->getTemplateParameters()->size()); |
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.
It is reasonable that some of it elements will be nullptr, because not all template parameters of the alias template will be rewritten.
I fear this is a case where we are going to 'miss' something if we add a new template param type.
For this particular case, we have covered it in transformTemplateParameter
by adding the llvm_unreachable
as per your other comment.
clang/lib/Sema/SemaTemplate.cpp
Outdated
} // namespace | ||
|
||
// FIXME: rename to DeclareAggrecateDeductionGuide. |
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.
oops, a typo. This FIXME was added at the last minute. Performed the rename change in this PR.
(happy to separate some refactoring changes to a separate change if the PR is too much).
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.
Feel free to do the diagnostic in a followup patch. Good to me after you deal with comments from others.
if (AliasTemplate->isInvalidDecl()) | ||
return; | ||
auto &Context = SemaRef.Context; | ||
// FIXME: if there is an explicit deduction guide after the first use of the |
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.
What about a diagnostic on an explicit deduction guide used after first use? If they are not covered/added to the candidate set, we should diagnose that it isn't valid (then, anything AFTER the error where we generate them 'wrong' is irrelevant anyway).
5834754
to
8c63fa5
Compare
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.
Sema.h
changes look good to me.
SemaTemplate.cpp, NFC. this is a NFC refactoring change, which is needed for the upcoming fix for alias templates.
8c63fa5
to
bb74800
Compare
Fixes #85767.
The aggregate deduction guides are handled in a separate code path. We don't generate dedicated aggregate deduction guides for alias templates (we just reuse the ones from the underlying template decl by accident). The patch fixes this incorrect issue.
Note: there is a small refactoring change in this PR, where we move the cache logic from
Sema::DeduceTemplateSpecializationFromInitializer
toSema::DeclareImplicitDeductionGuideFromInitList