[clang] fd51c78 - [clang] fix alias ctad producing function template with no template parameters (#195303)
via cfe-commits
cfe-commits at lists.llvm.org
Sat May 2 06:59:22 PDT 2026
Author: Matheus Izvekov
Date: 2026-05-02T10:59:17-03:00
New Revision: fd51c78584865accff4beebe877ef51bf5506caa
URL: https://github.com/llvm/llvm-project/commit/fd51c78584865accff4beebe877ef51bf5506caa
DIFF: https://github.com/llvm/llvm-project/commit/fd51c78584865accff4beebe877ef51bf5506caa.diff
LOG: [clang] fix alias ctad producing function template with no template parameters (#195303)
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Sema/Sema.h
clang/lib/AST/DeclTemplate.cpp
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaTemplateDeductionGuide.cpp
clang/test/SemaCXX/ctad.cpp
clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
clang/test/SemaTemplate/deduction-guide.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 61140ee6e880e..fdafc4871ed1b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -569,6 +569,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
diff erent 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 cfe-commits
mailing list