Browse Source

scripts/coccinelle: add some more coccinelle tests

kmerr: verify that malloc and calloc are followed by a check to verify
that we are not out of memory.

badzero: Compare pointer-typed values to NULL rather than 0

Both checks are copied from the Linux kernel archive.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
master
Heinrich Schuchardt 2 years ago
committed by Tom Rini
parent
commit
4320e2fda4
2 changed files with 316 additions and 0 deletions
  1. +241
    -0
      scripts/coccinelle/null/badzero.cocci
  2. +75
    -0
      scripts/coccinelle/null/kmerr.cocci

+ 241
- 0
scripts/coccinelle/null/badzero.cocci View File

@@ -0,0 +1,241 @@
/// Compare pointer-typed values to NULL rather than 0
///
//# This makes an effort to choose between !x and x == NULL. !x is used
//# if it has previously been used with the function used to initialize x.
//# This relies on type information. More type information can be obtained
//# using the option -all_includes and the option -I to specify an
//# include path.
//
// Confidence: High
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
// URL: http://coccinelle.lip6.fr/
// Requires: 1.0.0
// Options:
//
// SPDX-License-Identifier: GPL-2.0
//

virtual patch
virtual context
virtual org
virtual report

@initialize:ocaml@
@@
let negtable = Hashtbl.create 101

@depends on patch@
expression *E;
identifier f;
@@

(
(E = f(...)) ==
- 0
+ NULL
|
(E = f(...)) !=
- 0
+ NULL
|
- 0
+ NULL
== (E = f(...))
|
- 0
+ NULL
!= (E = f(...))
)


@t1 depends on !patch@
expression *E;
identifier f;
position p;
@@

(
(E = f(...)) ==
* 0@p
|
(E = f(...)) !=
* 0@p
|
* 0@p
== (E = f(...))
|
* 0@p
!= (E = f(...))
)

@script:python depends on org@
p << t1.p;
@@

coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")

@script:python depends on report@
p << t1.p;
@@

coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")

// Tests of returned values

@s@
identifier f;
expression E,E1;
@@

E = f(...)
... when != E = E1
!E

@script:ocaml depends on s@
f << s.f;
@@

try let _ = Hashtbl.find negtable f in ()
with Not_found -> Hashtbl.add negtable f ()

@ r disable is_zero,isnt_zero exists @
expression *E;
identifier f;
@@

E = f(...)
...
(E == 0
|E != 0
|0 == E
|0 != E
)

@script:ocaml@
f << r.f;
@@

try let _ = Hashtbl.find negtable f in ()
with Not_found -> include_match false

// This rule may lead to inconsistent path problems, if E is defined in two
// places
@ depends on patch disable is_zero,isnt_zero @
expression *E;
expression E1;
identifier r.f;
@@

E = f(...)
<...
(
- E == 0
+ !E
|
- E != 0
+ E
|
- 0 == E
+ !E
|
- 0 != E
+ E
)
...>
?E = E1

@t2 depends on !patch disable is_zero,isnt_zero @
expression *E;
expression E1;
identifier r.f;
position p1;
position p2;
@@

E = f(...)
<...
(
* E == 0@p1
|
* E != 0@p2
|
* 0@p1 == E
|
* 0@p1 != E
)
...>
?E = E1

@script:python depends on org@
p << t2.p1;
@@

coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E")

@script:python depends on org@
p << t2.p2;
@@

coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")

@script:python depends on report@
p << t2.p1;
@@

coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E")

@script:python depends on report@
p << t2.p2;
@@

coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")

@ depends on patch disable is_zero,isnt_zero @
expression *E;
@@

(
E ==
- 0
+ NULL
|
E !=
- 0
+ NULL
|
- 0
+ NULL
== E
|
- 0
+ NULL
!= E
)

@ t3 depends on !patch disable is_zero,isnt_zero @
expression *E;
position p;
@@

(
* E == 0@p
|
* E != 0@p
|
* 0@p == E
|
* 0@p != E
)

@script:python depends on org@
p << t3.p;
@@

coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0")

@script:python depends on report@
p << t3.p;
@@

coccilib.report.print_report(p[0], "WARNING comparing pointer to 0")

+ 75
- 0
scripts/coccinelle/null/kmerr.cocci View File

@@ -0,0 +1,75 @@
/// This semantic patch looks for malloc etc that are not followed by a
/// NULL check. It only gives a report in the case where there is some
/// error handling code later in the function, which may be helpful
/// in determining what the error handling code for the call to malloc etc
/// should be.
///
// Confidence: High
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
// URL: http://coccinelle.lip6.fr/
// Comments:
// Options: --no-includes --include-headers
//
// SPDX-License-Identifier: GPL-2.0
//

virtual context
virtual org
virtual report

@withtest@
expression x;
position p;
identifier f,fld;
@@

x@p = f(...);
... when != x->fld
\(x == NULL \| x != NULL\)

@fixed depends on context && !org && !report@
expression x,x1;
position p1 != withtest.p;
statement S;
position any withtest.p;
identifier f;
@@

*x@p1 = \(malloc\|calloc\)(...);
...
*x1@p = f(...);
if (!x1) S

// ------------------------------------------------------------------------

@rfixed depends on (org || report) && !context exists@
expression x,x1;
position p1 != withtest.p;
position p2;
statement S;
position any withtest.p;
identifier f;
@@

x@p1 = \(malloc\|calloc\)(...);
...
x1@p = f@p2(...);
if (!x1) S

@script:python depends on org@
p1 << rfixed.p1;
p2 << rfixed.p2;
@@

cocci.print_main("alloc call",p1)
cocci.print_secs("possible model",p2)

@script:python depends on report@
p1 << rfixed.p1;
p2 << rfixed.p2;
@@

msg = "alloc with no test, possible model on line %s" % (p2[0].line)
coccilib.report.print_report(p1[0],msg)

Loading…
Cancel
Save