From: Paul Eggert Date: Tue, 30 Jul 2024 23:19:35 +0000 (-0700) Subject: maint: use static_assert X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c6a5af16ba0ceff08b58d8a26cdbed2b300ccd0a;p=thirdparty%2Ftar.git maint: use static_assert * gnulib.modules: Add assert-h, for static_assert. * src/common.h, src/list.c, src/misc.c: Prefer static_assert to #if + #error. This doesn’t fix any bugs; it’s just that in general it’s better to avoid the preprocessor. --- diff --git a/gnulib.modules b/gnulib.modules index b31c0dfc..8c4e8e8e 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -22,6 +22,7 @@ areadlinkat-with-size argmatch argp argp-version-etc +assert-h attribute backupfile c-ctype diff --git a/src/common.h b/src/common.h index 12721760..e0528fd5 100644 --- a/src/common.h +++ b/src/common.h @@ -664,12 +664,11 @@ const char *tar_dirname (void); /* Represent N using a signed integer I such that (uintmax_t) I == N. With a good optimizing compiler, this is equivalent to (intmax_t) i and requires zero machine instructions. */ -#if ! (UINTMAX_MAX / 2 <= INTMAX_MAX) -# error "represent_uintmax returns intmax_t to represent uintmax_t" -#endif COMMON_INLINE intmax_t represent_uintmax (uintmax_t n) { + static_assert (UINTMAX_MAX / 2 <= INTMAX_MAX); + if (n <= INTMAX_MAX) return n; else diff --git a/src/list.c b/src/list.c index e6a5aa60..caacfd88 100644 --- a/src/list.c +++ b/src/list.c @@ -746,17 +746,17 @@ decode_header (union block *header, struct tar_stat_info *stat_info, (uintmax_t) V yields the correct result. If OCTAL_ONLY, allow only octal numbers instead of the other GNU extensions. Return -1 on error, diagnosing the error if TYPE is nonnull and if !SILENT. */ -#if ! (INTMAX_MAX <= UINTMAX_MAX && - (INTMAX_MIN + 1) <= UINTMAX_MAX) -# error "from_header internally represents intmax_t as uintmax_t + sign" -#endif -#if ! (UINTMAX_MAX / 2 <= INTMAX_MAX) -# error "from_header returns intmax_t to represent uintmax_t" -#endif static intmax_t from_header (char const *where0, size_t digs, char const *type, intmax_t minval, uintmax_t maxval, bool octal_only, bool silent) { + /* from_header internally represents intmax_t as uintmax_t + sign. */ + static_assert (INTMAX_MAX <= UINTMAX_MAX + && - (INTMAX_MIN + 1) <= UINTMAX_MAX); + /* from_header returns intmax_t to represent uintmax_t. */ + static_assert (UINTMAX_MAX / 2 <= INTMAX_MAX); + uintmax_t value; uintmax_t uminval = minval; uintmax_t minus_minval = - uminval; @@ -797,8 +797,7 @@ from_header (char const *where0, size_t digs, char const *type, value += *where++ - '0'; if (where == lim || ! is_octal_digit (*where)) break; - overflow |= value != (value << LG_8 >> LG_8); - value <<= LG_8; + overflow |= ckd_mul (&value, value, 8); } /* Parse the output of older, unportable tars, which generate diff --git a/src/misc.c b/src/misc.c index 2c5dec9a..1e2e8f3f 100644 --- a/src/misc.c +++ b/src/misc.c @@ -377,13 +377,12 @@ replace_prefix (char **pname, const char *samp, size_t slen, converted string. If VALUE is converted from a negative integer in the range MINVAL .. -1, represent it with a string representation of the negative integer, using leading '-'. */ -#if ! (INTMAX_MAX <= UINTMAX_MAX / 2) -# error "sysinttostr: uintmax_t cannot represent all intmax_t values" -#endif char * sysinttostr (uintmax_t value, intmax_t minval, uintmax_t maxval, char buf[SYSINT_BUFSIZE]) { + static_assert (INTMAX_MAX <= UINTMAX_MAX / 2); + if (value <= maxval) return umaxtostr (value, buf); else @@ -406,12 +405,11 @@ sysinttostr (uintmax_t value, intmax_t minval, uintmax_t maxval, On a normal return, set errno = 0. On conversion error, return 0 and set errno = EINVAL. On overflow, return an extreme value and set errno = ERANGE. */ -#if ! (INTMAX_MAX <= UINTMAX_MAX) -# error "strtosysint: nonnegative intmax_t does not fit in uintmax_t" -#endif intmax_t strtosysint (char const *arg, char **arglim, intmax_t minval, uintmax_t maxval) { + static_assert (INTMAX_MAX <= UINTMAX_MAX); + errno = 0; if (maxval <= INTMAX_MAX) {