diff options
author | Jason Merrill <jason@redhat.com> | 2021-04-10 14:00:15 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-04-29 14:34:05 -0400 |
commit | 58a92b789a77cdade1f41800efebf6e0686f9982 (patch) | |
tree | 480dac0f25d2e61c62b283b6090bb9c5ddf78588 /gcc/cp/decl.c | |
parent | a9fc64d8120937c5c37e1cacb2f55ae196e8897d (diff) | |
download | gcc-58a92b789a77cdade1f41800efebf6e0686f9982.zip gcc-58a92b789a77cdade1f41800efebf6e0686f9982.tar.gz gcc-58a92b789a77cdade1f41800efebf6e0686f9982.tar.bz2 |
c++: ICE with anonymous union [PR97974]
While working on the GCC 11 patch, it occurred to me that we could move
the errors about invalid members from finish_struct_anon_r to here, so we
properly get a diagnostic in g++.law/union4.C.
gcc/cp/ChangeLog:
PR c++/97974
* class.c (finish_struct_anon_r): Drop complain parm.
Remove non-field diagnostic.
(finish_struct_anon): Adjust.
* decl.c (fixup_anonymous_aggr): Move non-field diagnostic here.
gcc/testsuite/ChangeLog:
PR c++/97974
* g++.old-deja/g++.law/union4.C: Add expected diagnostic.
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 60dc2bf..e51c1b0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5005,12 +5005,47 @@ fixup_anonymous_aggr (tree t) TYPE_HAS_COPY_ASSIGN (t) = 0; TYPE_HAS_CONST_COPY_ASSIGN (t) = 0; - /* Splice the implicitly generated functions out of TYPE_FIELDS. */ + /* Splice the implicitly generated functions out of TYPE_FIELDS and diagnose + invalid members. */ for (tree probe, *prev_p = &TYPE_FIELDS (t); (probe = *prev_p);) - if (TREE_CODE (probe) == FUNCTION_DECL && DECL_ARTIFICIAL (probe)) - *prev_p = DECL_CHAIN (probe); - else - prev_p = &DECL_CHAIN (probe); + { + if (TREE_CODE (probe) == FUNCTION_DECL && DECL_ARTIFICIAL (probe)) + *prev_p = DECL_CHAIN (probe); + else + prev_p = &DECL_CHAIN (probe); + + if (DECL_ARTIFICIAL (probe) + && (!DECL_IMPLICIT_TYPEDEF_P (probe) + || TYPE_ANON_P (TREE_TYPE (probe)))) + continue; + + if (TREE_CODE (probe) != FIELD_DECL + || (TREE_PRIVATE (probe) || TREE_PROTECTED (probe))) + { + /* We already complained about static data members in + finish_static_data_member_decl. */ + if (!VAR_P (probe)) + { + auto_diagnostic_group d; + if (permerror (DECL_SOURCE_LOCATION (probe), + TREE_CODE (t) == UNION_TYPE + ? "%q#D invalid; an anonymous union may " + "only have public non-static data members" + : "%q#D invalid; an anonymous struct may " + "only have public non-static data members", probe)) + { + static bool hint; + if (flag_permissive && !hint) + { + hint = true; + inform (DECL_SOURCE_LOCATION (probe), + "this flexibility is deprecated and will be " + "removed"); + } + } + } + } + } /* Splice all functions out of CLASSTYPE_MEMBER_VEC. */ vec<tree,va_gc>* vec = CLASSTYPE_MEMBER_VEC (t); |