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