scripts/coccinelle: add script to preserve const qualifier on config_info
Drivers cast the device config_info pointer to a driver-specific structure. The referenced object is const-qualified; make sure the cast doesn't inadvertently remove that qualifier. Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
parent
21c7d42a64
commit
49e8c7080f
1 changed files with 137 additions and 0 deletions
137
scripts/coccinelle/const_config_info.cocci
Normal file
137
scripts/coccinelle/const_config_info.cocci
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
// Copyright (c) 2020 Nordic Semiconductor ASA
|
||||||
|
// SPDX-License-Identifer: Apache-2.0
|
||||||
|
|
||||||
|
// Enforce preservation of const qualifier on config_info casts
|
||||||
|
//
|
||||||
|
// Drivers cast the device config_info pointer to a driver-specific
|
||||||
|
// structure. The object is const-qualified; make sure the cast
|
||||||
|
// doesn't inadvertently remove that qualifier.
|
||||||
|
//
|
||||||
|
// Also add the qualifier to pointer definitions where it's missing.
|
||||||
|
//
|
||||||
|
// Note that this patch may produce incorrect results if config_info
|
||||||
|
// appears as a tag in non-device aggregate types.
|
||||||
|
//
|
||||||
|
// Options: --include-headers
|
||||||
|
|
||||||
|
virtual patch
|
||||||
|
virtual report
|
||||||
|
|
||||||
|
// bare: (struct T*)E
|
||||||
|
@r_cci_bare_patch
|
||||||
|
depends on patch
|
||||||
|
disable optional_qualifier
|
||||||
|
@
|
||||||
|
identifier T;
|
||||||
|
expression E;
|
||||||
|
@@
|
||||||
|
(
|
||||||
|
+const
|
||||||
|
struct T*)E->config_info
|
||||||
|
|
||||||
|
// bare const: (struct T* const)E
|
||||||
|
@r_cci_bare_lc_patch
|
||||||
|
depends on patch
|
||||||
|
disable optional_qualifier
|
||||||
|
@
|
||||||
|
identifier T;
|
||||||
|
expression E;
|
||||||
|
@@
|
||||||
|
(
|
||||||
|
+const
|
||||||
|
struct T * const)E->config_info
|
||||||
|
|
||||||
|
// asg: struct T *D = (const struct T*)
|
||||||
|
@r_cci_asg_patch
|
||||||
|
depends on patch
|
||||||
|
disable optional_qualifier
|
||||||
|
@
|
||||||
|
identifier T;
|
||||||
|
identifier D;
|
||||||
|
expression E;
|
||||||
|
@@
|
||||||
|
+const
|
||||||
|
struct T * D = (const struct T*)E->config_info;
|
||||||
|
|
||||||
|
// asg to const local: struct T * const D = (const struct T*)
|
||||||
|
@r_cci_lc_asg_patch
|
||||||
|
depends on patch
|
||||||
|
disable optional_qualifier
|
||||||
|
@
|
||||||
|
identifier T;
|
||||||
|
identifier D;
|
||||||
|
expression E;
|
||||||
|
@@
|
||||||
|
+const
|
||||||
|
struct T * const D = (const struct T*)E->config_info;
|
||||||
|
|
||||||
|
// asg via macro: struct T * D = DEV_CFG()
|
||||||
|
@r_cci_asg_macro_patch
|
||||||
|
depends on patch
|
||||||
|
disable optional_qualifier
|
||||||
|
@
|
||||||
|
identifier T;
|
||||||
|
identifier D;
|
||||||
|
expression E;
|
||||||
|
@@
|
||||||
|
+const
|
||||||
|
struct T * D = DEV_CFG(E);
|
||||||
|
|
||||||
|
// asg via macro to const local: struct T * const D = DEV_CFG()
|
||||||
|
@r_cci_lc_asg_macro_patch
|
||||||
|
depends on patch
|
||||||
|
disable optional_qualifier
|
||||||
|
@
|
||||||
|
identifier T;
|
||||||
|
identifier D;
|
||||||
|
expression E;
|
||||||
|
@@
|
||||||
|
+const
|
||||||
|
struct T * const D = DEV_CFG(E);
|
||||||
|
|
||||||
|
// asg via macro: struct T * D; ... ; D = (const struct T*)CI;
|
||||||
|
@r_cci_delayed_asg_patch
|
||||||
|
depends on patch
|
||||||
|
disable optional_qualifier
|
||||||
|
@
|
||||||
|
identifier T;
|
||||||
|
identifier D;
|
||||||
|
expression E;
|
||||||
|
@@
|
||||||
|
+const
|
||||||
|
struct T * D;
|
||||||
|
...
|
||||||
|
D = (const struct T*)E->config_info;
|
||||||
|
|
||||||
|
// delayed asg via macro: struct T * D; ... ; D = DEV_CFG();
|
||||||
|
@r_cci_delayed_asg_macro_patch
|
||||||
|
depends on patch
|
||||||
|
disable optional_qualifier
|
||||||
|
@
|
||||||
|
identifier T;
|
||||||
|
identifier D;
|
||||||
|
expression E;
|
||||||
|
@@
|
||||||
|
+const
|
||||||
|
struct T * D;
|
||||||
|
...
|
||||||
|
D = DEV_CFG(E);
|
||||||
|
|
||||||
|
@r_cci_report
|
||||||
|
depends on report
|
||||||
|
disable optional_qualifier
|
||||||
|
@
|
||||||
|
identifier T;
|
||||||
|
expression E;
|
||||||
|
position p;
|
||||||
|
@@
|
||||||
|
(struct T*)E->config_info@p
|
||||||
|
|
||||||
|
@script:python
|
||||||
|
depends on report
|
||||||
|
@
|
||||||
|
t << r_cci_report.T;
|
||||||
|
p << r_cci_report.p;
|
||||||
|
@@
|
||||||
|
msg = "WARNING: cast of config_info to struct {} requires 'const'".format(t)
|
||||||
|
coccilib.report.print_report(p[0], msg)
|
Loading…
Add table
Add a link
Reference in a new issue