@specs-feup/clava-misra 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/.gitignore +8 -0
  2. package/README.md +53 -19
  3. package/dist/MISRA.d.ts +28 -10
  4. package/dist/MISRA.d.ts.map +1 -1
  5. package/dist/MISRA.js +30 -10
  6. package/dist/MISRA.js.map +1 -1
  7. package/dist/MISRAContext.d.ts +65 -11
  8. package/dist/MISRAContext.d.ts.map +1 -1
  9. package/dist/MISRAContext.js +131 -35
  10. package/dist/MISRAContext.js.map +1 -1
  11. package/dist/MISRARule.d.ts +38 -25
  12. package/dist/MISRARule.d.ts.map +1 -1
  13. package/dist/MISRARule.js +40 -18
  14. package/dist/MISRARule.js.map +1 -1
  15. package/dist/MISRATool.d.ts +39 -5
  16. package/dist/MISRATool.d.ts.map +1 -1
  17. package/dist/MISRATool.js +102 -46
  18. package/dist/MISRATool.js.map +1 -1
  19. package/dist/StandardGuideline.d.ts +22 -0
  20. package/dist/StandardGuideline.d.ts.map +1 -0
  21. package/dist/StandardGuideline.js +12 -0
  22. package/dist/StandardGuideline.js.map +1 -0
  23. package/dist/ast-visitor/Context.d.ts +11 -0
  24. package/dist/ast-visitor/Context.d.ts.map +1 -0
  25. package/dist/ast-visitor/Context.js +15 -0
  26. package/dist/ast-visitor/Context.js.map +1 -0
  27. package/dist/ast-visitor/Visit.d.ts +23 -0
  28. package/dist/ast-visitor/Visit.d.ts.map +1 -0
  29. package/dist/ast-visitor/Visit.js +18 -0
  30. package/dist/ast-visitor/Visit.js.map +1 -0
  31. package/dist/ast-visitor/VisitWithContext.d.ts +32 -0
  32. package/dist/ast-visitor/VisitWithContext.d.ts.map +1 -0
  33. package/dist/ast-visitor/VisitWithContext.js +26 -0
  34. package/dist/ast-visitor/VisitWithContext.js.map +1 -0
  35. package/dist/main.js +1 -1
  36. package/dist/main.js.map +1 -1
  37. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts +27 -0
  38. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts.map +1 -0
  39. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js +98 -0
  40. package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js.map +1 -0
  41. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts +45 -6
  42. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts.map +1 -1
  43. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js +91 -8
  44. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js.map +1 -1
  45. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts +15 -5
  46. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts.map +1 -1
  47. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js +20 -6
  48. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js.map +1 -1
  49. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts +11 -5
  50. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts.map +1 -1
  51. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js +13 -10
  52. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js.map +1 -1
  53. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts +11 -6
  54. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts.map +1 -1
  55. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js +19 -11
  56. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js.map +1 -1
  57. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts +15 -5
  58. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts.map +1 -1
  59. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js +24 -10
  60. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js.map +1 -1
  61. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts +22 -6
  62. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts.map +1 -1
  63. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js +37 -10
  64. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js.map +1 -1
  65. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts +66 -0
  66. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts.map +1 -0
  67. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js +209 -0
  68. package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js.map +1 -0
  69. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts +37 -12
  70. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts.map +1 -1
  71. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js +112 -39
  72. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js.map +1 -1
  73. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts +15 -5
  74. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts.map +1 -1
  75. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js +21 -7
  76. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js.map +1 -1
  77. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts +11 -6
  78. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts.map +1 -1
  79. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js +17 -8
  80. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js.map +1 -1
  81. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts +105 -0
  82. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts.map +1 -0
  83. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js +258 -0
  84. package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js.map +1 -0
  85. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts +25 -0
  86. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts.map +1 -0
  87. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js +27 -0
  88. package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js.map +1 -0
  89. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts +29 -0
  90. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts.map +1 -0
  91. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js +31 -0
  92. package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js.map +1 -0
  93. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts +25 -0
  94. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts.map +1 -0
  95. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js +27 -0
  96. package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js.map +1 -0
  97. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts +25 -0
  98. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts.map +1 -0
  99. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js +27 -0
  100. package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js.map +1 -0
  101. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts +25 -0
  102. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts.map +1 -0
  103. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js +27 -0
  104. package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js.map +1 -0
  105. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts +30 -0
  106. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts.map +1 -0
  107. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js +32 -0
  108. package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js.map +1 -0
  109. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts +25 -0
  110. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts.map +1 -0
  111. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js +27 -0
  112. package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js.map +1 -0
  113. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts +6 -14
  114. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts.map +1 -1
  115. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js +17 -27
  116. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js.map +1 -1
  117. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts +13 -7
  118. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts.map +1 -1
  119. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js +31 -17
  120. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js.map +1 -1
  121. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts +26 -7
  122. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts.map +1 -1
  123. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js +32 -14
  124. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js.map +1 -1
  125. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts +48 -6
  126. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts.map +1 -1
  127. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js +84 -34
  128. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js.map +1 -1
  129. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts +24 -5
  130. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts.map +1 -1
  131. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js +27 -7
  132. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js.map +1 -1
  133. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts +46 -0
  134. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts.map +1 -0
  135. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js +40 -0
  136. package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js.map +1 -0
  137. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts +25 -0
  138. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts.map +1 -0
  139. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js +46 -0
  140. package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js.map +1 -0
  141. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts +26 -0
  142. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts.map +1 -0
  143. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js +54 -0
  144. package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js.map +1 -0
  145. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts +27 -0
  146. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts.map +1 -0
  147. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js +55 -0
  148. package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js.map +1 -0
  149. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts +24 -0
  150. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts.map +1 -0
  151. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js +42 -0
  152. package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js.map +1 -0
  153. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts +24 -0
  154. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts.map +1 -0
  155. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js +42 -0
  156. package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js.map +1 -0
  157. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts +35 -0
  158. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts.map +1 -0
  159. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js +98 -0
  160. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js.map +1 -0
  161. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts +35 -0
  162. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts.map +1 -0
  163. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js +76 -0
  164. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js.map +1 -0
  165. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts +32 -0
  166. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts.map +1 -0
  167. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js +57 -0
  168. package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js.map +1 -0
  169. package/dist/rules/UserConfigurableRule.d.ts +55 -0
  170. package/dist/rules/UserConfigurableRule.d.ts.map +1 -0
  171. package/dist/rules/UserConfigurableRule.js +16 -0
  172. package/dist/rules/UserConfigurableRule.js.map +1 -0
  173. package/dist/rules/index.d.ts +11 -18
  174. package/dist/rules/index.d.ts.map +1 -1
  175. package/dist/rules/index.js +47 -7
  176. package/dist/rules/index.js.map +1 -1
  177. package/dist/tests/Section17_Functions/misra_config.json +10 -0
  178. package/dist/tests/Section21-StandardLibraries/misra_config.json +88 -0
  179. package/dist/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
  180. package/dist/tests/utils.d.ts +6 -3
  181. package/dist/tests/utils.d.ts.map +1 -1
  182. package/dist/tests/utils.js +33 -7
  183. package/dist/tests/utils.js.map +1 -1
  184. package/dist/utils/CallUtils.d.ts +15 -0
  185. package/dist/utils/CallUtils.d.ts.map +1 -0
  186. package/dist/utils/CallUtils.js +34 -0
  187. package/dist/utils/CallUtils.js.map +1 -0
  188. package/dist/utils/CommentUtils.d.ts +21 -0
  189. package/dist/utils/CommentUtils.d.ts.map +1 -0
  190. package/dist/utils/CommentUtils.js +27 -0
  191. package/dist/utils/CommentUtils.js.map +1 -0
  192. package/dist/utils/FileUtils.d.ts +51 -0
  193. package/dist/utils/FileUtils.d.ts.map +1 -0
  194. package/dist/utils/FileUtils.js +121 -0
  195. package/dist/utils/FileUtils.js.map +1 -0
  196. package/dist/utils/FunctionUtils.d.ts +25 -0
  197. package/dist/utils/FunctionUtils.d.ts.map +1 -0
  198. package/dist/utils/FunctionUtils.js +65 -0
  199. package/dist/utils/FunctionUtils.js.map +1 -0
  200. package/dist/utils/IdentifierUtils.d.ts +14 -0
  201. package/dist/utils/IdentifierUtils.d.ts.map +1 -0
  202. package/dist/utils/IdentifierUtils.js +87 -0
  203. package/dist/utils/IdentifierUtils.js.map +1 -0
  204. package/dist/utils/JoinpointUtils.d.ts +19 -0
  205. package/dist/utils/JoinpointUtils.d.ts.map +1 -0
  206. package/dist/utils/JoinpointUtils.js +46 -0
  207. package/dist/utils/JoinpointUtils.js.map +1 -0
  208. package/dist/utils/ProgramUtils.d.ts +14 -0
  209. package/dist/utils/ProgramUtils.d.ts.map +1 -0
  210. package/dist/utils/ProgramUtils.js +72 -0
  211. package/dist/utils/ProgramUtils.js.map +1 -0
  212. package/dist/utils/SwitchUtils.d.ts +21 -0
  213. package/dist/utils/SwitchUtils.d.ts.map +1 -0
  214. package/dist/utils/SwitchUtils.js +47 -0
  215. package/dist/utils/SwitchUtils.js.map +1 -0
  216. package/dist/utils/TypeDeclUtils.d.ts +35 -0
  217. package/dist/utils/TypeDeclUtils.d.ts.map +1 -0
  218. package/dist/utils/TypeDeclUtils.js +78 -0
  219. package/dist/utils/TypeDeclUtils.js.map +1 -0
  220. package/dist/utils/VarUtils.d.ts +19 -0
  221. package/dist/utils/VarUtils.d.ts.map +1 -0
  222. package/dist/utils/VarUtils.js +59 -0
  223. package/dist/utils/VarUtils.js.map +1 -0
  224. package/package.json +16 -6
  225. package/src/MISRA.ts +33 -17
  226. package/src/MISRAContext.ts +128 -30
  227. package/src/MISRARule.ts +61 -29
  228. package/src/MISRATool.ts +108 -42
  229. package/src/StandardGuideline.ts +23 -0
  230. package/src/ast-visitor/Context.ts +16 -0
  231. package/src/ast-visitor/Visit.ts +26 -0
  232. package/src/ast-visitor/VisitWithContext.ts +42 -0
  233. package/src/main.ts +1 -1
  234. package/src/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.ts +114 -0
  235. package/src/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.ts +103 -13
  236. package/src/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.ts +24 -10
  237. package/src/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.ts +17 -8
  238. package/src/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.ts +20 -12
  239. package/src/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.ts +23 -12
  240. package/src/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.ts +44 -13
  241. package/src/rules/Section17_Functions/Rule_17_3_ImplicitFunction.ts +153 -104
  242. package/src/rules/Section17_Functions/Rule_17_4_NonVoidReturn.ts +114 -44
  243. package/src/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.ts +27 -10
  244. package/src/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.ts +20 -12
  245. package/src/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.ts +317 -0
  246. package/src/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.ts +30 -0
  247. package/src/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.ts +35 -0
  248. package/src/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.ts +30 -0
  249. package/src/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.ts +30 -0
  250. package/src/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.ts +29 -0
  251. package/src/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.ts +36 -0
  252. package/src/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.ts +30 -0
  253. package/src/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.ts +14 -29
  254. package/src/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.ts +33 -19
  255. package/src/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.ts +33 -20
  256. package/src/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.ts +90 -45
  257. package/src/rules/Section3_Comments/Rule_3_1_CommentSequences.ts +27 -8
  258. package/src/rules/Section5_Identifiers/IdentifierRenameRule.ts +63 -0
  259. package/src/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.ts +52 -0
  260. package/src/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.ts +62 -0
  261. package/src/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.ts +61 -0
  262. package/src/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.ts +47 -0
  263. package/src/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.ts +47 -0
  264. package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.ts +118 -0
  265. package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.ts +89 -0
  266. package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.ts +65 -0
  267. package/src/rules/UserConfigurableRule.ts +60 -0
  268. package/src/rules/index.ts +45 -7
  269. package/src/tests/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.test.ts +114 -0
  270. package/src/tests/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.test.ts +7 -5
  271. package/src/tests/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.test.ts +40 -13
  272. package/src/tests/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.test.ts +10 -12
  273. package/src/tests/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.test.ts +5 -5
  274. package/src/tests/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.test.ts +5 -5
  275. package/src/tests/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.test.ts +5 -5
  276. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions.test.ts +68 -40
  277. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_MissingConfig.test.ts +98 -0
  278. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_ProblematicConfig.test.ts +71 -0
  279. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn.test.ts +103 -49
  280. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn_MissingConfig.test.ts +7 -7
  281. package/src/tests/Section17_Functions/Rule_17_6_StaticArraySizeParam.test.ts +36 -7
  282. package/src/tests/Section17_Functions/Rule_17_7_UnusedReturnValue.test.ts +25 -21
  283. package/src/tests/Section17_Functions/misra_config.json +4 -3
  284. package/src/tests/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.test.ts +62 -0
  285. package/src/tests/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.test.ts +67 -0
  286. package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.test.ts +84 -0
  287. package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_MissingConfig.test.ts +33 -0
  288. package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_ProblematicConfig.test.ts +71 -0
  289. package/src/tests/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.test.ts +63 -0
  290. package/src/tests/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.test.ts +91 -0
  291. package/src/tests/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.test.ts +65 -0
  292. package/src/tests/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.test.ts +89 -0
  293. package/src/tests/Section21-StandardLibraries/misra_config.json +88 -0
  294. package/src/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
  295. package/src/tests/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.test.ts +148 -113
  296. package/src/tests/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.test.ts +243 -163
  297. package/src/tests/Section2_UnusedCode/Rule_2_6_UnusedLabels.test.ts +32 -20
  298. package/src/tests/Section2_UnusedCode/Rule_2_7_UnusedParameters.test.ts +36 -30
  299. package/src/tests/Section3_Comments/Rule_3_1_CommentSequences.test.ts +37 -8
  300. package/src/tests/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.test.ts +78 -0
  301. package/src/tests/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.test.ts +120 -0
  302. package/src/tests/Section5_Identifiers/Rule_5_7_UniqueTagNames.test.ts +51 -0
  303. package/src/tests/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.test.ts +73 -0
  304. package/src/tests/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.test.ts +97 -0
  305. package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.test.ts +160 -0
  306. package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.test.ts +46 -0
  307. package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.test.ts +69 -0
  308. package/src/tests/utils.ts +32 -7
  309. package/src/utils/CallUtils.ts +40 -0
  310. package/src/utils/CommentUtils.ts +29 -0
  311. package/src/utils/FileUtils.ts +141 -0
  312. package/src/utils/FunctionUtils.ts +75 -0
  313. package/src/utils/IdentifierUtils.ts +94 -0
  314. package/src/utils/JoinpointUtils.ts +53 -0
  315. package/src/utils/ProgramUtils.ts +83 -0
  316. package/src/utils/SwitchUtils.ts +52 -0
  317. package/src/utils/TypeDeclUtils.ts +89 -0
  318. package/src/utils/VarUtils.ts +70 -0
  319. package/tsconfig.json +2 -1
  320. package/src/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.ts +0 -120
  321. package/src/rules/Section3_Comments/Rule_3_2_LineSplicing.ts +0 -36
  322. package/src/utils/utils.ts +0 -280
