Bootstrapped and successfully run all 'dg.exp=reflect/*' tests on my 
x86_64-linux-gnu. Ok for trunk?

-- >8 --

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: Change test case since it's allowed per 
class.mem.general/3. 
        * g++.dg/reflect/anon4.C: New test based on original bug report.

Signed-off-by: Valentyn Yukhymenko <[email protected]>
---
 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(-)
 create mode 100644 gcc/testsuite/g++.dg/reflect/anon4.C

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 20ef2a4d6df..79eb3b5ba28 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 00000000000..45117a3c048
--- /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 35c3ff4dd0a..6e38ef6b64a 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