test: simplify ASSERT_OK macro for static analysis

I was testing a static analyzer on libuv's code, and it could not
understand the use of a constant variable in the condition as an assert
branch. This simplifies the code for easier static analysis. I also
removed the explicit casts, relying instead on C's casting rules to
catch some misuse.
This commit is contained in:
Jameson Nash 2025-07-10 14:18:34 -04:00
parent 7026ae0fe2
commit 375c641580
5 changed files with 39 additions and 21 deletions

View File

@ -31,7 +31,7 @@
#ifdef __MVS__
#include "zos-base.h"
/* Initialize environment and zoslib */
__attribute__((constructor)) void init() {
__attribute__((constructor)) void init(void) {
zoslib_config_t config;
init_zoslib_config(&config);
init_zoslib(config);

View File

@ -40,7 +40,7 @@
#ifdef __MVS__
#include "zos-base.h"
/* Initialize environment and zoslib */
__attribute__((constructor)) void init() {
__attribute__((constructor)) void init(void) {
zoslib_config_t config;
init_zoslib_config(&config);
init_zoslib(config);

View File

@ -340,7 +340,7 @@ static int clear_line(void) {
}
void rewind_cursor() {
void rewind_cursor(void) {
if (clear_line() == -1) {
/* If clear_line fails (stdout is not a console), print a newline. */
fprintf(stderr, "\n");

View File

@ -113,8 +113,8 @@ typedef enum {
#define ASSERT_BASE(a, operator, b, type, conv) \
do { \
volatile type eval_a = (type) (a); \
volatile type eval_b = (type) (b); \
type const eval_a = (a); \
type const eval_b = (b); \
if (!(eval_a operator eval_b)) { \
fprintf(stderr, \
"Assertion failed in %s on line %d: `%s %s %s` " \
@ -131,6 +131,21 @@ typedef enum {
} \
} while (0)
#define ASSERT_OK(a) \
do { \
int64_t const eval_a = (a); \
if (eval_a) { \
fprintf(stderr, \
"Assertion failed in %s on line %d: `%s` okay " \
"(error: %"PRId64")\n", \
__FILE__, \
__LINE__, \
#a, \
eval_a); \
abort(); \
} \
} while (0)
#define ASSERT_BASE_STR(expr, a, operator, b, type, conv) \
do { \
if (!(expr)) { \
@ -173,8 +188,8 @@ typedef enum {
do { \
if (!(expr)) { \
int i; \
unsigned char* a_ = (unsigned char*)a; \
unsigned char* b_ = (unsigned char*)b; \
const unsigned char* a_ = (a); \
const unsigned char* b_ = (b); \
fprintf(stderr, \
"Assertion failed in %s on line %d: `%s %s %s` (", \
__FILE__, \
@ -202,7 +217,6 @@ typedef enum {
#define ASSERT_LE(a, b) ASSERT_BASE(a, <=, b, int64_t, PRId64)
#define ASSERT_LT(a, b) ASSERT_BASE(a, <, b, int64_t, PRId64)
#define ASSERT_NE(a, b) ASSERT_BASE(a, !=, b, int64_t, PRId64)
#define ASSERT_OK(a) ASSERT_BASE(a, ==, 0, int64_t, PRId64)
#define ASSERT_UINT64_EQ(a, b) ASSERT_BASE(a, ==, b, uint64_t, PRIu64)
#define ASSERT_UINT64_GE(a, b) ASSERT_BASE(a, >=, b, uint64_t, PRIu64)
@ -211,12 +225,12 @@ typedef enum {
#define ASSERT_UINT64_LT(a, b) ASSERT_BASE(a, <, b, uint64_t, PRIu64)
#define ASSERT_UINT64_NE(a, b) ASSERT_BASE(a, !=, b, uint64_t, PRIu64)
#define ASSERT_DOUBLE_EQ(a, b) ASSERT_BASE(a, ==, b, double, "f")
#define ASSERT_DOUBLE_GE(a, b) ASSERT_BASE(a, >=, b, double, "f")
#define ASSERT_DOUBLE_GT(a, b) ASSERT_BASE(a, >, b, double, "f")
#define ASSERT_DOUBLE_LE(a, b) ASSERT_BASE(a, <=, b, double, "f")
#define ASSERT_DOUBLE_LT(a, b) ASSERT_BASE(a, <, b, double, "f")
#define ASSERT_DOUBLE_NE(a, b) ASSERT_BASE(a, !=, b, double, "f")
#define ASSERT_DOUBLE_EQ(a, b) ASSERT_BASE(a, ==, b, volatile double, "f")
#define ASSERT_DOUBLE_GE(a, b) ASSERT_BASE(a, >=, b, volatile double, "f")
#define ASSERT_DOUBLE_GT(a, b) ASSERT_BASE(a, >, b, volatile double, "f")
#define ASSERT_DOUBLE_LE(a, b) ASSERT_BASE(a, <=, b, volatile double, "f")
#define ASSERT_DOUBLE_LT(a, b) ASSERT_BASE(a, <, b, volatile double, "f")
#define ASSERT_DOUBLE_NE(a, b) ASSERT_BASE(a, !=, b, volatile double, "f")
#define ASSERT_STR_EQ(a, b) \
ASSERT_BASE_STR(strcmp(a, b) == 0, a, == , b, char*, "s")
@ -237,19 +251,23 @@ typedef enum {
ASSERT_BASE_HEX(memcmp(a, b, size) != 0, a, !=, b, size)
#define ASSERT_NULL(a) \
ASSERT_BASE(a, ==, NULL, void*, "p")
ASSERT_BASE(a, ==, NULL, const void*, "p")
#define ASSERT_NOT_NULL(a) \
ASSERT_BASE(a, !=, NULL, void*, "p")
ASSERT_BASE(a, !=, NULL, const void*, "p")
#define ASSERT_PTR_EQ(a, b) \
ASSERT_BASE(a, ==, b, void*, "p")
ASSERT_BASE(a, ==, b, const void*, "p")
#define ASSERT_PTR_NE(a, b) \
ASSERT_BASE(a, !=, b, void*, "p")
ASSERT_BASE(a, !=, b, const void*, "p")
#define ASSERT_PTR_LT(a, b) \
ASSERT_BASE(a, <, b, void*, "p")
ASSERT_BASE(a, <, b, const void*, "p")
#define ASSERT_PTR_LE(a, b) \
ASSERT_BASE(a, <=, b, const void*, "p")
#define ASSERT_PTR_GE(a, b) \
ASSERT_BASE(a, >=, b, const void*, "p")
/* This macro cleans up the event loop. This is used to avoid valgrind
* warnings about memory being "leaked" by the event loop.

View File

@ -69,8 +69,8 @@ static void connect_cb(uv_connect_t* req, int status) {
}
ASSERT_OK(status);
ASSERT_LE(connect_reqs, req);
ASSERT_LE(req, connect_reqs + ARRAY_SIZE(connect_reqs));
ASSERT_PTR_LE(connect_reqs, req);
ASSERT_PTR_LE(req, connect_reqs + ARRAY_SIZE(connect_reqs));
i = req - connect_reqs;
buf = uv_buf_init("x", 1);