From: Marek Polacek Date: Sun, 1 Feb 2026 23:06:20 +0000 (-0500) Subject: c++/reflection: fix ICE with object_of [PR123695] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b2a3804758bb8e731ad18420cf79fd03cf280d9;p=thirdparty%2Fgcc.git c++/reflection: fix ICE with object_of [PR123695] In eval_object_of we are calling cxx_eval_constant_expression on references to get the referent. We should check that the type is non-null before checking TYPE_REF_P, because for invalid arguments it can be null, as shown in the test. PR c++/123695 gcc/cp/ChangeLog: * reflect.cc (eval_object_of): Check type before TYPE_REF_P. gcc/testsuite/ChangeLog: * g++.dg/reflect/object_of3.C: New test. Co-authored-by: Boris Staletic Reviewed-by: Jason Merrill --- diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index 56f36e917e9..24b8d744810 100644 --- a/gcc/cp/reflect.cc +++ b/gcc/cp/reflect.cc @@ -2602,7 +2602,8 @@ eval_object_of (location_t loc, const constexpr_ctx *ctx, tree r, tree *jump_target, tree fun) { tree orig = r; - if (TYPE_REF_P (TREE_TYPE (r))) + tree type = TREE_TYPE (r); + if (type && TYPE_REF_P (type)) r = cxx_eval_constant_expression (ctx, r, vc_prvalue, non_constant_p, overflow_p, jump_target); r = maybe_get_reference_referent (r); diff --git a/gcc/testsuite/g++.dg/reflect/object_of3.C b/gcc/testsuite/g++.dg/reflect/object_of3.C new file mode 100644 index 00000000000..d7d0f13a87a --- /dev/null +++ b/gcc/testsuite/g++.dg/reflect/object_of3.C @@ -0,0 +1,34 @@ +// PR c++/123695 +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } +// Test std::meta::object_of with invalid arguments. + +#include +using namespace std::meta; + +struct A {}; +struct B : A {}; + +using U = int; + +enum E { EE }; +auto fn (); +[[=1]] void foo (); + +consteval bool +object_of_ok (info r) +{ + try { object_of (r); } + catch (std::meta::exception &) { return false; } + return true; +} + +static_assert (!object_of_ok (^^EE)); +static_assert (!object_of_ok (^^::)); +static_assert (!object_of_ok (^^int)); +static_assert (!object_of_ok (^^U)); +static_assert (!object_of_ok (^^fn)); +static_assert (!object_of_ok (annotations_of (^^foo)[0])); +static_assert (!object_of_ok (reflect_constant (42))); +static_assert (!object_of_ok (bases_of (^^B, access_context::unchecked ())[0])); +static_assert (!object_of_ok (data_member_spec (^^int, { .name = "dms" })));