https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123823
--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The trunk branch has been updated by Marek Polacek <[email protected]>: https://gcc.gnu.org/g:5d9de7136b30b104606e85fc4284a25a8063a0c0 commit r16-7389-g5d9de7136b30b104606e85fc4284a25a8063a0c0 Author: Marek Polacek <[email protected]> Date: Mon Jan 26 14:51:02 2026 -0500 c++/reflection: splice parsing fixes [PR123823] This patch fixes the problem that when cp_parser_splice_specifier sees :]<, it always thinks it's a template-id. Consequently, this should compile but does not: int i; constexpr auto r = ^^i; bool b = [:r:] < 42; because we think that a template argument list follows the splice. Fixed by implementing [temp.names]/3 better: only attempt to parse a template argument list if we saw template or typename. As an extension, also parse a template argument list if the splice yielded a TEMPLATE_DECL -- in that case, chances are that the user simply forgot to specify 'template'. In that case we'll suggest adding 'template' in cp_parser_splice_expression. We should accept the following given [temp.names]/3: S<[:r:] < 43> s; and we should also accept: [:r:] < 42 > 0; I also realized that my code to detect unparenthesized splice expressions as template arguments is wrong. [expr.prim.splice] says that constexpr auto i = e<[:^^h:]>; is ill-formed, but "S<[:r:] >= 1>" is fine as per [temp.names]/6. I moved the checking to cp_parser_template_argument while making sure that we only complain when the splice-expression is the whole template-argument. This patch also fixes 123640. PR c++/123823 PR c++/123640 gcc/cp/ChangeLog: * parser.cc (cp_parser_splice_specifier): New typename_p parameter. Use cp_parser_nth_token_starts_template_argument_list_p instead of checking CPP_LESS. Check for typename/template/TEMPLATE_DECL before parsing a template-id. (cp_parser_splice_type_specifier): Adjust the call to cp_parser_splice_specifier. (cp_parser_splice_expression): Don't detect unparenthesized splice expressions here. Adjust the call to cp_parser_splice_specifier. (cp_parser_splice_scope_specifier): Adjust the call to cp_parser_splice_specifier. (cp_parser_skip_entire_splice_expr): New, broken out of... (cp_parser_splice_spec_is_nns_p): ...this. (cp_parser_template_id): Call pop_deferring_access_checks. (cp_parser_template_argument): Detect unparenthesized splice expressions here. gcc/testsuite/ChangeLog: * g++.dg/reflect/crash6.C: Adjust expected diagnostic. * g++.dg/reflect/expr3.C: Likewise. Test more cases. * g++.dg/reflect/splice4.C: Adjust expected diagnostic. * g++.dg/reflect/error12.C: New test. * g++.dg/reflect/parse1.C: New test. * g++.dg/reflect/parse2.C: New test. * g++.dg/reflect/parse3.C: New test. * g++.dg/reflect/parse4.C: New test. * g++.dg/reflect/parse5.C: New test. * g++.dg/reflect/parse6.C: New test. Reviewed-by: Jason Merrill <[email protected]>
