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");
+ 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
--
2.53.0