const_config_info.cocci 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright (c) 2020 Nordic Semiconductor ASA
  2. // SPDX-License-Identifer: Apache-2.0
  3. // Enforce preservation of const qualifier on config_info casts
  4. //
  5. // Drivers cast the device config_info pointer to a driver-specific
  6. // structure. The object is const-qualified; make sure the cast
  7. // doesn't inadvertently remove that qualifier.
  8. //
  9. // Also add the qualifier to pointer definitions where it's missing.
  10. //
  11. // Note that this patch may produce incorrect results if config_info
  12. // appears as a tag in non-device aggregate types.
  13. //
  14. // Options: --include-headers
  15. virtual patch
  16. virtual report
  17. // bare: (struct T*)E
  18. @r_cci_bare_patch
  19. depends on patch
  20. disable optional_qualifier
  21. @
  22. identifier T;
  23. expression E;
  24. @@
  25. (
  26. +const
  27. struct T*)E->config_info
  28. // bare const: (struct T* const)E
  29. @r_cci_bare_lc_patch
  30. depends on patch
  31. disable optional_qualifier
  32. @
  33. identifier T;
  34. expression E;
  35. @@
  36. (
  37. +const
  38. struct T * const)E->config_info
  39. // asg: struct T *D = (const struct T*)
  40. @r_cci_asg_patch
  41. depends on patch
  42. disable optional_qualifier
  43. @
  44. identifier T;
  45. identifier D;
  46. expression E;
  47. @@
  48. +const
  49. struct T * D = (const struct T*)E->config_info;
  50. // asg to const local: struct T * const D = (const struct T*)
  51. @r_cci_lc_asg_patch
  52. depends on patch
  53. disable optional_qualifier
  54. @
  55. identifier T;
  56. identifier D;
  57. expression E;
  58. @@
  59. +const
  60. struct T * const D = (const struct T*)E->config_info;
  61. // asg via macro: struct T * D = DEV_CFG()
  62. @r_cci_asg_macro_patch
  63. depends on patch
  64. disable optional_qualifier
  65. @
  66. identifier T;
  67. identifier D;
  68. expression E;
  69. @@
  70. +const
  71. struct T * D = DEV_CFG(E);
  72. // asg via macro to const local: struct T * const D = DEV_CFG()
  73. @r_cci_lc_asg_macro_patch
  74. depends on patch
  75. disable optional_qualifier
  76. @
  77. identifier T;
  78. identifier D;
  79. expression E;
  80. @@
  81. +const
  82. struct T * const D = DEV_CFG(E);
  83. // asg via macro: struct T * D; ... ; D = (const struct T*)CI;
  84. @r_cci_delayed_asg_patch
  85. depends on patch
  86. disable optional_qualifier
  87. @
  88. identifier T;
  89. identifier D;
  90. expression E;
  91. @@
  92. +const
  93. struct T * D;
  94. ...
  95. D = (const struct T*)E->config_info;
  96. // delayed asg via macro: struct T * D; ... ; D = DEV_CFG();
  97. @r_cci_delayed_asg_macro_patch
  98. depends on patch
  99. disable optional_qualifier
  100. @
  101. identifier T;
  102. identifier D;
  103. expression E;
  104. @@
  105. +const
  106. struct T * D;
  107. ...
  108. D = DEV_CFG(E);
  109. @r_cci_report
  110. depends on report
  111. disable optional_qualifier
  112. @
  113. identifier T;
  114. expression E;
  115. position p;
  116. @@
  117. (struct T*)E->config_info@p
  118. @script:python
  119. depends on report
  120. @
  121. t << r_cci_report.T;
  122. p << r_cci_report.p;
  123. @@
  124. msg = "WARNING: cast of config_info to struct {} requires 'const'".format(t)
  125. coccilib.report.print_report(p[0], msg)