Commit 408e057870c8680a50963b08f9f7efaa151a74ec

Authored by Linus Torvalds

Merge branch 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild

* 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild:
  scripts/coccinelle: improve the coverage of some semantic patches
  coccinelle: semantic patches related to devm_ functions (part 2)
  coccinelle: semantic patches related to devm_ functions (part 1)
  coccinelle.txt: update documentation to include M= option
  coccicheck: add M= option to control which dir is processed
  ctags: remove struct forward declarations
  scripts/tags.sh: Add Page flag function magic

Showing 16 changed files Side-by-side Diff

Documentation/coccinelle.txt
... ... @@ -102,9 +102,15 @@
102 102 make coccicheck COCCI=<my_SP.cocci> MODE=report
103 103  
104 104  
105   - Using Coccinelle on (modified) files
106   -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  105 + Controlling Which Files are Processed by Coccinelle
  106 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  107 +By default the entire kernel source tree is checked.
107 108  
  109 +To apply Coccinelle to a specific directory, M= can be used.
  110 +For example, to check drivers/net/wireless/ one may write:
  111 +
  112 + make coccicheck M=drivers/net/wireless/
  113 +
108 114 To apply Coccinelle on a file basis, instead of a directory basis, the
109 115 following command may be used:
110 116  
... ... @@ -9,14 +9,23 @@
9 9 # FLAGS="-ignore_unknown_options -very_quiet"
10 10 # OPTIONS=$*
11 11  
12   -# Workaround for Coccinelle < 0.2.3
13   - FLAGS="-I $srctree/include -very_quiet"
14   - shift $(( $# - 1 ))
15   - OPTIONS=$1
  12 + if [ "$KBUILD_EXTMOD" = "" ] ; then
  13 + # Workaround for Coccinelle < 0.2.3
  14 + FLAGS="-I $srctree/include -very_quiet"
  15 + shift $(( $# - 1 ))
  16 + OPTIONS=$1
  17 + else
  18 + echo M= is not currently supported when C=1 or C=2
  19 + exit 1
  20 + fi
16 21 else
17 22 ONLINE=0
18 23 FLAGS="-very_quiet"
19   - OPTIONS="-dir $srctree"
  24 + if [ "$KBUILD_EXTMOD" = "" ] ; then
  25 + OPTIONS="-dir $srctree"
  26 + else
  27 + OPTIONS="-dir $KBUILD_EXTMOD -patch $srctree -I $srctree/include -I $KBUILD_EXTMOD/include"
  28 + fi
20 29 fi
21 30  
22 31 if [ ! -x "$SPATCH" ]; then
scripts/coccinelle/api/devm_request_and_ioremap.cocci
  1 +/// Reimplement a call to devm_request_mem_region followed by a call to ioremap
  2 +/// or ioremap_nocache by a call to devm_request_and_ioremap.
  3 +/// Devm_request_and_ioremap was introduced in
  4 +/// 72f8c0bfa0de64c68ee59f40eb9b2683bffffbb0. It makes the code much more
  5 +/// concise.
  6 +///
  7 +///
  8 +// Confidence: High
  9 +// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. GPLv2.
  10 +// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. GPLv2.
  11 +// URL: http://coccinelle.lip6.fr/
  12 +// Comments:
  13 +// Options: -no_includes -include_headers
  14 +
  15 +virtual patch
  16 +virtual org
  17 +virtual report
  18 +virtual context
  19 +
  20 +@nm@
  21 +expression myname;
  22 +identifier i;
  23 +@@
  24 +
  25 +struct platform_driver i = { .driver = { .name = myname } };
  26 +
  27 +@depends on patch@
  28 +expression dev,res,size;
  29 +@@
  30 +
  31 +-if (!devm_request_mem_region(dev, res->start, size,
  32 +- \(res->name\|dev_name(dev)\))) {
  33 +- ...
  34 +- return ...;
  35 +-}
  36 +... when != res->start
  37 +(
  38 +-devm_ioremap(dev,res->start,size)
  39 ++devm_request_and_ioremap(dev,res)
  40 +|
  41 +-devm_ioremap_nocache(dev,res->start,size)
  42 ++devm_request_and_ioremap(dev,res)
  43 +)
  44 +... when any
  45 + when != res->start
  46 +
  47 +// this rule is separate from the previous one, because a single file can
  48 +// have multiple values of myname
  49 +@depends on patch@
  50 +expression dev,res,size;
  51 +expression nm.myname;
  52 +@@
  53 +
  54 +-if (!devm_request_mem_region(dev, res->start, size,myname)) {
  55 +- ...
  56 +- return ...;
  57 +-}
  58 +... when != res->start
  59 +(
  60 +-devm_ioremap(dev,res->start,size)
  61 ++devm_request_and_ioremap(dev,res)
  62 +|
  63 +-devm_ioremap_nocache(dev,res->start,size)
  64 ++devm_request_and_ioremap(dev,res)
  65 +)
  66 +... when any
  67 + when != res->start
  68 +
  69 +
  70 +@pb depends on org || report || context@
  71 +expression dev,res,size;
  72 +expression nm.myname;
  73 +position p1,p2;
  74 +@@
  75 +
  76 +*if
  77 + (!devm_request_mem_region@p1(dev, res->start, size,
  78 + \(res->name\|dev_name(dev)\|myname\))) {
  79 + ...
  80 + return ...;
  81 +}
  82 +... when != res->start
  83 +(
  84 +*devm_ioremap@p2(dev,res->start,size)
  85 +|
  86 +*devm_ioremap_nocache@p2(dev,res->start,size)
  87 +)
  88 +... when any
  89 + when != res->start
  90 +
  91 +@script:python depends on org@
  92 +p1 << pb.p1;
  93 +p2 << pb.p2;
  94 +@@
  95 +
  96 +cocci.print_main("INFO: replace by devm_request_and_ioremap",p1)
  97 +cocci.print_secs("",p2)
  98 +
  99 +@script:python depends on report@
  100 +p1 << pb.p1;
  101 +p2 << pb.p2;
  102 +@@
  103 +
  104 +msg = "INFO: devm_request_mem_region followed by ioremap on line %s can be replaced by devm_request_and_ioremap" % (p2[0].line)
  105 +coccilib.report.print_report(p1[0],msg)
scripts/coccinelle/api/kstrdup.cocci
1 1 /// Use kstrdup rather than duplicating its implementation
2 2 ///
3 3 // Confidence: High
4   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  4 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  5 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  6 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
7 7 // URL: http://coccinelle.lip6.fr/
8 8 // Comments:
9 9 // Options: -no_includes -include_headers
10 10  
11 11 virtual patch
  12 +virtual context
  13 +virtual org
  14 +virtual report
12 15  
13   -@@
  16 +@depends on patch@
14 17 expression from,to;
15 18 expression flag,E1,E2;
16 19 statement S;
... ... @@ -23,7 +26,7 @@
23 26 ... when != \(from = E2 \| to = E2 \)
24 27 - strcpy(to, from);
25 28  
26   -@@
  29 +@depends on patch@
27 30 expression x,from,to;
28 31 expression flag,E1,E2,E3;
29 32 statement S;
... ... @@ -37,4 +40,66 @@
37 40 if (to==NULL || ...) S
38 41 ... when != \(x = E3 \| from = E3 \| to = E3 \)
39 42 - memcpy(to, from, x);
  43 +
  44 +// ---------------------------------------------------------------------
  45 +
  46 +@r1 depends on !patch exists@
  47 +expression from,to;
  48 +expression flag,E1,E2;
  49 +statement S;
  50 +position p1,p2;
  51 +@@
  52 +
  53 +* to = kmalloc@p1(strlen(from) + 1,flag);
  54 + ... when != \(from = E1 \| to = E1 \)
  55 + if (to==NULL || ...) S
  56 + ... when != \(from = E2 \| to = E2 \)
  57 +* strcpy@p2(to, from);
  58 +
  59 +@r2 depends on !patch exists@
  60 +expression x,from,to;
  61 +expression flag,E1,E2,E3;
  62 +statement S;
  63 +position p1,p2;
  64 +@@
  65 +
  66 +* x = strlen(from) + 1;
  67 + ... when != \( x = E1 \| from = E1 \)
  68 +* to = \(kmalloc@p1\|kzalloc@p2\)(x,flag);
  69 + ... when != \(x = E2 \| from = E2 \| to = E2 \)
  70 + if (to==NULL || ...) S
  71 + ... when != \(x = E3 \| from = E3 \| to = E3 \)
  72 +* memcpy@p2(to, from, x);
  73 +
  74 +@script:python depends on org@
  75 +p1 << r1.p1;
  76 +p2 << r1.p2;
  77 +@@
  78 +
  79 +cocci.print_main("WARNING opportunity for kstrdep",p1)
  80 +cocci.print_secs("strcpy",p2)
  81 +
  82 +@script:python depends on org@
  83 +p1 << r2.p1;
  84 +p2 << r2.p2;
  85 +@@
  86 +
  87 +cocci.print_main("WARNING opportunity for kstrdep",p1)
  88 +cocci.print_secs("memcpy",p2)
  89 +
  90 +@script:python depends on report@
  91 +p1 << r1.p1;
  92 +p2 << r1.p2;
  93 +@@
  94 +
  95 +msg = "WARNING opportunity for kstrdep (strcpy on line %s)" % (p2[0].line)
  96 +coccilib.report.print_report(p1[0], msg)
  97 +
  98 +@script:python depends on report@
  99 +p1 << r2.p1;
  100 +p2 << r2.p2;
  101 +@@
  102 +
  103 +msg = "WARNING opportunity for kstrdep (memcpy on line %s)" % (p2[0].line)
  104 +coccilib.report.print_report(p1[0], msg)
scripts/coccinelle/api/memdup.cocci
1 1 /// Use kmemdup rather than duplicating its implementation
2 2 ///
3 3 // Confidence: High
4   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  4 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  5 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  6 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
7 7 // URL: http://coccinelle.lip6.fr/
8 8 // Comments:
9 9 // Options: -no_includes -include_headers
10 10  
11 11 virtual patch
  12 +virtual context
  13 +virtual org
  14 +virtual report
12 15  
13 16 @r1@
14 17 expression from,to;
... ... @@ -28,7 +31,7 @@
28 31 ... when != \( x = E1 \| from = E1 \)
29 32 to = \(kmalloc@p\|kzalloc@p\)(x,flag);
30 33  
31   -@@
  34 +@depends on patch@
32 35 expression from,to,size,flag;
33 36 position p != {r1.p,r2.p};
34 37 statement S;
... ... @@ -38,4 +41,27 @@
38 41 + to = kmemdup(from,size,flag);
39 42 if (to==NULL || ...) S
40 43 - memcpy(to, from, size);
  44 +
  45 +@r depends on !patch@
  46 +expression from,to,size,flag;
  47 +position p != {r1.p,r2.p};
  48 +statement S;
  49 +@@
  50 +
  51 +* to = \(kmalloc@p\|kzalloc@p\)(size,flag);
  52 + to = kmemdup(from,size,flag);
  53 + if (to==NULL || ...) S
  54 +* memcpy(to, from, size);
  55 +
  56 +@script:python depends on org@
  57 +p << r.p;
  58 +@@
  59 +
  60 +coccilib.org.print_todo(p[0], "WARNING opportunity for kmemdep")
  61 +
  62 +@script:python depends on report@
  63 +p << r.p;
  64 +@@
  65 +
  66 +coccilib.report.print_report(p[0], "WARNING opportunity for kmemdep")
scripts/coccinelle/api/memdup_user.cocci
1   -/// Use kmemdup_user rather than duplicating its implementation
  1 +/// Use memdup_user rather than duplicating its implementation
2 2 /// This is a little bit restricted to reduce false positives
3 3 ///
4 4 // Confidence: High
5   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
6   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
7   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  5 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  6 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  7 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
8 8 // URL: http://coccinelle.lip6.fr/
9 9 // Comments:
10 10 // Options: -no_includes -include_headers
11 11  
12 12 virtual patch
  13 +virtual context
  14 +virtual org
  15 +virtual report
13 16  
14   -@@
  17 +@depends on patch@
15 18 expression from,to,size,flag;
16   -position p;
17 19 identifier l1,l2;
18 20 @@
19 21  
20   -- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
  22 +- to = \(kmalloc\|kzalloc\)(size,flag);
21 23 + to = memdup_user(from,size);
22 24 if (
23 25 - to==NULL
... ... @@ -33,4 +35,27 @@
33 35 - -EFAULT
34 36 - ...+>
35 37 - }
  38 +
  39 +@r depends on !patch@
  40 +expression from,to,size,flag;
  41 +position p;
  42 +statement S1,S2;
  43 +@@
  44 +
  45 +* to = \(kmalloc@p\|kzalloc@p\)(size,flag);
  46 + if (to==NULL || ...) S1
  47 + if (copy_from_user(to, from, size) != 0)
  48 + S2
  49 +
  50 +@script:python depends on org@
  51 +p << r.p;
  52 +@@
  53 +
  54 +coccilib.org.print_todo(p[0], "WARNING opportunity for memdep_user")
  55 +
  56 +@script:python depends on report@
  57 +p << r.p;
  58 +@@
  59 +
  60 +coccilib.report.print_report(p[0], "WARNING opportunity for memdep_user")
scripts/coccinelle/free/devm_free.cocci
  1 +/// Find uses of standard freeing functons on values allocated using devm_
  2 +/// functions. Values allocated using the devm_functions are freed when
  3 +/// the device is detached, and thus the use of the standard freeing
  4 +/// function would cause a double free.
  5 +/// See Documentation/driver-model/devres.txt for more information.
  6 +///
  7 +/// A difficulty of detecting this problem is that the standard freeing
  8 +/// function might be called from a different function than the one
  9 +/// containing the allocation function. It is thus necessary to make the
  10 +/// connection between the allocation function and the freeing function.
  11 +/// Here this is done using the specific argument text, which is prone to
  12 +/// false positives. There is no rule for the request_region and
  13 +/// request_mem_region variants because this heuristic seems to be a bit
  14 +/// less reliable in these cases.
  15 +///
  16 +// Confidence: Moderate
  17 +// Copyright: (C) 2011 Julia Lawall, INRIA/LIP6. GPLv2.
  18 +// Copyright: (C) 2011 Gilles Muller, INRIA/LiP6. GPLv2.
  19 +// URL: http://coccinelle.lip6.fr/
  20 +// Comments:
  21 +// Options: -no_includes -include_headers
  22 +
  23 +virtual org
  24 +virtual report
  25 +virtual context
  26 +
  27 +@r depends on context || org || report@
  28 +expression x;
  29 +@@
  30 +
  31 +(
  32 + x = devm_kzalloc(...)
  33 +|
  34 + x = devm_request_irq(...)
  35 +|
  36 + x = devm_ioremap(...)
  37 +|
  38 + x = devm_ioremap_nocache(...)
  39 +|
  40 + x = devm_ioport_map(...)
  41 +)
  42 +
  43 +@pb@
  44 +expression r.x;
  45 +position p;
  46 +@@
  47 +
  48 +(
  49 +* kfree@p(x)
  50 +|
  51 +* free_irq@p(x)
  52 +|
  53 +* iounmap@p(x)
  54 +|
  55 +* ioport_unmap@p(x)
  56 +)
  57 +
  58 +@script:python depends on org@
  59 +p << pb.p;
  60 +@@
  61 +
  62 +msg="WARNING: invalid free of devm_ allocated data"
  63 +coccilib.org.print_todo(p[0], msg)
  64 +
  65 +@script:python depends on report@
  66 +p << pb.p;
  67 +@@
  68 +
  69 +msg="WARNING: invalid free of devm_ allocated data"
  70 +coccilib.report.print_report(p[0], msg)
scripts/coccinelle/free/kfree.cocci
... ... @@ -5,9 +5,9 @@
5 5 //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
6 6 ///
7 7 // Confidence: Moderate
8   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  8 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  9 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  10 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
11 11 // URL: http://coccinelle.lip6.fr/
12 12 // Comments:
13 13 // Options: -no_includes -include_headers
... ... @@ -23,7 +23,7 @@
23 23 kfree@p1(E)
24 24  
25 25 @print expression@
26   -constant char *c;
  26 +constant char [] c;
27 27 expression free.E,E2;
28 28 type T;
29 29 position p;
... ... @@ -37,6 +37,10 @@
37 37 |
38 38 E@p != E2
39 39 |
  40 + E2 == E@p
  41 +|
  42 + E2 != E@p
  43 +|
40 44 !E@p
41 45 |
42 46 E@p || ...
... ... @@ -113,6 +117,6 @@
113 117 p2 << r.p2;
114 118 @@
115 119  
116   -msg = "reference preceded by free on line %s" % (p1[0].line)
  120 +msg = "ERROR: reference preceded by free on line %s" % (p1[0].line)
117 121 coccilib.report.print_report(p2[0],msg)
scripts/coccinelle/iterators/fen.cocci
... ... @@ -2,16 +2,19 @@
2 2 /// is no point to call of_node_put on the final value.
3 3 ///
4 4 // Confidence: High
5   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
6   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
7   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  5 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  6 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  7 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
8 8 // URL: http://coccinelle.lip6.fr/
9 9 // Comments:
10 10 // Options: -no_includes -include_headers
11 11  
12 12 virtual patch
  13 +virtual context
  14 +virtual org
  15 +virtual report
13 16  
14   -@@
  17 +@depends on patch@
15 18 iterator name for_each_node_by_name;
16 19 expression np,E;
17 20 identifier l;
... ... @@ -24,7 +27,7 @@
24 27 ... when != np = E
25 28 - of_node_put(np);
26 29  
27   -@@
  30 +@depends on patch@
28 31 iterator name for_each_node_by_type;
29 32 expression np,E;
30 33 identifier l;
... ... @@ -37,7 +40,7 @@
37 40 ... when != np = E
38 41 - of_node_put(np);
39 42  
40   -@@
  43 +@depends on patch@
41 44 iterator name for_each_compatible_node;
42 45 expression np,E;
43 46 identifier l;
... ... @@ -50,7 +53,7 @@
50 53 ... when != np = E
51 54 - of_node_put(np);
52 55  
53   -@@
  56 +@depends on patch@
54 57 iterator name for_each_matching_node;
55 58 expression np,E;
56 59 identifier l;
... ... @@ -62,4 +65,60 @@
62 65 }
63 66 ... when != np = E
64 67 - of_node_put(np);
  68 +
  69 +// ----------------------------------------------------------------------
  70 +
  71 +@r depends on !patch forall@
  72 +//iterator name for_each_node_by_name;
  73 +//iterator name for_each_node_by_type;
  74 +//iterator name for_each_compatible_node;
  75 +//iterator name for_each_matching_node;
  76 +expression np,E;
  77 +identifier l;
  78 +position p1,p2;
  79 +@@
  80 +
  81 +(
  82 +*for_each_node_by_name@p1(np,...)
  83 +{
  84 + ... when != break;
  85 + when != goto l;
  86 +}
  87 +|
  88 +*for_each_node_by_type@p1(np,...)
  89 +{
  90 + ... when != break;
  91 + when != goto l;
  92 +}
  93 +|
  94 +*for_each_compatible_node@p1(np,...)
  95 +{
  96 + ... when != break;
  97 + when != goto l;
  98 +}
  99 +|
  100 +*for_each_matching_node@p1(np,...)
  101 +{
  102 + ... when != break;
  103 + when != goto l;
  104 +}
  105 +)
  106 +... when != np = E
  107 +* of_node_put@p2(np);
  108 +
  109 +@script:python depends on org@
  110 +p1 << r.p1;
  111 +p2 << r.p2;
  112 +@@
  113 +
  114 +cocci.print_main("unneeded of_node_put",p2)
  115 +cocci.print_secs("iterator",p1)
  116 +
  117 +@script:python depends on report@
  118 +p1 << r.p1;
  119 +p2 << r.p2;
  120 +@@
  121 +
  122 +msg = "ERROR: of_node_put not needed after iterator on line %s" % (p1[0].line)
  123 +coccilib.report.print_report(p2[0], msg)
scripts/coccinelle/iterators/itnull.cocci
1 1 /// Many iterators have the property that the first argument is always bound
2   -/// to a real list element, never NULL. False positives arise for some
3   -/// iterators that do not have this property, or in cases when the loop
4   -/// cursor is reassigned. The latter should only happen when the matched
5   -/// code is on the way to a loop exit (break, goto, or return).
  2 +/// to a real list element, never NULL.
  3 +//# False positives arise for some iterators that do not have this property,
  4 +//# or in cases when the loop cursor is reassigned. The latter should only
  5 +//# happen when the matched code is on the way to a loop exit (break, goto,
  6 +//# or return).
6 7 ///
7 8 // Confidence: Moderate
8   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
9   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
10   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  9 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  10 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  11 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
11 12 // URL: http://coccinelle.lip6.fr/
12 13 // Comments:
13 14 // Options: -no_includes -include_headers
14 15  
15 16 virtual patch
  17 +virtual context
  18 +virtual org
  19 +virtual report
16 20  
17   -@@
  21 +@depends on patch@
18 22 iterator I;
19 23 expression x,E,E1,E2;
20 24 statement S,S1,S2;
... ... @@ -56,4 +60,36 @@
56 60 + )
57 61 )
58 62 ...> }
  63 +
  64 +@r depends on !patch exists@
  65 +iterator I;
  66 +expression x,E;
  67 +position p1,p2;
  68 +@@
  69 +
  70 +*I@p1(x,...)
  71 +{ ... when != x = E
  72 +(
  73 +* x@p2 == NULL
  74 +|
  75 +* x@p2 != NULL
  76 +)
  77 + ... when any
  78 +}
  79 +
  80 +@script:python depends on org@
  81 +p1 << r.p1;
  82 +p2 << r.p2;
  83 +@@
  84 +
  85 +cocci.print_main("iterator-bound variable",p1)
  86 +cocci.print_secs("useless NULL test",p2)
  87 +
  88 +@script:python depends on report@
  89 +p1 << r.p1;
  90 +p2 << r.p2;
  91 +@@
  92 +
  93 +msg = "ERROR: iterator variable bound on line %s cannot be NULL" % (p1[0].line)
  94 +coccilib.report.print_report(p2[0], msg)
