fprintf: Deal with zero sized arrays in the midle of a union

gcc dislikes invalid C:

  /home/acme/git/build/v5.1-rc4+/fs/ceph/export.o
  /tmp/fullcircle.CvAfpM.c:591:22: error: flexible array member in union
     __u32              raw[];                /*     0     0 */
                        ^~~
Before:

  $ pahole -C fid /home/acme/git/build/v5.1-rc4+/fs/ceph/export.o
  struct fid {
  	union {
  		struct {
  			u32        ino;                  /*     0     4 */
  			u32        gen;                  /*     4     4 */
  			u32        parent_ino;           /*     8     4 */
  			u32        parent_gen;           /*    12     4 */
  		} i32;                                   /*     0    16 */
  		struct {
  			u32        block;                /*     0     4 */
  			u16        partref;              /*     4     2 */
  			u16        parent_partref;       /*     6     2 */
  			u32        generation;           /*     8     4 */
  			u32        parent_block;         /*    12     4 */
  			u32        parent_generation;    /*    16     4 */
  		} udf;                                   /*     0    20 */
  		__u32              raw[];                /*     0     0 */
  	};                                               /*     0    20 */

  	/* size: 20, cachelines: 1, members: 1 */
  	/* last cacheline: 20 bytes */
  };
  $

After:

  $ pahole -C fid /home/acme/git/build/v5.1-rc4+/fs/ceph/export.o
  struct fid {
  	union {
  		struct {
  			u32        ino;                  /*     0     4 */
  			u32        gen;                  /*     4     4 */
  			u32        parent_ino;           /*     8     4 */
  			u32        parent_gen;           /*    12     4 */
  		} i32;                                   /*     0    16 */
  		struct {
  			u32        block;                /*     0     4 */
  			u16        partref;              /*     4     2 */
  			u16        parent_partref;       /*     6     2 */
  			u32        generation;           /*     8     4 */
  			u32        parent_block;         /*    12     4 */
  			u32        parent_generation;    /*    16     4 */
  		} udf;                                   /*     0    20 */
  		__u32              raw[0];               /*     0     0 */
  	};                                               /*     0    20 */

  	/* size: 20, cachelines: 1, members: 1 */
  	/* last cacheline: 20 bytes */
  };
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2019-04-15 17:09:03 -03:00
parent 1101337a74
commit 0987266cd9
2 changed files with 4 additions and 2 deletions

View File

@ -86,6 +86,7 @@ struct conf_fprintf {
uint8_t show_first_biggest_size_base_type_member:1;
uint8_t flat_arrays:1;
uint8_t last_member:1;
uint8_t union_member:1;
uint8_t no_parm_names:1;
uint8_t classes_as_structs:1;
uint8_t hex_fmt:1;

View File

@ -218,7 +218,7 @@ static size_t array_type__fprintf(const struct tag *tag,
else
flat_dimensions *= at->nr_entries[i];
} else {
if (at->nr_entries[i] != 0 || !conf->last_member)
if (at->nr_entries[i] != 0 || !conf->last_member || conf->union_member)
printed += fprintf(fp, "[%u]", at->nr_entries[i]);
else
printed += fprintf(fp, "[]");
@ -233,7 +233,7 @@ static size_t array_type__fprintf(const struct tag *tag,
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)
if (flat_dimensions != 0 || !conf->last_member || conf->union_member)
printed += fprintf(fp, "[%llu]", flat_dimensions);
else
printed += fprintf(fp, "[]");
@ -953,6 +953,7 @@ static size_t union__fprintf(struct type *type, const struct cu *cu,
continue;
}
uconf.union_member = 1;
printed += fprintf(fp, "%.*s", uconf.indent, tabs);
printed += union_member__fprintf(pos, pos_type, cu, &uconf, fp);
fputc('\n', fp);