https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/230766
Fixes https://github.com/llvm/llvm-project/issues/75248 >From 883868380df0aa1169f52fbcf7d9f33f46fd2e78 Mon Sep 17 00:00:00 2001 From: Younan Zhang <[email protected]> Date: Sat, 10 Oct 2026 17:14:19 +0800 Subject: [PATCH] [Clang] Suggest missing typename to dependent packs --- clang/docs/ReleaseNotes.md | 4 +++- clang/lib/Sema/SemaTemplate.cpp | 16 +++++++++++++--- clang/test/SemaTemplate/typename-specifier.cpp | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 2ea67cbd78bcc..d6079299657bc 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -587,6 +587,8 @@ features cannot lower the translation-unit ABI level; `operator delete`, since such a delete expression never invokes the destructor. (#GH65524) +- Suggest missing `typename` prefixes to dependent packs within template arguments. (#GH75248) + - Fixed a false-positive `-Wshadow` warning when a variable in an inline-defined friend function shares the name of a non-static class member variable. (#GH221190) @@ -605,7 +607,7 @@ features cannot lower the translation-unit ABI level; keyword, such as when deferring the last statement of a block; when used as the body of a conditional; or when it immediately precedes a `break`/`continue` statement or a `return` with no argument. - + - Clang now diagnoses arrays whose size is deduced from an initializer list when they exceed the maximum object size ### Improvements to Clang's time-trace diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 8e7433bc71281..d2c5ec821c038 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5245,13 +5245,17 @@ bool Sema::CheckTemplateTypeArgument( // expression; see if maybe it is missing the "typename" keyword. CXXScopeSpec SS; DeclarationNameInfo NameInfo; + TemplateArgument Pattern = Arg; + if (Pattern.isPackExpansion()) + Pattern = Pattern.getPackExpansionPattern(); + Expr *E = Pattern.getAsExpr(); - if (DependentScopeDeclRefExpr *ArgExpr = - dyn_cast<DependentScopeDeclRefExpr>(Arg.getAsExpr())) { + if (DependentScopeDeclRefExpr *ArgExpr = + dyn_cast<DependentScopeDeclRefExpr>(E)) { SS.Adopt(ArgExpr->getQualifierLoc()); NameInfo = ArgExpr->getNameInfo(); } else if (CXXDependentScopeMemberExpr *ArgExpr = - dyn_cast<CXXDependentScopeMemberExpr>(Arg.getAsExpr())) { + dyn_cast<CXXDependentScopeMemberExpr>(E)) { if (ArgExpr->isImplicitAccess()) { SS.Adopt(ArgExpr->getQualifierLoc()); NameInfo = ArgExpr->getMemberNameInfo(); @@ -5282,6 +5286,12 @@ bool Sema::CheckTemplateTypeArgument( TL.setElaboratedKeywordLoc(SourceLocation(/*synthesized*/)); TL.setQualifierLoc(SS.getWithLocInContext(Context)); TL.setNameLoc(NameInfo.getLoc()); + if (Arg.isPackExpansion()) { + ArgType = Context.getPackExpansionType(ArgType, std::nullopt); + PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(ArgType); + TL.setEllipsisLoc( + cast<PackExpansionExpr>(Arg.getAsExpr())->getEllipsisLoc()); + } TSI = TLB.getTypeSourceInfo(Context, ArgType); // Overwrite our input TemplateArgumentLoc so that we can recover diff --git a/clang/test/SemaTemplate/typename-specifier.cpp b/clang/test/SemaTemplate/typename-specifier.cpp index 27175c5b0b568..3c88d0806ffd8 100644 --- a/clang/test/SemaTemplate/typename-specifier.cpp +++ b/clang/test/SemaTemplate/typename-specifier.cpp @@ -192,6 +192,24 @@ class ExampleClass1 { pair<ExampleItemMap::iterator, int> entry; pair<bar, int> foobar; // expected-error {{template argument for template type parameter must be a type}} }; + +#if __cplusplus >= 201103L +namespace GH75248 { + +template <typename... Ts> struct S; + +template <typename... Ts> +using U2 = S<Ts::Type...>; +#ifdef MSVC +// expected-warning@-2 {{must be a type; omitted 'typename' is a Microsoft extension}} +#else +// expected-error@-4 {{must be a type; did you forget 'typename'?}} +#endif +// expected-note@-9 {{declared here}} + +} +#endif + } // namespace missing_typename namespace missing_typename_and_base { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