scripts/coccinelle/locks/call_kern.cocci
1 1 /// Find functions that refer to GFP_KERNEL but are called with locks held.
2   -/// The proposed change of converting the GFP_KERNEL is not necessarily the
3   -/// correct one. It may be desired to unlock the lock, or to not call the
4   -/// function under the lock in the first place.
  2 +//# The proposed change of converting the GFP_KERNEL is not necessarily the
  3 +//# correct one. It may be desired to unlock the lock, or to not call the
  4 +//# function under the lock in the first place.
5 5 ///
6 6 // Confidence: Moderate
7   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
8   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
9   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  7 +// Copyright: (C) 2012 Nicolas Palix. GPLv2.
  8 +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
  9 +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
10 10 // URL: http://coccinelle.lip6.fr/
11 11 // Comments:
12 12 // Options: -no_includes -include_headers
13 13  
14 14 virtual patch
  15 +virtual context
  16 +virtual org
  17 +virtual report
15 18  
16 19 @gfp exists@
17 20 identifier fn;
18 21  
19 22  
20 23  
21 24  
22 25  
23 26  
24 27  
25 28  
26 29  
27 30  
... ... @@ -32,28 +35,29 @@
32 35 ... when any
33 36 }
34 37  
35   -@locked@
  38 +@locked exists@
