bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] getopt: pacify gcc -Wanalyzer-null-dereference


From: Paul Eggert
Subject: [PATCH] getopt: pacify gcc -Wanalyzer-null-dereference
Date: Mon, 11 Dec 2023 12:09:47 -0800

* 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).
---
 ChangeLog    |  7 +++++++
 lib/getopt.c | 29 ++++++++++++++++-------------
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a017833f64..0b8c3fc640 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-12-11  Paul Eggert  <eggert@cs.ucla.edu>
+
+       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  <P@draigBrady.com>
 
        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;
-- 
2.43.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]