1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #6946 from kaspar030/add_coccinelle_testing

dist: tools: add coccinelle scripts
This commit is contained in:
Martine Lenders 2017-05-13 08:37:34 +02:00 committed by GitHub
commit 5226a08e2a
9 changed files with 289 additions and 1 deletions

View File

@ -89,6 +89,7 @@ then
run ./dist/tools/externc/check.sh
run ./dist/tools/cppcheck/check.sh
run ./dist/tools/pr_check/pr_check.sh ${CI_BASE_BRANCH}
run ./dist/tools/coccinelle/check.sh
exit $RESULT
fi

View File

@ -8,7 +8,7 @@
changed_files() {
: ${FILEREGEX:='\.([CcHh]|[ch]pp)$'}
: ${EXCLUDE:='^(.+/include/vendor/)'}
: ${EXCLUDE:='^(.+/include/vendor/|dist/tools/coccinelle/include)'}
: ${DIFFFILTER:='ACMR'}
DIFFFILTER="--diff-filter=${DIFFFILTER}"

View File

@ -58,6 +58,17 @@ cppcheck_version() {
printf "%s" "$ver"
}
spatch_version() {
local cmd="spatch"
if command -v "$cmd" 2>&1 >/dev/null; then
ver=$("$cmd" --version | head -n 1)
else
ver="missing"
fi
printf "%s" "$ver"
}
printf "%s\n" "Installed toolchain versions"
printf "%s\n" "----------------------------"
VER=$(gcc --version | head -n 1)
@ -79,4 +90,5 @@ for p in avr; do
printf "%20s: %s\n" "$p-libc" "$(avr_libc_version "$p")"
done
printf "%20s: %s\n" "cppcheck" "$(cppcheck_version)"
printf "%20s: %s\n" "coccinelle" "$(spatch_version)"
exit 0

78
dist/tools/coccinelle/check.sh vendored Executable file
View File

@ -0,0 +1,78 @@
#!/bin/sh
# Copyright 2017 Kaspar Schleiser <kaspar@schleiser.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
: ${RIOTBASE:=$(pwd)}
. ${RIOTBASE}/dist/tools/ci/changed_files.sh
EXIT_CODE=0
filter() {
if [ $COCCINELLE_QUIET -eq 0 ]; then
cat
else
grep '^---' | cut -f 2 -d ' '
fi
}
indent() {
sed 's/^/ /g'
}
coccinelle_checkone() {
OUT="$(spatch --very-quiet \
--macro-file-builtins ${RIOTBASE}/dist/tools/coccinelle/include/riot-standard.h \
--sp-file $patch ${FILES} | filter)"
if [ -n "$OUT" ]; then
if [ $COCCINELLE_QUIET -eq 1 ]; then
echo "$patch:"
echo "$OUT" | indent
if [ COCCINELLE_WARNONLY -eq 0 ]; then
EXIT_CODE=1
fi
else
echo "$OUT"
fi
fi
}
coccinelle_checkall() {
local dir="$1"
local warn="${2:-0}"
[ -d "$dir" ] || {
echo "$0: coccinelle_checkall(): $dir doesn't exist!"
exit 1
}
for patch in $dir/*; do
coccinelle_checkone $patch
done
}
: ${FILES:=$(FILEREGEX='\.c$' changed_files)}
if [ -z "${FILES}" ]; then
exit
fi
: ${COCCINELLE_QUIET:=0}
if [ -z "$*" ]; then
coccinelle_checkall ${RIOTBASE}/dist/tools/coccinelle/force
COCCINELLE_WARNONLY=1 \
coccinelle_checkall ${RIOTBASE}/dist/tools/coccinelle/warn
else
for patch in "$@"; do
coccinelle_checkone "$patch"
done
fi
exit $EXIT_CODE

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: http://coccinelle.lip6.fr/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,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: http://coccinelle.lip6.fr/rules/continue.html
// Options:
@@
@@
for (...;...;...) {
...
if (...) {
...
- continue;
}
}

View File

@ -0,0 +1,25 @@
// remove unused static property of function-local static variable
// (from Julia Lawall, see https://lists.riot-os.org/pipermail/devel/2017-May/005133.html)
@bad exists@
position p;
identifier x;
type T;
@@
static T x@p;
...
x = <+...x...+>
@@
identifier x;
expression e;
type T;
position p != bad.p;
@@
-static
T x@p;
... when != x
when strict
?x = e;

View File

@ -0,0 +1 @@
#define LL_SEARCH_SCALAR(pkt, tcp, type, GNRC_NETTYPE_TCP) tcp = XXX

103
dist/tools/coccinelle/warn/notnull.cocci vendored Normal file
View File

@ -0,0 +1,103 @@
// 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: http://coccinelle.lip6.fr/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)