[Lldb-commits] [clang] [lldb] [clang] fix alias ctad producing function template with no template parameters (PR #195303)
Matheus Izvekov via lldb-commits
lldb-commits at lists.llvm.org
Fri May 1 11:38:01 PDT 2026
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/195303
>From 2af02cd7fc5937579ea526fdedc7bf09e03f0d95 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Fri, 1 May 2026 11:40:41 -0300
Subject: [PATCH] [clang] fix alias ctad producing function template with no
template parameters
Also fixes the same problem with error recovery for invalid template template
parameters.
This also adds asserts to the template constructors to make sure this
doesn't happen again.
---
clang/docs/ReleaseNotes.rst | 2 +
clang/include/clang/Sema/Sema.h | 2 +-
clang/lib/AST/DeclTemplate.cpp | 9 ++
clang/lib/Sema/SemaInit.cpp | 6 +-
clang/lib/Sema/SemaTemplate.cpp | 27 ++++--
clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 83 +++++++++----------
clang/test/SemaCXX/ctad.cpp | 2 +-
clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 7 +-
clang/test/SemaTemplate/deduction-guide.cpp | 4 +-
.../TypeSystem/Clang/TypeSystemClang.cpp | 2 +
10 files changed, 82 insertions(+), 62 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 84b8554db57b1..e710ba289e299 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -575,6 +575,8 @@ Bug Fixes to C++ Support
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed a bug where explicit nullability property attributes were not stored in AST nodes in Objective-C. (#GH179703)
+- Fixed a bug where alias CTAD, or an invalid template template parameter, could create a template with an empty template
+ parameter list. This also adds asserts to prevent this from happening again.
- Fixed a crash when parsing Doxygen ``@param`` commands attached to invalid declarations or non-function entities. (#GH182737)
- Fixed the SourceLocation and SourceRange of reversed rewritten CXXOperatorCallExpr. (#GH192467)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f9bf3e4de0a5e..8f98e104d3797 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13098,7 +13098,7 @@ class Sema final : public SemaBase {
void DeclareImplicitDeductionGuides(TemplateDecl *Template,
SourceLocation Loc);
- FunctionTemplateDecl *DeclareAggregateDeductionGuideFromInitList(
+ CXXDeductionGuideDecl *DeclareAggregateDeductionGuideFromInitList(
TemplateDecl *Template, MutableArrayRef<QualType> ParamTypes,
SourceLocation Loc);
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index f5d3c7b6f1c33..08e6512a1c74d 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -441,6 +441,7 @@ FunctionTemplateDecl *
FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl) {
+ assert(!Params->empty() && "template with no template parameters");
bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
if (Invalid)
@@ -528,6 +529,7 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl) {
+ assert(!Params->empty() && "template with no template parameters");
bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
if (Invalid)
@@ -877,6 +879,7 @@ TemplateTemplateParmDecl *TemplateTemplateParmDecl::Create(
const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind,
bool Typename, TemplateParameterList *Params) {
+ assert(!Params->empty() && "template with no template parameters");
return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
Kind, Typename, Params);
}
@@ -887,6 +890,7 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
IdentifierInfo *Id, TemplateNameKind Kind,
bool Typename, TemplateParameterList *Params,
ArrayRef<TemplateParameterList *> Expansions) {
+ assert(!Params->empty() && "template with no template parameters");
return new (C, DC,
additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
TemplateTemplateParmDecl(DC, L, D, P, Id, Kind, Typename, Params,
@@ -1104,6 +1108,7 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params,
Expr *ConstraintExpr) {
+ assert(!Params->empty() && "template with no template parameters");
bool Invalid = AdoptTemplateParameterList(Params, DC);
auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
if (Invalid)
@@ -1185,6 +1190,7 @@ ClassTemplatePartialSpecializationDecl::Create(
ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
CanQualType CanonInjectedTST,
ClassTemplatePartialSpecializationDecl *PrevDecl) {
+ assert(!Params->empty() && "template with no template parameters");
auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
CanonInjectedTST, PrevDecl);
@@ -1256,6 +1262,7 @@ TypeAliasTemplateDecl *
TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl) {
+ assert(!Params->empty() && "template with no template parameters");
bool Invalid = AdoptTemplateParameterList(Params, DC);
auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
if (Invalid)
@@ -1294,6 +1301,7 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params,
VarDecl *Decl) {
+ assert(!Params->empty() && "template with no template parameters");
bool Invalid = AdoptTemplateParameterList(Params, DC);
auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
if (Invalid)
@@ -1551,6 +1559,7 @@ VarTemplatePartialSpecializationDecl::Create(
SourceLocation IdLoc, TemplateParameterList *Params,
VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
StorageClass S, ArrayRef<TemplateArgument> Args) {
+ assert(!Params->empty() && "template with no template parameters");
auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
Args);
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index e54a25405c816..92fc73814deb8 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -10337,11 +10337,11 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
Context.getLValueReferenceType(ElementTypes[I].withConst());
}
- if (FunctionTemplateDecl *TD =
+ if (CXXDeductionGuideDecl *GD =
DeclareAggregateDeductionGuideFromInitList(
LookupTemplateDecl, ElementTypes,
TSInfo->getTypeLoc().getEndLoc())) {
- auto *GD = cast<CXXDeductionGuideDecl>(TD->getTemplatedDecl());
+ auto *TD = GD->getDescribedFunctionTemplate();
addDeductionCandidate(TD, GD, DeclAccessPair::make(TD, AS_public),
OnlyListConstructors,
/*AllowAggregateDeductionCandidate=*/true);
@@ -10492,7 +10492,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
// Make sure we didn't select an unusable deduction guide, and mark it
// as referenced.
- DiagnoseUseOfDecl(Best->FoundDecl, Kind.getLocation());
+ DiagnoseUseOfDecl(Best->Function, Kind.getLocation());
MarkFunctionReferenced(Kind.getLocation(), Best->Function);
break;
}
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 7b7d43ef3234c..8c6ae204d6d19 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1675,6 +1675,22 @@ NamedDecl *Sema::ActOnTemplateTemplateParameter(
bool IsParameterPack = EllipsisLoc.isValid();
+ SourceLocation Loc = NameLoc.isInvalid() ? TmpLoc : NameLoc;
+ if (Params->size() == 0) {
+ Diag(Loc, diag::err_template_template_parm_no_parms)
+ << SourceRange(Params->getLAngleLoc(), Params->getRAngleLoc());
+
+ // Recover as if there was a type template parameter pack.
+ SmallVector<NamedDecl *, 4> ParamDecls;
+ ParamDecls.push_back(TemplateTypeParmDecl::Create(
+ Context, Context.getTranslationUnitDecl(), Loc, SourceLocation(),
+ Depth + 1, 0, /*Id=*/nullptr,
+ /*Typename=*/false, /*ParameterPack=*/true));
+ Params = TemplateParameterList::Create(
+ Context, Params->getTemplateLoc(), Params->getLAngleLoc(), ParamDecls,
+ Params->getRAngleLoc(), Params->getRequiresClause());
+ }
+
bool Invalid = false;
if (CheckTemplateParameterList(
Params,
@@ -1684,9 +1700,8 @@ NamedDecl *Sema::ActOnTemplateTemplateParameter(
// Construct the parameter object.
TemplateTemplateParmDecl *Param = TemplateTemplateParmDecl::Create(
- Context, Context.getTranslationUnitDecl(),
- NameLoc.isInvalid() ? TmpLoc : NameLoc, Depth, Position, IsParameterPack,
- Name, Kind, Typename, Params);
+ Context, Context.getTranslationUnitDecl(), Loc, Depth, Position,
+ IsParameterPack, Name, Kind, Typename, Params);
Param->setAccess(AS_public);
if (Param->isParameterPack())
@@ -1702,12 +1717,6 @@ NamedDecl *Sema::ActOnTemplateTemplateParameter(
IdResolver.AddDecl(Param);
}
- if (Params->size() == 0) {
- Diag(Param->getLocation(), diag::err_template_template_parm_no_parms)
- << SourceRange(Params->getLAngleLoc(), Params->getRAngleLoc());
- Invalid = true;
- }
-
if (Invalid)
Param->setInvalidDecl();
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index 11a671cb9ff8d..c6502105b6acd 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -220,7 +220,7 @@ class ExtractTypeForDeductionGuide
// A deduction guide can be either a template or a non-template function
// declaration. If \p TemplateParams is null, a non-template function
// declaration will be created.
-NamedDecl *
+CXXDeductionGuideDecl *
buildDeductionGuide(Sema &SemaRef, TemplateDecl *OriginalTemplate,
TemplateParameterList *TemplateParams,
CXXConstructorDecl *Ctor, ExplicitSpecifier ES,
@@ -276,7 +276,7 @@ buildDeductionGuide(Sema &SemaRef, TemplateDecl *OriginalTemplate,
if (HaveSameAssociatedConstraints(SemaRef, ExistingCtor, ExistingACs,
Ctor, NewACs))
- return Existing;
+ return ExistingGuide;
}
}
@@ -307,7 +307,7 @@ buildDeductionGuide(Sema &SemaRef, TemplateDecl *OriginalTemplate,
GuideTemplate->setAccess(AS_public);
DC->addDecl(GuideTemplate);
- return GuideTemplate;
+ return Guide;
}
// Transform a given template type parameter `TTP`.
@@ -570,7 +570,8 @@ struct ConvertConstructorToDeductionGuideTransform {
}
/// Build a deduction guide with the specified parameter types.
- NamedDecl *buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
+ CXXDeductionGuideDecl *
+ buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
SourceLocation Loc = Template->getLocation();
// Build the requested type.
@@ -1081,11 +1082,14 @@ bool IsNonDeducedArgument(const TemplateArgument &TA) {
}
// Build deduction guides for a type alias template from the given underlying
-// deduction guide F.
-FunctionTemplateDecl *
-BuildDeductionGuideForTypeAlias(Sema &SemaRef,
- TypeAliasTemplateDecl *AliasTemplate,
- FunctionTemplateDecl *F, SourceLocation Loc) {
+// source deduction guide.
+CXXDeductionGuideDecl *BuildDeductionGuideForTypeAlias(
+ Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
+ CXXDeductionGuideDecl *SourceDeductionGuide, SourceLocation Loc) {
+ FunctionTemplateDecl *F =
+ SourceDeductionGuide->getDescribedFunctionTemplate();
+ assert(F && "deduction guide for alias template must be a function template");
+
LocalInstantiationScope Scope(SemaRef);
Sema::NonSFINAEContext _1(SemaRef);
Sema::InstantiatingTemplate BuildingDeductionGuides(
@@ -1116,7 +1120,7 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
//
// Instead, we need to canonicalize both against A, i.e. A<A<T>> and A<A<U>>,
// such that T can be deduced as U.
- auto RType = F->getTemplatedDecl()->getReturnType();
+ auto RType = SourceDeductionGuide->getReturnType();
// The (trailing) return type of the deduction guide.
const auto *FReturnType = RType->getAs<TemplateSpecializationType>();
if (const auto *ICNT = RType->getAsCanonical<InjectedClassNameType>())
@@ -1316,25 +1320,26 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
buildAssociatedConstraints(SemaRef, F, AliasTemplate, DeduceResults,
FirstUndeducedParamIdx, IsDeducible);
- auto *FPrimeTemplateParamList = TemplateParameterList::Create(
- Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
- AliasTemplate->getTemplateParameters()->getLAngleLoc(),
- FPrimeTemplateParams,
- AliasTemplate->getTemplateParameters()->getRAngleLoc(),
- /*RequiresClause=*/RequiresClause);
- auto *Result = cast<FunctionTemplateDecl>(buildDeductionGuide(
+ TemplateParameterList *FPrimeTemplateParamList = nullptr;
+ if (!FPrimeTemplateParams.empty())
+ FPrimeTemplateParamList = TemplateParameterList::Create(
+ Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
+ AliasTemplate->getTemplateParameters()->getLAngleLoc(),
+ FPrimeTemplateParams,
+ AliasTemplate->getTemplateParameters()->getRAngleLoc(),
+ /*RequiresClause=*/RequiresClause);
+
+ auto *DGuide = buildDeductionGuide(
SemaRef, AliasTemplate, FPrimeTemplateParamList,
GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(),
GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(),
AliasTemplate->getLocation(), AliasTemplate->getEndLoc(),
- F->isImplicit()));
- auto *DGuide = cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl());
+ F->isImplicit());
DGuide->setDeductionCandidateKind(GG->getDeductionCandidateKind());
- DGuide->setSourceDeductionGuide(
- cast<CXXDeductionGuideDecl>(F->getTemplatedDecl()));
+ DGuide->setSourceDeductionGuide(SourceDeductionGuide);
DGuide->setSourceDeductionGuideKind(
CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias);
- return Result;
+ return DGuide;
}
return nullptr;
}
@@ -1412,16 +1417,16 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
// The **aggregate** deduction guides are handled in a different code path
// (DeclareAggregateDeductionGuideFromInitList), which involves the tricky
// cache.
- if (cast<CXXDeductionGuideDecl>(F->getTemplatedDecl())
- ->getDeductionCandidateKind() == DeductionCandidate::Aggregate)
+ auto *DGuide = cast<CXXDeductionGuideDecl>(F->getTemplatedDecl());
+ if (DGuide->getDeductionCandidateKind() == DeductionCandidate::Aggregate)
continue;
- BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, F, Loc);
+ BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, DGuide, Loc);
}
}
// Build an aggregate deduction guide for a type alias template.
-FunctionTemplateDecl *DeclareAggregateDeductionGuideForTypeAlias(
+CXXDeductionGuideDecl *DeclareAggregateDeductionGuideForTypeAlias(
Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
MutableArrayRef<QualType> ParamTypes, SourceLocation Loc) {
TemplateDecl *RHSTemplate =
@@ -1445,7 +1450,7 @@ FunctionTemplateDecl *DeclareAggregateDeductionGuideForTypeAlias(
return nullptr;
for (TypedefNameDecl *TD : TypedefDecls)
- TD->setDeclContext(RHSDeductionGuide->getTemplatedDecl());
+ TD->setDeclContext(RHSDeductionGuide);
return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate,
RHSDeductionGuide, Loc);
@@ -1453,7 +1458,7 @@ FunctionTemplateDecl *DeclareAggregateDeductionGuideForTypeAlias(
} // namespace
-FunctionTemplateDecl *Sema::DeclareAggregateDeductionGuideFromInitList(
+CXXDeductionGuideDecl *Sema::DeclareAggregateDeductionGuideFromInitList(
TemplateDecl *Template, MutableArrayRef<QualType> ParamTypes,
SourceLocation Loc) {
llvm::FoldingSetNodeID ID;
@@ -1463,18 +1468,15 @@ FunctionTemplateDecl *Sema::DeclareAggregateDeductionGuideFromInitList(
unsigned Hash = ID.ComputeHash();
auto Found = AggregateDeductionCandidates.find(Hash);
- if (Found != AggregateDeductionCandidates.end()) {
- CXXDeductionGuideDecl *GD = Found->getSecond();
- return GD->getDescribedFunctionTemplate();
- }
+ if (Found != AggregateDeductionCandidates.end())
+ return Found->getSecond();
if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
- if (auto *FTD = DeclareAggregateDeductionGuideForTypeAlias(
+ if (auto *GD = DeclareAggregateDeductionGuideForTypeAlias(
*this, AliasTemplate, ParamTypes, Loc)) {
- auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
AggregateDeductionCandidates[Hash] = GD;
- return FTD;
+ return GD;
}
}
@@ -1509,13 +1511,11 @@ FunctionTemplateDecl *Sema::DeclareAggregateDeductionGuideFromInitList(
Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
- auto *FTD = cast<FunctionTemplateDecl>(
- Transform.buildSimpleDeductionGuide(ParamTypes));
+ CXXDeductionGuideDecl *GD = Transform.buildSimpleDeductionGuide(ParamTypes);
SavedContext.pop();
- auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
AggregateDeductionCandidates[Hash] = GD;
- return FTD;
+ return GD;
}
void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
@@ -1607,10 +1607,7 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
// -- An additional function template derived as above from a hypothetical
// constructor C(C), called the copy deduction candidate.
- cast<CXXDeductionGuideDecl>(
- cast<FunctionTemplateDecl>(
- Transform.buildSimpleDeductionGuide(Transform.DeducedType))
- ->getTemplatedDecl())
+ Transform.buildSimpleDeductionGuide(Transform.DeducedType)
->setDeductionCandidateKind(DeductionCandidate::Copy);
SavedContext.pop();
diff --git a/clang/test/SemaCXX/ctad.cpp b/clang/test/SemaCXX/ctad.cpp
index 7de7f50337e8c..2a4e1c571ac5c 100644
--- a/clang/test/SemaCXX/ctad.cpp
+++ b/clang/test/SemaCXX/ctad.cpp
@@ -74,7 +74,7 @@ template <int>
using AstNode = variant<>;
// expected-note at -1 {{couldn't infer template argument ''}} \
// expected-note at -1 2{{implicit deduction guide declared as}} \
-// expected-note at -1 {{candidate function template not viable}}
+// expected-note at -1 {{candidate function not viable}}
AstNode tree; // expected-error {{no viable constructor or deduction guide}}
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 0349428295f54..78911cbaed67b 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -622,9 +622,10 @@ Alias b(42);
namespace GH190517 {
template <typename T> struct S1 {};
template <typename T> using S2 = S1<char>;
-template <typename T> using S3 = S2<T>; // expected-note {{candidate function template not viable}} \
+template <typename T> using S3 = S2<T>; // expected-note {{candidate function not viable}} \
// expected-note {{implicit deduction guide declared}} \
- // expected-note {{candidate function template not viable}} \
- // expected-note {{implicit deduction guide declared}}
+ // expected-note {{candidate function not viable}} \
+ // expected-note {{implicit deduction guide declared}} \
+ // expected-note {{cannot deduce template arguments for 'GH190517::S3' from 'GH190517::S1<char>'}}
S3 foo(42); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'S3'}}
}
diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp
index 9e5756ffec3fc..348f8a5018082 100644
--- a/clang/test/SemaTemplate/deduction-guide.cpp
+++ b/clang/test/SemaTemplate/deduction-guide.cpp
@@ -267,8 +267,8 @@ template <typename X = int>
using BG = G<int>;
BG bg(1.0);
// CHECK-LABEL: Dumping <deduction guide for BG>
-// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for BG>
-// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G<int>' aggregate
+// CHECK-NOT: FunctionTemplateDecl
+// CHECK: CXXDeductionGuideDecl {{.*}} 'auto (int) -> G<int>' aggregate
template <typename D>
requires (sizeof(D) == 4)
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index e63d247c01d11..62c3742652537 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -1632,6 +1632,8 @@ TypeSystemClang::CreateTemplateTemplateParmDecl(const char *template_name) {
llvm::SmallVector<NamedDecl *, 8> template_param_decls;
TypeSystemClang::TemplateParameterInfos template_param_infos;
+ template_param_infos.SetParameterPack(
+ std::make_unique<TemplateParameterInfos>());
TemplateParameterList *template_param_list = CreateTemplateParameterList(
ast, template_param_infos, template_param_decls);
More information about the lldb-commits
mailing list