36 39 identifier gfp.fn;
  40 +position p1,p2;
37 41 @@
38 42  
39 43 (
40   -read_lock_irq
  44 +read_lock_irq@p1
41 45 |
42   -write_lock_irq
  46 +write_lock_irq@p1
43 47 |
44   -read_lock_irqsave
  48 +read_lock_irqsave@p1
45 49 |
46   -write_lock_irqsave
  50 +write_lock_irqsave@p1
47 51 |
48   -spin_lock
  52 +spin_lock@p1
49 53 |
50   -spin_trylock
  54 +spin_trylock@p1
51 55 |
52   -spin_lock_irq
  56 +spin_lock_irq@p1
53 57 |
54   -spin_lock_irqsave
  58 +spin_lock_irqsave@p1
55 59 |
56   -local_irq_disable
  60 +local_irq_disable@p1
57 61 )
58 62 (...)
59 63 ... when != read_unlock_irq(...)
60 64  
61 65  
... ... @@ -64,12 +68,39 @@
64 68 when != spin_unlock_irq(...)
65 69 when != spin_unlock_irqrestore(...)
66 70 when != local_irq_enable(...)
67   -fn(...)
  71 +fn@p2(...)
68 72  
69   -@depends on locked@
  73 +@depends on locked && patch@
70 74 position gfp.p;
71 75 @@
72 76  
73 77 - GFP_KERNEL@p
74 78 + GFP_ATOMIC
  79 +
  80 +@depends on locked && !patch@
  81 +position gfp.p;
  82 +@@
  83 +
  84 +* GFP_KERNEL@p
  85 +
  86 +@script:python depends on !patch && org@
  87 +p << gfp.p;
  88 +fn << gfp.fn;
  89 +p1 << locked.p1;
  90 +p2 << locked.p2;
  91 +@@
  92 +
  93 +cocci.print_main("lock",p1)
  94 +cocci.print_secs("call",p2)
  95 +cocci.print_secs("GFP_KERNEL",p)
  96 +
  97 +@script:python depends on !patch && report@
  98 +p << gfp.p;
  99 +fn << gfp.fn;
  100 +p1 << locked.p1;
  101 +p2 << locked.p2;
  102 +@@
  103 +
  104 +msg = "ERROR: function %s called on line %s inside lock on line %s but uses GFP_KERNEL" % (fn,p2[0].line,p1[0].line)
  105 +coccilib.report.print_report(p[0], msg)
