From: Jason Merrill Date: Sat, 10 Apr 2021 18:00:15 +0000 (-0400) Subject: c++: ICE with anonymous union [PR97974] X-Git-Tag: basepoints/gcc-12~137 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=936d500dfc17f58f2507ecd0f7f26e4f197052ee;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3294b4fa943c..ec05ee1f0b49 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* 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 b9b7a3135266..c22b95ce8f94 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 000000000000..616dea87e88d --- /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 "" } +};