diff mbox series

[1/2] misc: Replace zero-length arrays with flexible array member (automatic)

Message ID 20200304005105.27454-2-philmd@redhat.com (mailing list archive)
State New, archived
Headers show
Series misc: Replace zero-length arrays with flexible array member | expand

Commit Message

Philippe Mathieu-Daudé March 4, 2020, 12:51 a.m. UTC
Description copied from Linux kernel commit from Gustavo A. R. Silva
(see [3]):

--v-- description start --v--

  The current codebase makes use of the zero-length array language
  extension to the C90 standard, but the preferred mechanism to
  declare variable-length types such as these ones is a flexible
  array member [1], introduced in C99:

  struct foo {
      int stuff;
      struct boo array[];
  };

  By making use of the mechanism above, we will get a compiler
  warning in case the flexible array does not occur last in the
  structure, which will help us prevent some kind of undefined
  behavior bugs from being unadvertenly introduced [2] to the
  Linux codebase from now on.

--^-- description end --^--

Do the similar housekeeping in the QEMU codebase (which uses
C99 since commit 7be41675f7cb).

All these instances of code were found with the help of the
following Coccinelle script:

  @@
  identifier s, a;
  type T;
  @@
   struct s {
      ...
  -   T a[0];
  +   T a[];
  };
  @@
  identifier s, a;
  type T;
  @@
   struct s {
      ...
  -   T a[0];
  +   T a[];
   } QEMU_PACKED;

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
[3] https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1

Inspired-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 bsd-user/qemu.h                       |  2 +-
 contrib/libvhost-user/libvhost-user.h |  2 +-
 hw/m68k/bootinfo.h                    |  2 +-
 hw/scsi/srp.h                         |  6 +++---
 hw/xen/xen_pt.h                       |  2 +-
 include/hw/acpi/acpi-defs.h           | 12 ++++++------
 include/hw/arm/smmu-common.h          |  2 +-
 include/hw/i386/intel_iommu.h         |  3 ++-
 include/hw/virtio/virtio-iommu.h      |  2 +-
 include/sysemu/cryptodev.h            |  2 +-
 include/tcg/tcg.h                     |  2 +-
 pc-bios/s390-ccw/bootmap.h            |  2 +-
 pc-bios/s390-ccw/sclp.h               |  2 +-
 tests/qtest/libqos/ahci.h             |  2 +-
 block/linux-aio.c                     |  2 +-
 hw/acpi/nvdimm.c                      |  6 +++---
 hw/dma/soc_dma.c                      |  2 +-
 hw/i386/x86.c                         |  2 +-
 hw/misc/omap_l4.c                     |  2 +-
 hw/nvram/eeprom93xx.c                 |  2 +-
 hw/rdma/vmw/pvrdma_qp_ops.c           |  4 ++--
 hw/usb/dev-network.c                  |  2 +-
 hw/usb/dev-smartcard-reader.c         |  4 ++--
 hw/virtio/virtio.c                    |  4 ++--
 net/queue.c                           |  2 +-
 25 files changed, 38 insertions(+), 37 deletions(-)

Comments

