scripts/coccinelle: updates and improvements for integer timeout values

Add support for the report and patch modes so this can be invoked by
coccicheck.

Use PCRE options to make the kernel timeout API identifier rule more
readable.  Extend the pattern to new API.

Use rule extends and depends clauses, and pattern disjunction, to
avoid replicating metavariable content.

Hint that using --include-headers may be helpful (some patterns can be
found in static inline functions).

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2019-10-04 11:28:52 -05:00 committed by Anas Nashif
commit 3a0a582119

View file

@ -7,75 +7,132 @@
// integer milliseconds, when they were intended to be timeout values
// produced by specific constants and macros. Convert the integer
// literals to the desired equivalent.
//
// Options: --include-headers
// Handle k_timer_start delay parameters
@delay_id@
expression T, P;
position p;
virtual patch
virtual report
// ** Handle timeouts at the last position of kernel API arguments
// Base rule provides the complex identifier regular expression
@r_last_timeout@
identifier last_timeout =~ "(?x)^k_
( timer_start
| queue_get
| futex_wait
| stack_pop
| delayed_work_submit(|_to_queue)
| work_poll_submit(|_to_queue)
| mutex_lock
| sem_take
| (msgq|mbox|pipe)_(block_)?(put|get)
| mem_(slab|pool)_alloc
| poll
| thread_deadline_set
)$";
@@
last_timeout(...)
// Identify call sites where an identifier is used for the timeout
@r_last_timeout_id
extends r_last_timeout
@
identifier D;
position p;
@@
k_timer_start@p(T, D, P)
last_timeout@p(..., D)
// Select call sites where a constant literal (not identifier) is used
// for the timeout and replace the constant with the appropriate macro
@r_last_timeout_const_patch
extends r_last_timeout
depends on patch
@
constant C;
position p != r_last_timeout_id.p;
@@
expression T, P;
position p != delay_id.p;
@@
k_timer_start@p(T,
last_timeout@p(...,
(
- 0
+ K_NO_WAIT
, P)
@@
expression T, P;
position p != delay_id.p;
@@
k_timer_start@p(T,
|
- -1
+ K_FOREVER
, P)
|
- C
+ K_MSEC(C)
)
)
@r_last_timeout_const_report
extends r_last_timeout
depends on report
@
constant C;
position p != r_last_timeout_id.p;
@@
expression T, P;
constant int D;
position p != delay_id.p;
last_timeout@p(..., C)
@script:python
depends on report
@
fn << r_last_timeout.last_timeout;
p << r_last_timeout_const_report.p;
C << r_last_timeout_const_report.C;
@@
msg = "WARNING: replace constant {} with timeout in {}".format(C, fn)
coccilib.report.print_report(p[0], msg);
// ** Handle k_timer_start where the second (not last) argument is a
// ** constant literal.
// Select call sites where an identifier is used for the duration timeout
@r_timer_duration@
expression T;
identifier D;
expression I;
position p;
@@
k_timer_start@p(T, D, I)
// Select call sites where a constant literal (not identifier) is used
// for the timeout and replace the constant with the appropriate macro
@depends on patch@
expression T;
constant C;
expression I;
position p != r_timer_duration.p;
@@
k_timer_start@p(T,
- D
+ K_MSEC(D)
, P)
// Handle timeouts at the end of the argument list
@end_id@
identifier f =~ "^k_(timer_start|queue_get|futex_wait|stack_pop|delayed_work_submit_to_queue|mutex_lock|sem_take|(msgq|mbox|pipe)_(block_)?(put|get)|mem_(slab|pool)_alloc|poll|thread_deadline_set)$";
position p;
identifier D;
@@
f@p(..., D)
@@
identifier f =~ "^k_(timer_start|queue_get|futex_wait|stack_pop|delayed_work_submit_to_queue|mutex_lock|sem_take|(msgq|mbox|pipe)_(block_)?(put|get)|mem_(slab|pool)_alloc|poll|thread_deadline_set)$";
position p != end_id.p;
@@
f@p(...,
(
- 0
+ K_NO_WAIT
)
@@
identifier f =~ "^k_(timer_start|queue_get|futex_wait|stack_pop|delayed_work_submit_to_queue|mutex_lock|sem_take|(msgq|mbox|pipe)_(block_)?(put|get)|mem_(slab|pool)_alloc|poll|thread_deadline_set)$";
position p != end_id.p;
@@
f@p(...,
|
- -1
+ K_FOREVER
)
|
- C
+ K_MSEC(C)
)
, I)
@r_timer_duration_report
depends on report
@
expression T;
constant C;
expression I;
position p != r_timer_duration.p;
@@
identifier f =~ "^k_(timer_start|queue_get|futex_wait|stack_pop|delayed_work_submit_to_queue|mutex_lock|sem_take|(msgq|mbox|pipe)_(block_)?(put|get)|mem_(slab|pool)_alloc|poll|thread_deadline_set)$";
position p != end_id.p;
constant int D;
k_timer_start@p(T, C, I)
@script:python
depends on report
@
p << r_timer_duration_report.p;
C << r_timer_duration_report.C;
@@
f@p(...,
- D
+ K_MSEC(D)
)
msg = "WARNING: replace constant {} with duration timeout in k_timer_start".format(C)
coccilib.report.print_report(p[0], msg);