fprintf: Handle single zero sized array member structs

  /home/acme/git/build/v5.1-rc4+/fs/proc/kcore.o
  /tmp/fullcircle.Vnd2oz.c:788:29: error: flexible array member in a struct with no named members
    char                       x[];                  /*     0     0 */

Original:

include/linux/mmzone.h, line 109:

  /*
   * zone->lock and the zone lru_lock are two of the hottest locks in the kernel.
   * So add a wild amount of padding here to ensure that they fall into separate
   * cachelines.  There are very few zone structures in the machine, so space
   * consumption is not a concern here.
   */
  #if defined(CONFIG_SMP)
  struct zone_padding {
          char x[0];
  } ____cacheline_internodealigned_in_smp;
  #define ZONE_PADDING(name)      struct zone_padding name;
  #else
  #define ZONE_PADDING(name)
  #endif

B0rken:

  struct zone_padding {
          char                       x[];                 /*     0     0 */

          /* size: 0, cachelines: 0, members: 1 */
  } __attribute__((__aligned__(64)));

Fixed:

  struct zone_padding {
          char                       x[0];                 /*     0     0 */

          /* size: 0, cachelines: 0, members: 1 */
  } __attribute__((__aligned__(64)));

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
diff --git a/dwarves.h b/dwarves.h
index 2c1e99e..9a601d4 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -85,6 +85,7 @@
 	uint8_t	   no_semicolon:1;
 	uint8_t	   show_first_biggest_size_base_type_member:1;
 	uint8_t	   flat_arrays:1;
+	uint8_t	   first_member:1;
 	uint8_t	   last_member:1;
 	uint8_t	   union_member:1;
 	uint8_t	   no_parm_names:1;
diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c
index d467445..492bd66 100644
--- a/dwarves_fprintf.c
+++ b/dwarves_fprintf.c
@@ -218,7 +218,9 @@
 			else
 				flat_dimensions *= at->nr_entries[i];
 		} else {
-			if (at->nr_entries[i] != 0 || !conf->last_member || conf->union_member)
+			bool single_member = conf->last_member && conf->first_member;
+
+			if (at->nr_entries[i] != 0 || !conf->last_member || single_member || conf->union_member)
 				printed += fprintf(fp, "[%u]", at->nr_entries[i]);
 			else
 				printed += fprintf(fp, "[]");
@@ -233,7 +235,9 @@
 		printed += fprintf(fp, " __attribute__ ((__vector_size__ (%llu)))",
 				   flat_dimensions * tag__size(type, cu));
 	} else if (conf->flat_arrays) {
-		if (flat_dimensions != 0 || !conf->last_member || conf->union_member)
+		bool single_member = conf->last_member && conf->first_member;
+
+		if (flat_dimensions != 0 || !conf->last_member || single_member || conf->union_member)
 			printed += fprintf(fp, "[%llu]", flat_dimensions);
 		else
 			printed += fprintf(fp, "[]");
@@ -1487,6 +1491,7 @@
 		}
 
 		cconf.last_member = list_is_last(&tag_pos->node, &type->namespace.tags);
+		cconf.first_member = last == NULL;
 
 		size = pos->byte_size;
 		printed += fprintf(fp, "%.*s", cconf.indent, tabs);