From: Lennart Poettering Date: Thu, 11 Oct 2018 20:07:14 +0000 (+0200) Subject: macro: rework IN_SET a bit X-Git-Tag: v240~562^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8e2b687957a77eb7f360cc22cf78d270b699a64c;p=thirdparty%2Fsystemd.git macro: rework IN_SET a bit This makes use of assert_cc() to guard against missing CASE macros, instead of a manual implementation that might result in a static variable to be allocated. More importantly though this changes the base type for the array used to determine the number of arguments for the compile time check from "int" to "long double". This is done in order to avoid warnings from "ubsan" that possibly large constants are assigned to small types. "long double" hopefully isn't vulnerable to that. Fixes: #10332 --- diff --git a/src/basic/macro.h b/src/basic/macro.h index 361ffbc5d02..63a8be440f2 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -415,8 +415,11 @@ static inline int __coverity_check__(int condition) { #define IN_SET(x, ...) \ ({ \ bool _found = false; \ - /* If the build breaks in the line below, you need to extend the case macros */ \ - static _unused_ char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){__VA_ARGS__})/sizeof(int)]; \ + /* If the build breaks in the line below, you need to extend the case macros. (We use "long double" as \ + * type for the array, in the hope that checkers such as ubsan don't complain that the initializers for \ + * the array are not representable by the base type. Ideally we'd use typeof(x) as base type, but that \ + * doesn't work, as we want to use this on bitfields and gcc refuses typeof() on bitfields.) */ \ + assert_cc((sizeof((long double[]){__VA_ARGS__})/sizeof(long double)) <= 20); \ switch(x) { \ FOR_EACH_MAKE_CASE(__VA_ARGS__) \ _found = true; \