From addae96a1a1f010b5db12cbf8b78719658fcc23b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 29 Jul 2021 18:39:09 +0200 Subject: macro: relax CONST_MAX() type check a tiny bit This checked for strict type compatibility so far, which mean CONST_MAX() couldn't be used on two differently signed integers, even though conceptually there's nothing wrong with allowing that here, as C correctly picks the larger type in the ternary op. hence, let's explicitly whitelist integer comparisons here, as long as the signedness matches. --- src/fundamental/macro-fundamental.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h index 967518600d4..e9fb4d39380 100644 --- a/src/fundamental/macro-fundamental.h +++ b/src/fundamental/macro-fundamental.h @@ -70,12 +70,29 @@ UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \ }) -/* evaluates to (void) if _A or _B are not constant or of different types */ +#define IS_UNSIGNED_INTEGER_TYPE(type) \ + (__builtin_types_compatible_p(typeof(type), unsigned char) || \ + __builtin_types_compatible_p(typeof(type), unsigned short) || \ + __builtin_types_compatible_p(typeof(type), unsigned) || \ + __builtin_types_compatible_p(typeof(type), unsigned long) || \ + __builtin_types_compatible_p(typeof(type), unsigned long long)) + +#define IS_SIGNED_INTEGER_TYPE(type) \ + (__builtin_types_compatible_p(typeof(type), signed char) || \ + __builtin_types_compatible_p(typeof(type), signed short) || \ + __builtin_types_compatible_p(typeof(type), signed) || \ + __builtin_types_compatible_p(typeof(type), signed long) || \ + __builtin_types_compatible_p(typeof(type), signed long long)) + +/* Evaluates to (void) if _A or _B are not constant or of different types (being integers of different sizes + * is also OK as long as the signedness matches) */ #define CONST_MAX(_A, _B) \ (__builtin_choose_expr( \ __builtin_constant_p(_A) && \ __builtin_constant_p(_B) && \ - __builtin_types_compatible_p(typeof(_A), typeof(_B)), \ + (__builtin_types_compatible_p(typeof(_A), typeof(_B)) || \ + (IS_UNSIGNED_INTEGER_TYPE(_A) && IS_UNSIGNED_INTEGER_TYPE(_B)) || \ + (IS_SIGNED_INTEGER_TYPE(_A) && IS_SIGNED_INTEGER_TYPE(_B))), \ ((_A) > (_B)) ? (_A) : (_B), \ VOID_0)) -- cgit v1.2.3-59-g8ed1b From 777003365a87aa6656938d0ecca9d54887fefab9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 29 Jul 2021 17:45:19 +0200 Subject: macro: sizeof() returns size_t, and that's good Now that CONST_MAX() is a bit more foregiving, let's stick to the native return type of sizeof() everywhere, which is size_t, instead of casting to "unsigned", so that on the common archs we don't unnecessarily lose the upper 32bits. This semi-reverts d3e40294572512810c9329933a488619e7ce22fd. --- src/basic/macro.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index a8476184c2d..829d8dc8a70 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -214,7 +214,7 @@ static inline size_t GREEDY_ALLOC_ROUND_UP(size_t l) { * Contrary to strlen(), this is a constant expression. * @x: a string literal. */ -#define STRLEN(x) ((unsigned) sizeof(""x"") - 1) +#define STRLEN(x) (sizeof(""x"") - 1U) /* * container_of - cast a member of a structure out to the containing structure @@ -345,7 +345,7 @@ static inline int __coverity_check_and_return__(int condition) { (2U+(sizeof(type) <= 1 ? 3U : \ sizeof(type) <= 2 ? 5U : \ sizeof(type) <= 4 ? 10U : \ - sizeof(type) <= 8 ? 20U : (unsigned) sizeof(int[-2*(sizeof(type) > 8)]))) + sizeof(type) <= 8 ? 20U : sizeof(int[-2*(sizeof(type) > 8)]))) #define DECIMAL_STR_WIDTH(x) \ ({ \ -- cgit v1.2.3-59-g8ed1b From d844529dc7a6c40d17d8ce74091dce1ec77d65b6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 29 Jul 2021 18:47:04 +0200 Subject: macro: change DECIMAL_STR_WIDTH() return type to size_t, like strlen() and so on --- src/basic/macro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index 829d8dc8a70..90f4e02d190 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -350,7 +350,7 @@ static inline int __coverity_check_and_return__(int condition) { #define DECIMAL_STR_WIDTH(x) \ ({ \ typeof(x) _x_ = (x); \ - unsigned ans = 1; \ + size_t ans = 1; \ while ((_x_ /= 10) != 0) \ ans++; \ ans; \ -- cgit v1.2.3-59-g8ed1b