Skip to content

Commit

Permalink
scripts: add coccinelle
Browse files Browse the repository at this point in the history
  • Loading branch information
dimmus committed Oct 17, 2023
1 parent bcad318 commit a2dd5ff
Show file tree
Hide file tree
Showing 13 changed files with 529 additions and 0 deletions.
18 changes: 18 additions & 0 deletions scripts/coccinelle/andconst.cocci
Original file line number Diff line number Diff line change
@@ -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
)
34 changes: 34 additions & 0 deletions scripts/coccinelle/bad_return_type.cocci
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@@
type T, B != T;
identifier func, i;
expression E;
@@

T func (...) {
...
(
T i;
|
T i = E;
|
static B i;
|
static B i = E;
|
-B i;
+T i;
|
-B i = E;
+T i = E;
)
<+...
(
return i;
|
return (T) i;
)
...+>
}



51 changes: 51 additions & 0 deletions scripts/coccinelle/badzero.cocci
Original file line number Diff line number Diff line change
@@ -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
)
39 changes: 39 additions & 0 deletions scripts/coccinelle/coccicheck.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/sh
set -eu

read -p "Type the path to the testing folder [src/bin]: " path
if [ -z $path ]; then
path='src/bin'
else
path=$path
fi

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
macros.cocci
"

HAS_ERROR=0
for f in $COCCI_FILES; do
OPTIONS=""
if [ "$f" = "macros.cocci" ]; then
OPTIONS="--defined DIV_ROUND_UP --defined ROUND_UP --defined MIN --defined MAX"
fi
CMD="spatch --timeout 200 --very-quiet --cocci-file scripts/coccinelle/$f --include-headers --dir $path $OPTIONS"
OUT=$($CMD)
echo "$CMD"
if [ -n "$OUT" ]; then
echo "$OUT"
HAS_ERROR=1
fi
done
exit $HAS_ERROR
17 changes: 17 additions & 0 deletions scripts/coccinelle/continue.cocci
Original file line number Diff line number Diff line change
@@ -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;
}
}
15 changes: 15 additions & 0 deletions scripts/coccinelle/free_stack.cocci
Original file line number Diff line number Diff line change
@@ -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);
)
38 changes: 38 additions & 0 deletions scripts/coccinelle/macros.cocci
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// DIV_ROUND_UP
@@
expression n, d;
@@
(
- (((n + d) - 1) / d)
+ DIV_ROUND_UP(n, d)
|
- ((n + (d - 1)) / d)
+ DIV_ROUND_UP(n, d)
)

// ROUND_UP
@@
expression n, d;
@@
(
- ((((n + d) - 1) / d) * d)
+ ROUND_UP(n, d)
|
- (((n + (d - 1)) / d) * d)
+ ROUND_UP(n, d)
|
- (DIV_ROUND_UP(n,d) * d)
+ ROUND_UP(n, d)
)

// MIN / MAX
@@
expression x, y;
@@
(
- (((x) > (y)) ? (y) : (x))
+ MIN(x, y)
|
- (((x) > (y)) ? (x) : (y))
+ MAX(x, y)
)
38 changes: 38 additions & 0 deletions scripts/coccinelle/mutex.cocci
Original file line number Diff line number Diff line change
@@ -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)
//)
14 changes: 14 additions & 0 deletions scripts/coccinelle/notand.cocci
Original file line number Diff line number Diff line change
@@ -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)
)
104 changes: 104 additions & 0 deletions scripts/coccinelle/notnull.cocci
Original file line number Diff line number Diff line change
@@ -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)
Loading

0 comments on commit a2dd5ff

Please sign in to comment.