David Hildenbrand March 4, 2020, 8:19 a.m. UTC | #1
On 04.03.20 01:51, Philippe Mathieu-Daudé wrote:
> Description copied from Linux kernel commit from Gustavo A. R. Silva
> (see [3]):
> 
> --v-- description start --v--
> 
>   The current codebase makes use of the zero-length array language
>   extension to the C90 standard, but the preferred mechanism to
>   declare variable-length types such as these ones is a flexible
>   array member [1], introduced in C99:
> 
>   struct foo {
>       int stuff;
>       struct boo array[];
>   };
> 
>   By making use of the mechanism above, we will get a compiler
>   warning in case the flexible array does not occur last in the
>   structure, which will help us prevent some kind of undefined
>   behavior bugs from being unadvertenly introduced [2] to the
>   Linux codebase from now on.
> 
> --^-- description end --^--
> 
> Do the similar housekeeping in the QEMU codebase (which uses
> C99 since commit 7be41675f7cb).
> 
> All these instances of code were found with the help of the
> following Coccinelle script:
> 
>   @@
>   identifier s, a;
>   type T;
>   @@
>    struct s {
>       ...
>   -   T a[0];
>   +   T a[];
>   };
>   @@
>   identifier s, a;
>   type T;
>   @@
>    struct s {
>       ...
>   -   T a[0];
>   +   T a[];
>    } QEMU_PACKED;
> 
> [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
> [3] https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1
> 
> Inspired-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
>  bsd-user/qemu.h                       |  2 +-
>  contrib/libvhost-user/libvhost-user.h |  2 +-
>  hw/m68k/bootinfo.h                    |  2 +-
>  hw/scsi/srp.h                         |  6 +++---
>  hw/xen/xen_pt.h                       |  2 +-
>  include/hw/acpi/acpi-defs.h           | 12 ++++++------
>  include/hw/arm/smmu-common.h          |  2 +-
>  include/hw/i386/intel_iommu.h         |  3 ++-
>  include/hw/virtio/virtio-iommu.h      |  2 +-
>  include/sysemu/cryptodev.h            |  2 +-
>  include/tcg/tcg.h                     |  2 +-
>  pc-bios/s390-ccw/bootmap.h            |  2 +-
>  pc-bios/s390-ccw/sclp.h               |  2 +-
>  tests/qtest/libqos/ahci.h             |  2 +-
>  block/linux-aio.c                     |  2 +-
>  hw/acpi/nvdimm.c                      |  6 +++---
>  hw/dma/soc_dma.c                      |  2 +-
>  hw/i386/x86.c                         |  2 +-
>  hw/misc/omap_l4.c                     |  2 +-
>  hw/nvram/eeprom93xx.c                 |  2 +-
>  hw/rdma/vmw/pvrdma_qp_ops.c           |  4 ++--
>  hw/usb/dev-network.c                  |  2 +-
>  hw/usb/dev-smartcard-reader.c         |  4 ++--
>  hw/virtio/virtio.c                    |  4 ++--
>  net/queue.c                           |  2 +-
>  25 files changed, 38 insertions(+), 37 deletions(-)
> 
> diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
> index 09e8aed9c7..f8bb1e5459 100644
> --- a/bsd-user/qemu.h
> +++ b/bsd-user/qemu.h
> @@ -95,7 +95,7 @@ typedef struct TaskState {
>      struct sigqueue *first_free; /* first free siginfo queue entry */
>      int signal_pending; /* non zero if a signal may be pending */
>  
> -    uint8_t stack[0];
> +    uint8_t stack[];
>  } __attribute__((aligned(16))) TaskState;
>  
>  void init_task_state(TaskState *ts);
> diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
> index 6fc8000e99..f30394fab6 100644
> --- a/contrib/libvhost-user/libvhost-user.h
> +++ b/contrib/libvhost-user/libvhost-user.h
> @@ -286,7 +286,7 @@ typedef struct VuVirtqInflight {
>      uint16_t used_idx;
>  
>      /* Used to track the state of each descriptor in descriptor table */
> -    VuDescStateSplit desc[0];
> +    VuDescStateSplit desc[];
>  } VuVirtqInflight;
>  
>  typedef struct VuVirtqInflightDesc {
> diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h
> index 5f8ded2686..c954270aad 100644
> --- a/hw/m68k/bootinfo.h
> +++ b/hw/m68k/bootinfo.h
> @@ -14,7 +14,7 @@
>  struct bi_record {
>      uint16_t tag;        /* tag ID */
>      uint16_t size;       /* size of record */
> -    uint32_t data[0];    /* data */
> +    uint32_t data[];     /* data */
>  };
>  
>  /* machine independent tags */
> diff --git a/hw/scsi/srp.h b/hw/scsi/srp.h
> index d27f31d2d5..54c954badd 100644
> --- a/hw/scsi/srp.h
> +++ b/hw/scsi/srp.h
> @@ -112,7 +112,7 @@ struct srp_direct_buf {
>  struct srp_indirect_buf {
>      struct srp_direct_buf    table_desc;
>      uint32_t                 len;
> -    struct srp_direct_buf    desc_list[0];
> +    struct srp_direct_buf    desc_list[];
>  } QEMU_PACKED;
>  
>  enum {
> @@ -211,7 +211,7 @@ struct srp_cmd {
>      uint8_t    reserved4;
>      uint8_t    add_cdb_len;
>      uint8_t    cdb[16];
> -    uint8_t    add_data[0];
> +    uint8_t    add_data[];
>  } QEMU_PACKED;
>  
>  enum {
> @@ -241,7 +241,7 @@ struct srp_rsp {
>      uint32_t   data_in_res_cnt;
>      uint32_t   sense_data_len;
>      uint32_t   resp_data_len;
> -    uint8_t    data[0];
> +    uint8_t    data[];
>  } QEMU_PACKED;
>  
>  #endif /* SCSI_SRP_H */
> diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
> index 9167bbaf6d..179775db7b 100644
> --- a/hw/xen/xen_pt.h
> +++ b/hw/xen/xen_pt.h
> @@ -203,7 +203,7 @@ typedef struct XenPTMSIX {
>      uint64_t mmio_base_addr;
>      MemoryRegion mmio;
>      void *phys_iomem_base;
> -    XenPTMSIXEntry msix_entry[0];
> +    XenPTMSIXEntry msix_entry[];
>  } XenPTMSIX;
>  
>  struct XenPCIPassthroughState {
> diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
> index 57a3f58b0c..19f7ba7b70 100644
> --- a/include/hw/acpi/acpi-defs.h
> +++ b/include/hw/acpi/acpi-defs.h
> @@ -518,7 +518,7 @@ struct AcpiDmarDeviceScope {
>      struct {
>          uint8_t device;
>          uint8_t function;
> -    } path[0];
> +    } path[];
>  } QEMU_PACKED;
>  typedef struct AcpiDmarDeviceScope AcpiDmarDeviceScope;
>  
> @@ -530,7 +530,7 @@ struct AcpiDmarHardwareUnit {
>      uint8_t reserved;
>      uint16_t pci_segment;   /* The PCI Segment associated with this unit */
>      uint64_t address;   /* Base address of remapping hardware register-set */
> -    AcpiDmarDeviceScope scope[0];
> +    AcpiDmarDeviceScope scope[];
>  } QEMU_PACKED;
>  typedef struct AcpiDmarHardwareUnit AcpiDmarHardwareUnit;
>  
> @@ -541,7 +541,7 @@ struct AcpiDmarRootPortATS {
>      uint8_t flags;
>      uint8_t reserved;
>      uint16_t pci_segment;
> -    AcpiDmarDeviceScope scope[0];
> +    AcpiDmarDeviceScope scope[];
>  } QEMU_PACKED;
>  typedef struct AcpiDmarRootPortATS AcpiDmarRootPortATS;
>  
> @@ -604,7 +604,7 @@ typedef struct AcpiIortMemoryAccess AcpiIortMemoryAccess;
>  struct AcpiIortItsGroup {
>      ACPI_IORT_NODE_HEADER_DEF
>      uint32_t its_count;
> -    uint32_t identifiers[0];
> +    uint32_t identifiers[];
>  } QEMU_PACKED;
>  typedef struct AcpiIortItsGroup AcpiIortItsGroup;
>  
> @@ -621,7 +621,7 @@ struct AcpiIortSmmu3 {
>      uint32_t pri_gsiv;
>      uint32_t gerr_gsiv;
>      uint32_t sync_gsiv;
> -    AcpiIortIdMapping id_mapping_array[0];
> +    AcpiIortIdMapping id_mapping_array[];
>  } QEMU_PACKED;
>  typedef struct AcpiIortSmmu3 AcpiIortSmmu3;
>  
> @@ -630,7 +630,7 @@ struct AcpiIortRC {
>      AcpiIortMemoryAccess memory_properties;
>      uint32_t ats_attribute;
>      uint32_t pci_segment_number;
> -    AcpiIortIdMapping id_mapping_array[0];
> +    AcpiIortIdMapping id_mapping_array[];
>  } QEMU_PACKED;
>  typedef struct AcpiIortRC AcpiIortRC;
>  
> diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
> index 1f37844e5c..ca4a4b1ad1 100644
> --- a/include/hw/arm/smmu-common.h
> +++ b/include/hw/arm/smmu-common.h
> @@ -85,7 +85,7 @@ typedef struct SMMUDevice {
>  
>  typedef struct SMMUPciBus {
>      PCIBus       *bus;
> -    SMMUDevice   *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
> +    SMMUDevice   *pbdev[]; /* Parent array is sparse, so dynamically alloc */
>  } SMMUPciBus;
>  
>  typedef struct SMMUIOTLBKey {
> diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
> index 66b931e526..67aaa64c1b 100644
> --- a/include/hw/i386/intel_iommu.h
> +++ b/include/hw/i386/intel_iommu.h
> @@ -118,7 +118,8 @@ struct VTDAddressSpace {
>  
>  struct VTDBus {
>      PCIBus* bus;		/* A reference to the bus to provide translation for */
> -    VTDAddressSpace *dev_as[0];	/* A table of VTDAddressSpace objects indexed by devfn */
> +    /* A table of VTDAddressSpace objects indexed by devfn */
> +    VTDAddressSpace *dev_as[];
>  };
>  
>  struct VTDIOTLBEntry {
> diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h
> index 6f67f1020a..e653004d7c 100644
> --- a/include/hw/virtio/virtio-iommu.h
> +++ b/include/hw/virtio/virtio-iommu.h
> @@ -41,7 +41,7 @@ typedef struct IOMMUDevice {
>  
>  typedef struct IOMMUPciBus {
>      PCIBus       *bus;
> -    IOMMUDevice  *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
> +    IOMMUDevice  *pbdev[]; /* Parent array is sparse, so dynamically alloc */
>  } IOMMUPciBus;
>  
>  typedef struct VirtIOIOMMU {
> diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
> index a9afb7e5b5..35eab06d0e 100644
> --- a/include/sysemu/cryptodev.h
> +++ b/include/sysemu/cryptodev.h
> @@ -143,7 +143,7 @@ typedef struct CryptoDevBackendSymOpInfo {
>      uint8_t *dst;
>      uint8_t *aad_data;
>      uint8_t *digest_result;
> -    uint8_t data[0];
> +    uint8_t data[];
>  } CryptoDevBackendSymOpInfo;
>  
>  typedef struct CryptoDevBackendClass {
> diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
> index 54e5446880..c48bd76b0a 100644
> --- a/include/tcg/tcg.h
> +++ b/include/tcg/tcg.h
> @@ -267,7 +267,7 @@ struct TCGLabel {
>  typedef struct TCGPool {
>      struct TCGPool *next;
>      int size;
> -    uint8_t data[0] __attribute__ ((aligned));
> +    uint8_t data[] __attribute__ ((aligned));
>  } TCGPool;
>  
>  #define TCG_POOL_CHUNK_SIZE 32768
> diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
> index 94f53a5f1e..12a0166aae 100644
> --- a/pc-bios/s390-ccw/bootmap.h
> +++ b/pc-bios/s390-ccw/bootmap.h
> @@ -136,7 +136,7 @@ typedef struct BootMapScriptHeader {
>  
>  typedef struct BootMapScript {
>      BootMapScriptHeader header;
> -    BootMapScriptEntry  entry[0];
> +    BootMapScriptEntry  entry[];
>  } __attribute__ ((packed)) BootMapScript;
>  
>  /*
> diff --git a/pc-bios/s390-ccw/sclp.h b/pc-bios/s390-ccw/sclp.h
> index 8450161ba7..64b53cad29 100644
> --- a/pc-bios/s390-ccw/sclp.h
> +++ b/pc-bios/s390-ccw/sclp.h
> @@ -95,7 +95,7 @@ typedef struct EventBufferHeader {
>  typedef struct WriteEventData {
>      SCCBHeader h;
>      EventBufferHeader ebh;
> -    char data[0];
> +    char data[];
>  } __attribute__((packed)) WriteEventData;
>  
>  typedef struct ReadEventData {
> diff --git a/tests/qtest/libqos/ahci.h b/tests/qtest/libqos/ahci.h
> index f05b3e5fce..44ab1104b5 100644
> --- a/tests/qtest/libqos/ahci.h
> +++ b/tests/qtest/libqos/ahci.h
> @@ -351,7 +351,7 @@ typedef struct AHCIQState {
>  typedef struct FIS {
>      uint8_t fis_type;
>      uint8_t flags;
> -    char data[0];
> +    char data[];
>  } __attribute__((__packed__)) FIS;
>  
>  /**
> diff --git a/block/linux-aio.c b/block/linux-aio.c
> index 91204a25a2..3c0527c2bf 100644
> --- a/block/linux-aio.c
> +++ b/block/linux-aio.c
> @@ -121,7 +121,7 @@ struct aio_ring {
>      unsigned    incompat_features;
>      unsigned    header_length;  /* size of aio_ring */
>  
> -    struct io_event io_events[0];
> +    struct io_event io_events[];
>  };
>  
>  /**
> diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
> index 5219dd0e2e..eb6a37b14e 100644
> --- a/hw/acpi/nvdimm.c
> +++ b/hw/acpi/nvdimm.c
> @@ -485,7 +485,7 @@ struct NvdimmFuncGetLabelDataOut {
>      /* the size of buffer filled by QEMU. */
>      uint32_t len;
>      uint32_t func_ret_status; /* return status code. */
> -    uint8_t out_buf[0]; /* the data got via Get Namesapce Label function. */
> +    uint8_t out_buf[]; /* the data got via Get Namesapce Label function. */
>  } QEMU_PACKED;
>  typedef struct NvdimmFuncGetLabelDataOut NvdimmFuncGetLabelDataOut;
>  QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > NVDIMM_DSM_MEMORY_SIZE);
> @@ -493,7 +493,7 @@ QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > NVDIMM_DSM_MEMORY_SIZE);
>  struct NvdimmFuncSetLabelDataIn {
>      uint32_t offset; /* the offset in the namespace label data area. */
>      uint32_t length; /* the size of data is to be written via the function. */
> -    uint8_t in_buf[0]; /* the data written to label data area. */
> +    uint8_t in_buf[]; /* the data written to label data area. */
>  } QEMU_PACKED;
>  typedef struct NvdimmFuncSetLabelDataIn NvdimmFuncSetLabelDataIn;
>  QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncSetLabelDataIn) +
> @@ -510,7 +510,7 @@ struct NvdimmFuncReadFITOut {
>      /* the size of buffer filled by QEMU. */
>      uint32_t len;
>      uint32_t func_ret_status; /* return status code. */
> -    uint8_t fit[0]; /* the FIT data. */
> +    uint8_t fit[]; /* the FIT data. */
>  } QEMU_PACKED;
>  typedef struct NvdimmFuncReadFITOut NvdimmFuncReadFITOut;
>  QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncReadFITOut) > NVDIMM_DSM_MEMORY_SIZE);
> diff --git a/hw/dma/soc_dma.c b/hw/dma/soc_dma.c
> index c3e41581b6..3a430057f5 100644
> --- a/hw/dma/soc_dma.c
> +++ b/hw/dma/soc_dma.c
> @@ -80,7 +80,7 @@ struct dma_s {
>      } *memmap;
>      int memmap_size;
>  
> -    struct soc_dma_ch_s ch[0];
> +    struct soc_dma_ch_s ch[];
>  };
>  
>  static void soc_dma_ch_schedule(struct soc_dma_ch_s *ch, int delay_bytes)
> diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> index 7f38e6ba8b..08246523f2 100644
> --- a/hw/i386/x86.c
> +++ b/hw/i386/x86.c
> @@ -328,7 +328,7 @@ struct setup_data {
>      uint64_t next;
>      uint32_t type;
>      uint32_t len;
> -    uint8_t data[0];
> +    uint8_t data[];
>  } __attribute__((packed));
>  
>  
> diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c
> index 61b6df564a..54aeaecd69 100644
> --- a/hw/misc/omap_l4.c
> +++ b/hw/misc/omap_l4.c
> @@ -24,7 +24,7 @@ struct omap_l4_s {
>      MemoryRegion *address_space;
>      hwaddr base;
>      int ta_num;
> -    struct omap_target_agent_s ta[0];
> +    struct omap_target_agent_s ta[];
>  };
>  
>  struct omap_l4_s *omap_l4_init(MemoryRegion *address_space,
> diff --git a/hw/nvram/eeprom93xx.c b/hw/nvram/eeprom93xx.c
> index 07f09549ed..ca6f591c84 100644
> --- a/hw/nvram/eeprom93xx.c
> +++ b/hw/nvram/eeprom93xx.c
> @@ -86,7 +86,7 @@ struct _eeprom_t {
>      uint8_t  addrbits;
>      uint16_t size;
>      uint16_t data;
> -    uint16_t contents[0];
> +    uint16_t contents[];
>  };
>  
>  /* Code for saving and restoring of EEPROM state. */
> diff --git a/hw/rdma/vmw/pvrdma_qp_ops.c b/hw/rdma/vmw/pvrdma_qp_ops.c
> index bd6db858de..8050287a6c 100644
> --- a/hw/rdma/vmw/pvrdma_qp_ops.c
> +++ b/hw/rdma/vmw/pvrdma_qp_ops.c
> @@ -34,13 +34,13 @@ typedef struct CompHandlerCtx {
>  /* Send Queue WQE */
>  typedef struct PvrdmaSqWqe {
>      struct pvrdma_sq_wqe_hdr hdr;
> -    struct pvrdma_sge sge[0];
> +    struct pvrdma_sge sge[];
>  } PvrdmaSqWqe;
>  
>  /* Recv Queue WQE */
>  typedef struct PvrdmaRqWqe {
>      struct pvrdma_rq_wqe_hdr hdr;
> -    struct pvrdma_sge sge[0];
> +    struct pvrdma_sge sge[];
>  } PvrdmaRqWqe;
>  
>  /*
> diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
> index 9a78ad928b..6210427544 100644
> --- a/hw/usb/dev-network.c
> +++ b/hw/usb/dev-network.c
> @@ -626,7 +626,7 @@ static const uint32_t oid_supported_list[] =
>  struct rndis_response {
>      QTAILQ_ENTRY(rndis_response) entries;
>      uint32_t length;
> -    uint8_t buf[0];
> +    uint8_t buf[];
>  };
>  
>  typedef struct USBNetState {
> diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
> index 02693a26ad..ef72738ced 100644
> --- a/hw/usb/dev-smartcard-reader.c
> +++ b/hw/usb/dev-smartcard-reader.c
> @@ -227,7 +227,7 @@ typedef struct QEMU_PACKED CCID_Parameter {
>  typedef struct QEMU_PACKED CCID_DataBlock {
>      CCID_BULK_IN b;
>      uint8_t      bChainParameter;
> -    uint8_t      abData[0];
> +    uint8_t      abData[];
>  } CCID_DataBlock;
>  
>  /* 6.1.4 PC_to_RDR_XfrBlock */
> @@ -235,7 +235,7 @@ typedef struct QEMU_PACKED CCID_XferBlock {
>      CCID_Header  hdr;
>      uint8_t      bBWI; /* Block Waiting Timeout */
>      uint16_t     wLevelParameter; /* XXX currently unused */
> -    uint8_t      abData[0];
> +    uint8_t      abData[];
>  } CCID_XferBlock;
>  
>  typedef struct QEMU_PACKED CCID_IccPowerOn {
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index b2d415e5dd..b6c8ef5bc0 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -54,7 +54,7 @@ typedef struct VRingAvail
>  {
>      uint16_t flags;
>      uint16_t idx;
> -    uint16_t ring[0];
> +    uint16_t ring[];
>  } VRingAvail;
>  
>  typedef struct VRingUsedElem
> @@ -67,7 +67,7 @@ typedef struct VRingUsed
>  {
>      uint16_t flags;
>      uint16_t idx;
> -    VRingUsedElem ring[0];
> +    VRingUsedElem ring[];
>  } VRingUsed;
>  
>  typedef struct VRingMemoryRegionCaches {
> diff --git a/net/queue.c b/net/queue.c
> index 61276ca4be..0164727e39 100644
> --- a/net/queue.c
> +++ b/net/queue.c
> @@ -46,7 +46,7 @@ struct NetPacket {
>      unsigned flags;
>      int size;
>      NetPacketSent *sent_cb;
> -    uint8_t data[0];
> +    uint8_t data[];
>  };
>  
>  struct NetQueue {
> 

Reviewed-by: David Hildenbrand <david@redhat.com>
Philippe Mathieu-Daudé March 4, 2020, 1:12 p.m. UTC | #2
On 3/4/20 1:51 AM, Philippe Mathieu-Daudé wrote:
> Description copied from Linux kernel commit from Gustavo A. R. Silva
> (see [3]):
> 
> --v-- description start --v--
> 
>    The current codebase makes use of the zero-length array language
>    extension to the C90 standard, but the preferred mechanism to
>    declare variable-length types such as these ones is a flexible
>    array member [1], introduced in C99:
> 
>    struct foo {
>        int stuff;
>        struct boo array[];
>    };
> 
>    By making use of the mechanism above, we will get a compiler
>    warning in case the flexible array does not occur last in the
>    structure, which will help us prevent some kind of undefined
>    behavior bugs from being unadvertenly introduced [2] to the
>    Linux codebase from now on.
> 
> --^-- description end --^--
> 
> Do the similar housekeeping in the QEMU codebase (which uses
> C99 since commit 7be41675f7cb).
> 
> All these instances of code were found with the help of the
> following Coccinelle script:
> 
>    @@
>    identifier s, a;
>    type T;
>    @@
>     struct s {
>        ...
>    -   T a[0];
>    +   T a[];
>    };
>    @@
>    identifier s, a;
>    type T;
>    @@
>     struct s {
>        ...
>    -   T a[0];
>    +   T a[];
>     } QEMU_PACKED;
> 
> [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76497732932f
> [3] https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/commit/?id=17642a2fbd2c1
> 
> Inspired-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
>   bsd-user/qemu.h                       |  2 +-
>   contrib/libvhost-user/libvhost-user.h |  2 +-
>   hw/m68k/bootinfo.h                    |  2 +-
>   hw/scsi/srp.h                         |  6 +++---
>   hw/xen/xen_pt.h                       |  2 +-
>   include/hw/acpi/acpi-defs.h           | 12 ++++++------
>   include/hw/arm/smmu-common.h          |  2 +-
>   include/hw/i386/intel_iommu.h         |  3 ++-
>   include/hw/virtio/virtio-iommu.h      |  2 +-
>   include/sysemu/cryptodev.h            |  2 +-
>   include/tcg/tcg.h                     |  2 +-
>   pc-bios/s390-ccw/bootmap.h            |  2 +-
>   pc-bios/s390-ccw/sclp.h               |  2 +-
>   tests/qtest/libqos/ahci.h             |  2 +-
>   block/linux-aio.c                     |  2 +-
>   hw/acpi/nvdimm.c                      |  6 +++---
>   hw/dma/soc_dma.c                      |  2 +-
>   hw/i386/x86.c                         |  2 +-
>   hw/misc/omap_l4.c                     |  2 +-
>   hw/nvram/eeprom93xx.c                 |  2 +-
>   hw/rdma/vmw/pvrdma_qp_ops.c           |  4 ++--
>   hw/usb/dev-network.c                  |  2 +-
>   hw/usb/dev-smartcard-reader.c         |  4 ++--
>   hw/virtio/virtio.c                    |  4 ++--
>   net/queue.c                           |  2 +-
>   25 files changed, 38 insertions(+), 37 deletions(-)
> 
[...]
> diff --git a/hw/scsi/srp.h b/hw/scsi/srp.h
> index d27f31d2d5..54c954badd 100644
> --- a/hw/scsi/srp.h
> +++ b/hw/scsi/srp.h
> @@ -112,7 +112,7 @@ struct srp_direct_buf {
>   struct srp_indirect_buf {
>       struct srp_direct_buf    table_desc;
>       uint32_t                 len;
> -    struct srp_direct_buf    desc_list[0];
> +    struct srp_direct_buf    desc_list[];
>   } QEMU_PACKED;
>   
>   enum {
> @@ -211,7 +211,7 @@ struct srp_cmd {
>       uint8_t    reserved4;
>       uint8_t    add_cdb_len;
>       uint8_t    cdb[16];
> -    uint8_t    add_data[0];
> +    uint8_t    add_data[];
>   } QEMU_PACKED;
>   
>   enum {
> @@ -241,7 +241,7 @@ struct srp_rsp {
>       uint32_t   data_in_res_cnt;
>       uint32_t   sense_data_len;
>       uint32_t   resp_data_len;
> -    uint8_t    data[0];
> +    uint8_t    data[];
>   } QEMU_PACKED;

hw/scsi/spapr_vscsi.c:69:29: error: field 'iu' with variable sized type 
'union viosrp_iu' not at the end of a struct or class is a GNU extension 
[-Werror,-Wgnu-variable-sized-type-not-at-end]
     union viosrp_iu         iu;
                             ^

Yay we found a bug! Thanks Gustavo :)

union srp_iu {
     struct srp_login_req login_req;
     struct srp_login_rsp login_rsp;
     struct srp_login_rej login_rej;
     struct srp_i_logout i_logout;
     struct srp_t_logout t_logout;
     struct srp_tsk_mgmt tsk_mgmt;
     struct srp_cmd cmd;
     struct srp_rsp rsp;
     uint8_t reserved[SRP_MAX_IU_LEN];
};

union viosrp_iu {
     union srp_iu srp;
     union mad_iu mad;
};

typedef struct vscsi_req {
     vscsi_crq               crq;
     union viosrp_iu         iu;

     /* SCSI request tracking */
     SCSIRequest             *sreq;
     uint32_t                qtag; /* qemu tag != srp tag */
     bool                    active;
     bool                    writing;
     bool                    dma_error;
     uint32_t                data_len;
     uint32_t                senselen;
     uint8_t                 sense[SCSI_SENSE_BUF_SIZE];

     /* RDMA related bits */
     uint8_t                 dma_fmt;
     uint16_t                local_desc;
     uint16_t                total_desc;
     uint16_t                cdb_offset;
     uint16_t                cur_desc_num;
     uint16_t                cur_desc_offset;
} vscsi_req;

>   
>   #endif /* SCSI_SRP_H */
[...]
Paolo Bonzini March 4, 2020, 1:44 p.m. UTC | #3
On 04/03/20 14:12, Philippe Mathieu-Daudé wrote:
> 
> hw/scsi/spapr_vscsi.c:69:29: error: field 'iu' with variable sized type
> 'union viosrp_iu' not at the end of a struct or class is a GNU extension
> [-Werror,-Wgnu-variable-sized-type-not-at-end]
>     union viosrp_iu         iu;
>                             ^
> 
> Yay we found a bug! Thanks Gustavo :)
> 
> union srp_iu {
>     struct srp_login_req login_req;
>     struct srp_login_rsp login_rsp;
>     struct srp_login_rej login_rej;
>     struct srp_i_logout i_logout;
>     struct srp_t_logout t_logout;
>     struct srp_tsk_mgmt tsk_mgmt;
>     struct srp_cmd cmd;
>     struct srp_rsp rsp;
>     uint8_t reserved[SRP_MAX_IU_LEN];
> };

It's variable-sized but it's okay as long as the total size doesn't
exceed SRP_MAX_IU_LEN.  So it's not a bug, but I agree it's a time bomb.
 Moving the field last should work, but it would still be quite
dangerous code.

Paolo
Philippe Mathieu-Daudé March 4, 2020, 2:12 p.m. UTC | #4
On 3/4/20 2:44 PM, Paolo Bonzini wrote:
> On 04/03/20 14:12, Philippe Mathieu-Daudé wrote:
>>
>> hw/scsi/spapr_vscsi.c:69:29: error: field 'iu' with variable sized type
>> 'union viosrp_iu' not at the end of a struct or class is a GNU extension
>> [-Werror,-Wgnu-variable-sized-type-not-at-end]
>>      union viosrp_iu         iu;
>>                              ^
>>
>> Yay we found a bug! Thanks Gustavo :)
>>
>> union srp_iu {
>>      struct srp_login_req login_req;
>>      struct srp_login_rsp login_rsp;
>>      struct srp_login_rej login_rej;
>>      struct srp_i_logout i_logout;
>>      struct srp_t_logout t_logout;
>>      struct srp_tsk_mgmt tsk_mgmt;
>>      struct srp_cmd cmd;
>>      struct srp_rsp rsp;
>>      uint8_t reserved[SRP_MAX_IU_LEN];
>> };
> 
> It's variable-sized but it's okay as long as the total size doesn't
> exceed SRP_MAX_IU_LEN.  So it's not a bug, but I agree it's a time bomb.
>   Moving the field last should work, but it would still be quite
> dangerous code.

Yeah I reached the same conclusion.

I'll send a fix for the dangerous code.
Do you want to drop this series, or only the change in 'struct srp_rsp' 
(or in all hw/scsi/srp.h). Actually I guess it makes sense I move the 
'hw/scsi/srp.h' changes with the series cleaning dangerous code.
Paolo Bonzini March 4, 2020, 2:19 p.m. UTC | #5
On 04/03/20 15:12, Philippe Mathieu-Daudé wrote:
> I'll send a fix for the dangerous code.
> Do you want to drop this series, or only the change in 'struct srp_rsp'
> (or in all hw/scsi/srp.h). Actually I guess it makes sense I move the
> 'hw/scsi/srp.h' changes with the series cleaning dangerous code.

As you prefer, it's not urgent to merge it.

Paolo
diff mbox series

Patch

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 09e8aed9c7..f8bb1e5459 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -95,7 +95,7 @@  typedef struct TaskState {
     struct sigqueue *first_free; /* first free siginfo queue entry */
     int signal_pending; /* non zero if a signal may be pending */
 
-    uint8_t stack[0];
+    uint8_t stack[];
 } __attribute__((aligned(16))) TaskState;
 
 void init_task_state(TaskState *ts);
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
index 6fc8000e99..f30394fab6 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -286,7 +286,7 @@  typedef struct VuVirtqInflight {
     uint16_t used_idx;
 
     /* Used to track the state of each descriptor in descriptor table */
-    VuDescStateSplit desc[0];
+    VuDescStateSplit desc[];
 } VuVirtqInflight;
 
 typedef struct VuVirtqInflightDesc {
diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h
index 5f8ded2686..c954270aad 100644
--- a/hw/m68k/bootinfo.h
+++ b/hw/m68k/bootinfo.h
@@ -14,7 +14,7 @@ 
 struct bi_record {
     uint16_t tag;        /* tag ID */
     uint16_t size;       /* size of record */
-    uint32_t data[0];    /* data */
+    uint32_t data[];     /* data */
 };
 
 /* machine independent tags */
diff --git a/hw/scsi/srp.h b/hw/scsi/srp.h
index d27f31d2d5..54c954badd 100644
--- a/hw/scsi/srp.h
+++ b/hw/scsi/srp.h
@@ -112,7 +112,7 @@  struct srp_direct_buf {
 struct srp_indirect_buf {
     struct srp_direct_buf    table_desc;
     uint32_t                 len;
-    struct srp_direct_buf    desc_list[0];
+    struct srp_direct_buf    desc_list[];
 } QEMU_PACKED;
 
 enum {
@@ -211,7 +211,7 @@  struct srp_cmd {
     uint8_t    reserved4;
     uint8_t    add_cdb_len;
     uint8_t    cdb[16];
-    uint8_t    add_data[0];
+    uint8_t    add_data[];
 } QEMU_PACKED;
 
 enum {
@@ -241,7 +241,7 @@  struct srp_rsp {
     uint32_t   data_in_res_cnt;
     uint32_t   sense_data_len;
     uint32_t   resp_data_len;
-    uint8_t    data[0];
+    uint8_t    data[];
 } QEMU_PACKED;
 
 #endif /* SCSI_SRP_H */
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 9167bbaf6d..179775db7b 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -203,7 +203,7 @@  typedef struct XenPTMSIX {
     uint64_t mmio_base_addr;
     MemoryRegion mmio;
     void *phys_iomem_base;
-    XenPTMSIXEntry msix_entry[0];
+    XenPTMSIXEntry msix_entry[];
 } XenPTMSIX;
 
 struct XenPCIPassthroughState {
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 57a3f58b0c..19f7ba7b70 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -518,7 +518,7 @@  struct AcpiDmarDeviceScope {
     struct {
         uint8_t device;
         uint8_t function;
-    } path[0];
+    } path[];
 } QEMU_PACKED;
 typedef struct AcpiDmarDeviceScope AcpiDmarDeviceScope;
 
@@ -530,7 +530,7 @@  struct AcpiDmarHardwareUnit {
     uint8_t reserved;
     uint16_t pci_segment;   /* The PCI Segment associated with this unit */
     uint64_t address;   /* Base address of remapping hardware register-set */
-    AcpiDmarDeviceScope scope[0];
+    AcpiDmarDeviceScope scope[];
 } QEMU_PACKED;
 typedef struct AcpiDmarHardwareUnit AcpiDmarHardwareUnit;
 
@@ -541,7 +541,7 @@  struct AcpiDmarRootPortATS {
     uint8_t flags;
     uint8_t reserved;
     uint16_t pci_segment;
-    AcpiDmarDeviceScope scope[0];
+    AcpiDmarDeviceScope scope[];
 } QEMU_PACKED;
 typedef struct AcpiDmarRootPortATS AcpiDmarRootPortATS;
 
@@ -604,7 +604,7 @@  typedef struct AcpiIortMemoryAccess AcpiIortMemoryAccess;
 struct AcpiIortItsGroup {
     ACPI_IORT_NODE_HEADER_DEF
     uint32_t its_count;
-    uint32_t identifiers[0];
+    uint32_t identifiers[];
 } QEMU_PACKED;
 typedef struct AcpiIortItsGroup AcpiIortItsGroup;
 
@@ -621,7 +621,7 @@  struct AcpiIortSmmu3 {
     uint32_t pri_gsiv;
     uint32_t gerr_gsiv;
     uint32_t sync_gsiv;
-    AcpiIortIdMapping id_mapping_array[0];
+    AcpiIortIdMapping id_mapping_array[];
 } QEMU_PACKED;
 typedef struct AcpiIortSmmu3 AcpiIortSmmu3;
 
@@ -630,7 +630,7 @@  struct AcpiIortRC {
     AcpiIortMemoryAccess memory_properties;
     uint32_t ats_attribute;
     uint32_t pci_segment_number;
-    AcpiIortIdMapping id_mapping_array[0];
+    AcpiIortIdMapping id_mapping_array[];
 } QEMU_PACKED;
 typedef struct AcpiIortRC AcpiIortRC;
 
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
index 1f37844e5c..ca4a4b1ad1 100644
--- a/include/hw/arm/smmu-common.h
+++ b/include/hw/arm/smmu-common.h
@@ -85,7 +85,7 @@  typedef struct SMMUDevice {
 
 typedef struct SMMUPciBus {
     PCIBus       *bus;
-    SMMUDevice   *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
+    SMMUDevice   *pbdev[]; /* Parent array is sparse, so dynamically alloc */
 } SMMUPciBus;
 
 typedef struct SMMUIOTLBKey {
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 66b931e526..67aaa64c1b 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -118,7 +118,8 @@  struct VTDAddressSpace {
 
 struct VTDBus {
     PCIBus* bus;		/* A reference to the bus to provide translation for */
-    VTDAddressSpace *dev_as[0];	/* A table of VTDAddressSpace objects indexed by devfn */
+    /* A table of VTDAddressSpace objects indexed by devfn */
+    VTDAddressSpace *dev_as[];
 };
 
 struct VTDIOTLBEntry {
diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h
index 6f67f1020a..e653004d7c 100644
--- a/include/hw/virtio/virtio-iommu.h
+++ b/include/hw/virtio/virtio-iommu.h
@@ -41,7 +41,7 @@  typedef struct IOMMUDevice {
 
 typedef struct IOMMUPciBus {
     PCIBus       *bus;
-    IOMMUDevice  *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
+    IOMMUDevice  *pbdev[]; /* Parent array is sparse, so dynamically alloc */
 } IOMMUPciBus;
 
 typedef struct VirtIOIOMMU {
diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
index a9afb7e5b5..35eab06d0e 100644
--- a/include/sysemu/cryptodev.h
+++ b/include/sysemu/cryptodev.h
@@ -143,7 +143,7 @@  typedef struct CryptoDevBackendSymOpInfo {
     uint8_t *dst;
     uint8_t *aad_data;
     uint8_t *digest_result;
-    uint8_t data[0];
+    uint8_t data[];
 } CryptoDevBackendSymOpInfo;
 
 typedef struct CryptoDevBackendClass {
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 54e5446880..c48bd76b0a 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -267,7 +267,7 @@  struct TCGLabel {
 typedef struct TCGPool {
     struct TCGPool *next;
     int size;
-    uint8_t data[0] __attribute__ ((aligned));
+    uint8_t data[] __attribute__ ((aligned));
 } TCGPool;
 
 #define TCG_POOL_CHUNK_SIZE 32768
diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
index 94f53a5f1e..12a0166aae 100644
--- a/pc-bios/s390-ccw/bootmap.h
+++ b/pc-bios/s390-ccw/bootmap.h
@@ -136,7 +136,7 @@  typedef struct BootMapScriptHeader {
 
 typedef struct BootMapScript {
     BootMapScriptHeader header;
-    BootMapScriptEntry  entry[0];
+    BootMapScriptEntry  entry[];
 } __attribute__ ((packed)) BootMapScript;
 
 /*
diff --git a/pc-bios/s390-ccw/sclp.h b/pc-bios/s390-ccw/sclp.h
index 8450161ba7..64b53cad29 100644
--- a/pc-bios/s390-ccw/sclp.h
+++ b/pc-bios/s390-ccw/sclp.h
@@ -95,7 +95,7 @@  typedef struct EventBufferHeader {
 typedef struct WriteEventData {
     SCCBHeader h;
     EventBufferHeader ebh;
-    char data[0];
+    char data[];
 } __attribute__((packed)) WriteEventData;
 
 typedef struct ReadEventData {
diff --git a/tests/qtest/libqos/ahci.h b/tests/qtest/libqos/ahci.h
index f05b3e5fce..44ab1104b5 100644
--- a/tests/qtest/libqos/ahci.h
+++ b/tests/qtest/libqos/ahci.h
@@ -351,7 +351,7 @@  typedef struct AHCIQState {
 typedef struct FIS {
     uint8_t fis_type;
     uint8_t flags;
-    char data[0];
+    char data[];
 } __attribute__((__packed__)) FIS;
 
 /**
diff --git a/block/linux-aio.c b/block/linux-aio.c
index 91204a25a2..3c0527c2bf 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -121,7 +121,7 @@  struct aio_ring {
     unsigned    incompat_features;
     unsigned    header_length;  /* size of aio_ring */
 
-    struct io_event io_events[0];
+    struct io_event io_events[];
 };
 
 /**
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 5219dd0e2e..eb6a37b14e 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -485,7 +485,7 @@  struct NvdimmFuncGetLabelDataOut {
     /* the size of buffer filled by QEMU. */
     uint32_t len;
     uint32_t func_ret_status; /* return status code. */
-    uint8_t out_buf[0]; /* the data got via Get Namesapce Label function. */
+    uint8_t out_buf[]; /* the data got via Get Namesapce Label function. */
 } QEMU_PACKED;
 typedef struct NvdimmFuncGetLabelDataOut NvdimmFuncGetLabelDataOut;
 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > NVDIMM_DSM_MEMORY_SIZE);
@@ -493,7 +493,7 @@  QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > NVDIMM_DSM_MEMORY_SIZE);
 struct NvdimmFuncSetLabelDataIn {
     uint32_t offset; /* the offset in the namespace label data area. */
     uint32_t length; /* the size of data is to be written via the function. */
-    uint8_t in_buf[0]; /* the data written to label data area. */
+    uint8_t in_buf[]; /* the data written to label data area. */
 } QEMU_PACKED;
 typedef struct NvdimmFuncSetLabelDataIn NvdimmFuncSetLabelDataIn;
 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncSetLabelDataIn) +
@@ -510,7 +510,7 @@  struct NvdimmFuncReadFITOut {
     /* the size of buffer filled by QEMU. */
     uint32_t len;
     uint32_t func_ret_status; /* return status code. */
-    uint8_t fit[0]; /* the FIT data. */
+    uint8_t fit[]; /* the FIT data. */
 } QEMU_PACKED;
 typedef struct NvdimmFuncReadFITOut NvdimmFuncReadFITOut;
 QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncReadFITOut) > NVDIMM_DSM_MEMORY_SIZE);
diff --git a/hw/dma/soc_dma.c b/hw/dma/soc_dma.c
index c3e41581b6..3a430057f5 100644
--- a/hw/dma/soc_dma.c
+++ b/hw/dma/soc_dma.c
@@ -80,7 +80,7 @@  struct dma_s {
     } *memmap;
     int memmap_size;
 
-    struct soc_dma_ch_s ch[0];
+    struct soc_dma_ch_s ch[];
 };
 
 static void soc_dma_ch_schedule(struct soc_dma_ch_s *ch, int delay_bytes)
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 7f38e6ba8b..08246523f2 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -328,7 +328,7 @@  struct setup_data {
     uint64_t next;
     uint32_t type;
     uint32_t len;
-    uint8_t data[0];
+    uint8_t data[];
 } __attribute__((packed));
 
 
diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c
index 61b6df564a..54aeaecd69 100644
--- a/hw/misc/omap_l4.c
+++ b/hw/misc/omap_l4.c
@@ -24,7 +24,7 @@  struct omap_l4_s {
     MemoryRegion *address_space;
     hwaddr base;
     int ta_num;
-    struct omap_target_agent_s ta[0];
+    struct omap_target_agent_s ta[];
 };
 
 struct omap_l4_s *omap_l4_init(MemoryRegion *address_space,
diff --git a/hw/nvram/eeprom93xx.c b/hw/nvram/eeprom93xx.c
index 07f09549ed..ca6f591c84 100644
--- a/hw/nvram/eeprom93xx.c
+++ b/hw/nvram/eeprom93xx.c
@@ -86,7 +86,7 @@  struct _eeprom_t {
     uint8_t  addrbits;
     uint16_t size;
     uint16_t data;
-    uint16_t contents[0];
+    uint16_t contents[];
 };
 
 /* Code for saving and restoring of EEPROM state. */
diff --git a/hw/rdma/vmw/pvrdma_qp_ops.c b/hw/rdma/vmw/pvrdma_qp_ops.c
index bd6db858de..8050287a6c 100644
--- a/hw/rdma/vmw/pvrdma_qp_ops.c
+++ b/hw/rdma/vmw/pvrdma_qp_ops.c
@@ -34,13 +34,13 @@  typedef struct CompHandlerCtx {
 /* Send Queue WQE */
 typedef struct PvrdmaSqWqe {
     struct pvrdma_sq_wqe_hdr hdr;
-    struct pvrdma_sge sge[0];
+    struct pvrdma_sge sge[];
 } PvrdmaSqWqe;
 
 /* Recv Queue WQE */
 typedef struct PvrdmaRqWqe {
     struct pvrdma_rq_wqe_hdr hdr;
-    struct pvrdma_sge sge[0];
+    struct pvrdma_sge sge[];
 } PvrdmaRqWqe;
 
 /*
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 9a78ad928b..6210427544 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -626,7 +626,7 @@  static const uint32_t oid_supported_list[] =
 struct rndis_response {
     QTAILQ_ENTRY(rndis_response) entries;
     uint32_t length;
-    uint8_t buf[0];
+    uint8_t buf[];
 };
 
 typedef struct USBNetState {
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 02693a26ad..ef72738ced 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -227,7 +227,7 @@  typedef struct QEMU_PACKED CCID_Parameter {
 typedef struct QEMU_PACKED CCID_DataBlock {
     CCID_BULK_IN b;
     uint8_t      bChainParameter;
-    uint8_t      abData[0];
+    uint8_t      abData[];
 } CCID_DataBlock;
 
 /* 6.1.4 PC_to_RDR_XfrBlock */
@@ -235,7 +235,7 @@  typedef struct QEMU_PACKED CCID_XferBlock {
     CCID_Header  hdr;
     uint8_t      bBWI; /* Block Waiting Timeout */
     uint16_t     wLevelParameter; /* XXX currently unused */
-    uint8_t      abData[0];
+    uint8_t      abData[];
 } CCID_XferBlock;
 
 typedef struct QEMU_PACKED CCID_IccPowerOn {
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index b2d415e5dd..b6c8ef5bc0 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -54,7 +54,7 @@  typedef struct VRingAvail
 {
     uint16_t flags;
     uint16_t idx;
-    uint16_t ring[0];
+    uint16_t ring[];
 } VRingAvail;
 
 typedef struct VRingUsedElem
@@ -67,7 +67,7 @@  typedef struct VRingUsed
 {
     uint16_t flags;
     uint16_t idx;
-    VRingUsedElem ring[0];
+    VRingUsedElem ring[];
 } VRingUsed;
 
 typedef struct VRingMemoryRegionCaches {
diff --git a/net/queue.c b/net/queue.c
index 61276ca4be..0164727e39 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -46,7 +46,7 @@  struct NetPacket {
     unsigned flags;
     int size;
     NetPacketSent *sent_cb;
-    uint8_t data[0];
+    uint8_t data[];
 };
 
 struct NetQueue {