[PATCH v2] Enforce type check in ARRAY_SIZE macro
Michał Janiszewski
janisozaur at gmail.com
Thu Nov 15 14:56:48 CST 2018
Resend
On Sun, 8 Jul 2018 at 23:34, <janisozaur at gmail.com> wrote:
>
> From: Michał Janiszewski <janisozaur at gmail.com>
>
> Inspired by kernel check and recent unification of ARRAY_SIZE, provide
> a way of enforcing the macro can only be applied to actual arrays and
> not to pointers.
>
> v2: Fix parentheses
>
> Signed-off-by: Michał Janiszewski <janisozaur at gmail.com>
> ---
> include/winnt.h | 21 ++++++++++++++++++++-
> 1 file changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/include/winnt.h b/include/winnt.h
> index 7f822c4aec..b99a375ab0 100644
> --- a/include/winnt.h
> +++ b/include/winnt.h
> @@ -760,7 +760,26 @@ typedef struct _MEMORY_BASIC_INFORMATION
> ((type *)((PCHAR)(address) - offsetof(type, field)))
>
> #ifdef __WINESRC__
> -# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
> +// Validate types used in the expression.
> +// Based on https://elixir.bootlin.com/linux/v4.17.4/source/include/linux/kernel.h#L71
> +
> +#ifdef __GNUC__
> +/**
> + * Force a compilation error if condition is true, but also produce a
> + * result (of value 0 and type size_t), so the expression can be used
> + * e.g. in a structure initializer (or where-ever else comma expressions
> + * aren't permitted).
> + */
> +#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
> +
> +/* &a[0] degrades to a pointer: a different type from an array */
> +#define __must_be_array(a) \
> + BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
> +#else
> +#define __must_be_array(a) 0
> +#endif
> +
> +# define ARRAY_SIZE(x) ((sizeof(x) / sizeof((x)[0])) + __must_be_array(x))
> #endif
>
> /* Types */
> --
> 2.18.0
>
--
Michal Janiszewski
More information about the wine-devel
mailing list