From a2e2fdf2f52c0d73e63a3005db459b4fa09bec7f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 9 Feb 2026 17:54:10 +0100 Subject: [PATCH] c++: Add self reference to define_aggregate created aggregates [PR123984] We weren't adding the DECL_SELF_REFERENCE_P TYPE_DECL to TYPE_FIELDS of eval_define_aggregate created aggregates, which resulted in ICE in accessible_base_p which relies on DECL_SELF_REFERENCE_P TYPE_DECL to be present in base classes of other classes. 2026-02-09 Jakub Jelinek PR c++/123984 * reflect.cc (eval_define_aggregate): Set TYPE_BEING_DEFINED on type after pushclass, call build_self_reference, remove assertion that TYPE_FIELDS (type) is NULL and instead set fields to TYPE_FIELDS (type). * g++.dg/reflect/define_aggregate6.C: New test. --- gcc/cp/reflect.cc | 5 +++-- .../g++.dg/reflect/define_aggregate6.C | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/reflect/define_aggregate6.C diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index b6b7556e424..d04930d732c 100644 --- a/gcc/cp/reflect.cc +++ b/gcc/cp/reflect.cc @@ -6080,8 +6080,9 @@ eval_define_aggregate (location_t loc, const constexpr_ctx *ctx, if (!TYPE_BINFO (type)) xref_basetypes (type, NULL_TREE); pushclass (type); - gcc_assert (!TYPE_FIELDS (type)); - tree fields = NULL_TREE; + TYPE_BEING_DEFINED (type) = 1; + build_self_reference (); + tree fields = TYPE_FIELDS (type); for (int i = 0; i < TREE_VEC_LENGTH (rvec); ++i) { tree ra = TREE_VEC_ELT (rvec, i); diff --git a/gcc/testsuite/g++.dg/reflect/define_aggregate6.C b/gcc/testsuite/g++.dg/reflect/define_aggregate6.C new file mode 100644 index 00000000000..96c37a311f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/reflect/define_aggregate6.C @@ -0,0 +1,22 @@ +// PR c++/123984 +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } + +#include + +struct A; +consteval +{ + define_aggregate (^^A, { data_member_spec (^^int, {.name{"_"}}) }); +} + +struct B : A {}; + +constexpr int +get (B &&d) +{ + constexpr auto ctx = std::meta::access_context::unchecked (); + return static_cast (&d)->[: nonstatic_data_members_of (^^A, ctx)[0] :]; +} + +static_assert (get (B { 123 }) == 123); -- 2.47.3