scripts/coccinelle/locks/flags.cocci
1 1 /// Find nested lock+irqsave functions that use the same flags variables
2 2 ///
3 3 // Confidence: High
4   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  4 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  5 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  6 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
7 7 // URL: http://coccinelle.lip6.fr/
8 8 // Comments:
9 9 // Options: -no_includes -include_headers
... ... @@ -12,7 +12,7 @@
12 12 virtual org
13 13 virtual report
14 14  
15   -@r@
  15 +@r exists@
16 16 expression lock1,lock2,flags;
17 17 position p1,p2;
18 18 @@
... ... @@ -39,7 +39,7 @@
39 39 write_lock_irqsave@p2(lock2,flags)
40 40 )
41 41  
42   -@d@
  42 +@d exists@
43 43 expression f <= r.flags;
44 44 expression lock1,lock2,flags;
45 45 position r.p1, r.p2;
... ... @@ -76,6 +76,6 @@
76 76 p2 << r.p2;
77 77 @@
78 78  
79   -msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line)
  79 +msg="ERROR: nested lock+irqsave that reuses flags from line %s." % (p1[0].line)
80 80 coccilib.report.print_report(p2[0], msg)
scripts/coccinelle/locks/mini_lock.cocci
... ... @@ -6,13 +6,14 @@
6 6 /// function call that releases the lock.
7 7 ///
8 8 // Confidence: Moderate
9   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
10   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
11   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  9 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  10 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  11 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
12 12 // URL: http://coccinelle.lip6.fr/
13 13 // Comments:
14 14 // Options: -no_includes -include_headers
15 15  
  16 +virtual context
