diff --git a/scripts/coccinelle/const_config_info.cocci b/scripts/coccinelle/const_config_info.cocci new file mode 100644 index 00000000000..718051f4e97 --- /dev/null +++ b/scripts/coccinelle/const_config_info.cocci @@ -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)