aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-04-10 14:00:15 -0400
committerJason Merrill <jason@redhat.com>2021-04-10 23:52:07 -0400
commit936d500dfc17f58f2507ecd0f7f26e4f197052ee (patch)
treee83b9cf454999e17c5303379f0abd5d7c5e31368
parent1d54b13841774aa40f5d0a5ab87b19e7e1276d42 (diff)
downloadgcc-936d500dfc17f58f2507ecd0f7f26e4f197052ee.zip
gcc-936d500dfc17f58f2507ecd0f7f26e4f197052ee.tar.gz
gcc-936d500dfc17f58f2507ecd0f7f26e4f197052ee.tar.bz2
c++: ICE with anonymous union [PR97974]
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.
-rw-r--r--gcc/cp/decl.c8
-rw-r--r--gcc/testsuite/g++.dg/lookup/pr84962.C2
-rw-r--r--gcc/testsuite/g++.dg/other/anon-union5.C9
3 files changed, 18 insertions, 1 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3294b4f..ec05ee1 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 b9b7a31..c22b95c 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 0000000..616dea8
--- /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 "" }
+};