From: Paul Eggert Date: Mon, 11 Dec 2023 18:57:06 +0000 (-0800) Subject: getopt: pacify gcc -Wanalyzer-null-dereference X-Git-Tag: v1.0~566 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=3bb26f17cbb32c4129c4a26cd6122bd2227ddf05;p=gnulib.git getopt: pacify gcc -Wanalyzer-null-dereference * lib/getopt.c (process_long_option): Simplify logic slightly. This pacifies gcc -flto -Wanalyzer-null-dereference when compiling GNU tar on x86-64 with gcc 13.2.1 20231205 (Red Hat 13.2.1-6). --- diff --git a/ChangeLog b/ChangeLog index a017833f64..0b8c3fc640 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-12-11 Paul Eggert + + getopt: pacify gcc -Wanalyzer-null-dereference + * lib/getopt.c (process_long_option): Simplify logic slightly. + This pacifies gcc -flto -Wanalyzer-null-dereference when compiling + GNU tar on x86-64 with gcc 13.2.1 20231205 (Red Hat 13.2.1-6). + 2023-12-10 Pádraig Brady bootstrap: fix option propagation with --bootstrap-sync diff --git a/lib/getopt.c b/lib/getopt.c index 1e2441c4af..a2a291d697 100644 --- a/lib/getopt.c +++ b/lib/getopt.c @@ -223,8 +223,9 @@ process_long_option (int argc, char **argv, const char *optstring, { /* Didn't find an exact match, so look for abbreviations. */ unsigned char *ambig_set = NULL; - int ambig_malloced = 0; - int ambig_fallback = 0; + /* Use simpler fallback diagnostic if ambig_set == &ambig_fallback. */ + unsigned char ambig_fallback; + void *ambig_malloced = NULL; int indfound = -1; for (p = longopts, option_index = 0; p->name; p++, option_index++) @@ -242,23 +243,26 @@ process_long_option (int argc, char **argv, const char *optstring, || pfound->val != p->val) { /* Second or later nonexact match found. */ - if (!ambig_fallback) + if (ambig_set != &ambig_fallback) { if (!print_errors) /* Don't waste effort tracking the ambig set if we're not going to print it anyway. */ - ambig_fallback = 1; + ambig_set = &ambig_fallback; else if (!ambig_set) { if (__libc_use_alloca (n_options)) ambig_set = alloca (n_options); - else if ((ambig_set = malloc (n_options)) == NULL) - /* Fall back to simpler error message. */ - ambig_fallback = 1; else - ambig_malloced = 1; + { + ambig_malloced = malloc (n_options); + /* Fall back to simpler diagnostic if + memory allocation fails. */ + ambig_set = (ambig_malloced ? ambig_malloced + : &ambig_fallback); + } - if (ambig_set) + if (ambig_set != &ambig_fallback) { memset (ambig_set, 0, n_options); ambig_set[indfound] = 1; @@ -270,11 +274,11 @@ process_long_option (int argc, char **argv, const char *optstring, } } - if (ambig_set || ambig_fallback) + if (ambig_set) { if (print_errors) { - if (ambig_fallback) + if (ambig_set == &ambig_fallback) fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"), argv[0], prefix, d->__nextchar); else @@ -296,8 +300,7 @@ process_long_option (int argc, char **argv, const char *optstring, funlockfile (stderr); } } - if (ambig_malloced) - free (ambig_set); + free (ambig_malloced); d->__nextchar += strlen (d->__nextchar); d->optind++; d->optopt = 0;