Commit 6549a8c0 authored by Gustavo A. R. Silva's avatar Gustavo A. R. Silva Committed by Arnaldo Carvalho de Melo

perf tools: Replace zero-length array with flexible-array

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][2], 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
inadvertently introduced[3] to the codebase from now on.

Also, notice that, dynamic memory allocations won't be affected by this
change:

"Flexible array members have incomplete type, and so the sizeof operator
may not be applied. As a quirk of the original implementation of
zero-length arrays, sizeof evaluates to zero."[1]

sizeof(flexible-array-member) triggers a warning because flexible array
members have incomplete type[1]. There are some instances of code in
which the sizeof operator is being incorrectly/erroneously applied to
zero-length arrays and the result is zero. Such instances may be hiding
some bugs. So, this work (flexible-array member conversions) will also
help to get completely rid of those sorts of issues.

This issue was found with the help of Coccinelle.

[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit 76497732 ("cxgb3/l2t: Fix undefined behaviour")
Signed-off-by: default avatarGustavo A. R. Silva <gustavoars@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Gustavo A. R. Silva <gustavo@embeddedor.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lore.kernel.org/lkml/20200515172926.GA31976@embeddedorSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 961224db
...@@ -40,7 +40,7 @@ struct sender_context { ...@@ -40,7 +40,7 @@ struct sender_context {
unsigned int num_fds; unsigned int num_fds;
int ready_out; int ready_out;
int wakefd; int wakefd;
int out_fds[0]; int out_fds[];
}; };
struct receiver_context { struct receiver_context {
......
...@@ -51,7 +51,7 @@ struct perf_inject { ...@@ -51,7 +51,7 @@ struct perf_inject {
struct event_entry { struct event_entry {
struct list_head node; struct list_head node;
u32 tid; u32 tid;
union perf_event event[0]; union perf_event event[];
}; };
static int output_bytes(struct perf_inject *inject, void *buf, size_t sz) static int output_bytes(struct perf_inject *inject, void *buf, size_t sz)
......
...@@ -2449,7 +2449,7 @@ static int __cmd_script(struct perf_script *script) ...@@ -2449,7 +2449,7 @@ static int __cmd_script(struct perf_script *script)
struct script_spec { struct script_spec {
struct list_head node; struct list_head node;
struct scripting_ops *ops; struct scripting_ops *ops;
char spec[0]; char spec[];
}; };
static LIST_HEAD(script_specs); static LIST_HEAD(script_specs);
......
...@@ -128,7 +128,7 @@ struct sample_wrapper { ...@@ -128,7 +128,7 @@ struct sample_wrapper {
struct sample_wrapper *next; struct sample_wrapper *next;
u64 timestamp; u64 timestamp;
unsigned char data[0]; unsigned char data[];
}; };
#define TYPE_NONE 0 #define TYPE_NONE 0
......
...@@ -144,7 +144,7 @@ struct annotation_line { ...@@ -144,7 +144,7 @@ struct annotation_line {
u32 idx; u32 idx;
int idx_asm; int idx_asm;
int data_nr; int data_nr;
struct annotation_data data[0]; struct annotation_data data[];
}; };
struct disasm_line { struct disasm_line {
...@@ -227,7 +227,7 @@ void symbol__calc_percent(struct symbol *sym, struct evsel *evsel); ...@@ -227,7 +227,7 @@ void symbol__calc_percent(struct symbol *sym, struct evsel *evsel);
struct sym_hist { struct sym_hist {
u64 nr_samples; u64 nr_samples;
u64 period; u64 period;
struct sym_hist_entry addr[0]; struct sym_hist_entry addr[];
}; };
struct cyc_hist { struct cyc_hist {
......
...@@ -22,7 +22,7 @@ struct numa_topology_node { ...@@ -22,7 +22,7 @@ struct numa_topology_node {
struct numa_topology { struct numa_topology {
u32 nr; u32 nr;
struct numa_topology_node nodes[0]; struct numa_topology_node nodes[];
}; };
struct cpu_topology *cpu_topology__new(void); struct cpu_topology *cpu_topology__new(void);
......
...@@ -137,7 +137,7 @@ struct dso_cache { ...@@ -137,7 +137,7 @@ struct dso_cache {
struct rb_node rb_node; struct rb_node rb_node;
u64 offset; u64 offset;
u64 size; u64 size;
char data[0]; char data[];
}; };
struct auxtrace_cache; struct auxtrace_cache;
...@@ -209,7 +209,7 @@ struct dso { ...@@ -209,7 +209,7 @@ struct dso {
struct nsinfo *nsinfo; struct nsinfo *nsinfo;
struct dso_id id; struct dso_id id;
refcount_t refcnt; refcount_t refcnt;
char name[0]; char name[];
}; };
/* dso__for_each_symbol - iterate over the symbols of given type /* dso__for_each_symbol - iterate over the symbols of given type
......
...@@ -79,7 +79,7 @@ struct sample_read { ...@@ -79,7 +79,7 @@ struct sample_read {
struct ip_callchain { struct ip_callchain {
u64 nr; u64 nr;
u64 ips[0]; u64 ips[];
}; };
struct branch_stack; struct branch_stack;
......
...@@ -57,7 +57,7 @@ struct debug_line_info { ...@@ -57,7 +57,7 @@ struct debug_line_info {
unsigned long vma; unsigned long vma;
unsigned int lineno; unsigned int lineno;
/* The filename format is unspecified, absolute path, relative etc. */ /* The filename format is unspecified, absolute path, relative etc. */
char const filename[0]; char const filename[];
}; };
struct jit_tool { struct jit_tool {
......
...@@ -93,7 +93,7 @@ struct debug_entry { ...@@ -93,7 +93,7 @@ struct debug_entry {
uint64_t addr; uint64_t addr;
int lineno; /* source line number starting at 1 */ int lineno; /* source line number starting at 1 */
int discrim; /* column discriminator, 0 is default */ int discrim; /* column discriminator, 0 is default */
const char name[0]; /* null terminated filename, \xff\0 if same as previous entry */ const char name[]; /* null terminated filename, \xff\0 if same as previous entry */
}; };
struct jr_code_debug_info { struct jr_code_debug_info {
...@@ -101,7 +101,7 @@ struct jr_code_debug_info { ...@@ -101,7 +101,7 @@ struct jr_code_debug_info {
uint64_t code_addr; uint64_t code_addr;
uint64_t nr_entry; uint64_t nr_entry;
struct debug_entry entries[0]; struct debug_entry entries[];
}; };
struct jr_code_unwinding_info { struct jr_code_unwinding_info {
...@@ -110,7 +110,7 @@ struct jr_code_unwinding_info { ...@@ -110,7 +110,7 @@ struct jr_code_unwinding_info {
uint64_t unwinding_size; uint64_t unwinding_size;
uint64_t eh_frame_hdr_size; uint64_t eh_frame_hdr_size;
uint64_t mapped_size; uint64_t mapped_size;
const char unwinding_data[0]; const char unwinding_data[];
}; };
union jr_entry { union jr_entry {
......
...@@ -29,7 +29,7 @@ typedef int (*ordered_events__deliver_t)(struct ordered_events *oe, ...@@ -29,7 +29,7 @@ typedef int (*ordered_events__deliver_t)(struct ordered_events *oe,
struct ordered_events_buffer { struct ordered_events_buffer {
struct list_head list; struct list_head list;
struct ordered_event event[0]; struct ordered_event event[];
}; };
struct ordered_events { struct ordered_events {
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
struct pstack { struct pstack {
unsigned short top; unsigned short top;
unsigned short max_nr_entries; unsigned short max_nr_entries;
void *entries[0]; void *entries[];
}; };
struct pstack *pstack__new(unsigned short max_nr_entries) struct pstack *pstack__new(unsigned short max_nr_entries)
......
...@@ -55,7 +55,7 @@ struct symbol { ...@@ -55,7 +55,7 @@ struct symbol {
u8 inlined:1; u8 inlined:1;
u8 arch_sym; u8 arch_sym;
bool annotate2; bool annotate2;
char name[0]; char name[];
}; };
void symbol__delete(struct symbol *sym); void symbol__delete(struct symbol *sym);
......
...@@ -243,7 +243,7 @@ struct eh_frame_hdr { ...@@ -243,7 +243,7 @@ struct eh_frame_hdr {
* encoded_t fde_addr; * encoded_t fde_addr;
* } binary_search_table[fde_count]; * } binary_search_table[fde_count];
*/ */
char data[0]; char data[];
} __packed; } __packed;
static int unwind_spec_ehframe(struct dso *dso, struct machine *machine, static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment