From 478055dc30b9d1565e6b577485aea824ef22b038 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 1 Jul 2023 11:31:40 -0700 Subject: [PATCH] maint: improve static and dynamic checking MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This modernizes the source code somewhat, to take advantage of advances in GCC over the years, and Gnulib’s ‘assure’ module. Include assure.h in files that now need it. Do not include assert.h directly; it’s no longer needed. * bootstrap.conf (gnulib_modules): Add ‘assure’. * gl/lib/randread.c (randread_error): * src/chmod.c (describe_change): * src/chown-core.c (describe_change): * src/cp.c (decode_preserve_arg): * src/head.c (diagnose_copy_fd_failure): * src/ls.c (parse_ls_color): * src/od.c (decode_one_format): * src/split.c (main): * src/test.c (binary_operator, posixtest): Prefer affirm to abort, since it has better diagnostics in the normal case and better performance with -DNDEBUG. * gl/lib/xdectoint.c, src/die.h: Include stddef.h, for unreachable. * gl/lib/xdectoint.c: Do not include verify.h; no longer needed. * gl/lib/xdectoint.c (__xnumtoint): * src/die.h (die): Prefer C23 unreachable () to assume (false). * gl/lib/xfts.c (xfts_open): * src/basenc.c (base32hex_encode): * src/copy.c (abandon_move, copy_internal, valid_options): * src/cut.c (cut_fields): * src/df.c (alloc_field, decode_output_arg, get_dev): * src/du.c (process_file, main): * src/echo.c (usage): * src/factor.c (udiv_qrnnd, mod2, gcd2_odd, factor_insert_large) (mulredc2, factor_using_pollard_rho, isqrt2, div_smallq) (factor_using_squfof): * src/iopoll.c (iopoll_internal, fwrite_wait): * src/join.c (add_field): * src/ls.c (dev_ino_pop, main, gobble_file, sort_files): * src/mv.c (do_move): * src/od.c (decode_format_string, read_block, dump, main): * src/remove.c (rm): * src/rm.c (main): * src/sort.c (stream_open): * src/split.c (next_file_name, lines_chunk_split): * src/stdbuf.c (main): * src/stty.c (set_speed): * src/tac-pipe.c (line_ptr_decrement, line_ptr_increment): * src/touch.c (touch): * src/tr.c (find_bracketed_repeat, get_next) (validate_case_classes, get_spec_stats, string2_extend, main): * src/tsort.c (search_item, tsort): * src/wc.c (main): Prefer affirm to assert, as it allows for better static checking when compiling with -DNDEBUG. * src/chown-core.c (change_file_owner): * src/df.c (get_field_list): * src/expr.c (printv, null, tostring, toarith, eval2): * src/ls.c (time_type_to_statx, calc_req_mask, get_funky_string) (print_long_format): * src/numfmt.c (simple_strtod_fatal): * src/od.c (decode_one_format): * src/stty.c (mode_type_flag): * src/tail.c (xlseek): * src/tr.c (is_char_class_member, get_next, get_spec_stats) (string2_extend): Prefer unreachable () to abort () or assert (false) when merely pacifying the compiler, e.g., in a switch statement on an enum where all cases are covered. * src/copy.c (valid_options): Now returns void; the bool was useless. Caller no longer needs to assert. * src/csplit.c (find_line): * src/expand-common.c (next_file): * src/shred.c (incname): * src/sort.c (main): * src/tr.c (append_normal_char, append_range, append_char_class) (append_repeated_char, append_equiv_class): * src/tsort.c (search_item): Omit assert, since the hardware will check for us. * src/df.c (header_mode): Now the enum type it should have been. * src/du.c (process_file): * src/ls.c (assert_matching_dev_ino): * src/tail.c (valid_file_spec): * src/tr.c (validate_case_classes): Mark defns with MAYBE_UNUSED if they’re not used when -DNDEBUG. * src/factor.c (prime_p, prime2_p, mp_prime_p): Now ATTRIBUTE_PURE. Prefer affirm to error+abort. No need to translate this diagnostic. * src/fmt.c (get_paragraph): * src/stty.c (display_changed, display_all, sane_mode): * src/who.c (idle_string): Prefer assume to assert, since the goal is merely pacification and assert doesn’t pacify anyway if -DNDEBUG is used. * src/join.c (decode_field_spec): Omit unreachable abort. * src/ls.c (assert_matching_dev_ino, main): * src/tr.c (get_next): Prefer assure to assert, since the check is relatively expensive and won’t help static analysis. * src/ls.c (main): Prefer static_assert to assert of a constant expression. (format_inode): Redo to make it clear that buflen doesn’t matter, and that buf must have a certain number of bytes. All callers changed. This pacifies -Wformat-overflow. * src/od.c (decode_one_format): Omit an assert that tested for obviously undefined behavior, as the compiler could optimize it away anyway. * src/od.c (decode_one_format, decode_format_string): Prefer ATTRIBUTE_NONNULL to runtime checking. * src/stat.c: Do not include since system.h does that now. * src/sync.c (sync_arg): Prefer unreachable () to assert (true), which was a typo. * src/system.h: Include stddef.h, for unreachable. * src/tail.c (xlseek): Simplify by relying on ‘error’ to exit. --- bootstrap.conf | 1 + gl/lib/randread.c | 10 ++++---- gl/lib/xdectoint.c | 4 ++-- gl/lib/xfts.c | 4 ++-- src/basenc.c | 4 ++-- src/blake2/b2sum.c | 1 - src/chmod.c | 3 ++- src/chown-core.c | 5 ++-- src/copy.c | 22 ++++++++--------- src/cp.c | 3 ++- src/csplit.c | 2 -- src/cut.c | 4 ++-- src/df.c | 22 +++++++---------- src/die.h | 4 ++-- src/du.c | 14 +++++------ src/echo.c | 4 ++-- src/expand-common.c | 2 -- src/expr.c | 10 ++++---- src/factor.c | 57 +++++++++++++++++++++------------------------ src/fmt.c | 3 +-- src/head.c | 3 ++- src/iopoll.c | 11 ++++----- src/join.c | 13 +++-------- src/ls.c | 46 +++++++++++++++++------------------- src/mv.c | 4 ++-- src/numfmt.c | 2 +- src/od.c | 33 +++++++++++--------------- src/remove.c | 4 ++-- src/rm.c | 4 ++-- src/shred.c | 7 +++--- src/sort.c | 9 ++----- src/split.c | 8 +++---- src/stat.c | 1 - src/stdbuf.c | 4 ++-- src/stty.c | 14 +++++------ src/sync.c | 3 +-- src/system.h | 1 + src/tac-pipe.c | 8 +++---- src/tail.c | 40 +++++++++++-------------------- src/test.c | 6 ++--- src/touch.c | 4 ++-- src/tr.c | 40 ++++++++++++++----------------- src/tsort.c | 17 +++++++------- src/wc.c | 4 ++-- src/who.c | 5 ++-- 45 files changed, 208 insertions(+), 262 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index 81991424dc..dbf253b645 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -36,6 +36,7 @@ gnulib_modules=" argv-iter assert assert-h + assure attribute autobuild backupfile diff --git a/gl/lib/randread.c b/gl/lib/randread.c index e210c7a8d6..9c572951d2 100644 --- a/gl/lib/randread.c +++ b/gl/lib/randread.c @@ -38,6 +38,7 @@ #include "gettext.h" #define _(msgid) gettext (msgid) +#include "assure.h" #include "minmax.h" #include "rand-isaac.h" #include "stdio-safer.h" @@ -103,11 +104,10 @@ struct randread_source static void randread_error (void const *file_name) { - if (file_name) - error (exit_failure, errno, - errno == 0 ? _("%s: end of file") : _("%s: read error"), - quote (file_name)); - abort (); + affirm (exit_failure); + error (exit_failure, errno, + errno == 0 ? _("%s: end of file") : _("%s: read error"), + quote (file_name)); } /* Simply return a new randread_source object with the default error diff --git a/gl/lib/xdectoint.c b/gl/lib/xdectoint.c index da3e655c67..061a08c225 100644 --- a/gl/lib/xdectoint.c +++ b/gl/lib/xdectoint.c @@ -21,11 +21,11 @@ #include #include +#include #include #include "error.h" #include "quote.h" -#include "verify.h" #include "xstrtol.h" /* Parse numeric string N_STR of base BASE, and return the value. @@ -69,7 +69,7 @@ __xnumtoint (char const *n_str, int base, __xdectoint_t min, __xdectoint_t max, /* EINVAL error message is redundant in this context. */ error (err_exit ? err_exit : EXIT_FAILURE, errno == EINVAL ? 0 : errno, "%s: %s", err, quote (n_str)); - assume (false); + unreachable (); } return tnum; diff --git a/gl/lib/xfts.c b/gl/lib/xfts.c index 3981da12c7..3cb77610ab 100644 --- a/gl/lib/xfts.c +++ b/gl/lib/xfts.c @@ -21,8 +21,8 @@ #include #include -#include +#include "assure.h" #include "xalloc.h" #include "xfts.h" @@ -37,7 +37,7 @@ xfts_open (char * const *argv, int options, { /* This can fail in two ways: out of memory or with errno==EINVAL, which indicates it was called with invalid bit_flags. */ - assert (errno != EINVAL); + affirm (errno != EINVAL); xalloc_die (); } diff --git a/src/basenc.c b/src/basenc.c index 965f73b0a5..dd1e426643 100644 --- a/src/basenc.c +++ b/src/basenc.c @@ -50,7 +50,7 @@ #elif BASE_TYPE == 42 # include "base32.h" # include "base64.h" -# include +# include "assure.h" # define PROGRAM_NAME "basenc" #else # error missing/invalid BASE_TYPE definition @@ -449,7 +449,7 @@ base32hex_encode (char const *restrict in, idx_t inlen, for (char *p = out; outlen--; p++) { - assert (0x32 <= *p && *p <= 0x5a); /* LCOV_EXCL_LINE */ + affirm (0x32 <= *p && *p <= 0x5a); /* LCOV_EXCL_LINE */ *p = base32_norm_to_hex[*p - 0x32]; } } diff --git a/src/blake2/b2sum.c b/src/blake2/b2sum.c index bcb293f3e4..1a7e99f0e2 100644 --- a/src/blake2/b2sum.c +++ b/src/blake2/b2sum.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include diff --git a/src/chmod.c b/src/chmod.c index 3cbfe07d85..25111c399e 100644 --- a/src/chmod.c +++ b/src/chmod.c @@ -22,6 +22,7 @@ #include #include "system.h" +#include "assure.h" #include "dev-ino.h" #include "die.h" #include "error.h" @@ -191,7 +192,7 @@ describe_change (char const *file, struct change_status const *ch) printf (fmt, quoted_file, m, &perms[1]); return; default: - abort (); + affirm (false); } printf (fmt, quoted_file, old_m, &old_perms[1], m, &perms[1]); } diff --git a/src/chown-core.c b/src/chown-core.c index 48ac4c8ebe..3aa0390b7a 100644 --- a/src/chown-core.c +++ b/src/chown-core.c @@ -23,6 +23,7 @@ #include #include "system.h" +#include "assure.h" #include "chown-core.h" #include "error.h" #include "ignore-value.h" @@ -198,7 +199,7 @@ describe_change (char const *file, enum Change_status changed, : _("ownership of %s retained\n")); break; default: - abort (); + affirm (false); } printf (fmt, quoteaf (file), old_spec, spec); @@ -467,7 +468,7 @@ change_file_owner (FTS *fts, FTSENT *ent, break; default: - abort (); + unreachable (); } } diff --git a/src/copy.c b/src/copy.c index 23bc26ab17..8d66099a5a 100644 --- a/src/copy.c +++ b/src/copy.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include "system.h" #include "acl.h" #include "alignalloc.h" +#include "assure.h" #include "backupfile.h" #include "buffer-lcm.h" #include "canonicalize.h" @@ -2063,7 +2063,7 @@ abandon_move (const struct cp_options *x, int dst_dirfd, char const *dst_relname, struct stat const *dst_sb) { - assert (x->move_mode); + affirm (x->move_mode); return (x->interactive == I_ALWAYS_NO || x->interactive == I_ALWAYS_SKIP || ((x->interactive == I_ASK_USER @@ -2267,7 +2267,7 @@ copy_internal (char const *src_name, char const *dst_name, else { #if defined lint && (defined __clang__ || defined __COVERITY__) - assert (x->move_mode); + affirm (x->move_mode); memset (&src_sb, 0, sizeof src_sb); #endif } @@ -3358,18 +3358,16 @@ un_backup: return false; } -ATTRIBUTE_PURE -static bool +static void valid_options (const struct cp_options *co) { - assert (VALID_BACKUP_TYPE (co->backup_type)); - assert (VALID_SPARSE_MODE (co->sparse_mode)); - assert (VALID_REFLINK_MODE (co->reflink_mode)); - assert (!(co->hard_link && co->symbolic_link)); - assert (! + affirm (VALID_BACKUP_TYPE (co->backup_type)); + affirm (VALID_SPARSE_MODE (co->sparse_mode)); + affirm (VALID_REFLINK_MODE (co->reflink_mode)); + affirm (!(co->hard_link && co->symbolic_link)); + affirm (! (co->reflink_mode == REFLINK_ALWAYS && co->sparse_mode != SPARSE_AUTO)); - return true; } /* Copy the file SRC_NAME to the file DST_NAME aka DST_DIRFD+DST_RELNAME. @@ -3389,7 +3387,7 @@ copy (char const *src_name, char const *dst_name, int nonexistent_dst, const struct cp_options *options, bool *copy_into_self, bool *rename_succeeded) { - assert (valid_options (options)); + valid_options (options); /* Record the file names: they're used in case of error, when copying a directory into itself. I don't like to make these tools do *any* diff --git a/src/cp.c b/src/cp.c index cc55534cf5..c0e6c32d3f 100644 --- a/src/cp.c +++ b/src/cp.c @@ -24,6 +24,7 @@ #include "system.h" #include "argmatch.h" +#include "assure.h" #include "backupfile.h" #include "copy.h" #include "cp-hash.h" @@ -956,7 +957,7 @@ decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off) break; default: - abort (); + affirm (false); } s = comma; } diff --git a/src/csplit.c b/src/csplit.c index 8104bab95d..295bc8f62f 100644 --- a/src/csplit.c +++ b/src/csplit.c @@ -19,7 +19,6 @@ #include -#include #include #include #include @@ -576,7 +575,6 @@ find_line (intmax_t linenum) for (b = head;;) { - assert (b); if (linenum < b->start_line + b->num_lines) { /* The line is in this buffer. */ diff --git a/src/cut.c b/src/cut.c index d032b80b18..27740ccc51 100644 --- a/src/cut.c +++ b/src/cut.c @@ -25,11 +25,11 @@ #include #include -#include #include #include #include "system.h" +#include "assure.h" #include "error.h" #include "fadvise.h" #include "getndelim2.h" @@ -311,7 +311,7 @@ cut_fields (FILE *stream) } n_bytes = len; - assert (n_bytes != 0); + affirm (n_bytes != 0); c = 0; diff --git a/src/df.c b/src/df.c index c1b6bc48b7..417791dd5d 100644 --- a/src/df.c +++ b/src/df.c @@ -22,12 +22,12 @@ #include #include #include -#include #include #include #include #include "system.h" +#include "assure.h" #include "canonicalize.h" #include "die.h" #include "error.h" @@ -129,15 +129,14 @@ static bool print_grand_total; static struct fs_usage grand_fsu; /* Display modes. */ -enum +static enum { DEFAULT_MODE, INODES_MODE, HUMAN_MODE, POSIX_MODE, OUTPUT_MODE -}; -static int header_mode = DEFAULT_MODE; +} header_mode = DEFAULT_MODE; /* Displayable fields. */ typedef enum @@ -421,8 +420,7 @@ alloc_field (int f, char const *c) if (c != nullptr) columns[ncolumns - 1]->caption = c; - if (field_data[f].used) - assert (!"field used"); + affirm (!field_data[f].used); /* Mark field as used. */ field_data[f].used = true; @@ -493,7 +491,7 @@ decode_output_arg (char const *arg) break; default: - assert (!"invalid field"); + affirm (!"invalid field"); } s = comma; } @@ -562,7 +560,7 @@ get_field_list (void) break; default: - assert (!"invalid header_mode"); + unreachable (); } } @@ -1148,8 +1146,7 @@ get_dev (char const *device, char const *mount_point, char const *file, v = nullptr; break; default: - v = nullptr; /* Avoid warnings where assert() is not __noreturn__. */ - assert (!"bad field_type"); + affirm (!"bad field_type"); } switch (columns[col]->field) @@ -1251,11 +1248,10 @@ get_dev (char const *device, char const *mount_point, char const *file, break; default: - assert (!"unhandled field"); + affirm (!"unhandled field"); } - if (!cell) - assert (!"empty cell"); + affirm (cell); replace_problematic_chars (cell); size_t cell_width = mbswidth (cell, 0); diff --git a/src/die.h b/src/die.h index a9afa2ff92..5d917c7024 100644 --- a/src/die.h +++ b/src/die.h @@ -20,11 +20,11 @@ # define DIE_H # include -# include +# include /* Like 'error (STATUS, ...)', except STATUS must be a nonzero constant. This may pacify the compiler or help it generate better code. */ # define die(status, ...) \ - verify_expr (status, (error (status, __VA_ARGS__), assume (false))) + verify_expr (status, (error (status, __VA_ARGS__), unreachable ())) #endif /* DIE_H */ diff --git a/src/du.c b/src/du.c index fa0bdc45a8..c858d9366b 100644 --- a/src/du.c +++ b/src/du.c @@ -26,10 +26,10 @@ #include #include #include -#include #include "system.h" #include "argmatch.h" #include "argv-iter.h" +#include "assure.h" #include "di-set.h" #include "die.h" #include "error.h" @@ -523,8 +523,8 @@ process_file (FTS *fts, FTSENT *ent) if (info == FTS_NSOK) { fts_set (fts, ent, FTS_AGAIN); - FTSENT const *e = fts_read (fts); - assert (e == ent); + MAYBE_UNUSED FTSENT const *e = fts_read (fts); + affirm (e == ent); info = ent->fts_info; } @@ -556,8 +556,8 @@ process_file (FTS *fts, FTSENT *ent) if (info == FTS_D) { fts_set (fts, ent, FTS_SKIP); - FTSENT const *e = fts_read (fts); - assert (e == ent); + MAYBE_UNUSED FTSENT const *e = fts_read (fts); + affirm (e == ent); } return true; @@ -635,7 +635,7 @@ process_file (FTS *fts, FTSENT *ent) propagate sums from the children (prev_level) to the parent. Here, the current level is always one smaller than the previous one. */ - assert (level == prev_level - 1); + affirm (level == prev_level - 1); duinfo_add (&dui_to_print, &dulvl[prev_level].ent); if (!opt_separate_dirs) duinfo_add (&dui_to_print, &dulvl[prev_level].subdir); @@ -1079,7 +1079,7 @@ main (int argc, char **argv) case AI_ERR_MEM: xalloc_die (); default: - assert (!"unexpected error code from argv_iter"); + affirm (!"unexpected error code from argv_iter"); } } if (files_from && STREQ (files_from, "-") && STREQ (file_name, "-")) diff --git a/src/echo.c b/src/echo.c index 74475218ad..278778ec67 100644 --- a/src/echo.c +++ b/src/echo.c @@ -16,9 +16,9 @@ #include #include -#include #include #include "system.h" +#include "assure.h" /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "echo" @@ -37,7 +37,7 @@ usage (int status) { /* STATUS should always be EXIT_SUCCESS (unlike in most other utilities which would call emit_try_help otherwise). */ - assert (status == EXIT_SUCCESS); + affirm (status == EXIT_SUCCESS); printf (_("\ Usage: %s [SHORT-OPTION]... [STRING]...\n\ diff --git a/src/expand-common.c b/src/expand-common.c index c8e17488c2..f5c64ba02d 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -16,7 +16,6 @@ #include -#include #include #include #include "system.h" @@ -337,7 +336,6 @@ next_file (FILE *fp) if (fp) { - assert (prev_file); int err = errno; if (!ferror (fp)) err = 0; diff --git a/src/expr.c b/src/expr.c index aaa82d3d25..6ae0fae79c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -409,7 +409,7 @@ printv (VALUE *v) puts (v->u.s); break; default: - abort (); + unreachable (); } } @@ -441,7 +441,7 @@ null (VALUE *v) return true; } default: - abort (); + unreachable (); } } @@ -479,7 +479,7 @@ tostring (VALUE *v) case string: break; default: - abort (); + unreachable (); } } @@ -505,7 +505,7 @@ toarith (VALUE *v) return true; } default: - abort (); + unreachable (); } } @@ -940,7 +940,7 @@ eval2 (bool evaluate) case not_equal: val = (cmp != 0); break; case greater_equal: val = (cmp >= 0); break; case greater_than: val = (cmp > 0); break; - default: abort (); + default: unreachable (); } } diff --git a/src/factor.c b/src/factor.c index f3d442b5db..6f61a1e12d 100644 --- a/src/factor.c +++ b/src/factor.c @@ -105,9 +105,9 @@ #include #include #include -#include #include "system.h" +#include "assure.h" #include "die.h" #include "error.h" #include "full-write.h" @@ -289,9 +289,9 @@ static void factor (uintmax_t, uintmax_t, struct factors *); do { \ uintmax_t __d1, __d0, __q, __r1, __r0; \ \ - assert ((n1) < (d)); \ __d1 = (d); __d0 = 0; \ __r1 = (n1); __r0 = (n0); \ + affirm (__r1 < __d1); \ __q = 0; \ for (unsigned int __i = W_TYPE_SIZE; __i > 0; __i--) \ { \ @@ -412,7 +412,7 @@ mod2 (uintmax_t *r1, uintmax_t a1, uintmax_t a0, uintmax_t d1, uintmax_t d0) { int cntd, cnta; - assert (d1 != 0); + affirm (d1 != 0); if (a1 == 0) { @@ -477,7 +477,7 @@ gcd_odd (uintmax_t a, uintmax_t b) static uintmax_t gcd2_odd (uintmax_t *r1, uintmax_t a1, uintmax_t a0, uintmax_t b1, uintmax_t b0) { - assert (b0 & 1); + affirm (b0 & 1); if ((a0 | a1) == 0) { @@ -559,7 +559,7 @@ factor_insert_large (struct factors *factors, { if (p1 > 0) { - assert (factors->plarge[1] == 0); + affirm (factors->plarge[1] == 0); factors->plarge[0] = p0; factors->plarge[1] = p1; } @@ -994,9 +994,9 @@ mulredc2 (uintmax_t *r1p, uintmax_t r1, r0, q, p1, t1, t0, s1, s0; MAYBE_UNUSED uintmax_t p0; mi = -mi; - assert ((a1 >> (W_TYPE_SIZE - 1)) == 0); - assert ((b1 >> (W_TYPE_SIZE - 1)) == 0); - assert ((m1 >> (W_TYPE_SIZE - 1)) == 0); + affirm ((a1 >> (W_TYPE_SIZE - 1)) == 0); + affirm ((b1 >> (W_TYPE_SIZE - 1)) == 0); + affirm ((m1 >> (W_TYPE_SIZE - 1)) == 0); /* First compute a0 * B^{-1} +-----+ @@ -1193,7 +1193,7 @@ mp_millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y, /* Lucas' prime test. The number of iterations vary greatly, up to a few dozen have been observed. The average seem to be about 2. */ -static bool +static bool ATTRIBUTE_PURE prime_p (uintmax_t n) { int k; @@ -1271,11 +1271,10 @@ prime_p (uintmax_t n) return false; } - error (0, 0, _("Lucas prime test failure. This should not happen")); - abort (); + affirm (!"Lucas prime test failure. This should not happen"); } -static bool +static bool ATTRIBUTE_PURE prime2_p (uintmax_t n1, uintmax_t n0) { uintmax_t q[2], nm1[2]; @@ -1371,8 +1370,7 @@ prime2_p (uintmax_t n1, uintmax_t n0) return false; } - error (0, 0, _("Lucas prime test failure. This should not happen")); - abort (); + affirm (!"Lucas prime test failure. This should not happen"); } static bool @@ -1446,8 +1444,7 @@ mp_prime_p (mpz_t n) } } - error (0, 0, _("Lucas prime test failure. This should not happen")); - abort (); + affirm (!"Lucas prime test failure. This should not happen"); ret1: if (flag_prove_primality) @@ -1473,7 +1470,7 @@ factor_using_pollard_rho (uintmax_t n, unsigned long int a, while (n != 1) { - assert (a < n); + affirm (a < n); binv (ni, n); /* FIXME: when could we use old 'ni' value? */ @@ -1795,7 +1792,7 @@ isqrt2 (uintmax_t nh, uintmax_t nl) uintmax_t x; /* Ensures the remainder fits in an uintmax_t. */ - assert (nh < ((uintmax_t) 1 << (W_TYPE_SIZE - 2))); + affirm (nh < ((uintmax_t) 1 << (W_TYPE_SIZE - 2))); if (nh == 0) return isqrt (nl); @@ -1819,12 +1816,12 @@ isqrt2 (uintmax_t nh, uintmax_t nl) { uintmax_t hi, lo; umul_ppmm (hi, lo, x + 1, x + 1); - assert (gt2 (hi, lo, nh, nl)); + affirm (gt2 (hi, lo, nh, nl)); umul_ppmm (hi, lo, x, x); - assert (ge2 (nh, nl, hi, lo)); + affirm (ge2 (nh, nl, hi, lo)); sub_ddmmss (hi, lo, nh, nl, hi, lo); - assert (hi == 0); + affirm (hi == 0); return x; } @@ -1906,7 +1903,7 @@ static const unsigned short invtab[0x81] = _mask = -(uintmax_t) (_r >= (d)); \ (r) = _r - (_mask & (d)); \ (q) = _q - _mask; \ - assert ((q) * (d) + (r) == u); \ + affirm ((q) * (d) + (r) == u); \ } \ else \ { \ @@ -1997,7 +1994,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors) uintmax_t p1, p0; umul_ppmm (p1, p0, sqrt_n, sqrt_n); - assert (p0 == n0); + affirm (p0 == n0); if (n1 == p1) { @@ -2030,7 +2027,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors) unsigned int mu = *m; unsigned int qpos = 0; - assert (mu * n0 % 4 == 3); + affirm (mu * n0 % 4 == 3); /* In the notation of the paper, with mu * n == 3 (mod 4), we get \Delta = 4 mu * n, and the paper's \mu is 2 mu. As far as @@ -2055,8 +2052,8 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors) umul_ppmm (Dh, Dl, n0, mu); Dh += n1 * mu; - assert (Dl % 4 != 1); - assert (Dh < (uintmax_t) 1 << (W_TYPE_SIZE - 2)); + affirm (Dl % 4 != 1); + affirm (Dh < (uintmax_t) 1 << (W_TYPE_SIZE - 2)); S = isqrt2 (Dh, Dl); @@ -2080,7 +2077,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors) div_smallq (q, rem, S + P, Q); P1 = S - rem; /* P1 = q*Q - P */ - assert (q > 0 && Q > 0); + affirm (q > 0 && Q > 0); # if STAT_SQUFOF q_freq[0]++; @@ -2146,7 +2143,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors) /* We have found a square form, which should give a factor. */ Q1 = r; - assert (S >= P); /* What signs are possible? */ + affirm (S >= P); /* What signs are possible? */ P += r * ((S - P) / r); /* Note: Paper says (N - P*P) / Q1, that seems incorrect @@ -2157,7 +2154,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors) umul_ppmm (hi, lo, P, P); sub_ddmmss (hi, lo, Dh, Dl, hi, lo); udiv_qrnnd (Q, rem, hi, lo, Q1); - assert (rem == 0); + affirm (rem == 0); for (;;) { @@ -2185,7 +2182,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors) Q /= 2; Q /= gcd_odd (Q, mu); - assert (Q > 1 && (n1 || Q < n0)); + affirm (Q > 1 && (n1 || Q < n0)); if (prime_p (Q)) factor_insert (factors, Q); diff --git a/src/fmt.c b/src/fmt.c index a68164e8da..8973ada76e 100644 --- a/src/fmt.c +++ b/src/fmt.c @@ -20,7 +20,6 @@ #include #include #include -#include /* Redefine. Otherwise, systems (Unicos for one) with headers that define it to be a type get syntax errors for the variable declaration below. */ @@ -621,7 +620,7 @@ get_paragraph (FILE *f) /* Tell static analysis tools that using word_limit[-1] is ok. word_limit is guaranteed to have been incremented by get_line. */ - assert (word < word_limit); + assume (word < word_limit); (word_limit - 1)->period = (word_limit - 1)->final = true; next_char = c; diff --git a/src/head.c b/src/head.c index 04bc9a1a15..ba66a5887c 100644 --- a/src/head.c +++ b/src/head.c @@ -31,6 +31,7 @@ #include "system.h" +#include "assure.h" #include "die.h" #include "error.h" #include "full-read.h" @@ -160,7 +161,7 @@ diagnose_copy_fd_failure (enum Copy_fd_status err, char const *filename) error (0, errno, _("%s: file has shrunk too much"), quotef (filename)); break; default: - abort (); + affirm (false); } } diff --git a/src/iopoll.c b/src/iopoll.c index da4c6c00fa..08b99f9f37 100644 --- a/src/iopoll.c +++ b/src/iopoll.c @@ -18,8 +18,6 @@ #include -#include - /* poll(2) is needed on AIX (where 'select' gives a readable event immediately) and Solaris (where 'select' never gave a readable event). Also use poll(2) on systems we know work @@ -43,6 +41,7 @@ #endif #include "system.h" +#include "assure.h" #include "iopoll.h" #include "isapipe.h" @@ -61,7 +60,7 @@ static int iopoll_internal (int fdin, int fdout, bool block, bool broken_output) { - assert (fdin != -1 || fdout != -1); + affirm (fdin != -1 || fdout != -1); #if IOPOLL_USES_POLL struct pollfd pfds[2] = { /* POLLRDBAND needed for illumos, macOS. */ @@ -85,7 +84,7 @@ iopoll_internal (int fdin, int fdout, bool block, bool broken_output) continue; if (ret == 0 && ! block) return 0; - assert (0 < ret); + affirm (0 < ret); if (pfds[0].revents) /* input available or pipe closed indicating EOF; */ return 0; /* should now be able to read() without blocking */ if (pfds[1].revents & check_out_events) @@ -124,7 +123,7 @@ iopoll_internal (int fdin, int fdout, bool block, bool broken_output) continue; if (ret == 0 && ! block) return 0; - assert (0 < ret); + affirm (0 < ret); if (0 <= fdin && FD_ISSET (fdin, &fds)) /* input available or EOF; */ return 0; /* should now be able to read() without blocking */ if (0 <= fdout && FD_ISSET (fdout, &fds)) /* equiv to POLLERR */ @@ -228,7 +227,7 @@ fwrite_wait (char const *buf, ssize_t size, FILE *f) { const size_t written = fwrite (buf, 1, size, f); size -= written; - assert (size >= 0); + affirm (size >= 0); if (size <= 0) /* everything written */ return true; diff --git a/src/join.c b/src/join.c index 3849f2e4fc..1a23614100 100644 --- a/src/join.c +++ b/src/join.c @@ -18,11 +18,11 @@ #include -#include #include #include #include "system.h" +#include "assure.h" #include "die.h" #include "error.h" #include "fadvise.h" @@ -820,8 +820,8 @@ add_field (int file, size_t field) { struct outlist *o; - assert (file == 0 || file == 1 || file == 2); - assert (file != 0 || field == 0); + affirm (file == 0 || file == 1 || file == 2); + affirm (file != 0 || field == 0); o = xmalloc (sizeof *o); o->file = file; @@ -887,13 +887,6 @@ decode_field_spec (char const *s, int *file_index, size_t *field_index) default: die (EXIT_FAILURE, 0, _("invalid file number in field spec: %s"), quote (s)); - - /* Tell gcc -W -Wall that we can't get beyond this point. - This avoids a warning (otherwise legit) that the caller's copies - of *file_index and *field_index might be used uninitialized. */ - abort (); - - break; } } diff --git a/src/ls.c b/src/ls.c index 35965819e2..de07940a8d 100644 --- a/src/ls.c +++ b/src/ls.c @@ -50,7 +50,6 @@ #endif #include -#include #include #include #include @@ -86,6 +85,7 @@ #include "acl.h" #include "argmatch.h" +#include "assure.h" #include "c-strcase.h" #include "dev-ino.h" #include "die.h" @@ -1052,7 +1052,7 @@ dev_ino_pop (void) void *vdi; struct dev_ino *di; int dev_ino_size = sizeof *di; - assert (dev_ino_size <= obstack_object_size (&dev_ino_obstack)); + affirm (dev_ino_size <= obstack_object_size (&dev_ino_obstack)); obstack_blank_fast (&dev_ino_obstack, -dev_ino_size); vdi = obstack_next_free (&dev_ino_obstack); di = vdi; @@ -1062,11 +1062,10 @@ dev_ino_pop (void) static void assert_matching_dev_ino (char const *name, struct dev_ino di) { - struct stat sb; - assert (name); - assert (0 <= stat (name, &sb)); - assert (sb.st_dev == di.st_dev); - assert (sb.st_ino == di.st_ino); + MAYBE_UNUSED struct stat sb; + assure (0 <= stat (name, &sb)); + assure (sb.st_dev == di.st_dev); + assure (sb.st_ino == di.st_ino); } static char eolbyte = '\n'; @@ -1127,7 +1126,7 @@ time_type_to_statx (void) case time_btime: return STATX_BTIME; default: - abort (); + unreachable (); } return 0; } @@ -1167,7 +1166,7 @@ calc_req_mask (void) mask |= STATX_SIZE; break; default: - abort (); + unreachable (); } return mask; @@ -1659,8 +1658,8 @@ main (int argc, char **argv) initialize_exit_failure (LS_FAILURE); atexit (close_stdout); - assert (ARRAY_CARDINALITY (color_indicator) + 1 - == ARRAY_CARDINALITY (indicator_name)); + static_assert (ARRAY_CARDINALITY (color_indicator) + 1 + == ARRAY_CARDINALITY (indicator_name)); exit_status = EXIT_SUCCESS; print_dir_name = true; @@ -1804,7 +1803,7 @@ main (int argc, char **argv) struct dev_ino *found = hash_remove (active_dir_set, &di); if (false) assert_matching_dev_ino (thispend->realname, di); - assert (found); + affirm (found); dev_ino_free (found); free_pending_ent (thispend); continue; @@ -1856,7 +1855,7 @@ main (int argc, char **argv) if (LOOP_DETECT) { - assert (hash_get_n_entries (active_dir_set) == 0); + assure (hash_get_n_entries (active_dir_set) == 0); hash_free (active_dir_set); } @@ -2679,7 +2678,7 @@ get_funky_string (char **dest, char const **src, bool equals_end, break; default: - abort (); + unreachable (); } } @@ -2840,7 +2839,7 @@ parse_ls_color (void) goto done; default: - abort (); + affirm (false); } } done: @@ -3378,7 +3377,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, /* An inode value prior to gobble_file necessarily came from readdir, which is not used for command line arguments. */ - assert (! command_line_arg || inode == NOT_AN_INODE_NUMBER); + affirm (! command_line_arg || inode == NOT_AN_INODE_NUMBER); if (cwd_n_used == cwd_n_alloc) { @@ -4114,7 +4113,7 @@ sort_files (void) else { use_strcmp = true; - assert (sort_type != sort_version); + affirm (sort_type != sort_version); initialize_ordering_vector (); } @@ -4291,12 +4290,12 @@ format_group_width (gid_t g) } /* Return a pointer to a formatted version of F->stat.st_ino, - possibly using buffer, BUF, of length BUFLEN, which must be at least + possibly using buffer, which must be at least INT_BUFSIZE_BOUND (uintmax_t) bytes. */ static char * -format_inode (char *buf, size_t buflen, const struct fileinfo *f) +format_inode (char buf[INT_BUFSIZE_BOUND (uintmax_t)], + const struct fileinfo *f) { - assert (INT_BUFSIZE_BOUND (uintmax_t) <= buflen); return (f->stat_ok && f->stat.st_ino != NOT_AN_INODE_NUMBER ? umaxtostr (f->stat.st_ino, buf) : (char *) "?"); @@ -4356,7 +4355,7 @@ print_long_format (const struct fileinfo *f) btime_ok = false; break; default: - abort (); + unreachable (); } p = buf; @@ -4364,8 +4363,7 @@ print_long_format (const struct fileinfo *f) if (print_inode) { char hbuf[INT_BUFSIZE_BOUND (uintmax_t)]; - p += sprintf (p, "%*s ", inode_number_width, - format_inode (hbuf, sizeof hbuf, f)); + p += sprintf (p, "%*s ", inode_number_width, format_inode (hbuf, f)); } if (print_block_size) @@ -4880,7 +4878,7 @@ print_file_name_and_frills (const struct fileinfo *f, size_t start_col) if (print_inode) printf ("%*s ", format == with_commas ? 0 : inode_number_width, - format_inode (buf, sizeof buf, f)); + format_inode (buf, f)); if (print_block_size) printf ("%*s ", format == with_commas ? 0 : block_size_width, diff --git a/src/mv.c b/src/mv.c index 29bf64f0bf..79354fc271 100644 --- a/src/mv.c +++ b/src/mv.c @@ -20,11 +20,11 @@ #include #include #include -#include #include #include "system.h" #include "argmatch.h" +#include "assure.h" #include "backupfile.h" #include "copy.h" #include "cp-hash.h" @@ -238,7 +238,7 @@ do_move (char const *source, char const *dest, dir[1] = nullptr; status = rm ((void *) dir, &rm_options); - assert (VALID_STATUS (status)); + affirm (VALID_STATUS (status)); if (status == RM_ERROR) ok = false; } diff --git a/src/numfmt.c b/src/numfmt.c index 34177354b5..cc386c531d 100644 --- a/src/numfmt.c +++ b/src/numfmt.c @@ -702,7 +702,7 @@ simple_strtod_fatal (enum simple_strtod_error err, char const *input_str) case SSE_OK_PRECISION_LOSS: case SSE_OK: /* should never happen - this function isn't called when OK. */ - abort (); + unreachable (); case SSE_OVERFLOW: msgid = N_("value too large to be converted: %s"); diff --git a/src/od.c b/src/od.c index 09782893b9..8f84659240 100644 --- a/src/od.c +++ b/src/od.c @@ -19,11 +19,11 @@ #include #include -#include #include #include #include "system.h" #include "argmatch.h" +#include "assure.h" #include "die.h" #include "error.h" #include "ftoastr.h" @@ -633,7 +633,7 @@ simple_strtoul (char const *s, char const **p, unsigned long int *val) string argument. */ -static bool +static bool ATTRIBUTE_NONNULL () decode_one_format (char const *s_orig, char const *s, char const **next, struct tspec *tspec) { @@ -646,8 +646,6 @@ decode_one_format (char const *s_orig, char const *s, char const **next, char c; int field_width; - assert (tspec != nullptr); - switch (*s) { case 'd': @@ -742,11 +740,9 @@ decode_one_format (char const *s_orig, char const *s, char const **next, break; default: - abort (); + unreachable (); } - assert (strlen (tspec->fmt_string) < FMT_BYTES_ALLOCATED); - switch (size_spec) { case CHAR: @@ -774,7 +770,7 @@ decode_one_format (char const *s_orig, char const *s, char const **next, break; default: - abort (); + affirm (false); } break; @@ -850,7 +846,7 @@ decode_one_format (char const *s_orig, char const *s, char const **next, break; default: - abort (); + affirm (false); } break; @@ -887,9 +883,7 @@ decode_one_format (char const *s_orig, char const *s, char const **next, if (tspec->hexl_mode_trailer) s++; - if (next != nullptr) - *next = s; - + *next = s; return true; } @@ -979,11 +973,10 @@ check_and_close (int in_errno) representation to the global array SPEC, reallocating SPEC if necessary. Return true if S is valid. */ -static bool +static bool ATTRIBUTE_NONNULL () decode_format_string (char const *s) { char const *s_orig = s; - assert (s != nullptr); while (*s != '\0') { @@ -995,7 +988,7 @@ decode_format_string (char const *s) if (! decode_one_format (s_orig, s, &next, &spec[n_specs])) return false; - assert (s != next); + affirm (s != next); s = next; ++n_specs; } @@ -1291,7 +1284,7 @@ read_block (size_t n, char *block, size_t *n_bytes_in_buffer) { bool ok = true; - assert (0 < n && n <= bytes_per_block); + affirm (0 < n && n <= bytes_per_block); *n_bytes_in_buffer = 0; @@ -1402,7 +1395,7 @@ dump (void) ok &= read_block (n_needed, block[idx], &n_bytes_read); if (n_bytes_read < bytes_per_block) break; - assert (n_bytes_read == bytes_per_block); + affirm (n_bytes_read == bytes_per_block); write_block (current_offset, n_bytes_read, block[!idx], block[idx]); current_offset += n_bytes_read; @@ -1416,7 +1409,7 @@ dump (void) ok &= read_block (bytes_per_block, block[idx], &n_bytes_read); if (n_bytes_read < bytes_per_block) break; - assert (n_bytes_read == bytes_per_block); + affirm (n_bytes_read == bytes_per_block); write_block (current_offset, n_bytes_read, block[!idx], block[idx]); current_offset += n_bytes_read; @@ -1971,8 +1964,8 @@ main (int argc, char **argv) for (i = 0; i < n_specs; i++) { int fields_per_block = bytes_per_block / width_bytes[spec[i].size]; - assert (bytes_per_block % width_bytes[spec[i].size] == 0); - assert (1 <= spec[i].pad_width / fields_per_block); + affirm (bytes_per_block % width_bytes[spec[i].size] == 0); + affirm (1 <= spec[i].pad_width / fields_per_block); printf ("%d: fmt=\"%s\" in_width=%d out_width=%d pad=%d\n", i, spec[i].fmt_string, width_bytes[spec[i].size], spec[i].field_width, spec[i].pad_width); diff --git a/src/remove.c b/src/remove.c index a2408de501..1cc4230d19 100644 --- a/src/remove.c +++ b/src/remove.c @@ -19,9 +19,9 @@ #include #include #include -#include #include "system.h" +#include "assure.h" #include "error.h" #include "file-type.h" #include "filenamecat.h" @@ -634,7 +634,7 @@ rm (char *const *file, struct rm_options const *x) enum RM_status s = rm_fts (fts, ent, x); - assert (VALID_STATUS (s)); + affirm (VALID_STATUS (s)); UPDATE_STATUS (rm_status, s); } diff --git a/src/rm.c b/src/rm.c index f8f12cacf0..2ad1fa8fb2 100644 --- a/src/rm.c +++ b/src/rm.c @@ -22,10 +22,10 @@ #include #include #include -#include #include "system.h" #include "argmatch.h" +#include "assure.h" #include "die.h" #include "error.h" #include "remove.h" @@ -368,6 +368,6 @@ main (int argc, char **argv) } enum RM_status status = rm (file, &x); - assert (VALID_STATUS (status)); + affirm (VALID_STATUS (status)); return status == RM_ERROR ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/src/shred.c b/src/shred.c index 3cec772868..a3f4a4ea03 100644 --- a/src/shred.c +++ b/src/shred.c @@ -77,7 +77,6 @@ #include #include -#include #include #include #if defined __linux__ && HAVE_SYS_MTIO_H @@ -87,6 +86,7 @@ #include "system.h" #include "alignalloc.h" #include "argmatch.h" +#include "assure.h" #include "xdectoint.h" #include "die.h" #include "error.h" @@ -768,7 +768,7 @@ genpattern (int *dest, size_t num, struct randint_source *s) } } top = num - randpasses; /* Top of initialized data */ - /* assert (d == dest + top); */ + /* affirm (d == dest + top); */ /* * We now have fixed patterns in the dest buffer up to @@ -809,7 +809,7 @@ genpattern (int *dest, size_t num, struct randint_source *s) } accum -= randpasses; } - /* assert (top == num); */ + /* affirm (top == num); */ } /* @@ -997,7 +997,6 @@ incname (char *name, size_t len) /* Given that NAME is composed of bytes from NAMESET, P will never be null here. */ - assert (p); /* If this character has a successor, use it. */ if (p[1]) diff --git a/src/sort.c b/src/sort.c index 5daf05065a..b3a1342133 100644 --- a/src/sort.c +++ b/src/sort.c @@ -28,9 +28,9 @@ #include #include #include -#include #include "system.h" #include "argmatch.h" +#include "assure.h" #include "die.h" #include "error.h" #include "fadvise.h" @@ -978,7 +978,7 @@ stream_open (char const *file, char const *how) fp = stdout; } else - assert (!"unexpected mode passed to stream_open"); + affirm (!"unexpected mode passed to stream_open"); return fp; } @@ -4439,11 +4439,6 @@ main (int argc, char **argv) char const *optarg1 = argv[optind++]; s = parse_field_count (optarg1 + 1, &key->eword, N_("invalid number after '-'")); - /* When called with a non-null message ID, - parse_field_count cannot return a null pointer. - Tell static analysis tools that - dereferencing S is safe. */ - assert (s); if (*s == '.') s = parse_field_count (s + 1, &key->echar, N_("invalid number after '.'")); diff --git a/src/split.c b/src/split.c index 994410d677..da21d5eb71 100644 --- a/src/split.c +++ b/src/split.c @@ -21,7 +21,6 @@ * support --suppress-matched as in csplit. */ #include -#include #include #include #include @@ -30,6 +29,7 @@ #include "system.h" #include "alignalloc.h" +#include "assure.h" #include "die.h" #include "error.h" #include "fadvise.h" @@ -423,7 +423,7 @@ new_name: if (numeric_suffix_start) { - assert (! widen); + affirm (! widen); /* Update the output file name. */ idx_t i = strlen (numeric_suffix_start); @@ -885,7 +885,7 @@ static void lines_chunk_split (intmax_t k, intmax_t n, char *buf, idx_t bufsize, ssize_t initial_read, off_t file_size) { - assert (n && k <= n); + affirm (n && k <= n); intmax_t rem_bytes = file_size % n; off_t chunk_size = file_size / n; @@ -1698,7 +1698,7 @@ main (int argc, char **argv) break; default: - abort (); + affirm (false); } if (close (STDIN_FILENO) != 0) diff --git a/src/stat.c b/src/stat.c index 4ab67b9fcf..05d0cb9f58 100644 --- a/src/stat.c +++ b/src/stat.c @@ -28,7 +28,6 @@ # define USE_STATVFS 0 #endif -#include #include #include #include diff --git a/src/stdbuf.c b/src/stdbuf.c index 8202f7746d..262b6d8223 100644 --- a/src/stdbuf.c +++ b/src/stdbuf.c @@ -20,9 +20,9 @@ #include #include #include -#include #include "system.h" +#include "assure.h" #include "die.h" #include "error.h" #include "filenamecat.h" @@ -336,7 +336,7 @@ main (int argc, char **argv) case 'i': case 'o': opt_fileno = optc_to_fileno (c); - assert (0 <= opt_fileno && opt_fileno < ARRAY_CARDINALITY (stdbuf)); + affirm (0 <= opt_fileno && opt_fileno < ARRAY_CARDINALITY (stdbuf)); stdbuf[opt_fileno].optc = c; while (c_isspace (*optarg)) optarg++; diff --git a/src/stty.c b/src/stty.c index e2cd335376..be8f4adeed 100644 --- a/src/stty.c +++ b/src/stty.c @@ -52,9 +52,9 @@ #endif #include #include -#include #include "system.h" +#include "assure.h" #include "die.h" #include "error.h" #include "fd-reopen.h" @@ -1726,7 +1726,7 @@ set_speed (enum speed_setting type, char const *arg, struct termios *mode) Therefore we don't report the device name in any errors. */ speed_t baud = string_to_baud (arg); - assert (baud != (speed_t) -1); + affirm (baud != (speed_t) -1); if (type == input_speed || type == both_speeds) { @@ -1887,7 +1887,7 @@ mode_type_flag (enum mode_type type, struct termios *mode) return nullptr; default: - abort (); + unreachable (); } } @@ -1987,7 +1987,7 @@ display_changed (struct termios *mode) /* bitsp would be null only for "combination" modes, yet those are filtered out above via the OMIT flag. Tell static analysis tools that it's ok to dereference bitsp here. */ - assert (bitsp); + assume (bitsp); if ((*bitsp & mask) == mode_info[i].bits) { @@ -2071,7 +2071,7 @@ display_all (struct termios *mode, char const *device_name) bitsp = mode_type_flag (mode_info[i].type, mode); mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; - assert (bitsp); /* See the identical assertion and comment above. */ + assume (bitsp); /* See the identical assertion and comment above. */ if ((*bitsp & mask) == mode_info[i].bits) wrapf ("%s", mode_info[i].name); else if (mode_info[i].flags & REV) @@ -2303,13 +2303,13 @@ sane_mode (struct termios *mode) if (mode_info[i].flags & SANE_SET) { bitsp = mode_type_flag (mode_info[i].type, mode); - assert (bitsp); /* combination modes will not have SANE_SET. */ + assume (bitsp); /* combination modes will not have SANE_SET. */ *bitsp = (*bitsp & ~mode_info[i].mask) | mode_info[i].bits; } else if (mode_info[i].flags & SANE_UNSET) { bitsp = mode_type_flag (mode_info[i].type, mode); - assert (bitsp); /* combination modes will not have SANE_UNSET. */ + assume (bitsp); /* combination modes will not have SANE_UNSET. */ *bitsp = *bitsp & ~mode_info[i].mask & ~mode_info[i].bits; } } diff --git a/src/sync.c b/src/sync.c index f5fd5d05b8..07b4392b35 100644 --- a/src/sync.c +++ b/src/sync.c @@ -17,7 +17,6 @@ /* Written by Jim Meyering */ #include -#include #include #include #include @@ -149,7 +148,7 @@ sync_arg (enum sync_mode mode, char const *file) #endif default: - assert ("invalid sync_mode"); + unreachable (); } if (sync_status < 0) diff --git a/src/system.h b/src/system.h index f184c4fdcd..082cbe5bd6 100644 --- a/src/system.h +++ b/src/system.h @@ -67,6 +67,7 @@ # define makedev(maj, min) mkdev (maj, min) #endif +#include #include #include diff --git a/src/tac-pipe.c b/src/tac-pipe.c index 0d9ccba928..cc2696dabc 100644 --- a/src/tac-pipe.c +++ b/src/tac-pipe.c @@ -16,7 +16,7 @@ along with this program. If not, see . */ /* FIXME */ -#include +#include "assure.h" #include "die.h" @@ -144,7 +144,7 @@ line_ptr_decrement (const Buf *x, const Line_ptr *lp) } else { - assert (lp->i > 0); + affirm (lp->i > 0); lp_new.i = lp->i - 1; lp_new.ptr = ONE_PAST_END (x, lp->i - 1) - 1; } @@ -156,7 +156,7 @@ line_ptr_increment (const Buf *x, const Line_ptr *lp) { Line_ptr lp_new; - assert (lp->ptr <= ONE_PAST_END (x, lp->i) - 1); + affirm (lp->ptr <= ONE_PAST_END (x, lp->i) - 1); if (lp->ptr < ONE_PAST_END (x, lp->i) - 1) { lp_new.i = lp->i; @@ -164,7 +164,7 @@ line_ptr_increment (const Buf *x, const Line_ptr *lp) } else { - assert (lp->i < x->n_bufs - 1); + affirm (lp->i < x->n_bufs - 1); lp_new.i = lp->i + 1; lp_new.ptr = x->p[lp->i + 1].start; } diff --git a/src/tail.c b/src/tail.c index f819448ca7..6c1b890cce 100644 --- a/src/tail.c +++ b/src/tail.c @@ -26,13 +26,13 @@ #include #include -#include #include #include #include #include "system.h" #include "argmatch.h" +#include "assure.h" #include "cl-strtod.h" #include "die.h" #include "error.h" @@ -354,7 +354,7 @@ check_output_alive (void) die_pipe (); } -static bool +MAYBE_UNUSED static bool valid_file_spec (struct File_spec const *f) { /* Exactly one of the following subexpressions must be true. */ @@ -484,22 +484,21 @@ xlseek (int fd, off_t offset, int whence, char const *filename) switch (whence) { case SEEK_SET: - error (0, errno, _("%s: cannot seek to offset %s"), + error (EXIT_FAILURE, errno, _("%s: cannot seek to offset %s"), quotef (filename), s); break; case SEEK_CUR: - error (0, errno, _("%s: cannot seek to relative offset %s"), + error (EXIT_FAILURE, errno, _("%s: cannot seek to relative offset %s"), quotef (filename), s); break; case SEEK_END: - error (0, errno, _("%s: cannot seek to end-relative offset %s"), + error (EXIT_FAILURE, errno, + _("%s: cannot seek to end-relative offset %s"), quotef (filename), s); break; default: - abort (); + unreachable (); } - - exit (EXIT_FAILURE); } /* Print the last N_LINES lines from the end of file FD. @@ -931,21 +930,10 @@ fremote (int fd, char const *name) } else { - switch (is_local_fs_type (buf.f_type)) - { - case 0: - break; - case -1: - /* Treat unrecognized file systems as "remote", so caller polls. - Note README-release has instructions for syncing the internal - list with the latest Linux kernel file system constants. */ - break; - case 1: - remote = false; - break; - default: - assert (!"unexpected return value from is_local_fs_type"); - } + /* Treat unrecognized file systems as "remote", so caller polls. + Note README-release has instructions for syncing the internal + list with the latest Linux kernel file system constants. */ + remote = is_local_fs_type (buf.f_type) <= 0; } #endif @@ -966,7 +954,7 @@ recheck (struct File_spec *f, bool blocking) ? STDIN_FILENO : open (f->name, O_RDONLY | (blocking ? 0 : O_NONBLOCK))); - assert (valid_file_spec (f)); + affirm (valid_file_spec (f)); /* If the open fails because the file doesn't exist, then mark the file as not tailable. */ @@ -1043,7 +1031,7 @@ recheck (struct File_spec *f, bool blocking) else if (prev_errnum && prev_errnum != ENOENT) { new_file = true; - assert (f->fd == -1); + affirm (f->fd == -1); error (0, 0, _("%s has become accessible"), quoteaf (pretty_name (f))); } else if (f->fd == -1) @@ -1218,7 +1206,7 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval) read_unchanged = true; } - assert (fd == f[i].fd); + affirm (fd == f[i].fd); /* This file has changed. Print out what we can, and then keep looping. */ diff --git a/src/test.c b/src/test.c index 1cf8e2663b..445eba08b9 100644 --- a/src/test.c +++ b/src/test.c @@ -44,6 +44,7 @@ #endif #include "system.h" +#include "assure.h" #include "quote.h" #include "stat-time.h" #include "strnumcmp.h" @@ -377,7 +378,7 @@ binary_operator (bool l_is_l) } /* Not reached. */ - abort (); + affirm (false); } static bool @@ -666,8 +667,7 @@ posixtest (int nargs) FALLTHROUGH; case 5: default: - if (nargs <= 0) - abort (); + affirm (0 < nargs); value = expr (); } diff --git a/src/touch.c b/src/touch.c index 018f7265a8..7bc199fda8 100644 --- a/src/touch.c +++ b/src/touch.c @@ -21,10 +21,10 @@ #include #include #include -#include #include "system.h" #include "argmatch.h" +#include "assure.h" #include "die.h" #include "error.h" #include "fd-reopen.h" @@ -144,7 +144,7 @@ touch (char const *file) newtime[0].tv_nsec = UTIME_OMIT; else { - assert (change_times == CH_ATIME); + affirm (change_times == CH_ATIME); newtime[1].tv_nsec = UTIME_OMIT; } } diff --git a/src/tr.c b/src/tr.c index 83a6d5412c..db669a7d45 100644 --- a/src/tr.c +++ b/src/tr.c @@ -19,11 +19,11 @@ #include #include -#include #include #include #include "system.h" +#include "assure.h" #include "die.h" #include "error.h" #include "fadvise.h" @@ -408,7 +408,7 @@ is_char_class_member (enum Char_class char_class, unsigned char c) result = isxdigit (c); break; default: - abort (); + unreachable (); } return !! result; @@ -646,7 +646,6 @@ append_normal_char (struct Spec_list *list, unsigned char c) new->next = nullptr; new->type = RE_NORMAL_CHAR; new->u.normal_char = c; - assert (list->tail); list->tail->next = new; list->tail = new; } @@ -676,7 +675,6 @@ append_range (struct Spec_list *list, unsigned char first, unsigned char last) new->type = RE_RANGE; new->u.range.first_char = first; new->u.range.last_char = last; - assert (list->tail); list->tail->next = new; list->tail = new; return true; @@ -698,7 +696,6 @@ append_char_class (struct Spec_list *list, new->next = nullptr; new->type = RE_CHAR_CLASS; new->u.char_class = char_class; - assert (list->tail); list->tail->next = new; list->tail = new; return true; @@ -718,7 +715,6 @@ append_repeated_char (struct Spec_list *list, unsigned char the_char, new->type = RE_REPEATED_CHAR; new->u.repeated_char.the_repeated_char = the_char; new->u.repeated_char.repeat_count = repeat_count; - assert (list->tail); list->tail->next = new; list->tail = new; } @@ -740,7 +736,6 @@ append_equiv_class (struct Spec_list *list, new->next = nullptr; new->type = RE_EQUIV_CLASS; new->u.equiv_code = *equiv_class_str; - assert (list->tail); list->tail->next = new; list->tail = new; return true; @@ -781,7 +776,7 @@ find_bracketed_repeat (const struct E_string *es, size_t start_idx, unsigned char *char_to_repeat, count *repeat_count, size_t *closing_bracket_idx) { - assert (start_idx + 1 < es->len); + affirm (start_idx + 1 < es->len); if (!es_match (es, start_idx + 1, '*')) return -1; @@ -1076,10 +1071,10 @@ get_next (struct Spec_list *s, enum Upper_Lower_class *class) for (i = 0; i < N_CHARS; i++) if (is_char_class_member (p->u.char_class, i)) break; - assert (i < N_CHARS); + affirm (i < N_CHARS); s->state = i; } - assert (is_char_class_member (p->u.char_class, s->state)); + assure (is_char_class_member (p->u.char_class, s->state)); return_val = s->state; for (i = s->state + 1; i < N_CHARS; i++) if (is_char_class_member (p->u.char_class, i)) @@ -1129,7 +1124,7 @@ get_next (struct Spec_list *s, enum Upper_Lower_class *class) break; default: - abort (); + unreachable (); } return return_val; @@ -1172,8 +1167,7 @@ validate_case_classes (struct Spec_list *s1, struct Spec_list *s2) size_t n_lower = 0; int c1 = 0; int c2 = 0; - count old_s1_len = s1->length; - count old_s2_len = s2->length; + MAYBE_UNUSED count old_s1_len = s1->length, old_s2_len = s2->length; struct List_element *s1_tail = s1->tail; struct List_element *s2_tail = s2->tail; bool s1_new_element = true; @@ -1221,7 +1215,7 @@ validate_case_classes (struct Spec_list *s1, struct Spec_list *s2) s2_new_element = s2->state == NEW_ELEMENT; /* Next element is new. */ } - assert (old_s1_len >= s1->length && old_s2_len >= s2->length); + affirm (old_s1_len >= s1->length && old_s2_len >= s2->length); s1->tail = s1_tail; s2->tail = s2_tail; @@ -1262,7 +1256,7 @@ get_spec_stats (struct Spec_list *s) break; case RE_RANGE: - assert (p->u.range.last_char >= p->u.range.first_char); + affirm (p->u.range.last_char >= p->u.range.first_char); len = p->u.range.last_char - p->u.range.first_char + 1; break; @@ -1300,7 +1294,7 @@ get_spec_stats (struct Spec_list *s) break; default: - abort (); + unreachable (); } /* Check for arithmetic overflow in computing length. Also, reject @@ -1374,9 +1368,9 @@ string2_extend (const struct Spec_list *s1, struct Spec_list *s2) struct List_element *p; unsigned char char_to_repeat; - assert (translating); - assert (s1->length > s2->length); - assert (s2->length > 0); + affirm (translating); + affirm (s1->length > s2->length); + affirm (s2->length > 0); p = s2->tail; switch (p->type) @@ -1403,10 +1397,10 @@ string2_extend (const struct Spec_list *s1, struct Spec_list *s2) case RE_EQUIV_CLASS: /* This shouldn't happen, because validate exits with an error if it finds an equiv class in string2 when translating. */ - abort (); + affirm (false); default: - abort (); + unreachable (); } append_repeated_char (s2, char_to_repeat, s1->length - s2->length); @@ -1837,7 +1831,7 @@ main (int argc, char **argv) if (!in_s1[i]) { int ch = get_next (s2, nullptr); - assert (ch != -1 || truncate_set1); + affirm (ch != -1 || truncate_set1); if (ch == -1) { /* This will happen when tr is invoked like e.g. @@ -1890,7 +1884,7 @@ main (int argc, char **argv) skip_construct (s2); } } - assert (c1 == -1 || truncate_set1); + affirm (c1 == -1 || truncate_set1); } if (squeeze_repeats) { diff --git a/src/tsort.c b/src/tsort.c index 2fdb07abf3..8345b59971 100644 --- a/src/tsort.c +++ b/src/tsort.c @@ -22,10 +22,10 @@ #include -#include #include #include "system.h" +#include "assure.h" #include "long-options.h" #include "die.h" #include "error.h" @@ -123,8 +123,6 @@ search_item (struct item *root, char const *str) struct item *p, *q, *r, *s, *t; int a; - assert (root); - /* Make sure the tree is not empty, since that is what the algorithm below expects. */ if (root->right == nullptr) @@ -137,7 +135,6 @@ search_item (struct item *root, char const *str) while (true) { /* A2. Compare. */ - assert (str && p && p->str); a = strcmp (str, p->str); if (a == 0) return p; @@ -160,28 +157,30 @@ search_item (struct item *root, char const *str) p->right = q; /* A6. Adjust balance factors. */ - assert (str && s && s->str && !STREQ (str, s->str)); - if (strcmp (str, s->str) < 0) + a = strcmp (str, s->str); + if (a < 0) { r = p = s->left; a = -1; } else { + affirm (0 < a); r = p = s->right; a = 1; } while (p != q) { - assert (str && p && p->str && !STREQ (str, p->str)); - if (strcmp (str, p->str) < 0) + int cmp = strcmp (str, p->str); + if (cmp < 0) { p->balance = -1; p = p->left; } else { + affirm (0 < cmp); p->balance = 1; p = p->right; } @@ -459,7 +458,7 @@ tsort (char const *file) break; } - assert (len != 0); + affirm (len != 0); k = search_item (root, tokenbuffer.buffer); if (j) diff --git a/src/wc.c b/src/wc.c index 9f345aa727..318fcaa3d1 100644 --- a/src/wc.c +++ b/src/wc.c @@ -20,13 +20,13 @@ #include #include -#include #include #include #include #include #include "system.h" +#include "assure.h" #include "argmatch.h" #include "argv-iter.h" #include "die.h" @@ -938,7 +938,7 @@ main (int argc, char **argv) case AI_ERR_MEM: xalloc_die (); default: - assert (!"unexpected error code from argv_iter"); + affirm (!"unexpected error code from argv_iter"); } } if (files_from && STREQ (files_from, "-") && STREQ (file_name, "-")) diff --git a/src/who.c b/src/who.c index a0ab30802d..a8a3a8ba15 100644 --- a/src/who.c +++ b/src/who.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include "system.h" @@ -200,9 +199,9 @@ idle_string (time_t when, time_t boottime) else { static char idle_hhmm[IDLESTR_LEN]; - /* FIXME-in-2018: see if this assert is still required in order + /* FIXME-in-2024: see if this is still required in order to suppress gcc's unwarranted -Wformat-length= warning. */ - assert (seconds_idle / (60 * 60) < 24); + assume (seconds_idle / (60 * 60) < 24); sprintf (idle_hhmm, "%02d:%02d", seconds_idle / (60 * 60), (seconds_idle % (60 * 60)) / 60); -- 2.47.2