// This detects NULL tests that can only be reached when the value is known 
// not to be NULL
//
// Confidence: High
// Copyright: (C) Gilles Muller, Julia Lawall, EMN, DIKU.  GPLv2.
// URL: http://www.emn.fr/x-info/coccinelle/rules/notnull.html
// Options:

virtual org,diff

@r exists@
local idexpression x;
expression E;
position p1,p2;
@@

if (x@p1 == NULL || ...) { ... when forall
   return ...; }
... when != \(x=E\|x--\|x++\|--x\|++x\|x-=E\|x+=E\|x|=E\|x&=E\)
    when != &x
(
x@p2 == NULL
|
x@p2 != NULL
)

// another path to the test that is not through p1?

@s exists@
local idexpression r.x;
position r.p1,r.p2;
@@

... when != x@p1
(
x@p2 == NULL
|
x@p2 != NULL
)

// another path to the test from p1?

@t exists@
local idexpression x;
position r.p1,r.p2;
@@

if (x@p1 == NULL || ...) { ... x@p2 ... when any
   return ...; }

// another path to the test containing an assignment?

@u exists@
local idexpression x;
expression E;
position r.p1,r.p2;
@@

if (x@p1 == NULL || ...) { ... when forall
   return ...; }
 ...
 \(x=E\|x--\|x++\|--x\|++x\|x-=E\|x+=E\|x|=E\|x&=E\|&x\)
 ...  when != x@p1
      when any
(
x@p2 == NULL
|
x@p2 != NULL
)

@script:python depends on !s && !t && !u && org @
p1 << r.p1;
p2 << r.p2;
@@

cocci.print_main("",p2)
cocci.print_secs("",p1)

@depends on !s && !t && !u && diff@
position r.p1, r.p2;
expression x;
@@

*x@p1
...
*x@p2