package/src/MISRARule.ts CHANGED
@@ -1,56 +1,64 @@
1
- import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
1
+ import { Joinpoint, Program } from "@specs-feup/clava/api/Joinpoints.js";
2
2
  import MISRAContext from "./MISRAContext.js";
3
- import { MISRATransformationReport } from "./MISRA.js";
3
+ import { AnalysisType, MISRATransformationReport, MISRATransformationResults } from "./MISRA.js";
4
+ import { LaraJoinPoint } from "@specs-feup/lara/api/LaraJoinPoint.js";
5
+ import Clava from "@specs-feup/clava/api/clava/Clava.js";
6
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
7
+ import { resetCaches } from "./utils/ProgramUtils.js";
8
+ import StandardGuideline from "./StandardGuideline.js";
4
9
 
5
10
  /**
6
11
  * Represents a MISRA Rule that detects and corrects violations in the code according to MISRA standards.
7
12
  *
8
- * Need to implement:
13
+ * Need to implement/define:
14
+ * - analysisType
15
+ * - name()
9
16
  * - match($jp, logErrors)
10
- * - transform($jp)
17
+ * - apply($jp)
11
18
  */
12
- export default abstract class MISRARule {
19
+ export default abstract class MISRARule extends StandardGuideline<MISRATransformationResults, MISRAContext> {
13
20
  /**
14
- * Unique identifier for the MISRA rule.
21
+ * A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
22
+ * By default, a rule has the lowest priority unless overridden.
15
23
  */
16
- readonly ruleID: string;
24
+ readonly priority: number = Number.MAX_VALUE;
17
25
 
18
26
  /**
19
- * Priority of the rule which is low by default.
27
+ * Scope of analysis: single unit or entire system.
20
28
  */
21
- readonly priority: number = 4;
22
-
23
- /**
24
- * MISRA context for error tracking and rule transformations state
25
- */
26
- protected context: MISRAContext;
29
+ abstract readonly analysisType: AnalysisType;
30
+
31
+ /**
32
+ * Standards to which this rule applies to
33
+ */
34
+ protected readonly appliesTo: Set<string> = new Set(["c90", "c99", "c11"]);
27
35
 
28
36
  /**
29
37
  *
30
- * @param ruleID - Unique identifier for the MISRA-C rule
31
38
  * @param context - MISRA context for error tracking and rule transformations state
32
39
  */
33
- constructor(ruleID: string, context: MISRAContext) {
34
- this.ruleID = ruleID;
35
- this.context = context;
40
+ constructor(context: MISRAContext) {
41
+ super(context);
36
42
  }
37
43
 
38
44
  /**
39
- * Checks if the joinpoint violates the rule
40
- *
41
- * @param $jp - Joinpoint to analyze
42
- * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
43
- * @returns Returns true if the joinpoint violates the rule, false otherwise
45
+ * @returns Initial value stored in the shared context
44
46
  */
45
- abstract match($jp: Joinpoint, logErrors: boolean): boolean;
47
+ override initialValue(): MISRATransformationResults {
48
+ return new Map();
49
+ }
46
50
 
47
51
  /**
48
- * Transforms the joinpoint to comply with the MISRA-C rule
49
- *
50
- * @param $jp - Joinpoint to transform
51
- * @returns Report detailing the transformation result
52
+ * @returns Rule identifier according to MISRA-C:2012
52
53
  */
53
- abstract transform($jp: Joinpoint): MISRATransformationReport;
54
+ abstract override get name(): string;
55
+
56
+ /**
57
+ * An alias for 'name'
58
+ */
59
+ get ruleID(): string {
60
+ return this.name;
61
+ }
54
62
 
55
63
  /**
56
64
  * Logs a MISRA-C rule violation error
@@ -61,4 +69,28 @@ export default abstract class MISRARule {
61
69
  protected logMISRAError($jp: Joinpoint, msg:string): void {
62
70
  this.context.addMISRAError(this.ruleID, $jp, msg);
63
71
  }
72
+
73
+ /**
74
+ * Verifies if the rule applies to the standard being used
75
+ */
76
+ protected appliesToCurrentStandard(): boolean {
77
+ return this.appliesTo.has(Clava.getStandard());
78
+ }
79
+
80
+ /**
81
+ * Rebuilds the program based on the current AST, clears stored data in the shared context, and resets all caches
82
+ */
83
+ protected rebuildProgram() {
84
+ (Query.root() as Program).rebuild();
85
+ this.context.resetStorage();
86
+ resetCaches();
87
+ }
88
+
89
+ /**
90
+ * Transforms the joinpoint to comply with the MISRA-C rule
91
+ *
92
+ * @param $jp - Joinpoint to transform
93
+ * @returns Report detailing the transformation result
94
+ */
95
+ abstract apply($jp: LaraJoinPoint): MISRATransformationReport;
64
96
  }
package/src/MISRATool.ts CHANGED
@@ -1,33 +1,25 @@
1
1
  import Query from "@specs-feup/lara/api/weaver/Query.js";
2
- import { Call, FileJp, Joinpoint, Program } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import { FileJp, Joinpoint, Program } from "@specs-feup/clava/api/Joinpoints.js";
3
3
  import MISRARule from "./MISRARule.js";
4
- import sortRules from "./rules/index.js";
5
4
  import MISRAContext from "./MISRAContext.js";
6
- import { MISRAError, MISRATransformationType } from "./MISRA.js";
7
- import { isCallToImplicitFunction } from "./utils/utils.js";
5
+ import { MISRATransformationType } from "./MISRA.js";
6
+ import Clava from "@specs-feup/clava/api/clava/Clava.js";
7
+ import { resetCaches } from "./utils/ProgramUtils.js";
8
+ import { selectRules } from "./rules/index.js";
9
+
10
+ enum ExecutionMode {
11
+ CORRECTION,
12
+ DETECTION
13
+ }
8
14
 
9
15
  export default class MISRATool {
10
16
  static #misraRules: MISRARule[];
11
- static #context: MISRAContext;
12
-
13
- private static init(startingPoint: FileJp | Program) {
14
- this.validateStdVersion(startingPoint);
15
- this.#context = new MISRAContext();
16
- this.#misraRules = sortRules(this.#context);
17
- }
18
-
19
- private static validateStdVersion(startingPoint: FileJp | Program) {
20
- const allowedVersions = ["c90", "c99", "c11"];
21
- const stdVersion = startingPoint instanceof Program ? startingPoint.standard : (startingPoint.root as Program).standard;
22
-
23
- if (!allowedVersions.includes(stdVersion)) {
24
- console.error(`[Clava-MISRATool] Invalid --std value. Allowed values: ${allowedVersions.join(", ")}`);
25
- process.exit(1);
26
- }
27
- }
17
+ public static context: MISRAContext;
18
+ static readonly #standards = new Set(["c90", "c99", "c11"]);
19
+ static readonly #ruleTypes = new Set(["all", "single", "system"]);
28
20
 
29
21
  public static checkCompliance(startingPoint: Program | FileJp = Query.root() as Program) {
30
- this.init(startingPoint);
22
+ this.init();
31
23
 
32
24
  const nodes = [startingPoint, ...startingPoint.descendants];
33
25
  for (const node of nodes) {
@@ -35,39 +27,42 @@ export default class MISRATool {
35
27
  rule.match(node, true);
36
28
  }
37
29
  }
38
- if (this.#context.errors.length > 0) {
39
- this.#context.printAllErrors();
40
- } else {
41
- console.log("[Clava-MISRATool] No MISRA-C violations detected.");
42
- }
30
+ this.outputReport(ExecutionMode.DETECTION);
43
31
  }
44
32
 
45
- public static applyCorrections(configFilePath?: string) {
46
- this.init(Query.root() as Program);
33
+ /**
34
+ * Transforms the source code to comply with the coding guidelines.
35
+ * After the transformation, any violations that could not be fixed will be displayed along with their justification.
36
+ */
37
+ public static correctViolations() {
38
+ this.init();
39
+
40
+ // Store config file in context, if provided
41
+ const configFilePath = this.getArgValue("config");
47
42
  if (configFilePath) {
48
- this.#context.config = configFilePath;
43
+ this.context.config = configFilePath;
49
44
  }
50
45
 
51
46
  let iteration = 0;
52
- let modified = false;
53
- do {
47
+ let modified = true;
48
+ while (modified) {
54
49
  console.log(`[Clava-MISRATool] Iteration #${++iteration}: Applying MISRA-C transformations...`);
55
50
  modified = this.transformAST(Query.root() as Program);
56
- } while(modified);
57
-
58
- if (this.#context.errors.length === 0) {
59
- console.log("[Clava-MISRATool] All detected violations were corrected.");
60
- } else {
61
- console.log("\n[Clava-MISRATool] Remaining MISRA-C violations:");
62
- this.#context.printActiveErrors();
63
51
  }
52
+ this.outputReport(ExecutionMode.CORRECTION);
64
53
  }
65
54
 
55
+ /**
56
+ * Recursively transforms the AST using a pre-order traversal
57
+ *
58
+ * @param $jp AST node from which to start the visit.
59
+ * @returns Return true if any modifications were made (removal, replacement, or changes in descendants). Otherwise, returns false.
60
+ */
66
61
  private static transformAST($jp: Joinpoint): boolean {
67
62
  let modified = false;
68
63
 
69
64
  for (const rule of this.#misraRules) {
70
- const transformReport = rule.transform($jp);
65
+ const transformReport = rule.apply($jp);
71
66
 
72
67
  if (transformReport.type !== MISRATransformationType.NoChange) {
73
68
  modified = true;
@@ -85,11 +80,82 @@ export default class MISRATool {
85
80
  return modified;
86
81
  }
87
82
 
83
+ private static init() {
84
+ this.validateStdVersion();
85
+ this.context = new MISRAContext();
86
+ resetCaches();
87
+ this.initRules();
88
+ }
89
+
90
+ /**
91
+ * Selects applicable rules according to the analysis type. When not specified, both system and single translation unit rules are selected.
92
+ */
93
+ private static initRules() {
94
+ const typeStr = this.getArgValue("type", this.#ruleTypes) ?? "all";
95
+ this.#misraRules = selectRules(this.context, typeStr);
96
+ }
97
+
98
+ /**
99
+ * Checks whether the provided standard version is valid and supported
100
+ */
101
+ private static validateStdVersion() {
102
+ const stdVersion = (Query.root() as Program).standard;
103
+
104
+ if (!this.#standards.has(stdVersion)) {
105
+ console.error(`[Clava-MISRATool] Invalid -std value. Allowed values: ${[...this.#standards].join(", ")}`);
106
+ process.exit(1);
107
+ }
108
+ }
109
+
110
+ private static getArgValue(field: string, validValues?: Set<string>): string | undefined{
111
+ const args = Clava.getData().get("argv") as string;
112
+ if (!args) return undefined;
113
+
114
+ const pair = args.split(/\s+/).find(arg => arg.startsWith(field + "="));
115
+ if (!pair) return undefined;
116
+
117
+ const value = pair.split("=")[1];
118
+ if (validValues && !validValues.has(value)) {
119
+ console.error(`[Clava-MISRATool] Invalid '${field}' value. Allowed values: ${[...validValues].join(", ")}`);
120
+ process.exit(1);
121
+ }
122
+ return value;
123
+ }
124
+
125
+ /**
126
+ * Displays standard violations based on execution mode.
127
+ * - In detection mode, all violations are shown.
128
+ * - In correction mode, only the remaining violations are displayed
129
+ *
130
+ * @param mode execution mode
131
+ */
132
+ private static outputReport(mode: ExecutionMode) {
133
+ const isDetection = mode === ExecutionMode.DETECTION;
134
+ const errorCount = isDetection ? this.getErrorCount() : this.getActiveErrorCount();
135
+
136
+ if (errorCount > 0) {
137
+ console.log(isDetection
138
+ ? `[Clava-MISRATool] Detected ${errorCount} MISRA-C violation${errorCount === 1 ? "" : "s"}:\n`
139
+ : `[Clava-MISRATool] ${errorCount} MISRA-C violation${errorCount === 1 ? "" : "s"} remain${errorCount === 1 ? "s" : ""} after transformation:\n`
140
+ );
141
+ isDetection ? this.context.outputAllErrors() : this.context.outputActiveErrors();
142
+ }
143
+ else {
144
+ console.log(isDetection ? "[Clava-MISRATool] No MISRA-C violations detected.\n" : "[Clava-MISRATool] All detected violations were corrected.\n");
145
+ }
146
+ }
147
+
148
+ /**
149
+ * @returns Returns the number of identified violations.
150
+ */
88
151
  public static getErrorCount(): number {
89
- return this.#context.errors.length;
152
+ return this.context.errors.length;
90
153
  }
91
154
 
155
+ /**
156
+ * @returns Returns the number of active errors linked to nodes that are still present in the AST after correction.
157
+ */
92
158
  public static getActiveErrorCount(): number {
93
- return this.#context.activeErrors.length;
159
+ return this.context.activeErrors.length;
94
160
  }
95
161
  }
@@ -0,0 +1,23 @@
1
+ import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import Context from "./ast-visitor/Context.js";
3
+ import VisitWithContext from "./ast-visitor/VisitWithContext.js";
4
+
5
+ /**
6
+ * Represents a standard guideline that detects and corrects violations in the code according to a particular coding standard.
7
+ *
8
+ * Need to implement/define:
9
+ * - initialValue()
10
+ * - match($jp, logErrors)
11
+ * - apply($jp)
12
+ */
13
+ export default abstract class StandardGuideline<T,C extends Context<T> = Context<T>> extends VisitWithContext<T, C> {
14
+
15
+ /**
16
+ * Checks if the joinpoint violates the guideline
17
+ *
18
+ * @param $jp - Joinpoint to analyze
19
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
20
+ * @returns Returns true if the joinpoint violates the guideline, false otherwise
21
+ */
22
+ abstract match($jp: Joinpoint, logErrors: boolean): boolean;
23
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Key-value storage to share data between visits
3
+ *
4
+ * @template T Type of the stored values
5
+ */
6
+ export default class Context<T> {
7
+ protected storage: Map<string, T> = new Map();
8
+
9
+ put(key: string, value: T) {
10
+ this.storage.set(key, value);
11
+ }
12
+
13
+ get(key: string): T | undefined {
14
+ return this.storage.get(key);
15
+ }
16
+ }
@@ -0,0 +1,26 @@
1
+ import { LaraJoinPoint } from "@specs-feup/lara/api/LaraJoinPoint.js";
2
+
3
+ /**
4
+ * Common interface for AST transformations applied to a single node
5
+ *
6
+ * Need to implement:
7
+ * - apply($jp)
8
+ *
9
+ * @template T Type of data stored in the shared context
10
+ * @template C Type of the context (default is Context<T>)
11
+ */
12
+ export default abstract class Visit {
13
+ /**
14
+ * Applies the transformation to the given node
15
+ * @param $jp The node to transform
16
+ * @returns Transformation result
17
+ */
18
+ abstract apply($jp: LaraJoinPoint): unknown;
19
+
20
+ /**
21
+ * @returns List of dependent visits, which is empty by default
22
+ */
23
+ get dependencies(): Visit[] {
24
+ return [];
25
+ }
26
+ }
@@ -0,0 +1,42 @@
1
+ import { LaraJoinPoint } from "@specs-feup/lara/api/LaraJoinPoint.js";
2
+ import Context from "./Context.js";
3
+ import Visit from "./Visit.js";
4
+
5
+ /**
6
+ * Visit with a shared context to enable communication between visits
7
+ *
8
+ * Need to implement:
9
+ * - apply($jp)
10
+ * - initialValue()
11
+ */
12
+ export default abstract class VisitWithContext<T, C extends Context<T> = Context<T>> extends Visit {
13
+ protected context: C;
14
+
15
+ /**
16
+ * @param context Shared context object
17
+ */
18
+ constructor(context: C) {
19
+ super();
20
+ this.context = context;
21
+ this.context.put(this.name, this.initialValue());
22
+ }
23
+
24
+ /**
25
+ * @return Visit name, defaults to class name
26
+ */
27
+ get name(): string {
28
+ return this.constructor.name;
29
+ }
30
+
31
+ /**
32
+ * @returns Initial value stored in the shared context
33
+ */
34
+ abstract initialValue(): T;
35
+
36
+ /**
37
+ * Applies the transformation to the given node
38
+ * @param $jp The node to transform
39
+ * @returns Transformation result
40
+ */
41
+ abstract apply($jp: LaraJoinPoint): unknown;
42
+ }
package/src/main.ts CHANGED
@@ -2,6 +2,6 @@ import VisualizationTool from "@specs-feup/clava-visualization/api/Visualization
2
2
  import MISRATool from "./MISRATool.js";
3
3
 
4
4
  MISRATool.checkCompliance();
5
- MISRATool.applyCorrections();
5
+ MISRATool.correctViolations();
6
6
 
7
7
  //await VisualizationTool.visualize();
@@ -0,0 +1,114 @@
1
+ import { BinaryOp, Call, FileJp, Joinpoint, ParenExpr, UnaryExprOrType, UnaryOp, VariableArrayType, Varref } from "@specs-feup/clava/api/Joinpoints.js";
2
+ import MISRARule from "../../MISRARule.js";
3
+ import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
4
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
5
+ import { getVolatileVarRefs } from "../../utils/VarUtils.js";
6
+ import { isValidFile } from "../../utils/FileUtils.js";
7
+ import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
8
+
9
+ /**
10
+ * MISRA-C Rule 13.6: The operand of the sizeof operator shall not contain any expression which has potential side effects
11
+ */
12
+ export default class Rule_13_6_SafeSizeOfOperand extends MISRARule {
13
+ /**
14
+ * Scope of analysis
15
+ */
16
+ analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
17
+
18
+ #modifyingExpressions: (UnaryOp | BinaryOp)[] = [];
19
+ #functionCalls: Call[] = [];
20
+ #volatileRefs: Varref[] = [];
21
+
22
+ /**
23
+ * @returns Rule identifier according to MISRA-C:2012
24
+ */
25
+ override get name(): string {
26
+ return "13.6";
27
+ }
28
+
29
+ private operandIsVariableArrayType($jp: UnaryExprOrType) {
30
+ return $jp.argType != undefined && $jp.argType instanceof VariableArrayType;
31
+ }
32
+
33
+ /**
34
+ *
35
+ * @param $jp - Joinpoint to analyze
36
+ * @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
37
+ * @returns Returns true if the joinpoint violates the rule, false otherwise
38
+ */
39
+ match($jp: Joinpoint, logErrors: boolean = false): boolean {
40
+ if (!($jp instanceof UnaryExprOrType && $jp.kind === "sizeof")) {
41
+ return false;
42
+ }
43
+
44
+ this.#functionCalls = Query.searchFromInclusive($jp, Call).get();
45
+ this.#volatileRefs = this.operandIsVariableArrayType($jp) ? getVolatileVarRefs(($jp.argType as VariableArrayType).sizeExpr) : [];
46
+ this.#modifyingExpressions = [
47
+ ...Query.searchFromInclusive($jp, UnaryOp, {kind: /(post_inc)|(post_dec)|(pre_inc)|(pre_dec)/}).get(),
48
+ ...Query.searchFromInclusive($jp, BinaryOp, {kind: /(assign)|(add_assign)|(sub_assign)|(mul_assign)|(div_assign)|(rem_assign)|(shl_assign)|(shr_assign)|(and_assign)|(xor_assign)|(or_assign)/}).get()
49
+ ];
50
+
51
+ const isNonCompliant = this.#functionCalls.length > 0 || this.#modifyingExpressions.length > 0 || this.#volatileRefs.length > 0;
52
+
53
+ if (isNonCompliant && logErrors) {
54
+ this.#functionCalls.forEach(call => {
55
+ this.logMISRAError(call, `Function call '${call.name}' in sizeof is not allowed because it has no effect.`);
56
+ });
57
+
58
+ this.#modifyingExpressions.forEach(expr => {
59
+ this.logMISRAError(expr, `Modifying expression '${expr.code}' in sizeof is not allowed because it has no effect.`);
60
+ });
61
+
62
+ this.#volatileRefs.forEach(ref => {
63
+ this.logMISRAError(ref, `Access to volatile object ${ref.name} in sizeof is not allowed.`);
64
+ });
65
+ }
66
+
67
+ return isNonCompliant;
68
+ }
69
+
70
+ apply($jp: Joinpoint): MISRATransformationReport {
71
+ if (!this.match($jp)) {
72
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
73
+ }
74
+
75
+ if (!this.operandIsVariableArrayType($jp as UnaryExprOrType)) {
76
+ for (const callJp of this.#functionCalls) {
77
+ const callAncestor = callJp.getAncestor("call");
78
+ if (callAncestor === undefined || callAncestor.depth < $jp.depth) {
79
+ const functionType = callJp.functionType.returnType;
80
+ const fileJp = callJp.getAncestor("file") as FileJp;
81
+ const tempJp = fileJp.lastChild.insertAfter(ClavaJoinPoints.stmtLiteral(`static int _temp_misra_var = sizeof(${functionType.code});`));
82
+ const jpIndex = Query.searchFrom(fileJp, UnaryExprOrType).get().length;
83
+
84
+ let newSizeOf = isValidFile(fileJp, UnaryExprOrType, jpIndex) as UnaryExprOrType;
85
+ newSizeOf = $jp.replaceWith(newSizeOf) as UnaryExprOrType;
86
+ newSizeOf.setArgType(functionType);
87
+ tempJp.detach();
88
+ return new MISRATransformationReport(MISRATransformationType.Replacement, newSizeOf);
89
+ }
90
+ }
91
+
92
+ for (const expr of this.#modifyingExpressions) {
93
+ let varRef = expr instanceof BinaryOp ?
94
+ expr.left : Query.searchFrom(expr, Varref).get()[0];
95
+ expr.replaceWith(varRef);
96
+ }
97
+ return new MISRATransformationReport(MISRATransformationType.DescendantChange);
98
+ }
99
+ else {
100
+ this.#functionCalls.forEach(call => {
101
+ this.logMISRAError(call, `Function call '${call.name}' in sizeof is not allowed. Could not correct because it is used to define a variable-length array type and it is unspecified whether it will be evaluated or not.`);
102
+ });
103
+
104
+ this.#modifyingExpressions.forEach(expr => {
105
+ this.logMISRAError(expr, `Modifying expression '${expr.code}' in sizeof is not allowed. Could not correct because it is used to define a variable-length array type and it is unspecified whether it will be evaluated or not.`);
106
+ });
107
+
108
+ this.#volatileRefs.forEach(ref => {
109
+ this.logMISRAError(ref,`Access to volatile object '${ref.name}' in sizeof is not allowed. Could not correct because it is used to define a variable-length array type and it is unspecified whether it will be evaluated or not.`);
110
+ });
111
+ return new MISRATransformationReport(MISRATransformationType.NoChange);
112
+ }
113
+ }
114
+ }