summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-07-06 11:24:14 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-07-06 11:24:14 -0700
commit76e2d16bd5d0193f891a0e30f14ef5c8c370bc8f (patch)
treed36e9159bcb9c8760a75c6bebdcf51aaa434d4e5
parent8e4f3e15175ffab5d2126dc8e7c8cfcc1654a5aa (diff)
parent5e5234462756a39e56f4182694f47ec72b5abe52 (diff)
Merge branch 'for-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux
Pull coccinelle updates from Julia Lawall: "There are two new semantic patches: - minmax: To use min and max instead of ? : - swap: To use swap when possible Some other semantic patches have been updated to better conform to Linux kernel developer expectations or to make the explanation message more clear. Finally, there is a fix for the coccicheck script" * 'for-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/jlawall/linux: coccinelle: api: remove kobj_to_dev.cocci script scripts: coccicheck: fix troubles on non-English builds coccinelle: misc: minmax: suppress patch generation for err returns drop unneeded *s coccinelle: irqf_oneshot: reduce the severity due to false positives coccinelle: misc: add swap script coccinelle: misc: update uninitialized_var.cocci documentation coccinelle: misc: restrict patch mode in flexible_array.cocci coccinelle: misc: add minmax script
-rwxr-xr-xscripts/coccicheck2
-rw-r--r--scripts/coccinelle/api/kobj_to_dev.cocci45
-rw-r--r--scripts/coccinelle/free/kfree.cocci12
-rw-r--r--scripts/coccinelle/misc/flexible_array.cocci23
-rw-r--r--scripts/coccinelle/misc/irqf_oneshot.cocci4
-rw-r--r--scripts/coccinelle/misc/minmax.cocci222
-rw-r--r--scripts/coccinelle/misc/swap.cocci122
-rw-r--r--scripts/coccinelle/misc/uninitialized_var.cocci15
8 files changed, 384 insertions, 61 deletions
diff --git a/scripts/coccicheck b/scripts/coccicheck
index 65fee63aeadb..caba0bff6da7 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -87,7 +87,7 @@ else
fi
# Use only one thread per core by default if hyperthreading is enabled
- THREADS_PER_CORE=$(lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]")
+ THREADS_PER_CORE=$(LANG=C lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]")
if [ -z "$J" ]; then
NPROC=$(getconf _NPROCESSORS_ONLN)
if [ $THREADS_PER_CORE -gt 1 -a $NPROC -gt 4 ] ; then
diff --git a/scripts/coccinelle/api/kobj_to_dev.cocci b/scripts/coccinelle/api/kobj_to_dev.cocci
deleted file mode 100644
index cd5d31c6fe76..000000000000
--- a/scripts/coccinelle/api/kobj_to_dev.cocci
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-///
-/// Use kobj_to_dev() instead of container_of()
-///
-// Confidence: High
-// Copyright: (C) 2020 Denis Efremov ISPRAS
-// Options: --no-includes --include-headers
-//
-// Keywords: kobj_to_dev, container_of
-//
-
-virtual context
-virtual report
-virtual org
-virtual patch
-
-
-@r depends on !patch@
-expression ptr;
-symbol kobj;
-position p;
-@@
-
-* container_of(ptr, struct device, kobj)@p
-
-
-@depends on patch@
-expression ptr;
-@@
-
-- container_of(ptr, struct device, kobj)
-+ kobj_to_dev(ptr)
-
-
-@script:python depends on report@
-p << r.p;
-@@
-
-coccilib.report.print_report(p[0], "WARNING opportunity for kobj_to_dev()")
-
-@script:python depends on org@
-p << r.p;
-@@
-
-coccilib.org.print_todo(p[0], "WARNING opportunity for kobj_to_dev()")
diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci
index 168568386034..9b6e2037c2a9 100644
--- a/scripts/coccinelle/free/kfree.cocci
+++ b/scripts/coccinelle/free/kfree.cocci
@@ -22,9 +22,9 @@ position p1;
@@
(
-* kfree@p1(E)
+ kfree@p1(E)
|
-* kfree_sensitive@p1(E)
+ kfree_sensitive@p1(E)
)
@print expression@
@@ -66,9 +66,9 @@ position ok;
while (1) { ...
(
-* kfree@ok(E)
+ kfree@ok(E)
|
-* kfree_sensitive@ok(E)
+ kfree_sensitive@ok(E)
)
... when != break;
when != goto l;
@@ -84,9 +84,9 @@ position free.p1!=loop.ok,p2!={print.p,sz.p};
@@
(
-* kfree@p1(E,...)
+ kfree@p1(E,...)
|
-* kfree_sensitive@p1(E,...)
+ kfree_sensitive@p1(E,...)
)
...
(
diff --git a/scripts/coccinelle/misc/flexible_array.cocci b/scripts/coccinelle/misc/flexible_array.cocci
index 947fbaff82a9..f427fd68ed2d 100644
--- a/scripts/coccinelle/misc/flexible_array.cocci
+++ b/scripts/coccinelle/misc/flexible_array.cocci
@@ -51,21 +51,40 @@ position p : script:python() { relevant(p) };
};
)
+@only_field depends on patch@
+identifier name, array;
+type T;
+position q;
+@@
+
+(
+ struct name {@q
+ T array[0];
+ };
+|
+ struct {@q
+ T array[0];
+ };
+)
+
@depends on patch@
identifier name, array;
type T;
position p : script:python() { relevant(p) };
+// position @q with rule "only_field" simplifies
+// handling of bitfields, arrays, etc.
+position q != only_field.q;
@@
(
- struct name {
+ struct name {@q
...
T array@p[
- 0
];
};
|
- struct {
+ struct {@q
...
T array@p[
- 0
diff --git a/scripts/coccinelle/misc/irqf_oneshot.cocci b/scripts/coccinelle/misc/irqf_oneshot.cocci
index 7b48287b3dc1..9b6f404d07f2 100644
--- a/scripts/coccinelle/misc/irqf_oneshot.cocci
+++ b/scripts/coccinelle/misc/irqf_oneshot.cocci
@@ -103,11 +103,11 @@ devm_request_threaded_irq@p(dev, irq, NULL, ...)
@script:python depends on org@
p << match.p;
@@
-msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT"
+msg = "WARNING: Threaded IRQ with no primary handler requested without IRQF_ONESHOT (unless it is nested IRQ)"
coccilib.org.print_todo(p[0],msg)
@script:python depends on report@
p << match.p;
@@
-msg = "ERROR: Threaded IRQ with no primary handler requested without IRQF_ONESHOT"
+msg = "WARNING: Threaded IRQ with no primary handler requested without IRQF_ONESHOT (unless it is nested IRQ)"
coccilib.report.print_report(p[0],msg)
diff --git a/scripts/coccinelle/misc/minmax.cocci b/scripts/coccinelle/misc/minmax.cocci
new file mode 100644
index 000000000000..fcf908b34f27
--- /dev/null
+++ b/scripts/coccinelle/misc/minmax.cocci
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: GPL-2.0-only
+///
+/// Check for opencoded min(), max() implementations.
+/// Generated patches sometimes require adding a cast to fix compile warning.
+/// Warnings/patches scope intentionally limited to a function body.
+///
+// Confidence: Medium
+// Copyright: (C) 2021 Denis Efremov ISPRAS
+// Options: --no-includes --include-headers
+//
+// Keywords: min, max
+//
+
+
+virtual report
+virtual org
+virtual context
+virtual patch
+
+@rmax depends on !patch@
+identifier func;
+expression x, y;
+binary operator cmp = {>, >=};
+position p;
+@@
+
+func(...)
+{
+ <...
+* ((x) cmp@p (y) ? (x) : (y))
+ ...>
+}
+
+@rmaxif depends on !patch@
+identifier func;
+expression x, y;
+expression max_val;
+binary operator cmp = {>, >=};
+position p;
+@@
+
+func(...)
+{
+ <...
+* if ((x) cmp@p (y)) {
+* max_val = (x);
+* } else {
+* max_val = (y);
+* }
+ ...>
+}
+
+@rmin depends on !patch@
+identifier func;
+expression x, y;
+binary operator cmp = {<, <=};
+position p;
+@@
+
+func(...)
+{
+ <...
+* ((x) cmp@p (y) ? (x) : (y))
+ ...>
+}
+
+@rminif depends on !patch@
+identifier func;
+expression x, y;
+expression min_val;
+binary operator cmp = {<, <=};
+position p;
+@@
+
+func(...)
+{
+ <...
+* if ((x) cmp@p (y)) {
+* min_val = (x);
+* } else {
+* min_val = (y);
+* }
+ ...>
+}
+
+@pmax depends on patch@
+identifier func;
+expression x, y;
+binary operator cmp = {>=, >};
+@@
+
+func(...)
+{
+ <...
+- ((x) cmp (y) ? (x) : (y))
++ max(x, y)
+ ...>
+}
+
+@pmaxif depends on patch@
+identifier func;
+expression x, y;
+expression max_val;
+binary operator cmp = {>=, >};
+@@
+
+func(...)
+{
+ <...
+- if ((x) cmp (y)) {
+- max_val = x;
+- } else {
+- max_val = y;
+- }
++ max_val = max(x, y);
+ ...>
+}
+
+// Don't generate patches for errcode returns.
+@errcode depends on patch@
+position p;
+identifier func;
+expression x;
+binary operator cmp = {<, <=};
+@@
+
+func(...)
+{
+ <...
+ return ((x) cmp@p 0 ? (x) : 0);
+ ...>
+}
+
+@pmin depends on patch@
+identifier func;
+expression x, y;
+binary operator cmp = {<=, <};
+position p != errcode.p;
+@@
+
+func(...)
+{
+ <...
+- ((x) cmp@p (y) ? (x) : (y))
++ min(x, y)
+ ...>
+}
+
+@pminif depends on patch@
+identifier func;
+expression x, y;
+expression min_val;
+binary operator cmp = {<=, <};
+@@
+
+func(...)
+{
+ <...
+- if ((x) cmp (y)) {
+- min_val = x;
+- } else {
+- min_val = y;
+- }
++ min_val = min(x, y);
+ ...>
+}
+
+@script:python depends on report@
+p << rmax.p;
+@@
+
+for p0 in p:
+ coccilib.report.print_report(p0, "WARNING opportunity for max()")
+
+@script:python depends on org@
+p << rmax.p;
+@@
+
+for p0 in p:
+ coccilib.org.print_todo(p0, "WARNING opportunity for max()")
+
+@script:python depends on report@
+p << rmaxif.p;
+@@
+
+for p0 in p:
+ coccilib.report.print_report(p0, "WARNING opportunity for max()")
+
+@script:python depends on org@
+p << rmaxif.p;
+@@
+
+for p0 in p:
+ coccilib.org.print_todo(p0, "WARNING opportunity for max()")
+
+@script:python depends on report@
+p << rmin.p;
+@@
+
+for p0 in p:
+ coccilib.report.print_report(p0, "WARNING opportunity for min()")
+
+@script:python depends on org@
+p << rmin.p;
+@@
+
+for p0 in p:
+ coccilib.org.print_todo(p0, "WARNING opportunity for min()")
+
+@script:python depends on report@
+p << rminif.p;
+@@
+
+for p0 in p:
+ coccilib.report.print_report(p0, "WARNING opportunity for min()")
+
+@script:python depends on org@
+p << rminif.p;
+@@
+
+for p0 in p:
+ coccilib.org.print_todo(p0, "WARNING opportunity for min()")
diff --git a/scripts/coccinelle/misc/swap.cocci b/scripts/coccinelle/misc/swap.cocci
new file mode 100644
index 000000000000..c5e71b7ef7f5
--- /dev/null
+++ b/scripts/coccinelle/misc/swap.cocci
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0-only
+///
+/// Check for opencoded swap() implementation.
+///
+// Confidence: High
+// Copyright: (C) 2021 Denis Efremov ISPRAS
+// Options: --no-includes --include-headers
+//
+// Keywords: swap
+//
+
+virtual patch
+virtual org
+virtual report
+virtual context
+
+@rvar depends on !patch@
+identifier tmp;
+expression a, b;
+type T;
+position p;
+@@
+
+(
+* T tmp;
+|
+* T tmp = 0;
+|
+* T *tmp = NULL;
+)
+... when != tmp
+* tmp = a;
+* a = b;@p
+* b = tmp;
+... when != tmp
+
+@r depends on !patch@
+identifier tmp;
+expression a, b;
+position p != rvar.p;
+@@
+
+* tmp = a;
+* a = b;@p
+* b = tmp;
+
+@rpvar depends on patch@
+identifier tmp;
+expression a, b;
+type T;
+@@
+
+(
+- T tmp;
+|
+- T tmp = 0;
+|
+- T *tmp = NULL;
+)
+... when != tmp
+- tmp = a;
+- a = b;
+- b = tmp
++ swap(a, b)
+ ;
+... when != tmp
+
+@rp depends on patch@
+identifier tmp;
+expression a, b;
+@@
+
+- tmp = a;
+- a = b;
+- b = tmp
++ swap(a, b)
+ ;
+
+@depends on patch && (rpvar || rp)@
+@@
+
+(
+ for (...;...;...)
+- {
+ swap(...);
+- }
+|
+ while (...)
+- {
+ swap(...);
+- }
+|
+ if (...)
+- {
+ swap(...);
+- }
+)
+
+
+@script:python depends on report@
+p << r.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING opportunity for swap()")
+
+@script:python depends on org@
+p << r.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING opportunity for swap()")
+
+@script:python depends on report@
+p << rvar.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING opportunity for swap()")
+
+@script:python depends on org@
+p << rvar.p;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING opportunity for swap()")
diff --git a/scripts/coccinelle/misc/uninitialized_var.cocci b/scripts/coccinelle/misc/uninitialized_var.cocci
index 8fa845cefe11..69bbaae47e73 100644
--- a/scripts/coccinelle/misc/uninitialized_var.cocci
+++ b/scripts/coccinelle/misc/uninitialized_var.cocci
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
///
/// Please, don't reintroduce uninitialized_var().
-/// From Documentation/process/deprecated.rst:
+///
+/// From Documentation/process/deprecated.rst,
+/// commit 4b19bec97c88 ("docs: deprecated.rst: Add uninitialized_var()"):
/// For any compiler warnings about uninitialized variables, just add
/// an initializer. Using warning-silencing tricks is dangerous as it
/// papers over real bugs (or can in the future), and suppresses unrelated
@@ -11,6 +13,11 @@
/// obviously redundant, the compiler's dead-store elimination pass will make
/// sure there are no needless variable writes.
///
+/// Later, commit 3942ea7a10c9 ("deprecated.rst: Remove now removed
+/// uninitialized_var") removed this section because all initializations of
+/// this kind were cleaned-up from the kernel. This cocci rule checks that
+/// the macro is not explicitly or implicitly reintroduced.
+///
// Confidence: High
// Copyright: (C) 2020 Denis Efremov ISPRAS
// Options: --no-includes --include-headers
@@ -40,12 +47,10 @@ position p;
p << r.p;
@@
-coccilib.report.print_report(p[0],
- "WARNING this kind of initialization is deprecated (https://www.kernel.org/doc/html/latest/process/deprecated.html#uninitialized-var)")
+coccilib.report.print_report(p[0], "WARNING this kind of initialization is deprecated")
@script:python depends on org@
p << r.p;
@@
-coccilib.org.print_todo(p[0],
- "WARNING this kind of initialization is deprecated (https://www.kernel.org/doc/html/latest/process/deprecated.html#uninitialized-var)")
+coccilib.org.print_todo(p[0], "WARNING this kind of initialization is deprecated")