On 3/16/26 6:57 PM, Marek Polacek wrote:
On Mon, Mar 16, 2026 at 03:06:08PM -0400, Jason Merrill wrote:On 3/16/26 10:39 AM, Marek Polacek wrote:Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?-- >8 -- This is a crash on invalid [:X:]<args> where [:X:] doesn't designate a template. Like in cp_parser_template_id, we should check that we have an appropriate template before calling finish_template_type on it. PR c++/124493 gcc/cp/ChangeLog: * pt.cc (tsubst) <case TEMPLATE_ID_EXPR>: Check that templ is either DECL_TYPE_TEMPLATE_P or DECL_TEMPLATE_TEMPLATE_PARM_P. gcc/testsuite/ChangeLog: * g++.dg/reflect/crash19.C: New test. --- gcc/cp/pt.cc | 12 ++++++++++++ gcc/testsuite/g++.dg/reflect/crash19.C | 8 ++++++++ 2 files changed, 20 insertions(+) create mode 100644 gcc/testsuite/g++.dg/reflect/crash19.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 46621ecd2ea..05c05e65e68 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -17800,6 +17800,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) templ = tsubst_splice_expr (templ, args, complain, in_decl); if (templ == error_mark_node) return error_mark_node; + if (!DECL_TYPE_TEMPLATE_P (templ) + && !DECL_TEMPLATE_TEMPLATE_PARM_P (templ)) + { + if (complain & tf_error) + { + auto_diagnostic_group d; + error_at (cp_expr_loc_or_input_loc (TREE_OPERAND (t, 0)), + "expected a reflection of a template");What if templ is a function or variable template?They should (and will) be rejected too [*]. Initially this error said "expected a reflection of a class template" but that doesn't cover the alias/template template parm case. What if I change it to "expected a reflection of a type template"?
Sure, OK with this change.
[*] say,
template<typename T> void Y(T);
template<decltype(^^::) R>
constexpr auto f () -> [:R:]<0> { return {}; }
constexpr auto a = f<^^Y>();
And maybe add this to the/a test?
+ inform_tree_category (templ); + } + return error_mark_node; + } tree targs = TREE_OPERAND (t, 1); if (targs) targs = tsubst_template_args (targs, args, complain, in_decl); diff --git a/gcc/testsuite/g++.dg/reflect/crash19.C b/gcc/testsuite/g++.dg/reflect/crash19.C new file mode 100644 index 00000000000..2067dcaa869 --- /dev/null +++ b/gcc/testsuite/g++.dg/reflect/crash19.C @@ -0,0 +1,8 @@ +// PR c++/124493 +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } + +struct Y { }; +template<decltype(^^::) R> +constexpr auto f (typename [:R:]<0> x) { return x; } // { dg-error "expected a reflection of a template" } +constexpr auto a = f<^^Y>(Y{}); // { dg-error "no matching function for call" } base-commit: 64f95a0eeaf1cb6d07cc414c9b2953a494e03be1Marek
