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.
This commit is contained in:
Filipe Brandenburger 2018-07-17 19:43:20 -07:00 committed by Zbigniew Jędrzejewski-Szmek
parent 6a8b230585
commit d9fb7afb48

View file

@ -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)) \