]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
macro: rework IN_SET a bit 10366/head
authorLennart Poettering <lennart@poettering.net>
Thu, 11 Oct 2018 20:07:14 +0000 (22:07 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 11 Oct 2018 20:07:14 +0000 (22:07 +0200)
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
src/basic/macro.h

index 361ffbc5d028de646fa6eb184c3ae49bae8b0d18..63a8be440f2e286f56893d231f790eeeabcaa1b6 100644 (file)
@@ -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;          \