diff options
author | Thomas Haller <thaller@redhat.com> | 2023-07-28 11:38:33 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-08-07 09:24:47 +0200 |
commit | f27bf0b9ea83186d5b8104bb48182b2000a62c28 (patch) | |
tree | fb43f4d40f8c7b6d06a201fa60ff2bc43c3bbaed | |
parent | 3732f083191184d4e4ff1f6232e12f5018b016ba (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.h | 27 |
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) \ |