16 17 virtual org
17 18 virtual report
18 19  
... ... @@ -57,7 +58,7 @@
57 58  
58 59 for(...;...;...) { <+... return@r ...; ...+> }
59 60  
60   -@err@
  61 +@err exists@
61 62 expression E1;
62 63 position prelocked.p;
63 64 position up != prelocked.p1;
64 65  
65 66  
... ... @@ -65,14 +66,14 @@
65 66 identifier lock,unlock;
66 67 @@
67 68  
68   -lock(E1@p,...);
  69 +*lock(E1@p,...);
69 70 <+... when != E1
70 71 if (...) {
71 72 ... when != E1
72   - return@r ...;
  73 +* return@r ...;
73 74 }
74 75 ...+>
75   -unlock@up(E1,...);
  76 +*unlock@up(E1,...);
76 77  
77 78 @script:python depends on org@
78 79 p << prelocked.p1;
scripts/coccinelle/misc/doubleinit.cocci
... ... @@ -3,9 +3,9 @@
3 3 /// initialization.
4 4 ///
5 5 // Confidence: Low
6   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
7   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
8   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  6 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  7 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  8 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
9 9 // URL: http://coccinelle.lip6.fr/
10 10 // Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise
11 11 // Options: -no_includes -include_headers
... ... @@ -49,6 +49,6 @@
49 49 @@
50 50  
51 51 if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)):
52   - msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line)
  52 + msg = "%s: first occurrence line %s, second occurrence line %s" % (fld,ps[0].line,pr[0].line)
