Hi!

The following testcase ICEs during error recovery, because we aren't
prepared to handle error_mark_node type.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2026-05-25  Jakub Jelinek  <[email protected]>

        PR c++/125412
        * reflect.cc (eval_constant_of): If type is error_mark_node, set
        *non_constant_p and return.

        * g++.dg/reflect/pr125412.C: New test.

--- gcc/cp/reflect.cc.jj        2026-05-25 10:42:52.681817335 +0200
+++ gcc/cp/reflect.cc   2026-05-25 11:52:34.463284671 +0200
@@ -2789,6 +2789,11 @@ eval_constant_of (location_t loc, const
     type = type_of (r, kind);
   else
     type = maybe_strip_typedefs (r);
+  if (type == error_mark_node)
+    {
+      *non_constant_p = true;
+      return NULL_TREE;
+    }
 
   /* So that outer_automatic_var_p works below in check_splice_expr.  */
   temp_override<tree> ovr (current_function_decl);
--- gcc/testsuite/g++.dg/reflect/pr125412.C.jj  2026-05-25 12:02:08.456192292 
+0200
+++ gcc/testsuite/g++.dg/reflect/pr125412.C     2026-05-25 12:10:38.405976096 
+0200
@@ -0,0 +1,24 @@
+// PR c++/125412
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+#include <meta>
+
+void
+foo ()
+{
+}
+
+auto bar ();
+
+template <typename T>
+auto a = foo ();       // { dg-error "variable or field 'a' declared void" }
+template <typename T>
+auto b = bar ();       // { dg-error "use of 'auto bar\\\(\\\)' before 
deduction of 'auto'" }
+
+consteval {
+  auto c = substitute (^^a, { ^^int });
+  std::meta::extract <int> (c);
+  auto d = substitute (^^b, { ^^int });
+  std::meta::extract <int> (d);
+}

        Jakub

Reply via email to