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
