Here lookup got confused by finding a conversion operator from
lookup_anon_field.  Let's avoid this by pruning functions from
CLASSTYPE_MEMBER_VEC as well as TYPE_FIELDS.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

        PR c++/97974
        * decl.c (fixup_anonymous_aggr): Prune all functions from
        CLASSTYPE_MEMBER_VEC.

gcc/testsuite/ChangeLog:

        PR c++/97974
        * g++.dg/other/anon-union5.C: New test.
---
 gcc/cp/decl.c                            | 8 ++++++++
 gcc/testsuite/g++.dg/lookup/pr84962.C    | 2 +-
 gcc/testsuite/g++.dg/other/anon-union5.C | 9 +++++++++
 3 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/other/anon-union5.C

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3294b4fa943..ec05ee1f0b4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5005,6 +5005,14 @@ fixup_anonymous_aggr (tree t)
     else
       prev_p = &DECL_CHAIN (probe);
 
+  /* Splice all functions out of CLASSTYPE_MEMBER_VEC.  */
+  vec<tree,va_gc>* vec = CLASSTYPE_MEMBER_VEC (t);
+  unsigned store = 0;
+  for (tree elt : vec)
+    if (!is_overloaded_fn (elt))
+      (*vec)[store++] = elt;
+  vec_safe_truncate (vec, store);
+
   /* Anonymous aggregates cannot have fields with ctors, dtors or complex
      assignment operators (because they cannot have these methods themselves).
      For anonymous unions this is already checked because they are not allowed
diff --git a/gcc/testsuite/g++.dg/lookup/pr84962.C 
b/gcc/testsuite/g++.dg/lookup/pr84962.C
index b9b7a313526..c22b95ce8f9 100644
--- a/gcc/testsuite/g++.dg/lookup/pr84962.C
+++ b/gcc/testsuite/g++.dg/lookup/pr84962.C
@@ -9,6 +9,6 @@ struct X {
     // { dg-error "public non-static data member" "" { target *-*-* } .-1 }
   };
 
-  int  : a; // { dg-error "non-integral" }
+  int  : a; // { dg-error "" }
 };
 
diff --git a/gcc/testsuite/g++.dg/other/anon-union5.C 
b/gcc/testsuite/g++.dg/other/anon-union5.C
new file mode 100644
index 00000000000..616dea87e88
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/anon-union5.C
@@ -0,0 +1,9 @@
+// PR c++/97974
+
+struct A {
+  union {
+    operator int ();           // { dg-error "anonymous union" }
+    int a;
+  };
+  operator int;                        // { dg-error "" }
+};

base-commit: 1d54b13841774aa40f5d0a5ab87b19e7e1276d42
-- 
2.27.0

Reply via email to