diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-08-03 11:03:29 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-03 11:03:29 +0900 |
commit | c7cfde640d2b32ff1eb893d1fcd291c25cd421e7 (patch) | |
tree | 4ee174dfb50a5820ea3c54d4666e3d437cf4d3f6 | |
parent | time-set: adjust system clock if rtc is far in future (diff) | |
parent | macro: change DECIMAL_STR_WIDTH() return type to size_t, like strlen() and so on (diff) | |
download | systemd-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.h | 6 | ||||
-rw-r--r-- | src/fundamental/macro-fundamental.h | 21 |
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)) |