From 696c0b890ee1caa327daedc9dd6e5d67a6cae33c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Oct 2018 22:05:55 +0200 Subject: [PATCH 1/2] macro: drop -Wdeclaration-after-statement exclusion magic, we dropped that warning anyway from our build --- src/basic/macro.h | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index 9972b6f992..361ffbc5d0 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -56,10 +56,6 @@ #endif /* Temporarily disable some warnings */ -#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") - #define DISABLE_WARNING_FORMAT_NONLITERAL \ _Pragma("GCC diagnostic push"); \ _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") @@ -314,20 +310,13 @@ static inline int __coverity_check__(int condition) { } while (false) #if defined(static_assert) -/* static_assert() is sometimes defined in a way that trips up - * -Wdeclaration-after-statement, hence let's temporarily turn off - * this warning around it. */ #define assert_cc(expr) \ - DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \ - static_assert(expr, #expr); \ - REENABLE_WARNING + static_assert(expr, #expr); #else #define assert_cc(expr) \ - DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \ struct CONCATENATE(_assert_struct_, __COUNTER__) { \ char x[(expr) ? 0 : -1]; \ - }; \ - REENABLE_WARNING + }; #endif #define assert_return(expr, r) \ From 8e2b687957a77eb7f360cc22cf78d270b699a64c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Oct 2018 22:07:14 +0200 Subject: [PATCH 2/2] 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 --- src/basic/macro.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index 361ffbc5d0..63a8be440f 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; \