bug-gnulib
[Top][All Lists]
Advanced

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

[PATCH] useless-if-before-free: recognize more variants


From: Jim Meyering
Subject: [PATCH] useless-if-before-free: recognize more variants
Date: Wed, 28 Jan 2009 09:30:16 +0100

FYI, I've just pushed the patch below.
I added test cases to this stand-alone Makefile,
but added the final one (for (void*)0) only after
pushing the patch below.  Then I realized that
current limitations prevent detection of that
variant of 0/NULL, so have just revised the script accordingly.

u = ./useless-if-before-free
do_diff = \
  diff -u <($u <(printf "$$i")|sed 's/.*: //') \
    <(printf "$$i"'\n'|sed 's/;$$//')
SHELL = /bin/bash

all:
        i='if (p) free(p);'; $(do_diff)
        $u <(printf 'if (p) free(q);') > /dev/null && exit 1 || :
        i='if (p) free((void)p);'; $(do_diff)
        i='if (p) free( (void)p);'; $(do_diff)
        i='if (p) free((T *) p);'; $(do_diff)
        i='if (*p) free(*p);'; $(do_diff)
        i='if (p)\nfree(p);'; $(do_diff)
        i='if ( p ) free(p);'; $(do_diff)
        i='if (p) free( p );'; $(do_diff)
        i='if(p) free (p);'; $(do_diff)
        i='if(p){free (p);}'; $(do_diff)
        i='if(p){\nfree (p);}'; $(do_diff)
        $u --name=z <(printf 'if (p) z (p);') > /dev/null
        $u --name=z <(printf 'if(p)z(p);') > /dev/null
        $u <(printf 'if(p[i + 1]) free(p[i + 1]);') > /dev/null
        $u <(printf 'if(p[i + 1]) free(p[i+1]);') > /dev/null
        test $$($u --name=z <(printf 'if(p)z(p);if(p)z(p);')|wc -l) = 2
        i='if(NULL != p){\nfree (p);}'; $(do_diff)
        i='if(p != NULL){\nfree (p);}'; $(do_diff)
        i='if(p != 0){\nfree (p);}'; $(do_diff)
#       i='if((void *)0 != p){\nfree (p);}'; $(do_diff)


>From 471cbb075f76e489fa96fad80bca65da7e01f683 Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Wed, 28 Jan 2009 09:19:28 +0100
Subject: [PATCH] useless-if-before-free: recognize more variants

* build-aux/useless-if-before-free: Also recognize e.g.,
if (NULL != p) free (p);
---
 ChangeLog                        |    6 +++++
 build-aux/useless-if-before-free |   40 ++++++++++++++++++++++++++++---------
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3b3a0f0..3a3244e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-01-28  Jim Meyering  <address@hidden>
+
+       useless-if-before-free: recognize more variants
+       * build-aux/useless-if-before-free: Also recognize e.g.,
+       if (NULL != p) free (p);
+
 2009-01-27  Mark McLoughlin  <address@hidden>

        test-getaddrinfo: skip (don't fail) this test when there's no network
diff --git a/build-aux/useless-if-before-free b/build-aux/useless-if-before-free
index 0bae2c4..a2fc773 100755
--- a/build-aux/useless-if-before-free
+++ b/build-aux/useless-if-before-free
@@ -1,14 +1,16 @@
 #!/usr/bin/perl -T
 # Detect instances of "if (p) free (p);".
 # Likewise for "if (p != NULL) free (p);".  And with braces.
+# Also detect "if (NULL != p) free (p);".
+# And with 0 or "(void *)0" in place of NULL.

-my $VERSION = '2008-05-25 17:36'; # UTC
+my $VERSION = '2009-01-28 08:16'; # UTC
 # The definition above must lie within the first 8 lines in order
 # for the Emacs time-stamp write hook (at end) to update it.
 # If you change this file with Emacs, please let the write hook
 # do its job.  Otherwise, update this string manually.

-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.

 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -60,7 +62,7 @@ detect free-like functions named FOO and BAR.
 OPTIONS:

    --list       print only the name of each matching FILE (\0-terminated)
-   --name=N     add name N to the list of `free'-like functions to detect;
+   --name=N     add name N to the list of \`free\'-like functions to detect;
                   may be repeated

    --help       display this help and exit
@@ -84,6 +86,14 @@ EOF
   exit $exit_code;
 }

+sub is_NULL ($)
+{
+  my ($expr) = @_;
+  return ($expr eq 'NULL'
+          || $expr eq '0'
+          || $expr =~ /^\(\s*(char|void)\s*\*\s*\)\s*0$/);
+}
+
 {
   sub EXIT_MATCH {0}
   sub EXIT_NO_MATCH {1}
@@ -122,21 +132,31 @@ EOF
       while (defined (my $line = <FH>))
         {
           while ($line =~
-              /\b(if\s*\(\s*([^)]+?)(?:\s*!=\s*NULL)?\s*\)
+              /\b(if\s*\(\s*([^)]+?)(?:\s*!=\s*([^)]+?))?\s*\)
+              #  1          2                  3
                (?:   \s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)|
                 
\s*\{\s*$regexp\s*\((?:\s*\([^)]+\))?\s*([^)]+)\)\s*;\s*\}))/sxg)
             {
-              # Compare "if" expression and free'd expression,
-              # without regard to white space.
-              (my $e1 = $2) =~ tr/ \t//d;
-              my $e2 = defined $3 ? $3 : $4;
+              my $all = $1;
+              my ($lhs, $rhs) = ($2, $3);
+              my ($free_opnd, $braced_free_opnd) = ($4, $5);
+              my $non_NULL;
+              if (!defined $rhs) { $non_NULL = $lhs }
+              elsif (is_NULL $rhs) { $non_NULL = $lhs }
+              elsif (is_NULL $lhs) { $non_NULL = $rhs }
+              else { next }
+
+              # Compare the non-NULL part of the "if" expression and the
+              # free'd expression, without regard to white space.
+              $non_NULL =~ tr/ \t//d;
+              my $e2 = defined $free_opnd ? $free_opnd : $braced_free_opnd;
               $e2 =~ tr/ \t//d;
-              if ($e1 eq $e2)
+              if ($non_NULL eq $e2)
                 {
                   $found_match = 1;
                   $list
                     and (print "$file\0"), next FILE;
-                  print "$file: $1\n";
+                  print "$file: $all\n";
                 }
             }
         }
--
1.6.1.1.374.g0d9d7




reply via email to

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