summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-07-28 11:38:33 +0200
committerThomas Haller <thaller@redhat.com>2023-08-07 09:24:47 +0200
commitf27bf0b9ea83186d5b8104bb48182b2000a62c28 (patch)
treefb43f4d40f8c7b6d06a201fa60ff2bc43c3bbaed
parent3732f083191184d4e4ff1f6232e12f5018b016ba (diff)
std-aux: add static-asserts about signedness of NM_MIN()/NM_MAX()/NM_CLAMP()
The macros NM_MIN()/NM_MAX()/NM_CLAMP() use typeof() to accept any integer type as argument. Internally, they rely on standard C integral conversions of the <> operators and the ternary operator for evaluating the comparison and the result(type). That works mostly great. Except, comparing signed and unsigned values in C leads to oddities and the caller should explicitly take care of that. Add static assertions to check that the compared arguments have the same signedness.
-rw-r--r--src/libnm-std-aux/nm-std-aux.h27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/libnm-std-aux/nm-std-aux.h b/src/libnm-std-aux/nm-std-aux.h
index e65f2c417a..623a7c1e03 100644
--- a/src/libnm-std-aux/nm-std-aux.h
+++ b/src/libnm-std-aux/nm-std-aux.h
@@ -402,6 +402,9 @@ nm_mult_clamped_u(unsigned a, unsigned b)
({ \
typeof(a) NM_UNIQ_T(A, aq) = (a); \
typeof(b) NM_UNIQ_T(B, bq) = (b); \
+ \
+ G_STATIC_ASSERT(_NM_INT_SAME_SIGNEDNESS(NM_UNIQ_T(A, aq), NM_UNIQ_T(B, bq))); \
+ \
((NM_UNIQ_T(A, aq) < NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \
})
@@ -410,19 +413,25 @@ nm_mult_clamped_u(unsigned a, unsigned b)
({ \
typeof(a) NM_UNIQ_T(A, aq) = (a); \
typeof(b) NM_UNIQ_T(B, bq) = (b); \
+ \
+ G_STATIC_ASSERT(_NM_INT_SAME_SIGNEDNESS(NM_UNIQ_T(A, aq), NM_UNIQ_T(B, bq))); \
+ \
((NM_UNIQ_T(A, aq) > NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \
})
#define NM_CLAMP(x, low, high) __NM_CLAMP(NM_UNIQ, x, NM_UNIQ, low, NM_UNIQ, high)
-#define __NM_CLAMP(xq, x, lowq, low, highq, high) \
- ({ \
- typeof(x) NM_UNIQ_T(X, xq) = (x); \
- typeof(low) NM_UNIQ_T(LOW, lowq) = (low); \
- typeof(high) NM_UNIQ_T(HIGH, highq) = (high); \
- \
- ((NM_UNIQ_T(X, xq) > NM_UNIQ_T(HIGH, highq)) ? NM_UNIQ_T(HIGH, highq) \
- : (NM_UNIQ_T(X, xq) < NM_UNIQ_T(LOW, lowq)) ? NM_UNIQ_T(LOW, lowq) \
- : NM_UNIQ_T(X, xq)); \
+#define __NM_CLAMP(xq, x, lowq, low, highq, high) \
+ ({ \
+ typeof(x) NM_UNIQ_T(X, xq) = (x); \
+ typeof(low) NM_UNIQ_T(LOW, lowq) = (low); \
+ typeof(high) NM_UNIQ_T(HIGH, highq) = (high); \
+ \
+ G_STATIC_ASSERT(_NM_INT_SAME_SIGNEDNESS(NM_UNIQ_T(X, xq), NM_UNIQ_T(LOW, lowq))); \
+ G_STATIC_ASSERT(_NM_INT_SAME_SIGNEDNESS(NM_UNIQ_T(X, xq), NM_UNIQ_T(HIGH, highq))); \
+ \
+ ((NM_UNIQ_T(X, xq) > NM_UNIQ_T(HIGH, highq)) ? NM_UNIQ_T(HIGH, highq) \
+ : (NM_UNIQ_T(X, xq) < NM_UNIQ_T(LOW, lowq)) ? NM_UNIQ_T(LOW, lowq) \
+ : NM_UNIQ_T(X, xq)); \
})
#define NM_MAX_WITH_CMP(cmp, a, b) \