[PATCH] Enforce type check in ARRAY_SIZE macro

Michał Janiszewski janisozaur at gmail.com
Sat Jul 7 08:15:50 CDT 2018


On 7 July 2018 at 02:03, Ken Thomases <ken at codeweavers.com> wrote:

> On Jul 6, 2018, at 5:25 PM, 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.
>
> 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..ad945464f1 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
>
>
> Does that pose a licensing issue, since that code is GPL?
>

I would hope not, but honestly I don't know how to answer this question.


> +
> +#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])))
>
>
> In what version of GCC was __builtin_types_compatible_p() introduced?
>

It is already listed in manual for GCC 3.2:
https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Other-Builtins.html#Other-Builtins


> +#else
> +#define __must_be_array(a) 0
> +#endif
> +
> +# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + __must_be_array(x)
>
>
> The " + __must_be_array(x)" should be inside the parentheses.
>

Indeed. How do I send "v2" patch?


>
> #endif
>
>
> -Ken
>
>


-- 
Michal Janiszewski
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20180707/fba9c7ed/attachment.html>


More information about the wine-devel mailing list