add scripts/coccinelle

This commit is contained in:
Boris Faure 2022-06-08 23:57:36 +02:00
parent 1d264ea580
commit 13ffb1de64
Signed by untrusted user who does not match committer: borisfaure
GPG Key ID: EAA9CD729F522998
11 changed files with 447 additions and 0 deletions

View File

@ -0,0 +1,18 @@
// Two comparisons of the same expression to different constants,
// connected by a conjunction
// Confidence: Moderate
// Copyright: (C) Diego Liziero
// URL: https://coccinelle.gitlabpages.inria.fr/website/rules/andconst.html
// Options:
@@ identifier i; constant C1,C2; @@
(
- i == C1 && i == C2
+ i == C1 || i == C2
)
@@ identifier i; constant C1,C2; @@
(
- i != C1 || i != C2
+ i != C1 && i != C2
)

View File

@ -0,0 +1,51 @@
// A pointer should not be compared to zero
//
// Confidence: High
// Copyright: (C) Gilles Muller, Julia Lawall, EMN, INRIA, DIKU. GPLv2.
// URL: https://coccinelle.gitlabpages.inria.fr/website/rules/badzero.html
// Options:
@ disable is_zero,isnt_zero @
expression *E;
expression E1,f;
@@
E = f(...)
<...
(
- E == 0
+ !E
|
- E != 0
+ E
|
- 0 == E
+ !E
|
- 0 != E
+ E
)
...>
?E = E1
@ disable is_zero,isnt_zero @
expression *E;
@@
(
E ==
- 0
+ NULL
|
E !=
- 0
+ NULL
|
- 0
+ NULL
== E
|
- 0
+ NULL
!= E
)

View File

@ -0,0 +1,29 @@
#!/bin/sh
set -eu
DIR="src/bin"
COCCI_FILES="
andconst.cocci
badzero.cocci
continue.cocci
free_stack.cocci
mutex.cocci
notand.cocci
notnull.cocci
null_ref.cocci
unused.cocci
use_after_iter.cocci
"
HAS_ERROR=0
for f in $COCCI_FILES; do
CMD="spatch --timeout 200 --very-quiet --cocci-file scripts/coccinelle/$f --include-headers --dir $DIR"
#CMD="spatch --very-quiet --cocci-file scripts/coccinelle/$f --dir $DIR -allow_inconsistent_paths"
OUT=$($CMD)
echo "$CMD"
if [ -n "$OUT" ]; then
echo "$OUT"
HAS_ERROR=1
fi
done
exit $HAS_ERROR

View File

@ -0,0 +1,17 @@
// Continue at the end of a for loop has no purpose
//
// Confidence: Moderate
// Copyright: (C) Gilles Muller, Julia Lawall, EMN, INRIA, DIKU. GPLv2.
// URL: https://coccinelle.gitlabpages.inria.fr/website/rules/continue.html
// Options:
@@
@@
for (...;...;...) {
...
if (...) {
...
- continue;
}
}

View File

@ -0,0 +1,15 @@
// For fun, but gcc actually detects those by itself
@@
type T;
identifier K;
expression E;
@@
(
(
T K;
|
T K = E;
)
...
- free(&K);
)

View File

@ -0,0 +1,38 @@
// A mutex_lock is not matched by a mutex_unlock before an error return/goto.
@@
expression l;
identifier LOCK =~ "^.*_lock$";
identifier UN =~ "^.*_unlock$";
@@
LOCK(l);
... when != UN(l)
when any
when strict
(
{ ... when != UN(l)
+ todo_add_unlock(l);
return ...;
}
|
UN(l);
)
// unlock from not locked code
//@@
//expression E;
//identifier LOCK =~ "^.*_lock$";
//identifier UN =~ "^.*_unlock$";
//@@
//... when != LOCK(E)
//(
//if (...) {
//+add_LOCK(E);
//... when != LOCK(E)
// UN(E);
// return ...;
//}
//|
//UN(E)
//)

View File

@ -0,0 +1,14 @@
// !x&y combines boolean negation with bitwise and
//
// Confidence: High
// Copyright: (C) Gilles Muller, Julia Lawall, EMN, INRIA, DIKU. GPLv2.
// URL: https://coccinelle.gitlabpages.inria.fr/website/rules/notand.html
// Options:
@@ expression E; constant C; @@
(
!E & !C
|
- !E & C
+ !(E & C)
)

View File

