diff options
author | Filipe Brandenburger <filbranden@google.com> | 2018-07-18 04:43:20 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-07-19 09:07:25 +0200 |
commit | d9fb7afb4890a93db478616e7bfc639b2129b466 (patch) | |
tree | b0b77f733dfcc1c7116289e8dbfa5c5194a70c2e /src | |
parent | Add HP Chromebook 14 (Falco) HWDB rule to fix scroll stutter (#9646) (diff) | |
download | systemd-d9fb7afb4890a93db478616e7bfc639b2129b466.tar.xz systemd-d9fb7afb4890a93db478616e7bfc639b2129b466.zip |
coverity: Add custom assertion macros for Coverity
These custom macros make the expression go through a function, in order
to prevent ASSERT_SIDE_EFFECT false positives on our macros such as
assert_se() and assert_return() that cannot be disabled and will always
evaluate their expressions.
This technique has been described and recommended in:
https://community.synopsys.com/s/question/0D534000046Yuzb/suppressing-assertsideeffect-for-functions-that-allow-for-sideeffects
Tested by doing a local cov-build and uploading the resulting tarball to
scan.coverity.com, confirmed that the ASSERT_SIDE_EFFECT false positives
were gone.
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/macro.h | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/basic/macro.h b/src/basic/macro.h index d1365f7058..7e0f6b4ab5 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -247,12 +247,48 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { (__x / __y + !!(__x % __y)); \ }) +#ifdef __COVERITY__ + +/* Use special definitions of assertion macros in order to prevent + * false positives of ASSERT_SIDE_EFFECT on Coverity static analyzer + * for uses of assert_se() and assert_return(). + * + * These definitions make expression go through a (trivial) function + * call to ensure they are not discarded. Also use ! or !! to ensure + * the boolean expressions are seen as such. + * + * This technique has been described and recommended in: + * https://community.synopsys.com/s/question/0D534000046Yuzb/suppressing-assertsideeffect-for-functions-that-allow-for-sideeffects + */ + +extern void __coverity_panic__(void); + +static inline int __coverity_check__(int condition) { + return condition; +} + +#define assert_message_se(expr, message) \ + do { \ + if (__coverity_check__(!(expr))) \ + __coverity_panic__(); \ + } while (false) + +#define assert_log(expr, message) __coverity_check__(!!(expr)) + +#else /* ! __COVERITY__ */ + #define assert_message_se(expr, message) \ do { \ if (_unlikely_(!(expr))) \ log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ } while (false) +#define assert_log(expr, message) ((_likely_(expr)) \ + ? (true) \ + : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false)) + +#endif /* __COVERITY__ */ + #define assert_se(expr) assert_message_se(expr, #expr) /* We override the glibc assert() here. */ @@ -285,10 +321,6 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { REENABLE_WARNING #endif -#define assert_log(expr, message) ((_likely_(expr)) \ - ? (true) \ - : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false)) - #define assert_return(expr, r) \ do { \ if (!assert_log(expr, #expr)) \ |