/// 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/ // Comments: Requires Coccinelle version 1.0.0-rc20 or later // Options: 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") sLines