zephyr/scripts/coccinelle/find_dev_usage.cocci
Tomasz Bursztyka 72d9e8c8ab scripts: coccinelle: Scripts for finding wrong device instance usage
2 scripts are provided.
- find_functions.cocci (name probably sucks...)
- find_dev_usage.cocci (ditto...)

find_functions.cocci can patch files where device instance are not
const.

Then it is used to generate the function database:

./scripts/coccicheck --mode=report --jobs=1 \
--cocci=scripts/coccinelle/find_functions.cocci \
--sp-flag="--include-headers" ./

Then, find_dev_usage.cocci will check if the const qualifier is, or
might be lost in a function call.

For instance:
./scripts/coccicheck --mode=report --jobs=1 \
--cocci=scripts/coccinelle/find_dev_usage.cocci \
--sp-flag="--include-headers" drivers/i2c

Which will output a WARNING on non-zephyr functions calls with a device:

./drivers/i2c/i2c_cc13xx_cc26xx.c:393:5-8: WARNING: in i2c_cc13xx_cc26xx_pm_control calling cb param with dev, check if const qualifier is not lost
./drivers/i2c/i2c_mcux_lpi2c.c:205:40-43: WARNING: in mcux_lpi2c_init calling LPI2C_MasterTransferCreateHandle param with dev, check if const qualifier is not lost
./drivers/i2c/i2c_nrfx_twi.c:258:5-8: WARNING: in twi_nrfx_pm_control calling cb param with dev, check if const qualifier is not lost
./drivers/i2c/i2c_nrfx_twi.c:202:22-25: WARNING: in init_twi calling nrfx_twi_init param with dev, check if const qualifier is not lost
./drivers/i2c/i2c_mcux.c:187:38-41: WARNING: in i2c_mcux_init calling I2C_MasterTransferCreateHandle param with dev, check if const qualifier is not lost
./drivers/i2c/i2c_mcux_flexcomm.c:184:43-46: WARNING: in mcux_flexcomm_init calling I2C_MasterTransferCreateHandle param with dev, check if const qualifier is not lost
./drivers/i2c/i2c_nrfx_twim.c:232:5-8: WARNING: in twim_nrfx_pm_control calling cb param with dev, check if const qualifier is not lost
./drivers/i2c/i2c_nrfx_twim.c:174:8-11: WARNING: in init_twim calling nrfx_twim_init param with dev, check if const qualifier is not lost
./drivers/i2c/i2c_rv32m1_lpi2c.c:246:6-9: WARNING: in rv32m1_lpi2c_init calling LPI2C_MasterTransferCreateHandle param with dev, check if const qualifier is not lost

Or:
./scripts/coccicheck --mode=report --jobs=1 \
--cocci=scripts/coccinelle/find_dev_usage.cocci \
--sp-flag="--include-headers" drivers/ieee802154

Which will output an ERROR on using a zephyr function that looses the
const qualifier:

drivers/ieee802154/ieee802154_rf2xx.c:778:3-6: ERROR: in rf2xx_init calling k_thread_create param with dev, loosing const qualifier, please wrap
drivers/ieee802154/ieee802154_nrf5.c:477:19-22: ERROR: in nrf5_init calling k_thread_create param with dev, loosing const qualifier, please wrap
drivers/ieee802154/ieee802154_cc1200.c:819:3-6: ERROR: in cc1200_init calling k_thread_create param with dev, loosing const qualifier, please wrap
drivers/ieee802154/ieee802154_mcr20a.c:1443:3-6: ERROR: in mcr20a_init calling k_thread_create param with dev, loosing const qualifier, please wrap
drivers/ieee802154/ieee802154_cc2520.c:1116:3-6: ERROR: in cc2520_init calling k_thread_create param with dev, loosing const qualifier, please wrap
drivers/ieee802154/ieee802154_cc13xx_cc26xx.c:439:32-35: ERROR: in ieee802154_cc13xx_cc26xx_data_init calling k_thread_create param with dev, loosing const qualifier, please wrap

ISSUE:
- Is it possible to run a set of rules first on all the code, and then
  another set, both sets being in the same .cocci file?
  Would be nice to have all at once.

Fixes #27399

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2020-09-02 13:48:13 +02:00

65 lines
1.6 KiB
Plaintext

// Copyright (c) 2020 Intel Corporation
// SPDX-License-Identifer: Apache-2.0
// Uses a python database (a dict) to find where const struct device
// variable are being used in zephyr functions and, if it's being in place
// of a void*, it will print an ERROR for loosing the const qualifier.
// If it's being used on an unknown functions from an external module such
// as a HAL, it will print a WARNING in order to check if the const qualifier
// is not lost.
virtual report
////////////////////
// Initialization //
////////////////////
@initialize:python
depends on report
@
@@
import pickle
def check_and_report(F, f, D, nb_args, p):
if f in f_void and int(nb_args) in f_void[f]:
msg = "ERROR: in {} calling {} param with {}, \
loosing const qualifier, please wrap".format(F, f, D)
coccilib.report.print_report(p[0], msg)
elif f not in f_void and f not in f_other and not f.isupper():
msg = "WARNING: in {} calling {} param with {}, \
check if const qualifier is not lost".format(F, f, D)
coccilib.report.print_report(p[0], msg)
// Loading function data base
with open("function_names.pickle", "rb") as f:
data = pickle.load(f)
f_void = data["f_void"]
f_other = data["f_other"]
///////////
// Rules //
///////////
// Find usage of a device instance
@r_find_dev_usage
depends on report
@
local idexpression struct device *D;
expression list[nb_args] args;
identifier f;
position p;
@@
f(args, D@p, ...)
@script:python
depends on r_find_dev_usage
@
f << r_find_dev_usage.f;
D << r_find_dev_usage.D;
nb_args << r_find_dev_usage.nb_args;
p << r_find_dev_usage.p;
@@
check_and_report(p[0].current_element, f, D, nb_args, p)