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

Reply via email to