aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-08-03 11:03:29 +0900
committerGitHub <noreply@github.com>2021-08-03 11:03:29 +0900
commitc7cfde640d2b32ff1eb893d1fcd291c25cd421e7 (patch)
tree4ee174dfb50a5820ea3c54d4666e3d437cf4d3f6
parenttime-set: adjust system clock if rtc is far in future (diff)
parentmacro: change DECIMAL_STR_WIDTH() return type to size_t, like strlen() and so on (diff)
downloadsystemd-c7cfde640d2b32ff1eb893d1fcd291c25cd421e7.tar.xz
systemd-c7cfde640d2b32ff1eb893d1fcd291c25cd421e7.zip
Merge pull request #20346 from poettering/strlen-unsigned-fix
CONST_MAX() integer size fix
-rw-r--r--src/basic/macro.h6
-rw-r--r--src/fundamental/macro-fundamental.h21
2 files changed, 22 insertions, 5 deletions
diff --git a/src/basic/macro.h b/src/basic/macro.h
index a8476184c2d..90f4e02d190 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,12 +345,12 @@ 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) \
({ \
typeof(x) _x_ = (x); \
- unsigned ans = 1; \
+ size_t ans = 1; \
while ((_x_ /= 10) != 0) \
ans++; \
ans; \
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))