https://gcc.gnu.org/g:403ffd5d11ccaa5cf68d0220c4b2b793b6b7d3f7
commit r16-7625-g403ffd5d11ccaa5cf68d0220c4b2b793b6b7d3f7 Author: Valentyn Yukhymenko <[email protected]> Date: Fri Feb 20 16:31:36 2026 +0000 c++/reflection: anon union member from splice [PR123642] Fixes a bogus "'Cls::<unnamed union>' is not a base of 'const Cls'" error when user tries to do a class member lookup using splice with reflection of anon union member. PR c++/123642 gcc/cp/ChangeLog: * typeck.cc (finish_class_member_access_expr): Change context lookup to handle anon union members. gcc/testsuite/ChangeLog: * g++.dg/reflect/member4.C: Remove expected error. * g++.dg/reflect/anon4.C: New test based on original bug report. Signed-off-by: Valentyn Yukhymenko <[email protected]> Diff: --- gcc/cp/typeck.cc | 2 +- gcc/testsuite/g++.dg/reflect/anon4.C | 33 +++++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/reflect/member4.C | 2 +- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 20ef2a4d6df5..79eb3b5ba286 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -3600,7 +3600,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, || TREE_CODE (name) == CONST_DECL || TREE_CODE (name) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name)))) - scope = DECL_CONTEXT (OVL_FIRST (name)); + scope = context_for_name_lookup (OVL_FIRST (name)); if (TREE_CODE (name) == TEMPLATE_ID_EXPR) { diff --git a/gcc/testsuite/g++.dg/reflect/anon4.C b/gcc/testsuite/g++.dg/reflect/anon4.C new file mode 100644 index 000000000000..45117a3c0481 --- /dev/null +++ b/gcc/testsuite/g++.dg/reflect/anon4.C @@ -0,0 +1,33 @@ +// PR c++/123642 +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } + +struct foo +{ + int i; + union + { + int a; + long b; + union + { + double c; + }; + }; +}; + +void test () +{ + constexpr foo bar { .i = 11, .a = 1 }; + + static_assert (bar.a == 1); + static_assert (bar.[: ^^foo::a :] == 1); + + static_assert (bar.*(&foo::a) == 1); + static_assert (bar.*&[: ^^foo::a :] == 1); + + constexpr foo bar1 { .i = 42, .c = 3.14 }; + + static_assert (bar1.c == 3.14); + static_assert (bar1.[: ^^foo::c :] == 3.14); +} diff --git a/gcc/testsuite/g++.dg/reflect/member4.C b/gcc/testsuite/g++.dg/reflect/member4.C index 35c3ff4dd0a8..6e38ef6b64ac 100644 --- a/gcc/testsuite/g++.dg/reflect/member4.C +++ b/gcc/testsuite/g++.dg/reflect/member4.C @@ -10,5 +10,5 @@ struct C { struct D { int i; }; auto c = C{.i=2}; -auto v = c.[:^^C::i:]; // { dg-error "not a base" } +auto v = c.[:^^C::i:]; auto e = c.[: ^^D::i :]; // { dg-error "not a base" }
