Author: Serosh Date: 2026-03-01T18:38:52-03:00 New Revision: d947f8f699eb7d14c883f180f72329cae3a23fd3
URL: https://github.com/llvm/llvm-project/commit/d947f8f699eb7d14c883f180f72329cae3a23fd3 DIFF: https://github.com/llvm/llvm-project/commit/d947f8f699eb7d14c883f180f72329cae3a23fd3.diff LOG: [clang][Sema] fix crash on __type_pack_element with dependent packs (GH180307) (#180407) dependent pack expansions in __type_pack_element can result in single-element template argument lists. When performing semantic analysis for these builtins, the compiler needs to account for the dependent expansions and handle them without triggering strict size assertions. The patch adds this analysis and ensures we either defer evaluation for dependent cases or report clear out-of-bounds diagnostics instead of crashing Ai was used for test generation and CI debugging fixes #180307 Added: clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaTemplate.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index fe268ef2133b5..668097236fe97 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -322,6 +322,7 @@ Bug Fixes to C++ Support template parameters when one of its parameters is also a pack. (#GH181166) - Fixed a crash when a default argument is passed to an explicit object parameter. (#GH176639) - Fixed a crash when diagnosing an invalid static member function with an explicit object parameter (#GH177741) +- Fixed a crash when pack expansions are used as arguments for non-pack parameters of built-in templates. (#GH180307) - Fixed a bug where captured variables in non-mutable lambdas were incorrectly treated as mutable when used inside decltype in the return type. (#GH180460) - Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type vectors in ``constexpr``. (#GH180044) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a0a74f52f8aa9..ef0e29af0f224 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6159,7 +6159,7 @@ def note_template_declared_here : Note< "%1 declared here">; def err_template_expansion_into_fixed_list : Error< "pack expansion used as argument for non-pack parameter of %select{alias " - "template|concept}0">; + "template|concept|builtin template}0">; def note_parameter_type : Note< "parameter of type %0 is declared here">; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index b71dc371508b9..9f3bf7437fc54 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3408,6 +3408,9 @@ static QualType checkBuiltinTemplateIdType( TemplateArgumentListInfo &TemplateArgs) { ASTContext &Context = SemaRef.getASTContext(); + assert(Converted.size() == BTD->getTemplateParameters()->size() && + "Builtin template arguments do not match its parameters"); + switch (BTD->getBuiltinTemplateKind()) { case BTK__make_integer_seq: { // Specializations of __make_integer_seq<S, T, N> are treated like @@ -5981,13 +5984,16 @@ bool Sema::CheckTemplateArgumentList( Params->getDepth())); if (ArgIsExpansion && NonPackParameter) { // CWG1430/CWG2686: we have a pack expansion as an argument to an - // alias template or concept, and it's not part of a parameter pack. - // This can't be canonicalized, so reject it now. - if (isa<TypeAliasTemplateDecl, ConceptDecl>(Template)) { + // alias template, builtin template, or concept, and it's not part of + // a parameter pack. This can't be canonicalized, so reject it now. + if (isa<TypeAliasTemplateDecl, ConceptDecl, BuiltinTemplateDecl>( + Template)) { + unsigned DiagSelect = isa<ConceptDecl>(Template) ? 1 + : isa<BuiltinTemplateDecl>(Template) ? 2 + : 0; Diag(ArgLoc.getLocation(), diag::err_template_expansion_into_fixed_list) - << (isa<ConceptDecl>(Template) ? 1 : 0) - << ArgLoc.getSourceRange(); + << DiagSelect << ArgLoc.getSourceRange(); NoteTemplateParameterLocation(**Param); return true; } diff --git a/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp b/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp new file mode 100644 index 0000000000000..35526ed792ef8 --- /dev/null +++ b/clang/test/SemaCXX/builtin_templates_invalid_parameters.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// expected-note@* 0+ {{from hidden source}} + +using SizeT = decltype(sizeof(int)); + +// 1. Check pack expansion into non-pack parameter +template <SizeT... Seq> +using error_expansion = __type_pack_element<Seq...>; +// expected-error@-1 {{pack expansion used as argument for non-pack parameter of builtin template}} + +// 2. Check Arity mismatch (Too many/few) +template <int N> struct S; // expected-note 1+ {{template parameter is declared here}} +using too_many_args = __make_integer_seq<S, int, 2, int>; +// expected-error@* {{template argument for non-type template parameter must be an expression}} +// expected-note@* {{template template argument has diff erent template parameters}} + +using too_few_args = __type_pack_element<>; +// expected-error@-1 {{too few template arguments for template '__type_pack_element'}} + +// Verify that the compiler survives even if the alias refers back to an invalid one +// (We expect an 'undeclared identifier' here because error_expansion failed above) +template <typename T> +using bis = __make_integer_seq<error_expansion, T>; +// expected-error@-1 {{use of undeclared identifier 'error_expansion'}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