53 53 coccilib.report.print_report(p0[0],msg)
scripts/coccinelle/null/eno.cocci
1 1 /// The various basic memory allocation functions don't return ERR_PTR
2 2 ///
3 3 // Confidence: High
4   -// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
5   -// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
6   -// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
  4 +// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2.
  5 +// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2.
  6 +// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2.
7 7 // URL: http://coccinelle.lip6.fr/
8 8 // Comments:
9 9 // Options: -no_includes -include_headers
10 10  
11 11 virtual patch
  12 +virtual context
  13 +virtual org
  14 +virtual report
12 15  
13   -@@
  16 +@depends on patch@
14 17 expression x,E;
15 18 @@
16 19  
... ... @@ -18,4 +21,29 @@
18 21 ... when != x = E
19 22 - IS_ERR(x)
20 23 + !x
  24 +
  25 +@r depends on !patch exists@
  26 +expression x,E;
  27 +position p1,p2;
  28 +@@
  29 +
  30 +*x = \(kmalloc@p1\|kzalloc@p1\|kcalloc@p1\|kmem_cache_alloc@p1\|kmem_cache_zalloc@p1\|kmem_cache_alloc_node@p1\|kmalloc_node@p1\|kzalloc_node@p1\)(...)
  31 +... when != x = E
  32 +* IS_ERR@p2(x)
  33 +
  34 +@script:python depends on org@
  35 +p1 << r.p1;
  36 +p2 << r.p2;
  37 +@@
  38 +
  39 +cocci.print_main("alloc call",p1)
  40 +cocci.print_secs("IS_ERR that should be NULL tests",p2)
  41 +
  42 +@script:python depends on report@
  43 +p1 << r.p1;
  44 +p2 << r.p2;
  45 +@@
  46 +
  47 +msg = "ERROR: allocation function on line %s returns NULL not ERR_PTR on failure" % (p1[0].line)
  48 +coccilib.report.print_report(p2[0], msg)