@ -0,0 +1,104 @@
// 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, INRIA, DIKU. GPLv2.
// URL: https://coccinelle.gitlabpages.inria.fr/website/rules/notnull.html
// Options:
@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
)
@fix depends on !s && !t && !u@
position r.p2;
expression x,E;
statement S1,S2;
@@
(
- if ((x@p2 != NULL) || ...)
S1
|
- if ((x@p2 != NULL) || ...)
S1
- else S2
|
- (x@p2 != NULL) && E
+ E
|
- (x@p2 == NULL) || E
+ E
|
- if ((x@p2 == NULL) && ...) S1
|
- if ((x@p2 == NULL) && ...) S1 else
S2
|
- BUG_ON(x@p2 == NULL);
)
@script:python depends on !s && !t && !u && !fix@
p1 << r.p1;
p2 << r.p2;
@@
cocci.print_main("",p1)
cocci.print_secs("retest",p2)

View File

@ -0,0 +1,66 @@
// find cases where a pointer is dereferenced and then compared to NULL
//
// Confidence: High
// Copyright: (C) Gilles Muller, Julia Lawall, EMN, INRIA, DIKU. GPLv2.
// URL: https://coccinelle.gitlabpages.inria.fr/website/rules/null_ref.html
// Options:
@match exists@
expression x, E,E1;
identifier fld;
position p1,p2;
@@
(
x = E;
... when != \(x = E1\|&x\)
x@p2 == NULL
... when any
|
x = E
... when != \(x = E1\|&x\)
x@p2 == NULL
... when any
|
x != NULL && (<+...x->fld...+>)
|
x == NULL || (<+...x->fld...+>)
|
x != NULL ? (<+...x->fld...+>) : E
|
x@p1->fld
... when != \(x = E\|&x\)
x@p2 == NULL
... when any
)
@other_match exists@
expression match.x, E1, E2;
position match.p1,match.p2;
@@
(
x = E1
|
x
)
... when != \(x = E2\|&x\)
when != x@p1
x@p2
@other_match1 exists@
expression match.x, E2;
position match.p1,match.p2;
@@
... when != \(x = E2\|&x\)
when != x@p1
x@p2
@ script:python depends on !other_match && !other_match1@
p1 << match.p1;
p2 << match.p2;
@@
cocci.print_main("",p1)
cocci.print_sec("NULL test",p2)

View File

@ -0,0 +1,26 @@
// A variable is only initialized to a constant and is never used otherwise
//
// Confidence: High
// Copyright: (C) Gilles Muller, Julia Lawall, EMN, INRIA, DIKU. GPLv2.
// URL: https://coccinelle.gitlabpages.inria.fr/website/rules/unused.html
// Options:
@e@
identifier i;
position p;
type T;
@@
extern T i@p;
@@
type T;
identifier i;
constant C;
position p != e.p;
@@
- T i@p;
<+... when != i
- i = C;
...+>

View File

@ -0,0 +1,69 @@
@@
identifier Iter, Next, M, Data;
iterator name EINA_LIST_FOREACH;
iterator name EINA_LIST_REVERSE_FOREACH;
iterator name EINA_LIST_FREE;
iterator name EINA_INLIST_FOREACH;
iterator name EINA_INLIST_FOREACH_SAFE;
iterator name EINA_ITERATOR_FOREACH;
iterator name EINA_ARRAY_ITER_NEXT;
expression E,x, i;
position p1,p2;
statement S;
@@
(
EINA_INLIST_FOREACH(x, Data@p1) { ... when != break;
when forall
when strict
}
|
EINA_INLIST_FOREACH_SAFE(x, Data@p1) { ... when != break;
when forall
when strict
}
|
EINA_LIST_FOREACH(x, Iter@p1, Data@p1) { ... when != break;
when forall
when strict
}
|
EINA_LIST_REVERSE_FOREACH(x, Iter@p1, Data@p1) { ... when != break;
when forall
when strict
}
|
EINA_LIST_FREE(x, Data@p1) { ... when != break;
when forall
when strict
}
|
EINA_ARRAY_ITER_NEXT(x, i, Data@p1, Iter@p1) { ... when != break;
when forall
when strict
}
)
...
(
EINA_INLIST_FOREACH(x, Data) S
|
EINA_INLIST_FOREACH_SAFE(x, Data) S
|
EINA_LIST_FREE(x, Data) S
|
EINA_LIST_FOREACH(x, Iter, Data) S
|
EINA_LIST_REVERSE_FOREACH(x, Iter, Data) S
|
EINA_ARRAY_ITER_NEXT(x, i, Data, Iter) S
|
- *Next@p2
|
- *Iter@p2
|
- *Data@p2
|
- Data->M@p2
|
- E = Data@p2
)