diff options
author | Ilya Maximets <i.maximets@ovn.org> | 2020-10-07 13:52:34 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-10-09 17:06:46 +0200 |
commit | b5d46df743be728431fe444008da2c6902cca872 (patch) | |
tree | 628ab7eb261c2642e5ddb6a69fde5c639650eb45 | |
parent | 1ba7c820275c3afe21b6fb70f4abe208ef67566c (diff) | |
download | sparse-b5d46df743be728431fe444008da2c6902cca872.tar.gz |
flex-array: allow arrays of unions with flexible members.
There is a common pattern on how to allocate memory for a flexible-size
structure, e.g.
union {
struct flex f; /* Structure that contains a flexible array. */
char buf[MAX_SIZE]; /* Memory buffer for structure 'flex' and
its flexible array. */
};
There is another example of such thing in CMSG manpage with the
alignment purposes:
union { /* Ancillary data buffer, wrapped in a union
in order to ensure it is suitably aligned */
char buf[CMSG_SPACE(sizeof(myfds))];
struct cmsghdr align;
} u;
Such unions could form an array in case user wants multiple
instances of them. For example, if you want receive up to
32 network packets via recvmmsg(), you will need 32 unions like 'u'.
Open vSwitch does exactly that and fails the check.
So, add a new option, -W[no-]flex-array-union, to enable or disable
any warning concerning flexible arrays and unions. This option needs
at least one of -Wflex-array-{array,nested,union} to be enabled in
order to have any effect.
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | options.c | 2 | ||||
-rw-r--r-- | options.h | 1 | ||||
-rw-r--r-- | sparse.1 | 9 | ||||
-rw-r--r-- | symbol.c | 2 | ||||
-rw-r--r-- | validation/flex-array-union-array-no.c | 9 | ||||
-rw-r--r-- | validation/flex-array-union-array-yes.c | 11 | ||||
-rw-r--r-- | validation/flex-array-union-array.h | 11 |
7 files changed, 44 insertions, 1 deletions
@@ -103,6 +103,7 @@ int Wexternal_function_has_definition = 1; int Wflexible_array_array = 1; int Wflexible_array_nested = 0; int Wflexible_array_sizeof = 0; +int Wflexible_array_union = 0; int Wimplicit_int = 1; int Winit_cstring = 0; int Wint_to_pointer_cast = 1; @@ -846,6 +847,7 @@ static const struct flag warnings[] = { { "flexible-array-array", &Wflexible_array_array }, { "flexible-array-nested", &Wflexible_array_nested }, { "flexible-array-sizeof", &Wflexible_array_sizeof }, + { "flexible-array-union", &Wflexible_array_union }, { "implicit-int", &Wimplicit_int }, { "init-cstring", &Winit_cstring }, { "int-to-pointer-cast", &Wint_to_pointer_cast }, @@ -102,6 +102,7 @@ extern int Wexternal_function_has_definition; extern int Wflexible_array_array; extern int Wflexible_array_nested; extern int Wflexible_array_sizeof; +extern int Wflexible_array_union; extern int Wimplicit_int; extern int Winit_cstring; extern int Wint_to_pointer_cast; @@ -278,6 +278,15 @@ possibly recursively. Sparse does not issue these warnings by default. . .TP +.B -Wflexible-array-union +Enable the warnings regarding flexible arrays and unions. +To have any effect, at least one of \fB-Wflexible-array-array\fR, +\fB-Wflexible-array-nested\fR or \fB-Wflexible-array-sizeof\fR must also +be enabled. + +Sparse does issue these warnings by default. +. +.TP .B \-Winit\-cstring Warn about initialization of a char array with a too long constant C string. @@ -214,7 +214,7 @@ static struct symbol * examine_struct_union_type(struct symbol *sym, int advance if (info.flex_array) { info.has_flex_array = 1; } - if (info.has_flex_array) + if (info.has_flex_array && (!is_union_type(sym) || Wflexible_array_union)) sym->has_flex_array = 1; sym->bit_size = bit_size; return sym; diff --git a/validation/flex-array-union-array-no.c b/validation/flex-array-union-array-no.c new file mode 100644 index 00000000..5a1de787 --- /dev/null +++ b/validation/flex-array-union-array-no.c @@ -0,0 +1,9 @@ +#include "flex-array-union-array.h" + +/* + * check-name: flex-array-union-no + * check-command: sparse -Wflexible-array-array -Wno-flexible-array-union $file + * + * check-error-start + * check-error-end + */ diff --git a/validation/flex-array-union-array-yes.c b/validation/flex-array-union-array-yes.c new file mode 100644 index 00000000..c2b71d65 --- /dev/null +++ b/validation/flex-array-union-array-yes.c @@ -0,0 +1,11 @@ +#include "flex-array-union-array.h" + +/* + * check-name: flex-array-union-yes + * check-command: sparse -Wflexible-array-array -Wflexible-array-union $file + * + * check-error-start +flex-array-union-array-yes.c: note: in included file: +flex-array-union-array.h:11:17: warning: array of flexible structures + * check-error-end + */ diff --git a/validation/flex-array-union-array.h b/validation/flex-array-union-array.h new file mode 100644 index 00000000..b2a74d1a --- /dev/null +++ b/validation/flex-array-union-array.h @@ -0,0 +1,11 @@ +struct s_flex { + int i; + long f[]; +}; + +union s { + struct s_flex flex; + char buf[200]; +}; + +static union s a[2]; |