From 1ef0db7c9efb562fbb3a297ace99df51f408699d Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 17 Mar 2024 20:36:31 -0700 Subject: [PATCH 1/2] lib: make assertions visible to clang static analyzer --- common_defs.h | 7 +++++++ lib/lib_common.h | 12 ++++++++++-- lib/utils.c | 2 +- programs/test_util.c | 2 +- programs/test_util.h | 8 +------- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/common_defs.h b/common_defs.h index a3773c4e..094d4384 100644 --- a/common_defs.h +++ b/common_defs.h @@ -204,6 +204,13 @@ typedef size_t machine_word_t; # define MAYBE_UNUSED #endif +/* NORETURN - mark a function as never returning, e.g. due to calling abort() */ +#if defined(__GNUC__) || __has_attribute(noreturn) +# define NORETURN __attribute__((noreturn)) +#else +# define NORETURN +#endif + /* * restrict - hint that writes only occur through the given pointer. * diff --git a/lib/lib_common.h b/lib/lib_common.h index 8c9ff5fe..faedfcb0 100644 --- a/lib/lib_common.h +++ b/lib/lib_common.h @@ -76,7 +76,14 @@ int memcmp(const void *s1, const void *s2, size_t n); #undef LIBDEFLATE_ENABLE_ASSERTIONS #else -#include +# include + /* + * To prevent false positive static analyzer warnings, ensure that assertions + * are visible to the static analyzer. + */ +# ifdef __clang_analyzer__ +# define LIBDEFLATE_ENABLE_ASSERTIONS +# endif #endif /* @@ -84,7 +91,8 @@ int memcmp(const void *s1, const void *s2, size_t n); * hurt performance significantly. */ #ifdef LIBDEFLATE_ENABLE_ASSERTIONS -void libdeflate_assertion_failed(const char *expr, const char *file, int line); +NORETURN void +libdeflate_assertion_failed(const char *expr, const char *file, int line); #define ASSERT(expr) { if (unlikely(!(expr))) \ libdeflate_assertion_failed(#expr, __FILE__, __LINE__); } #else diff --git a/lib/utils.c b/lib/utils.c index c1e4cc26..5bb34eda 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -132,7 +132,7 @@ memcmp(const void *s1, const void *s2, size_t n) #ifdef LIBDEFLATE_ENABLE_ASSERTIONS #include #include -void +NORETURN void libdeflate_assertion_failed(const char *expr, const char *file, int line) { fprintf(stderr, "Assertion failed: %s at %s:%d\n", expr, file, line); diff --git a/programs/test_util.c b/programs/test_util.c index 11cd4875..7ba93b3c 100644 --- a/programs/test_util.c +++ b/programs/test_util.c @@ -42,7 +42,7 @@ #endif /* Abort with an error message */ -_noreturn void +NORETURN void assertion_failed(const char *expr, const char *file, int line) { msg("Assertion failed: %s at %s:%d", expr, file, line); diff --git a/programs/test_util.h b/programs/test_util.h index 9df6ca71..db51a076 100644 --- a/programs/test_util.h +++ b/programs/test_util.h @@ -32,13 +32,7 @@ #include /* for comparison purposes */ -#if defined(__GNUC__) || __has_attribute(noreturn) -# define _noreturn __attribute__((noreturn)) -#else -# define _noreturn -#endif - -void _noreturn +NORETURN void assertion_failed(const char *expr, const char *file, int line); #define ASSERT(expr) { if (unlikely(!(expr))) \ From 9e79696644b826d2009acda4455d9fa43708a17a Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 17 Mar 2024 20:36:31 -0700 Subject: [PATCH 2/2] lib: avoid clang static analyzer warning in deflate_get_offset_slot() Resolves https://github.com/ebiggers/libdeflate/issues/357 --- lib/deflate_compress.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/deflate_compress.c b/lib/deflate_compress.c index 32c736d8..f8856d24 100644 --- a/lib/deflate_compress.c +++ b/lib/deflate_compress.c @@ -1474,6 +1474,8 @@ deflate_get_offset_slot(u32 offset) */ unsigned n = (256 - offset) >> 29; + ASSERT(offset >= 1 && offset <= 32768); + return deflate_offset_slot[(offset - 1) >> n] + (n << 1); }