]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/reflection: ICE with invalid splice-spec-spec [PR124493]
authorMarek Polacek <polacek@redhat.com>
Fri, 13 Mar 2026 20:25:00 +0000 (16:25 -0400)
committerMarek Polacek <polacek@redhat.com>
Tue, 17 Mar 2026 15:23:41 +0000 (11:23 -0400)
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 <jason@redhat.com>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/reflect/crash19.C [new file with mode: 0644]
gcc/testsuite/g++.dg/reflect/crash22.C [new file with mode: 0644]

index 58bb10eef1bd92142b824f7b516d33bba6d12041..020a70c11121d1fb50056f01338c6b6d30f2f0db 100644 (file)
@@ -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 (file)
index 0000000..41cab08
--- /dev/null
@@ -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 (file)
index 0000000..75b8e93
--- /dev/null
@@ -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" }