mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
Merge branch 'kbuild/coccinelle' into kbuild/misc
This commit is contained in:
commit
6ff21517c0
258
Documentation/coccinelle.txt
Normal file
258
Documentation/coccinelle.txt
Normal file
@ -0,0 +1,258 @@
|
||||
Copyright 2010 Nicolas Palix <npalix@diku.dk>
|
||||
Copyright 2010 Julia Lawall <julia@diku.dk>
|
||||
Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr>
|
||||
|
||||
|
||||
Getting Coccinelle
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The semantic patches included in the kernel use the 'virtual rule'
|
||||
feature which was introduced in Coccinelle version 0.1.11.
|
||||
|
||||
Coccinelle (>=0.2.0) is available through the package manager
|
||||
of many distributions, e.g. :
|
||||
|
||||
- Debian (>=squeeze)
|
||||
- Fedora (>=13)
|
||||
- Ubuntu (>=10.04 Karmic Koala)
|
||||
- OpenSUSE
|
||||
- Arch Linux
|
||||
- NetBSD
|
||||
- FreeBSD
|
||||
|
||||
|
||||
You can get the latest version released from the Coccinelle homepage at
|
||||
http://coccinelle.lip6.fr/
|
||||
|
||||
Once you have it, run the following command:
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
as a regular user, and install it with
|
||||
|
||||
sudo make install
|
||||
|
||||
|
||||
Using Coccinelle on the Linux kernel
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A Coccinelle-specific target is defined in the top level
|
||||
Makefile. This target is named 'coccicheck' and calls the 'coccicheck'
|
||||
front-end in the 'scripts' directory.
|
||||
|
||||
Four modes are defined: report, patch, context, and org. The mode to
|
||||
use is specified by setting the MODE variable with 'MODE=<mode>'.
|
||||
|
||||
'report' generates a list in the following format:
|
||||
file:line:column-column: message
|
||||
|
||||
'patch' proposes a fix, when possible.
|
||||
|
||||
'context' highlights lines of interest and their context in a
|
||||
diff-like style.Lines of interest are indicated with '-'.
|
||||
|
||||
'org' generates a report in the Org mode format of Emacs.
|
||||
|
||||
Note that not all semantic patches implement all modes.
|
||||
|
||||
To make a report for every semantic patch, run the following command:
|
||||
|
||||
make coccicheck MODE=report
|
||||
|
||||
NB: The 'report' mode is the default one.
|
||||
|
||||
To produce patches, run:
|
||||
|
||||
make coccicheck MODE=patch
|
||||
|
||||
|
||||
The coccicheck target applies every semantic patch available in the
|
||||
subdirectories of 'scripts/coccinelle' to the entire Linux kernel.
|
||||
|
||||
For each semantic patch, a changelog message is proposed. It gives a
|
||||
description of the problem being checked by the semantic patch, and
|
||||
includes a reference to Coccinelle.
|
||||
|
||||
As any static code analyzer, Coccinelle produces false
|
||||
positives. Thus, reports must be carefully checked, and patches
|
||||
reviewed.
|
||||
|
||||
|
||||
Using Coccinelle with a single semantic patch
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The optional make variable COCCI can be used to check a single
|
||||
semantic patch. In that case, the variable must be initialized with
|
||||
the name of the semantic patch to apply.
|
||||
|
||||
For instance:
|
||||
|
||||
make coccicheck COCCI=<my_SP.cocci> MODE=patch
|
||||
or
|
||||
make coccicheck COCCI=<my_SP.cocci> MODE=report
|
||||
|
||||
|
||||
Proposing new semantic patches
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
New semantic patches can be proposed and submitted by kernel
|
||||
developers. For sake of clarity, they should be organized in the
|
||||
subdirectories of 'scripts/coccinelle/'.
|
||||
|
||||
|
||||
Detailed description of the 'report' mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
'report' generates a list in the following format:
|
||||
file:line:column-column: message
|
||||
|
||||
Example:
|
||||
|
||||
Running
|
||||
|
||||
make coccicheck MODE=report COCCI=scripts/coccinelle/err_cast.cocci
|
||||
|
||||
will execute the following part of the SmPL script.
|
||||
|
||||
<smpl>
|
||||
@r depends on !context && !patch && (org || report)@
|
||||
expression x;
|
||||
position p;
|
||||
@@
|
||||
|
||||
ERR_PTR@p(PTR_ERR(x))
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="ERR_CAST can be used with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
</smpl>
|
||||
|
||||
This SmPL excerpt generates entries on the standard output, as
|
||||
illustrated below:
|
||||
|
||||
/home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
|
||||
/home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
|
||||
/home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg
|
||||
|
||||
|
||||
Detailed description of the 'patch' mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When the 'patch' mode is available, it proposes a fix for each problem
|
||||
identified.
|
||||
|
||||
Example:
|
||||
|
||||
Running
|
||||
make coccicheck MODE=patch COCCI=scripts/coccinelle/err_cast.cocci
|
||||
|
||||
will execute the following part of the SmPL script.
|
||||
|
||||
<smpl>
|
||||
@ depends on !context && patch && !org && !report @
|
||||
expression x;
|
||||
@@
|
||||
|
||||
- ERR_PTR(PTR_ERR(x))
|
||||
+ ERR_CAST(x)
|
||||
</smpl>
|
||||
|
||||
This SmPL excerpt generates patch hunks on the standard output, as
|
||||
illustrated below:
|
||||
|
||||
diff -u -p a/crypto/ctr.c b/crypto/ctr.c
|
||||
--- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
|
||||
+++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
|
||||
@@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
|
||||
alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
|
||||
CRYPTO_ALG_TYPE_MASK);
|
||||
if (IS_ERR(alg))
|
||||
- return ERR_PTR(PTR_ERR(alg));
|
||||
+ return ERR_CAST(alg);
|
||||
|
||||
/* Block size must be >= 4 bytes. */
|
||||
err = -EINVAL;
|
||||
|
||||
Detailed description of the 'context' mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
'context' highlights lines of interest and their context
|
||||
in a diff-like style.
|
||||
|
||||
NOTE: The diff-like output generated is NOT an applicable patch. The
|
||||
intent of the 'context' mode is to highlight the important lines
|
||||
(annotated with minus, '-') and gives some surrounding context
|
||||
lines around. This output can be used with the diff mode of
|
||||
Emacs to review the code.
|
||||
|
||||
Example:
|
||||
|
||||
Running
|
||||
make coccicheck MODE=context COCCI=scripts/coccinelle/err_cast.cocci
|
||||
|
||||
will execute the following part of the SmPL script.
|
||||
|
||||
<smpl>
|
||||
@ depends on context && !patch && !org && !report@
|
||||
expression x;
|
||||
@@
|
||||
|
||||
* ERR_PTR(PTR_ERR(x))
|
||||
</smpl>
|
||||
|
||||
This SmPL excerpt generates diff hunks on the standard output, as
|
||||
illustrated below:
|
||||
|
||||
diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
|
||||
--- /home/user/linux/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
|
||||
+++ /tmp/nothing
|
||||
@@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
|
||||
alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
|
||||
CRYPTO_ALG_TYPE_MASK);
|
||||
if (IS_ERR(alg))
|
||||
- return ERR_PTR(PTR_ERR(alg));
|
||||
|
||||
/* Block size must be >= 4 bytes. */
|
||||
err = -EINVAL;
|
||||
|
||||
Detailed description of the 'org' mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
'org' generates a report in the Org mode format of Emacs.
|
||||
|
||||
Example:
|
||||
|
||||
Running
|
||||
make coccicheck MODE=org COCCI=scripts/coccinelle/err_cast.cocci
|
||||
|
||||
will execute the following part of the SmPL script.
|
||||
|
||||
<smpl>
|
||||
@r depends on !context && !patch && (org || report)@
|
||||
expression x;
|
||||
position p;
|
||||
@@
|
||||
|
||||
ERR_PTR@p(PTR_ERR(x))
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="ERR_CAST can be used with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
</smpl>
|
||||
|
||||
This SmPL excerpt generates Org entries on the standard output, as
|
||||
illustrated below:
|
||||
|
||||
* TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
|
||||
* TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
|
||||
* TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]
|
10
MAINTAINERS
10
MAINTAINERS
@ -1476,6 +1476,16 @@ M: Daniel Oliveira Nascimento <don@syst.com.br>
|
||||
S: Supported
|
||||
F: drivers/platform/x86/classmate-laptop.c
|
||||
|
||||
COCCINELLE/Semantic Patches (SmPL)
|
||||
M: Julia Lawall <julia@diku.dk>
|
||||
M: Gilles Muller <Gilles.Muller@lip6.fr>
|
||||
M: Nicolas Palix <npalix@diku.dk>
|
||||
L: cocci@diku.dk (moderated for non-subscribers)
|
||||
W: http://coccinelle.lip6.fr/
|
||||
S: Supported
|
||||
F: scripts/coccinelle/
|
||||
F: scripts/coccicheck
|
||||
|
||||
CODA FILE SYSTEM
|
||||
M: Jan Harkes <jaharkes@cs.cmu.edu>
|
||||
M: coda@cs.cmu.edu
|
||||
|
10
Makefile
10
Makefile
@ -412,7 +412,7 @@ endif
|
||||
# of make so .config is not included in this case either (for *config).
|
||||
|
||||
no-dot-config-targets := clean mrproper distclean \
|
||||
cscope TAGS tags help %docs check% \
|
||||
cscope TAGS tags help %docs check% coccicheck \
|
||||
include/linux/version.h headers_% \
|
||||
kernelrelease kernelversion
|
||||
|
||||
@ -1279,8 +1279,9 @@ help:
|
||||
@echo ' includecheck - Check for duplicate included header files'
|
||||
@echo ' export_report - List the usages of all exported symbols'
|
||||
@echo ' headers_check - Sanity check on exported headers'
|
||||
@echo ' headerdep - Detect inclusion cycles in headers'; \
|
||||
echo ''
|
||||
@echo ' headerdep - Detect inclusion cycles in headers'
|
||||
@$(MAKE) -f $(srctree)/scripts/Makefile.help checker-help
|
||||
@echo ''
|
||||
@echo 'Kernel packaging:'
|
||||
@$(MAKE) $(build)=$(package-dir) help
|
||||
@echo ''
|
||||
@ -1439,6 +1440,9 @@ versioncheck:
|
||||
-name '*.[hcS]' -type f -print | sort \
|
||||
| xargs $(PERL) -w $(srctree)/scripts/checkversion.pl
|
||||
|
||||
coccicheck:
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@
|
||||
|
||||
namespacecheck:
|
||||
$(PERL) $(srctree)/scripts/namespace.pl
|
||||
|
||||
|
3
scripts/Makefile.help
Normal file
3
scripts/Makefile.help
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
checker-help:
|
||||
@echo ' coccicheck - Check with Coccinelle.'
|
54
scripts/coccicheck
Executable file
54
scripts/coccicheck
Executable file
@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
SPATCH="`which ${SPATCH:=spatch}`"
|
||||
|
||||
if [ ! -x "$SPATCH" ]; then
|
||||
echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$MODE" = "" ] ; then
|
||||
echo 'You have not explicitly specify the mode to use. Fallback to "report".'
|
||||
echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
|
||||
echo 'Available modes are: report, patch, context, org'
|
||||
MODE="report"
|
||||
fi
|
||||
|
||||
echo ''
|
||||
echo 'Please check for false positives in the output before submitting a patch.'
|
||||
echo 'When using "patch" mode, carefully review the patch before submitting it.'
|
||||
echo ''
|
||||
|
||||
function coccinelle {
|
||||
COCCI="$1"
|
||||
DIR="$2"
|
||||
|
||||
OPT=`grep "Option" $COCCI | cut -d':' -f2`
|
||||
FILE=`echo $COCCI | sed "s|$DIR/||"`
|
||||
|
||||
echo "Processing `basename $COCCI` with option(s) \"$OPT\""
|
||||
echo 'Message example to submit a patch:'
|
||||
|
||||
sed -e '/\/\/\//!d' -e 's|^///||' $COCCI
|
||||
|
||||
echo ' The semantic patch that makes this change is available'
|
||||
echo " in $FILE."
|
||||
echo ''
|
||||
echo ' More information about semantic patching is available at'
|
||||
echo ' http://coccinelle.lip6.fr/'
|
||||
echo ''
|
||||
|
||||
# The option '-parse_cocci' can be used to syntaxically check the SmPL files.
|
||||
#
|
||||
# $SPATCH -D $MODE -very_quiet -parse_cocci $COCCI $OPT > /dev/null
|
||||
|
||||
$SPATCH -D $MODE -very_quiet -sp_file $COCCI $OPT -dir $DIR
|
||||
}
|
||||
|
||||
if [ "$COCCI" = "" ] ; then
|
||||
for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
|
||||
coccinelle $f $srctree;
|
||||
done
|
||||
else
|
||||
coccinelle $COCCI $srctree
|
||||
fi
|
67
scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
Normal file
67
scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
Normal file
@ -0,0 +1,67 @@
|
||||
///
|
||||
/// Casting (void *) value returned by kmalloc is useless
|
||||
/// as mentioned in Documentation/CodingStyle, Chap 14.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options: -no_includes -include_headers
|
||||
//
|
||||
// Keywords: kmalloc, kzalloc, kcalloc
|
||||
// Version min: < 2.6.12 kmalloc
|
||||
// Version min: < 2.6.12 kcalloc
|
||||
// Version min: 2.6.14 kzalloc
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on context@
|
||||
type T;
|
||||
@@
|
||||
|
||||
* (T *)
|
||||
\(kmalloc\|kzalloc\|kcalloc\)(...)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on patch@
|
||||
type T;
|
||||
@@
|
||||
|
||||
- (T *)
|
||||
\(kmalloc\|kzalloc\|kcalloc\)(...)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org and report mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r depends on org || report@
|
||||
type T;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
t << r.T;
|
||||
@@
|
||||
|
||||
coccilib.org.print_safe_todo(p[0], t)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
t << r.T;
|
||||
@@
|
||||
|
||||
msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t)
|
||||
coccilib.report.print_report(p[0], msg)
|
82
scripts/coccinelle/alloc/kzalloc-simple.cocci
Normal file
82
scripts/coccinelle/alloc/kzalloc-simple.cocci
Normal file
@ -0,0 +1,82 @@
|
||||
///
|
||||
/// kzalloc should be used rather than kmalloc followed by memset 0
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
|
||||
// Options: -no_includes -include_headers
|
||||
//
|
||||
// Keywords: kmalloc, kzalloc
|
||||
// Version min: < 2.6.12 kmalloc
|
||||
// Version min: 2.6.14 kzalloc
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on context@
|
||||
type T, T2;
|
||||
expression x;
|
||||
expression E1,E2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
* x = (T)kmalloc(E1,E2);
|
||||
if ((x==NULL) || ...) S
|
||||
* memset((T2)x,0,E1);
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on patch@
|
||||
type T, T2;
|
||||
expression x;
|
||||
expression E1,E2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
- x = (T)kmalloc(E1,E2);
|
||||
+ x = kzalloc(E1,E2);
|
||||
if ((x==NULL) || ...) S
|
||||
- memset((T2)x,0,E1);
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r depends on org || report@
|
||||
type T, T2;
|
||||
expression x;
|
||||
expression E1,E2;
|
||||
statement S;
|
||||
position p;
|
||||
@@
|
||||
|
||||
x = (T)kmalloc@p(E1,E2);
|
||||
if ((x==NULL) || ...) S
|
||||
memset((T2)x,0,E1);
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="%s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
293
scripts/coccinelle/deref_null.cocci
Normal file
293
scripts/coccinelle/deref_null.cocci
Normal file
@ -0,0 +1,293 @@
|
||||
///
|
||||
/// A variable is dereference under a NULL test.
|
||||
/// Even though it is know to be NULL.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments: -I ... -all_includes can give more complete results
|
||||
// Options:
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@initialize:python depends on !context && patch && !org && !report@
|
||||
|
||||
import sys
|
||||
print >> sys.stderr, "This semantic patch does not support the 'patch' mode."
|
||||
|
||||
@depends on patch@
|
||||
@@
|
||||
|
||||
this_rule_should_never_matches();
|
||||
|
||||
@ifm depends on !patch@
|
||||
expression *E;
|
||||
statement S1,S2;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...) S1 else S2
|
||||
|
||||
// The following two rules are separate, because both can match a single
|
||||
// expression in different ways
|
||||
@pr1 depends on !patch expression@
|
||||
expression *ifm.E;
|
||||
identifier f;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
(E != NULL && ...) ? <+...E->f@p1...+> : ...
|
||||
|
||||
@pr2 depends on !patch expression@
|
||||
expression *ifm.E;
|
||||
identifier f;
|
||||
position p2;
|
||||
@@
|
||||
|
||||
(
|
||||
(E != NULL) && ... && <+...E->f@p2...+>
|
||||
|
|
||||
(E == NULL) || ... || <+...E->f@p2...+>
|
||||
|
|
||||
sizeof(<+...E->f@p2...+>)
|
||||
)
|
||||
|
||||
// For org and report modes
|
||||
|
||||
@r depends on !context && !patch && (org || report) exists@
|
||||
expression subE <= ifm.E;
|
||||
expression *ifm.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr1.p1,pr2.p2};
|
||||
position ifm.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
return ...;
|
||||
}
|
||||
else S3
|
||||
|
||||
@script:python depends on !context && !patch && !org && report@
|
||||
p << r.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
cocci.include_match(False)
|
||||
|
||||
@script:python depends on !context && !patch && org && !report@
|
||||
p << r.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
cocci.print_main(msg_safe,p)
|
||||
cocci.include_match(False)
|
||||
|
||||
@s depends on !context && !patch && (org || report) exists@
|
||||
expression subE <= ifm.E;
|
||||
expression *ifm.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr1.p1,pr2.p2};
|
||||
position ifm.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
}
|
||||
else S3
|
||||
|
||||
@script:python depends on !context && !patch && !org && report@
|
||||
p << s.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
||||
@script:python depends on !context && !patch && org && !report@
|
||||
p << s.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
cocci.print_main(msg_safe,p)
|
||||
|
||||
// For context mode
|
||||
|
||||
@depends on context && !patch && !org && !report exists@
|
||||
expression subE <= ifm.E;
|
||||
expression *ifm.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr1.p1,pr2.p2};
|
||||
position ifm.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
* E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
return ...;
|
||||
}
|
||||
else S3
|
||||
|
||||
// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
|
||||
// It is need because the previous rule as already made a "change".
|
||||
|
||||
@ifm1 depends on !patch@
|
||||
expression *E;
|
||||
statement S1,S2;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...) S1 else S2
|
||||
|
||||
@pr11 depends on !patch expression@
|
||||
expression *ifm1.E;
|
||||
identifier f;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
(E != NULL && ...) ? <+...E->f@p1...+> : ...
|
||||
|
||||
@pr12 depends on !patch expression@
|
||||
expression *ifm1.E;
|
||||
identifier f;
|
||||
position p2;
|
||||
@@
|
||||
|
||||
(
|
||||
(E != NULL) && ... && <+...E->f@p2...+>
|
||||
|
|
||||
(E == NULL) || ... || <+...E->f@p2...+>
|
||||
|
|
||||
sizeof(<+...E->f@p2...+>)
|
||||
)
|
||||
|
||||
@depends on context && !patch && !org && !report exists@
|
||||
expression subE <= ifm1.E;
|
||||
expression *ifm1.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr11.p1,pr12.p2};
|
||||
position ifm1.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
* E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
}
|
||||
else S3
|
56
scripts/coccinelle/err_cast.cocci
Normal file
56
scripts/coccinelle/err_cast.cocci
Normal file
@ -0,0 +1,56 @@
|
||||
///
|
||||
/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...))
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options:
|
||||
//
|
||||
// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
|
||||
// Version min: 2.6.25
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
|
||||
@ depends on context && !patch && !org && !report@
|
||||
expression x;
|
||||
@@
|
||||
|
||||
* ERR_PTR(PTR_ERR(x))
|
||||
|
||||
@ depends on !context && patch && !org && !report @
|
||||
expression x;
|
||||
@@
|
||||
|
||||
- ERR_PTR(PTR_ERR(x))
|
||||
+ ERR_CAST(x)
|
||||
|
||||
@r depends on !context && !patch && (org || report)@
|
||||
expression x;
|
||||
position p;
|
||||
@@
|
||||
|
||||
ERR_PTR@p(PTR_ERR(x))
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="WARNING ERR_CAST can be used with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="WARNING: ERR_CAST can be used with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
93
scripts/coccinelle/resource_size.cocci
Normal file
93
scripts/coccinelle/resource_size.cocci
Normal file
@ -0,0 +1,93 @@
|
||||
///
|
||||
/// Use resource_size function on resource object
|
||||
/// instead of explicit computation.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options:
|
||||
//
|
||||
// Keywords: resource_size
|
||||
// Version min: 2.6.27 resource_size
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r_context depends on context && !patch && !org@
|
||||
struct resource *res;
|
||||
@@
|
||||
|
||||
* (res->end - res->start) + 1
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r_patch depends on !context && patch && !org@
|
||||
struct resource *res;
|
||||
@@
|
||||
|
||||
- (res->end - res->start) + 1
|
||||
+ resource_size(res)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
||||
@r_org depends on !context && !patch && (org || report)@
|
||||
struct resource *res;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(res->end@p - res->start) + 1
|
||||
|
||||
@rbad_org depends on !context && !patch && (org || report)@
|
||||
struct resource *res;
|
||||
position p != r_org.p;
|
||||
@@
|
||||
|
||||
res->end@p - res->start
|
||||
|
||||
@script:python depends on org@
|
||||
p << r_org.p;
|
||||
x << r_org.res;
|
||||
@@
|
||||
|
||||
msg="ERROR with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r_org.p;
|
||||
x << r_org.res;
|
||||
@@
|
||||
|
||||
msg="ERROR: Missing resource_size with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
||||
@script:python depends on org@
|
||||
p << rbad_org.p;
|
||||
x << rbad_org.res;
|
||||
@@
|
||||
|
||||
msg="WARNING with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << rbad_org.p;
|
||||
x << rbad_org.res;
|
||||
@@
|
||||
|
||||
msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
Loading…
Reference in New Issue
Block a user