]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/reflection: anon union member from splice [PR123642]
authorValentyn Yukhymenko <valentin.yukhymenko@gmail.com>
Fri, 20 Feb 2026 16:31:36 +0000 (16:31 +0000)
committerJason Merrill <jason@redhat.com>
Sun, 22 Feb 2026 15:01:54 +0000 (00:01 +0900)
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 <valentin.yukhymenko@gmail.com>
gcc/cp/typeck.cc
gcc/testsuite/g++.dg/reflect/anon4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/reflect/member4.C

index 20ef2a4d6df5550d1f5e22dcc6289c4541239f3c..79eb3b5ba2863a217c40731f868042f3dbda207a 100644 (file)
@@ -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 (file)
index 0000000..45117a3
--- /dev/null
@@ -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);
+}
index 35c3ff4dd0a8431f63268088be6a13333e62950a..6e38ef6b64acbe8ebbb16c38a5f01fb4d6716866 100644 (file)
@@ -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" }