bug-gnulib
[Top][All Lists]
Advanced

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

[PATCH 03/27] dfa: improve -fanalyzer malloc checking


From: Paul Eggert
Subject: [PATCH 03/27] dfa: improve -fanalyzer malloc checking
Date: Sun, 1 Aug 2021 18:17:57 -0700

---
 ChangeLog |  5 ++++-
 lib/dfa.c | 15 +++++++++++++++
 lib/dfa.h |  9 +++++++--
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1af0b926a..d7740df52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,8 +2,11 @@
 
        maint: improve -fanalyzer malloc checking
        * lib/backup-internal.h, lib/backupfile.h:
-       * lib/canonicalize.h:
+       * lib/canonicalize.h, lib/dfa.h:
        Add malloc-related attributes and include stdlib.h as needed.
+       * lib/dfa.c: Include verify.h.
+       (assume_nonnull): New macro.
+       (dfamust): Use it to pacify GCC.
 
 2021-08-01  Jim Meyering  <meyering@fb.com>
 
diff --git a/lib/dfa.c b/lib/dfa.c
index 7e05a78da..44c3b65c2 100644
--- a/lib/dfa.c
+++ b/lib/dfa.c
@@ -26,6 +26,7 @@
 
 #include "flexmember.h"
 #include "idx.h"
+#include "verify.h"
 
 #include <assert.h>
 #include <ctype.h>
@@ -35,6 +36,13 @@
 #include <limits.h>
 #include <string.h>
 
+/* Pacify gcc -Wanalyzer-null-dereference in areas where GCC
+   understandably cannot deduce that the input comes from a
+   well-formed regular expression.  There's little point to the
+   runtime overhead of 'assert' instead of 'assume_nonnull' when the
+   MMU will check anyway.  */
+#define assume_nonnull(x) assume ((x) != NULL)
+
 static bool
 streq (char const *a, char const *b)
 {
@@ -4090,6 +4098,7 @@ dfamust (struct dfa const *d)
 
         case STAR:
         case QMARK:
+          assume_nonnull (mp);
           resetmust (mp);
           break;
 
@@ -4097,7 +4106,9 @@ dfamust (struct dfa const *d)
           {
             char **new;
             must *rmp = mp;
+            assume_nonnull (rmp);
             must *lmp = mp = mp->prev;
+            assume_nonnull (lmp);
             idx_t j, ln, rn, n;
 
             /* Guaranteed to be.  Unlikely, but ...  */
@@ -4138,10 +4149,12 @@ dfamust (struct dfa const *d)
           break;
 
         case PLUS:
+          assume_nonnull (mp);
           mp->is[0] = '\0';
           break;
 
         case END:
+          assume_nonnull (mp);
           assert (!mp->prev);
           for (idx_t i = 0; mp->in[i] != NULL; i++)
             if (strlen (mp->in[i]) > strlen (result))
@@ -4159,7 +4172,9 @@ dfamust (struct dfa const *d)
         case CAT:
           {
             must *rmp = mp;
+            assume_nonnull (rmp);
             must *lmp = mp = mp->prev;
+            assume_nonnull (lmp);
 
             /* In.  Everything in left, plus everything in
                right, plus concatenation of
diff --git a/lib/dfa.h b/lib/dfa.h
index 19a4127b6..28f9f6336 100644
--- a/lib/dfa.h
+++ b/lib/dfa.h
@@ -24,6 +24,7 @@
 #include <regex.h>
 #include <stdbool.h>
 #include <stddef.h>
+#include <stdlib.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -46,7 +47,9 @@ struct dfa;
 
 /* Needed when Gnulib is not used.  */
 #ifndef _GL_ATTRIBUTE_MALLOC
-# define  _GL_ATTRIBUTE_MALLOC
+# define _GL_ATTRIBUTE_MALLOC
+# define _GL_ATTRIBUTE_DEALLOC_FREE
+# define _GL_ATTRIBUTE_RETURNS_NONNULL
 #endif
 
 /* Entry points. */
@@ -55,7 +58,9 @@ struct dfa;
    It should be initialized via dfasyntax or dfacopysyntax before other use.
    The returned pointer should be passed directly to free() after
    calling dfafree() on it. */
-extern struct dfa *dfaalloc (void) _GL_ATTRIBUTE_MALLOC;
+extern struct dfa *dfaalloc (void)
+  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
+  _GL_ATTRIBUTE_RETURNS_NONNULL;
 
 /* DFA options that can be ORed together, for dfasyntax's 4th arg.  */
 enum
-- 
2.31.1




reply via email to

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