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?

-- >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

Reply via email to