aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-04-10 14:00:15 -0400
committerJason Merrill <jason@redhat.com>2021-04-29 14:34:05 -0400
commit58a92b789a77cdade1f41800efebf6e0686f9982 (patch)
tree480dac0f25d2e61c62b283b6090bb9c5ddf78588 /gcc/cp/decl.c
parenta9fc64d8120937c5c37e1cacb2f55ae196e8897d (diff)
downloadgcc-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.c45
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);