On Tue, Mar 17, 2026 at 01:15:17AM -0400, Jason Merrill wrote:
> 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?

Done, thanks.

-- >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.
        * g++.dg/reflect/crash22.C: New test.

Reviewed-by: Jason Merrill <[email protected]>

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 58bb10eef1b..020a70c1112 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 type template");
+               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..41cab081044
--- /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 type template" }
+constexpr auto a = f<^^Y>(Y{}); // { dg-error "no matching function for call" }
diff --git a/gcc/testsuite/g++.dg/reflect/crash22.C 
b/gcc/testsuite/g++.dg/reflect/crash22.C
new file mode 100644
index 00000000000..75b8e931a67
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/crash22.C
@@ -0,0 +1,8 @@
+// PR c++/124493
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+template<typename T> void Y(T);        // { dg-message "but .Y. is a function 
template" }
+template<decltype(^^::) R>
+constexpr auto f () -> [:R:]<0> { return {}; } // { dg-error "expected a 
reflection of a type template" }
+constexpr auto a = f<^^Y>(); // { dg-error "no matching function" }

Reply via email to