]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: ICE with anonymous union [PR97974]
authorJason Merrill <jason@redhat.com>
Sat, 10 Apr 2021 18:00:15 +0000 (14:00 -0400)
committerJason Merrill <jason@redhat.com>
Sun, 11 Apr 2021 03:52:07 +0000 (23:52 -0400)
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.

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/lookup/pr84962.C: Adjust diagnostic.
* g++.dg/other/anon-union5.C: New test.

gcc/cp/decl.c
gcc/testsuite/g++.dg/lookup/pr84962.C
gcc/testsuite/g++.dg/other/anon-union5.C [new file with mode: 0644]

index 3294b4fa943c86136e94b75db1caa93c16e2dbb4..ec05ee1f0b49365f6843cb7477883b302188619f 100644 (file)
@@ -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
index b9b7a3135266693097737cca1eb8a1581aaaf5ac..c22b95ce8f94fae3b45fb8c6add79e1846534488 100644 (file)
@@ -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 (file)
index 0000000..616dea8
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/97974
+
+struct A {
+  union {
+    operator int ();           // { dg-error "anonymous union" }
+    int a;
+  };
+  operator int;                        // { dg-error "" }
+};