|  | // Copyright (c) 2020 Nordic Semiconductor ASA | 
|  | // SPDX-License-Identifier: 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) |