... ... @@ -132,7 +132,28 @@
132 132 --regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \
133 133 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
134 134 --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
135   - --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/'
  135 + --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' \
  136 + --regex-c++='/PAGEFLAG\(([^,)]*).*/Page\1/' \
  137 + --regex-c++='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \
  138 + --regex-c++='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \
  139 + --regex-c++='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \
  140 + --regex-c++='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \
  141 + --regex-c++='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \
  142 + --regex-c++='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \
  143 + --regex-c++='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
  144 + --regex-c++='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
  145 + --regex-c++='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \
  146 + --regex-c++='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
  147 + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \
  148 + --regex-c++='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
  149 + --regex-c++='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \
  150 + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \
  151 + --regex-c++='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \
  152 + --regex-c++='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \
  153 + --regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \
  154 + --regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \
  155 + --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
  156 + --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/'
136 157  
137 158 all_kconfigs | xargs $1 -a \
138 159 --langdef=kconfig --language-force=kconfig \
... ... @@ -146,6 +167,8 @@
146 167 --langdef=dotconfig --language-force=dotconfig \
147 168 --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'
148 169  
  170 + # Remove structure forward declarations.
  171 + LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' tags
149 172 }
150 173  
151 174 emacs()
... ... @@ -154,7 +177,28 @@
154 177 --regex='/^(ENTRY|_GLOBAL)(\([^)]*\)).*/\2/' \
155 178 --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \
156 179 --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \
157   - --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/'
  180 + --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' \
  181 + --regex='/PAGEFLAG\(([^,)]*).*/Page\1/' \
  182 + --regex='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \
  183 + --regex='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \
  184 + --regex='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \
  185 + --regex='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \
  186 + --regex='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \
  187 + --regex='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \
  188 + --regex='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
  189 + --regex='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
  190 + --regex='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \
  191 + --regex='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
  192 + --regex='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \
  193 + --regex='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
  194 + --regex='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \
  195 + --regex='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \
  196 + --regex='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \
  197 + --regex='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \
  198 + --regex='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \
  199 + --regex='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \
  200 + --regex='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
  201 + --regex='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/'
158 202  
159 203 all_kconfigs | xargs $1 -a \
160 204 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'