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"?
[*] say,
template<typename T> void Y(T);
template<decltype(^^::) R>
constexpr auto f () -> [:R:]<0> { return {}; }
constexpr auto a = f<^^Y>();
> > + 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: 64f95a0eeaf1cb6d07cc414c9b2953a494e03be1
>
Marek