===================================================================
@@ -7506,12 +7506,23 @@
/* Finish up struct info used by -Wc++-compat. */
static void
-warn_cxx_compat_finish_struct (tree fieldlist)
+warn_cxx_compat_finish_struct (tree fieldlist, enum tree_code code,
+ location_t record_loc)
{
unsigned int ix;
tree x;
struct c_binding *b;
+ if (fieldlist == NULL_TREE)
+ {
+ if (code == RECORD_TYPE)
+ warning_at (record_loc, OPT_Wc___compat,
+ "empty struct has size 0 in C, size 1 in C++");
+ else
+ warning_at (record_loc, OPT_Wc___compat,
+ "empty union has size 0 in C, size 1 in C++");
+ }
+
/* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
the current struct. We do this now at the end of the struct
because the flag is used to issue visibility warnings, and we
@@ -7844,7 +7855,7 @@
DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
if (warn_cxx_compat)
- warn_cxx_compat_finish_struct (fieldlist);
+ warn_cxx_compat_finish_struct (fieldlist, TREE_CODE (t), loc);
struct_parse_info->struct_types.release ();
struct_parse_info->fields.release ();
===================================================================
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+struct A {}; /* { dg-warning "empty struct has size 0 in C" } */
+union B {}; /* { dg-warning "empty union has size 0 in C" } */
+struct C { struct D {}; int x; }; /* { dg-warning "empty struct has size 0 in C|declaration does not declare anything" } */
+struct E { union F {}; int x; }; /* { dg-warning "empty union has size 0 in C|declaration does not declare anything" } */
+union G { union H {}; int x; }; /* { dg-warning "empty union has size 0 in C|declaration does not declare anything" } */
+union I { struct J {}; int x; }; /* { dg-warning "empty struct has size 0 in C|declaration does not declare anything" } */