On Mon, Feb 02, 2026 at 10:11:19PM +0800, Jason Merrill wrote: > On 2/2/26 7:13 AM, Marek Polacek wrote: > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > OK, though would it make sense to check is_object || is_variable since those > are the valid cases?
The eval_has_static_storage_duration checks in eval_object_of check both of these and I didn't want to repeat them. But I think it would work, too. Thanks, > > -- >8 -- > > 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 <[email protected]> > > --- > > gcc/cp/reflect.cc | 3 +- > > gcc/testsuite/g++.dg/reflect/object_of3.C | 34 +++++++++++++++++++++++ > > 2 files changed, 36 insertions(+), 1 deletion(-) > > create mode 100644 gcc/testsuite/g++.dg/reflect/object_of3.C > > > > 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 <meta> > > +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" > > }))); > > > > base-commit: 7eac62572c7955e38760a906debea5cbed846491 > Marek
