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")