@specs-feup/clava-misra 1.0.0 → 1.0.2

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 (352) hide show
  1. package/.gitignore +117 -0
  2. package/README.md +70 -15
  3. package/dist/MISRA.d.ts +129 -0
  4. package/dist/MISRA.d.ts.map +1 -0
  5. package/dist/MISRA.js +245 -0
  6. package/dist/MISRA.js.map +1 -0
  7. package/dist/MISRAContext.d.ts +21 -0
  8. package/dist/MISRAContext.d.ts.map +1 -0
  9. package/dist/MISRAContext.js +75 -0
  10. package/dist/MISRAContext.js.map +1 -0
  11. package/dist/MISRARule.d.ts +56 -0
  12. package/dist/MISRARule.d.ts.map +1 -0
  13. package/dist/MISRARule.js +45 -0
  14. package/dist/MISRARule.js.map +1 -0
  15. package/dist/MISRATool.d.ts +12 -0
  16. package/dist/MISRATool.d.ts.map +1 -0
  17. package/dist/MISRATool.js +84 -0
  18. package/dist/MISRATool.js.map +1 -0
  19. package/dist/foo.d.ts +2 -0
  20. package/dist/foo.d.ts.map +1 -0
  21. package/{src/foo.ts → dist/foo.js} +3 -2
  22. package/dist/foo.js.map +1 -0
  23. package/dist/main.d.ts +2 -0
  24. package/dist/main.d.ts.map +1 -0
  25. package/dist/main.js +5 -0
  26. package/dist/main.js.map +1 -0
  27. package/dist/misra/MISRAAnalyser.d.ts +14 -0
  28. package/dist/misra/MISRAAnalyser.d.ts.map +1 -0
  29. package/{src/misra/MISRAAnalyser.ts → dist/misra/MISRAAnalyser.js} +13 -23
  30. package/dist/misra/MISRAAnalyser.js.map +1 -0
  31. package/dist/misra/MISRAPass.d.ts +27 -0
  32. package/dist/misra/MISRAPass.d.ts.map +1 -0
  33. package/dist/misra/MISRAPass.js +60 -0
  34. package/dist/misra/MISRAPass.js.map +1 -0
  35. package/dist/misra/MISRAPassResult.d.ts +13 -0
  36. package/dist/misra/MISRAPassResult.d.ts.map +1 -0
  37. package/dist/misra/MISRAPassResult.js +11 -0
  38. package/dist/misra/MISRAPassResult.js.map +1 -0
  39. package/dist/misra/MISRAReporter.d.ts +20 -0
  40. package/dist/misra/MISRAReporter.d.ts.map +1 -0
  41. package/dist/misra/MISRAReporter.js +43 -0
  42. package/dist/misra/MISRAReporter.js.map +1 -0
  43. package/dist/misra/passes/S10_EssentialTypePass.d.ts +42 -0
  44. package/dist/misra/passes/S10_EssentialTypePass.d.ts.map +1 -0
  45. package/dist/misra/passes/S10_EssentialTypePass.js +370 -0
  46. package/dist/misra/passes/S10_EssentialTypePass.js.map +1 -0
  47. package/dist/misra/passes/S12_ExpressionPass.d.ts +18 -0
  48. package/dist/misra/passes/S12_ExpressionPass.d.ts.map +1 -0
  49. package/dist/misra/passes/S12_ExpressionPass.js +72 -0
  50. package/dist/misra/passes/S12_ExpressionPass.js.map +1 -0
  51. package/dist/misra/passes/S13_SideEffectPass.d.ts +18 -0
  52. package/dist/misra/passes/S13_SideEffectPass.d.ts.map +1 -0
  53. package/dist/misra/passes/S13_SideEffectPass.js +105 -0
  54. package/dist/misra/passes/S13_SideEffectPass.js.map +1 -0
  55. package/dist/misra/passes/S15_ControlFlowPass.d.ts +19 -0
  56. package/dist/misra/passes/S15_ControlFlowPass.d.ts.map +1 -0
  57. package/dist/misra/passes/S15_ControlFlowPass.js +94 -0
  58. package/dist/misra/passes/S15_ControlFlowPass.js.map +1 -0
  59. package/dist/misra/passes/S16_SwitchStatementPass.d.ts +17 -0
  60. package/dist/misra/passes/S16_SwitchStatementPass.d.ts.map +1 -0
  61. package/dist/misra/passes/S16_SwitchStatementPass.js +152 -0
  62. package/dist/misra/passes/S16_SwitchStatementPass.js.map +1 -0
  63. package/dist/misra/passes/S17_FunctionPass.d.ts +12 -0
  64. package/dist/misra/passes/S17_FunctionPass.d.ts.map +1 -0
  65. package/dist/misra/passes/S17_FunctionPass.js +38 -0
  66. package/dist/misra/passes/S17_FunctionPass.js.map +1 -0
  67. package/dist/misra/passes/S18_PointersArraysPass.d.ts +17 -0
  68. package/dist/misra/passes/S18_PointersArraysPass.d.ts.map +1 -0
  69. package/dist/misra/passes/S18_PointersArraysPass.js +115 -0
  70. package/dist/misra/passes/S18_PointersArraysPass.js.map +1 -0
  71. package/dist/misra/passes/S19_OverlappingStoragePass.d.ts +11 -0
  72. package/dist/misra/passes/S19_OverlappingStoragePass.d.ts.map +1 -0
  73. package/dist/misra/passes/S19_OverlappingStoragePass.js +20 -0
  74. package/dist/misra/passes/S19_OverlappingStoragePass.js.map +1 -0
  75. package/dist/misra/passes/S21_StandardLibPass.d.ts +20 -0
  76. package/dist/misra/passes/S21_StandardLibPass.d.ts.map +1 -0
  77. package/dist/misra/passes/S21_StandardLibPass.js +77 -0
  78. package/dist/misra/passes/S21_StandardLibPass.js.map +1 -0
  79. package/dist/misra/passes/S3_CommentPass.d.ts +12 -0
  80. package/dist/misra/passes/S3_CommentPass.d.ts.map +1 -0
  81. package/dist/misra/passes/S3_CommentPass.js +27 -0
  82. package/dist/misra/passes/S3_CommentPass.js.map +1 -0
  83. package/dist/misra/passes/S5_IdentifierPass.d.ts +13 -0
  84. package/dist/misra/passes/S5_IdentifierPass.d.ts.map +1 -0
  85. package/dist/misra/passes/S5_IdentifierPass.js +60 -0
  86. package/dist/misra/passes/S5_IdentifierPass.js.map +1 -0
  87. package/dist/misra/passes/S6_TypePass.d.ts +11 -0
  88. package/dist/misra/passes/S6_TypePass.d.ts.map +1 -0
  89. package/dist/misra/passes/S6_TypePass.js +25 -0
  90. package/dist/misra/passes/S6_TypePass.js.map +1 -0
  91. package/dist/misra/passes/S7_LiteralsConstantsPass.d.ts +14 -0
  92. package/dist/misra/passes/S7_LiteralsConstantsPass.d.ts.map +1 -0
  93. package/dist/misra/passes/S7_LiteralsConstantsPass.js +71 -0
  94. package/dist/misra/passes/S7_LiteralsConstantsPass.js.map +1 -0
  95. package/dist/misra/passes/S8_DeclDefPass.d.ts +18 -0
  96. package/dist/misra/passes/S8_DeclDefPass.d.ts.map +1 -0
  97. package/dist/misra/passes/S8_DeclDefPass.js +127 -0
  98. package/dist/misra/passes/S8_DeclDefPass.js.map +1 -0
  99. package/dist/misra/sections/Section10_EssentialTypeModel.d.ts +33 -0
  100. package/dist/misra/sections/Section10_EssentialTypeModel.d.ts.map +1 -0
  101. package/{src/misra/sections/Section10_EssentialTypeModel.ts → dist/misra/sections/Section10_EssentialTypeModel.js} +58 -73
  102. package/dist/misra/sections/Section10_EssentialTypeModel.js.map +1 -0
  103. package/dist/misra/sections/Section11_PointerTypeConversions.d.ts +12 -0
  104. package/dist/misra/sections/Section11_PointerTypeConversions.d.ts.map +1 -0
  105. package/{src/misra/sections/Section11_PointerTypeConversions.ts → dist/misra/sections/Section11_PointerTypeConversions.js} +16 -27
  106. package/dist/misra/sections/Section11_PointerTypeConversions.js.map +1 -0
  107. package/dist/misra/sections/Section12_Expressions.d.ts +15 -0
  108. package/dist/misra/sections/Section12_Expressions.d.ts.map +1 -0
  109. package/dist/misra/sections/Section12_Expressions.js +70 -0
  110. package/dist/misra/sections/Section12_Expressions.js.map +1 -0
  111. package/dist/misra/sections/Section13_SideEffects.d.ts +14 -0
  112. package/dist/misra/sections/Section13_SideEffects.d.ts.map +1 -0
  113. package/dist/misra/sections/Section13_SideEffects.js +90 -0
  114. package/dist/misra/sections/Section13_SideEffects.js.map +1 -0
  115. package/dist/misra/sections/Section14_ControlStmtExprs.d.ts +8 -0
  116. package/dist/misra/sections/Section14_ControlStmtExprs.d.ts.map +1 -0
  117. package/{src/misra/sections/Section14_ControlStmtExprs.ts → dist/misra/sections/Section14_ControlStmtExprs.js} +8 -10
  118. package/dist/misra/sections/Section14_ControlStmtExprs.js.map +1 -0
  119. package/dist/misra/sections/Section15_ControlFlow.d.ts +14 -0
  120. package/dist/misra/sections/Section15_ControlFlow.d.ts.map +1 -0
  121. package/dist/misra/sections/Section15_ControlFlow.js +97 -0
  122. package/dist/misra/sections/Section15_ControlFlow.js.map +1 -0
  123. package/dist/misra/sections/Section16_SwitchStatements.d.ts +13 -0
  124. package/dist/misra/sections/Section16_SwitchStatements.d.ts.map +1 -0
  125. package/{src/misra/sections/Section16_SwitchStatements.ts → dist/misra/sections/Section16_SwitchStatements.js} +49 -74
  126. package/dist/misra/sections/Section16_SwitchStatements.js.map +1 -0
  127. package/dist/misra/sections/Section17_Functions.d.ts +9 -0
  128. package/dist/misra/sections/Section17_Functions.d.ts.map +1 -0
  129. package/{src/misra/sections/Section17_Functions.ts → dist/misra/sections/Section17_Functions.js} +10 -13
  130. package/dist/misra/sections/Section17_Functions.js.map +1 -0
  131. package/dist/misra/sections/Section18_PointersAndArrays.d.ts +13 -0
  132. package/dist/misra/sections/Section18_PointersAndArrays.d.ts.map +1 -0
  133. package/{src/misra/sections/Section18_PointersAndArrays.ts → dist/misra/sections/Section18_PointersAndArrays.js} +36 -40
  134. package/dist/misra/sections/Section18_PointersAndArrays.js.map +1 -0
  135. package/dist/misra/sections/Section19_OverlappingStorage.d.ts +8 -0
  136. package/dist/misra/sections/Section19_OverlappingStorage.d.ts.map +1 -0
  137. package/dist/misra/sections/Section19_OverlappingStorage.js +16 -0
  138. package/dist/misra/sections/Section19_OverlappingStorage.js.map +1 -0
  139. package/dist/misra/sections/Section20_PreprocessingDirectives.d.ts +8 -0
  140. package/dist/misra/sections/Section20_PreprocessingDirectives.d.ts.map +1 -0
  141. package/{src/misra/sections/Section20_PreprocessingDirectives.ts → dist/misra/sections/Section20_PreprocessingDirectives.js} +7 -9
  142. package/dist/misra/sections/Section20_PreprocessingDirectives.js.map +1 -0
  143. package/dist/misra/sections/Section21_StandardLibraries.d.ts +17 -0
  144. package/dist/misra/sections/Section21_StandardLibraries.d.ts.map +1 -0
  145. package/dist/misra/sections/Section21_StandardLibraries.js +54 -0
  146. package/dist/misra/sections/Section21_StandardLibraries.js.map +1 -0
  147. package/dist/misra/sections/Section2_UnusedCode.d.ts +9 -0
  148. package/dist/misra/sections/Section2_UnusedCode.d.ts.map +1 -0
  149. package/{src/misra/sections/Section2_UnusedCode.ts → dist/misra/sections/Section2_UnusedCode.js} +11 -16
  150. package/dist/misra/sections/Section2_UnusedCode.js.map +1 -0
  151. package/dist/misra/sections/Section3_Comments.d.ts +9 -0
  152. package/dist/misra/sections/Section3_Comments.d.ts.map +1 -0
  153. package/{src/misra/sections/Section3_Comments.ts → dist/misra/sections/Section3_Comments.js} +7 -10
  154. package/dist/misra/sections/Section3_Comments.js.map +1 -0
  155. package/dist/misra/sections/Section5_Identifiers.d.ts +12 -0
  156. package/dist/misra/sections/Section5_Identifiers.d.ts.map +1 -0
  157. package/dist/misra/sections/Section5_Identifiers.js +139 -0
  158. package/dist/misra/sections/Section5_Identifiers.js.map +1 -0
  159. package/dist/misra/sections/Section6_Types.d.ts +8 -0
  160. package/dist/misra/sections/Section6_Types.d.ts.map +1 -0
  161. package/dist/misra/sections/Section6_Types.js +23 -0
  162. package/dist/misra/sections/Section6_Types.js.map +1 -0
  163. package/dist/misra/sections/Section7_LiteralsConstants.d.ts +11 -0
  164. package/dist/misra/sections/Section7_LiteralsConstants.d.ts.map +1 -0
  165. package/{src/misra/sections/Section7_LiteralsConstants.ts → dist/misra/sections/Section7_LiteralsConstants.js} +18 -25
  166. package/dist/misra/sections/Section7_LiteralsConstants.js.map +1 -0
  167. package/dist/misra/sections/Section8_DeclarationsDefinitions.d.ts +15 -0
  168. package/dist/misra/sections/Section8_DeclarationsDefinitions.d.ts.map +1 -0
  169. package/{src/misra/sections/Section8_DeclarationsDefinitions.ts → dist/misra/sections/Section8_DeclarationsDefinitions.js} +18 -33
  170. package/dist/misra/sections/Section8_DeclarationsDefinitions.js.map +1 -0
  171. package/dist/misra/tests/utils.d.ts +10 -0
  172. package/dist/misra/tests/utils.d.ts.map +1 -0
  173. package/dist/misra/tests/utils.js +33 -0
  174. package/dist/misra/tests/utils.js.map +1 -0
  175. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts +15 -0
  176. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts.map +1 -0
  177. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js +33 -0
  178. package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js.map +1 -0
  179. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts +16 -0
  180. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts.map +1 -0
  181. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js +60 -0
  182. package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js.map +1 -0
  183. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts +19 -0
  184. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts.map +1 -0
  185. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js +42 -0
  186. package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js.map +1 -0
  187. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts +43 -0
  188. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts.map +1 -0
  189. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js +103 -0
  190. package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js.map +1 -0
  191. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts +26 -0
  192. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts.map +1 -0
  193. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js +49 -0
  194. package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js.map +1 -0
  195. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts +26 -0
  196. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts.map +1 -0
  197. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js +49 -0
  198. package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js.map +1 -0
  199. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts +31 -0
  200. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts.map +1 -0
  201. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js +71 -0
  202. package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js.map +1 -0
  203. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts +27 -0
  204. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts.map +1 -0
  205. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js +58 -0
  206. package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js.map +1 -0
  207. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts +28 -0
  208. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts.map +1 -0
  209. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js +44 -0
  210. package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js.map +1 -0
  211. package/dist/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.d.ts +55 -0
  212. package/dist/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.d.ts.map +1 -0
  213. package/dist/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.js +108 -0
  214. package/dist/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.js.map +1 -0
  215. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts +43 -0
  216. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts.map +1 -0
  217. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js +68 -0
  218. package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js.map +1 -0
  219. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts +29 -0
  220. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts.map +1 -0
  221. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js +53 -0
  222. package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js.map +1 -0
  223. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts +15 -0
  224. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts.map +1 -0
  225. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js +35 -0
  226. package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js.map +1 -0
  227. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts +13 -0
  228. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts.map +1 -0
  229. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js +53 -0
  230. package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js.map +1 -0
  231. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts +13 -0
  232. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts.map +1 -0
  233. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js +32 -0
  234. package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js.map +1 -0
  235. package/dist/rules/Section3_Comments/Rule_3_2_LineSplicing.d.ts +10 -0
  236. package/dist/rules/Section3_Comments/Rule_3_2_LineSplicing.d.ts.map +1 -0
  237. package/dist/rules/Section3_Comments/Rule_3_2_LineSplicing.js +26 -0
  238. package/dist/rules/Section3_Comments/Rule_3_2_LineSplicing.js.map +1 -0
  239. package/dist/rules/index.d.ts +20 -0
  240. package/dist/rules/index.d.ts.map +1 -0
  241. package/dist/rules/index.js +38 -0
  242. package/dist/rules/index.js.map +1 -0
  243. package/dist/tests/Section17_Functions/misra_config.json +10 -0
  244. package/dist/tests/utils.d.ts +10 -0
  245. package/dist/tests/utils.d.ts.map +1 -0
  246. package/dist/tests/utils.js +29 -0
  247. package/dist/tests/utils.js.map +1 -0
  248. package/dist/utils/utils.d.ts +102 -0
  249. package/dist/utils/utils.d.ts.map +1 -0
  250. package/dist/utils/utils.js +202 -0
  251. package/dist/utils/utils.js.map +1 -0
  252. package/jest.config.js +6 -6
  253. package/package.json +44 -8
  254. package/src/MISRA.ts +276 -0
  255. package/src/MISRAContext.ts +84 -0
  256. package/src/MISRARule.ts +64 -0
  257. package/src/MISRATool.ts +95 -0
  258. package/src/main.ts +4 -33
  259. package/src/misra-old/MISRAAnalyser.ts +60 -0
  260. package/src/misra-old/MISRAAnalyserResult.ts +16 -0
  261. package/src/misra-old/sections/Section10_EssentialTypeModel.ts +377 -0
  262. package/src/misra-old/sections/Section11_PointerTypeConversions.ts +104 -0
  263. package/src/{misra → misra-old}/sections/Section12_Expressions.ts +7 -7
  264. package/src/{misra → misra-old}/sections/Section13_SideEffects.ts +15 -15
  265. package/src/misra-old/sections/Section14_ControlStmtExprs.ts +27 -0
  266. package/src/{misra → misra-old}/sections/Section15_ControlFlow.ts +10 -10
  267. package/src/misra-old/sections/Section18_PointersAndArrays.ts +108 -0
  268. package/src/{misra → misra-old}/sections/Section19_OverlappingStorage.ts +4 -4
  269. package/src/misra-old/sections/Section20_PreprocessingDirectives.ts +22 -0
  270. package/src/misra-old/sections/Section21_StandardLibraries.ts +99 -0
  271. package/src/{misra → misra-old}/sections/Section5_Identifiers.ts +16 -15
  272. package/src/{misra → misra-old}/sections/Section6_Types.ts +4 -4
  273. package/src/misra-old/sections/Section7_LiteralsConstants.ts +76 -0
  274. package/src/misra-old/sections/Section8_DeclarationsDefinitions.ts +133 -0
  275. package/src/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.ts +41 -0
  276. package/src/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.ts +70 -0
  277. package/src/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.ts +41 -0
  278. package/src/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.ts +113 -0
  279. package/src/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.ts +61 -0
  280. package/src/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.ts +57 -0
  281. package/src/rules/Section17_Functions/Rule_17_3_ImplicitFunction.ts +180 -0
  282. package/src/rules/Section17_Functions/Rule_17_4_NonVoidReturn.ts +91 -0
  283. package/src/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.ts +68 -0
  284. package/src/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.ts +49 -0
  285. package/src/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.ts +120 -0
  286. package/src/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.ts +78 -0
  287. package/src/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.ts +61 -0
  288. package/src/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.ts +47 -0
  289. package/src/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.ts +67 -0
  290. package/src/rules/Section3_Comments/Rule_3_1_CommentSequences.ts +41 -0
  291. package/src/rules/Section3_Comments/Rule_3_2_LineSplicing.ts +36 -0
  292. package/src/rules/index.ts +44 -0
  293. package/src/tests/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.test.ts +55 -0
  294. package/src/tests/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.test.ts +70 -0
  295. package/src/tests/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.test.ts +128 -0
  296. package/src/tests/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.test.ts +132 -0
  297. package/src/tests/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.test.ts +146 -0
  298. package/src/tests/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.test.ts +102 -0
  299. package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions.test.ts +79 -0
  300. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn.test.ts +98 -0
  301. package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn_MissingConfig.test.ts +77 -0
  302. package/src/tests/Section17_Functions/Rule_17_6_StaticArraySizeParam.test.ts +36 -0
  303. package/src/tests/Section17_Functions/Rule_17_7_UnusedReturnValue.test.ts +44 -0
  304. package/src/tests/Section17_Functions/misra_config.json +19 -0
  305. package/src/tests/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.test.ts +175 -0
  306. package/src/tests/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.test.ts +219 -0
  307. package/src/tests/Section2_UnusedCode/Rule_2_6_UnusedLabels.test.ts +49 -0
  308. package/src/tests/Section2_UnusedCode/Rule_2_7_UnusedParameters.test.ts +55 -0
  309. package/src/tests/Section3_Comments/Rule_3_1_CommentSequences.test.ts +37 -0
  310. package/src/tests/utils.ts +51 -0
  311. package/src/utils/utils.ts +280 -0
  312. package/tsconfig.json +4 -3
  313. package/typedoc.config.js +1 -1
  314. package/CxxSources/lib.cpp +0 -3
  315. package/CxxSources/lib.h +0 -8
  316. package/CxxSources/main.cpp +0 -40
  317. package/TODO.md +0 -1
  318. package/consumer_order.txt +0 -2
  319. package/enum_integer_type.txt +0 -0
  320. package/is_temporary.txt +0 -0
  321. package/omp.txt +0 -0
  322. package/src/misra/passes/S16_SwitchStatementPass.ts +0 -168
  323. package/src/misra/passes/S3_CommentPass.ts +0 -40
  324. package/src/misra/sections/Section21_StandardLibraries.ts +0 -65
  325. package/src/misra/tests/S10_EssentialTypes.test.ts +0 -253
  326. package/src/misra/tests/S12_Expressions.test.ts +0 -43
  327. package/src/misra/tests/S13_SideEffects.test.ts +0 -77
  328. package/src/misra/tests/S15_ControlFlow.test.ts +0 -144
  329. package/src/misra/tests/S16_SwitchStatements.test.ts +0 -164
  330. package/src/misra/tests/S17_Functions.test.ts +0 -46
  331. package/src/misra/tests/S18_PointersArrays.test.ts +0 -167
  332. package/src/misra/tests/S19_OverlappingStorage.test.ts +0 -38
  333. package/src/misra/tests/S3_Comments.test.ts +0 -36
  334. package/src/misra/tests/S6_Types.test.ts +0 -36
  335. package/src/misra/tests/S7_LiteralsConstants.test.ts +0 -48
  336. package/src/misra/tests/utils.ts +0 -47
  337. package/types_with_templates.txt +0 -0
  338. /package/src/{misra → misra-old}/MISRAPass.ts +0 -0
  339. /package/src/{misra → misra-old}/MISRAPassResult.ts +0 -0
  340. /package/src/{misra → misra-old}/MISRAReporter.ts +0 -0
  341. /package/src/{misra → misra-old}/passes/S10_EssentialTypePass.ts +0 -0
  342. /package/src/{misra → misra-old}/passes/S12_ExpressionPass.ts +0 -0
  343. /package/src/{misra → misra-old}/passes/S13_SideEffectPass.ts +0 -0
  344. /package/src/{misra → misra-old}/passes/S15_ControlFlowPass.ts +0 -0
  345. /package/src/{misra → misra-old}/passes/S17_FunctionPass.ts +0 -0
  346. /package/src/{misra → misra-old}/passes/S18_PointersArraysPass.ts +0 -0
  347. /package/src/{misra → misra-old}/passes/S19_OverlappingStoragePass.ts +0 -0
  348. /package/src/{misra → misra-old}/passes/S21_StandardLibPass.ts +0 -0
  349. /package/src/{misra → misra-old}/passes/S5_IdentifierPass.ts +0 -0
  350. /package/src/{misra → misra-old}/passes/S6_TypePass.ts +0 -0
  351. /package/src/{misra → misra-old}/passes/S7_LiteralsConstantsPass.ts +0 -0
  352. /package/src/{misra → misra-old}/passes/S8_DeclDefPass.ts +0 -0
@@ -0,0 +1,377 @@
1
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
2
+ import { Program, FileJp, TernaryOp, UnaryOp, BinaryOp, Joinpoint, Cast, BuiltinType, Type, Expression, IntLiteral, EnumType, QualType, ReturnStmt, FunctionJp, Call, Op, ParenExpr, Varref } from "@specs-feup/clava/api/Joinpoints.js";
3
+ import MISRAAnalyser from "../MISRAAnalyser.js";
4
+ import Fix from "@specs-feup/clava/api/clava/analysis/Fix.js";
5
+ import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
6
+
7
+ export enum EssentialTypes {
8
+ UNSIGNED = "unsigned",
9
+ CHAR = "char",
10
+ SIGNED = "signed",
11
+ ENUM = "enum",
12
+ FLOAT = "float",
13
+ BOOL = "bool",
14
+ UNKOWN = "unkown"
15
+ };
16
+
17
+ export default class Section10_EssentialTypeModel extends MISRAAnalyser {
18
+ ruleMapper: Map<string, (jp: Program | FileJp) => void>;
19
+
20
+ constructor(rules?: string[]) {
21
+ super(rules);
22
+ this.ruleMapper = new Map([
23
+ ["10.1", this.r10_1_appropriateEssentialOperands.bind(this)],
24
+ ["10.2", this.r10_2_appropriateCharOperands.bind(this)],
25
+ ["10.3", this.r10_3_noInvalidAssignments.bind(this)],
26
+ ["10.5", this.r10_5_noInvalidCasts.bind(this)],
27
+ ["10.6", this.r10_6_noWiderCompositeExprAssignments.bind(this)],
28
+ ["10.8", this.r10_8_noWiderCompositeCasts.bind(this)]
29
+ ]);
30
+ }
31
+
32
+ static getEssentialType(bType: Type): EssentialTypes {
33
+ let type = bType.desugarAll;
34
+ while (type instanceof QualType) {
35
+ type = type.unqualifiedType.desugarAll;
36
+ }
37
+
38
+ if (type instanceof BuiltinType) {
39
+ if (type.builtinKind === "Bool") {
40
+ return EssentialTypes.BOOL;
41
+ }
42
+ else if (type.builtinKind === "Char_S") {
43
+ return EssentialTypes.CHAR;
44
+ }
45
+ else if (type.isInteger && type.isSigned) {
46
+ return EssentialTypes.SIGNED;
47
+ }
48
+ else if (type.isInteger && !type.isSigned) {
49
+ return EssentialTypes.UNSIGNED;
50
+ }
51
+ else if (type.isFloat) {
52
+ return EssentialTypes.FLOAT;
53
+ }
54
+ }
55
+ else if (type instanceof EnumType) {
56
+ return type.name === undefined ? EssentialTypes.SIGNED : EssentialTypes.ENUM;
57
+ }
58
+
59
+ return EssentialTypes.UNKOWN;
60
+ }
61
+
62
+ static isInteger($et: EssentialTypes): boolean {
63
+ return $et === EssentialTypes.SIGNED || $et === EssentialTypes.UNSIGNED;
64
+ }
65
+
66
+ static getExprEssentialType($expr: Expression): EssentialTypes {
67
+ if ($expr instanceof BinaryOp) {
68
+ if ($expr.kind === "add") {
69
+ if ((this.getExprEssentialType($expr.left) === EssentialTypes.CHAR && this.isInteger(this.getExprEssentialType($expr.right)))
70
+ || (this.getExprEssentialType($expr.right) === EssentialTypes.CHAR && this.isInteger(this.getExprEssentialType($expr.left)))) {
71
+ return EssentialTypes.CHAR;
72
+ }
73
+ }
74
+ else if ($expr.kind === "sub") {
75
+ if (this.getExprEssentialType($expr.left) === EssentialTypes.CHAR) {
76
+ if (this.getExprEssentialType($expr.right) === EssentialTypes.CHAR) {
77
+ return EssentialTypes.CHAR;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ return this.getEssentialType($expr.type);
83
+ }
84
+
85
+ private restrictOperand($expr: Expression, $restrictedType: EssentialTypes, $baseExpr: Expression, $castTo?: BuiltinType) {
86
+ const et = Section10_EssentialTypeModel.getExprEssentialType($expr);
87
+ if (et === $restrictedType) {
88
+ const fix = $castTo ? new Fix($expr, ($jp) => {
89
+ $jp.replaceWith(ClavaJoinPoints.cStyleCast($castTo, $jp as Expression));
90
+ }) : undefined;
91
+ this.logMISRAError(this.currentRule, $baseExpr, `Operand ${$expr.code} of expression ${$baseExpr.code} must not have essentially ${et} type.`, fix);
92
+ }
93
+ }
94
+
95
+ private restrictOperandList($expr: Expression, $restrictedTypes: EssentialTypes[], $baseExpr: Expression, $castTo?: BuiltinType) {
96
+ for (const type of $restrictedTypes) {
97
+ this.restrictOperand($expr, type, $baseExpr, $castTo);
98
+ }
99
+ }
100
+
101
+ private r10_1_appropriateEssentialOperands($startNode: Joinpoint) { //missing exception and compound operators
102
+ Query.searchFrom($startNode, Op).get().forEach(op => {
103
+ if (op instanceof TernaryOp) {
104
+ this.restrictOperandList(op.cond, [EssentialTypes.CHAR, EssentialTypes.ENUM, EssentialTypes.FLOAT, EssentialTypes.SIGNED, EssentialTypes.UNSIGNED], op);
105
+ }
106
+ else if (op instanceof BinaryOp) {
107
+ switch (op.kind) {
108
+ case "shl":
109
+ case "shr":
110
+ if (!(op.right instanceof IntLiteral)) this.restrictOperand(op.right, EssentialTypes.SIGNED, op);
111
+ case "and":
112
+ case "or":
113
+ case "x_or":
114
+ this.restrictOperand(op.left, EssentialTypes.SIGNED, op);
115
+ if (op.kind !== "shl" && op.kind !== "shr") this.restrictOperand(op.right, EssentialTypes.SIGNED, op);
116
+ case "rem":
117
+ this.restrictOperand(op.left, EssentialTypes.FLOAT, op);
118
+ this.restrictOperand(op.right, EssentialTypes.FLOAT, op);
119
+ case "mul":
120
+ case "div":
121
+ this.restrictOperand(op.left, EssentialTypes.CHAR, op);
122
+ this.restrictOperand(op.right, EssentialTypes.CHAR, op);
123
+ case "add":
124
+ case "sub":
125
+ this.restrictOperand(op.left, EssentialTypes.ENUM, op);
126
+ this.restrictOperand(op.right, EssentialTypes.ENUM, op);
127
+ case "le":
128
+ case "ge":
129
+ case "lt":
130
+ case "gt":
131
+ this.restrictOperand(op.left, EssentialTypes.BOOL, op);
132
+ this.restrictOperand(op.right, EssentialTypes.BOOL, op);
133
+ break;
134
+ case "l_and":
135
+ case "l_or":
136
+ this.restrictOperandList(op.left, [EssentialTypes.ENUM, EssentialTypes.CHAR, EssentialTypes.SIGNED, EssentialTypes.UNSIGNED, EssentialTypes.FLOAT], op);
137
+ this.restrictOperandList(op.right, [EssentialTypes.ENUM, EssentialTypes.CHAR, EssentialTypes.SIGNED, EssentialTypes.UNSIGNED, EssentialTypes.FLOAT], op);
138
+ break;
139
+ }
140
+ }
141
+ else if (op instanceof UnaryOp) {
142
+ switch (op.kind) {
143
+ case "minus":
144
+ this.restrictOperand(op.operand, EssentialTypes.UNSIGNED, op);
145
+ case "plus":
146
+ this.restrictOperandList(op.operand, [EssentialTypes.BOOL, EssentialTypes.CHAR, EssentialTypes.ENUM], op);
147
+ break;
148
+ case "l_not":
149
+ this.restrictOperandList(op.operand, [EssentialTypes.ENUM, EssentialTypes.CHAR, EssentialTypes.SIGNED, EssentialTypes.UNSIGNED, EssentialTypes.FLOAT], op);
150
+ break;
151
+ case "not":
152
+ this.restrictOperandList(op.operand, [EssentialTypes.BOOL, EssentialTypes.CHAR, EssentialTypes.ENUM, EssentialTypes.FLOAT, EssentialTypes.SIGNED], op);
153
+ break;
154
+ }
155
+ }
156
+ }, this);
157
+ }
158
+
159
+ private r10_2_appropriateCharOperands($startNode: Joinpoint) {
160
+ Query.searchFrom($startNode, BinaryOp, {kind: /(add|sub)/}).get().forEach(bOp => {
161
+ if (bOp.kind === "add") {
162
+ if (Section10_EssentialTypeModel.getExprEssentialType(bOp.left) === EssentialTypes.CHAR && Section10_EssentialTypeModel.getExprEssentialType(bOp.right) === EssentialTypes.CHAR) {
163
+ this.logMISRAError(this.currentRule, bOp, `Both operands of addition ${bOp.code} have essentially character type.`);
164
+ return;
165
+ }
166
+
167
+ let otherType;
168
+ if (Section10_EssentialTypeModel.getExprEssentialType(bOp.left) === EssentialTypes.CHAR) {
169
+ otherType = Section10_EssentialTypeModel.getExprEssentialType(bOp.right);
170
+ }
171
+ else if (Section10_EssentialTypeModel.getExprEssentialType(bOp.right) === EssentialTypes.CHAR) {
172
+ otherType = Section10_EssentialTypeModel.getExprEssentialType(bOp.left);
173
+ }
174
+
175
+ if (otherType && !Section10_EssentialTypeModel.isInteger(otherType)) {
176
+ this.logMISRAError(this.currentRule, bOp, `One operand of addition ${bOp.code} has essentially character type, so the other one must have either essentially signed or unsigned type.`);
177
+ return;
178
+ }
179
+ }
180
+ else if (bOp.kind === "sub") {
181
+ if (Section10_EssentialTypeModel.getExprEssentialType(bOp.left) === EssentialTypes.CHAR) {
182
+ const rightType = Section10_EssentialTypeModel.getExprEssentialType(bOp.right);
183
+ if (!([EssentialTypes.CHAR, EssentialTypes.SIGNED, EssentialTypes.UNKOWN].some(et => et === rightType))) {
184
+ this.logMISRAError(this.currentRule, bOp, `Left operand of subtraction ${bOp.code} has essentially character type, so the RHS must be essentially signed, unsigned, or char.`);
185
+ return;
186
+ }
187
+ }
188
+ else if (Section10_EssentialTypeModel.getExprEssentialType(bOp.right) === EssentialTypes.CHAR) {
189
+ this.logMISRAError(this.currentRule, bOp, `Right operand of subtraction ${bOp.code} can only be of essentially character type if the LHS is too.`);
190
+ return;
191
+ }
192
+ }
193
+ }, this);
194
+ }
195
+
196
+ private r10_3_noInvalidAssignments($startNode: Joinpoint) { //not working for decls
197
+ Query.searchFrom($startNode, BinaryOp, {kind: "assign"}).get().forEach(bOp => {
198
+ if (Section10_EssentialTypeModel.getEssentialType(bOp.left.type) !== Section10_EssentialTypeModel.getEssentialType(bOp.right.type)) {
199
+ this.logMISRAError(this.currentRule, bOp, `Value ${bOp.right.code} cannot be assigned to ${bOp.left.code}, since it has a different essential type category.`);
200
+ }
201
+ else if (bOp.left.bitWidth < bOp.right.bitWidth) {
202
+ this.logMISRAError(this.currentRule, bOp, `Value ${bOp.right.code} cannot be assigned to ${bOp.left.code} since it has a narrower type.`);
203
+ }
204
+ }, this);
205
+ Query.searchFrom($startNode, ReturnStmt).get().forEach(ret => {
206
+ const fun = ret.getAncestor("function") as FunctionJp;
207
+ //console.log(ret.returnExpr.code, ret.returnExpr.bitWidth);
208
+ //console.log(fun.bitWidth);
209
+ if (Section10_EssentialTypeModel.getEssentialType(ret.returnExpr.type) !== Section10_EssentialTypeModel.getEssentialType(fun.returnType)) {
210
+ this.logMISRAError(this.currentRule, ret, `Value ${ret.returnExpr.code} cannot be returned by ${fun.signature}, since it has a different essential type category.`);
211
+ }
212
+ else if (fun.bitWidth < ret.returnExpr.bitWidth) {
213
+ this.logMISRAError(this.currentRule, ret, `Value ${ret.returnExpr.code} cannot be returned by ${fun.signature} since it has a narrower type.`);
214
+ }
215
+ }, this);
216
+ Query.searchFrom($startNode, Call).get().forEach(call => {
217
+ const funParams = call.directCallee.params;
218
+ for (let i = 0; i < funParams.length; i++) {
219
+ if (Section10_EssentialTypeModel.getEssentialType(funParams[i].type) !== Section10_EssentialTypeModel.getEssentialType(call.argList[0].type)) {
220
+ this.logMISRAError(this.currentRule, call, `Value ${call.argList[i].code} cannot be assigned to parameter ${funParams[i].code}, since it has a different essential type category.`);
221
+ }
222
+ else if (funParams[i].bitWidth < call.argList[i].bitWidth) {
223
+ this.logMISRAError(this.currentRule, call, `Value ${call.argList[i].code} cannot be assigned to parameter ${funParams[i].code}, since it has a narrower type.`);
224
+ }
225
+ }
226
+ }, this);
227
+ }
228
+
229
+ private static checkBoolSource(subExpr: Expression) {
230
+ if (subExpr.type.desugarAll instanceof BuiltinType && subExpr.type.desugarAll.builtinKind === "Bool") {
231
+ return true;
232
+ }
233
+ else if (subExpr instanceof IntLiteral && (Number(subExpr.value) === 0 || Number(subExpr.value) === 1)) {
234
+ return true;
235
+ }
236
+ else return false;
237
+ }
238
+
239
+ private r10_5_noInvalidCasts($startNode: Joinpoint) {//chars, anonymous enums
240
+ Query.searchFrom($startNode, Cast).get().forEach(cast => {
241
+ const fromType = cast.fromType.desugarAll;
242
+ const toType = cast.toType.desugarAll;
243
+
244
+ if (toType instanceof BuiltinType) {
245
+ console.log(toType.builtinKind)
246
+ }
247
+
248
+ if (toType instanceof BuiltinType && toType.builtinKind === "Bool" && !Section10_EssentialTypeModel.checkBoolSource(cast.subExpr)) {
249
+ this.logMISRAError(this.currentRule, cast, "Only essentially boolean values, or the integer constants 0 or 1, may be cast to an essentially boolean type.");
250
+ }
251
+ else if (toType instanceof EnumType && !(fromType instanceof EnumType && toType.name === fromType.name)) {
252
+ this.logMISRAError(this.currentRule, cast, "Only essentially enum values of the same enum may be cast to an essentially enum type.");
253
+ }
254
+ else if (toType instanceof BuiltinType && toType.builtinKind === "Int" && toType.isSigned && fromType instanceof BuiltinType && fromType.builtinKind === "Bool") {
255
+ this.logMISRAError(this.currentRule, cast, "Essentially boolean values should not be cast to an essentially signed type.");
256
+ }
257
+ else if (toType instanceof BuiltinType && toType.builtinKind === "Int" && !toType.isSigned && fromType instanceof BuiltinType && fromType.builtinKind === "Bool") {
258
+ this.logMISRAError(this.currentRule, cast, "Essentially boolean values should not be cast to an essentially unsigned type.");
259
+ }
260
+ else if (toType instanceof BuiltinType && toType.isFloat && fromType instanceof BuiltinType && fromType.builtinKind === "Bool") {
261
+ this.logMISRAError(this.currentRule, cast, "Essentially boolean values should not be cast to an essentially floating type.");
262
+ }
263
+ }, this);
264
+ }
265
+
266
+ private static isCompositeBinaryExpr($op: BinaryOp) {
267
+ return /(add)|(sub)|(mul)|(div)|(rem)|(shl)|(shr)|(l_and)|(l_or)|(xor)/.test($op.kind);
268
+ }
269
+
270
+ private static isCompositeExpr($expr: Expression): Expression | undefined {
271
+ if ($expr instanceof ParenExpr) {
272
+ return this.isCompositeExpr($expr.subExpr);
273
+ }
274
+ else if ($expr instanceof BinaryOp) {
275
+ if (this.isCompositeBinaryExpr($expr)) {
276
+ return $expr;
277
+ }
278
+ }
279
+ else if ($expr instanceof TernaryOp) {
280
+ if (this.isCompositeExpr($expr.trueExpr) || this.isCompositeExpr($expr.falseExpr)) {
281
+ return $expr;
282
+ }
283
+ }
284
+ else return undefined;
285
+ }
286
+
287
+ private static compositeExprWidth($op: Expression): number {
288
+ if ($op instanceof BinaryOp && Section10_EssentialTypeModel.isCompositeBinaryExpr($op)) {
289
+ const leftW = Section10_EssentialTypeModel.compositeExprWidth($op.left);
290
+ const rightW = Section10_EssentialTypeModel.compositeExprWidth($op.right);
291
+ return Math.max(leftW, rightW);
292
+ }
293
+ else if ($op instanceof TernaryOp) {
294
+ const secondW = Section10_EssentialTypeModel.compositeExprWidth($op.trueExpr);
295
+ const thirdW = Section10_EssentialTypeModel.compositeExprWidth($op.falseExpr);
296
+ return Math.min(secondW, thirdW);
297
+ }
298
+ else if ($op instanceof ParenExpr) {
299
+ return this.compositeExprWidth($op.subExpr);
300
+ }
301
+ else return $op.bitWidth;
302
+ }
303
+
304
+ private static transformBinaryOp($expr: BinaryOp, $type: Type) {
305
+ $expr.left.replaceWith(ClavaJoinPoints.cStyleCast($type, $expr.left));
306
+ }
307
+
308
+ private static transformTernaryOp($expr: TernaryOp, $type: Type, $bitWidth: number) {
309
+ const trueExpr = this.isCompositeExpr($expr.trueExpr);
310
+ const falseExpr = this.isCompositeExpr($expr.falseExpr);
311
+ if (trueExpr && this.compositeExprWidth(trueExpr) < $bitWidth) {
312
+ if (trueExpr instanceof TernaryOp) this.transformTernaryOp(trueExpr, $type, $bitWidth);
313
+ else if (trueExpr instanceof BinaryOp) this.transformBinaryOp(trueExpr, $type);
314
+ }
315
+
316
+ if (falseExpr && this.compositeExprWidth(falseExpr) < $type.bitWidth) {
317
+ if (falseExpr instanceof TernaryOp) this.transformTernaryOp(falseExpr, $type, $bitWidth);
318
+ else if (falseExpr instanceof BinaryOp) this.transformBinaryOp(falseExpr, $type);
319
+ }
320
+ }
321
+
322
+ private r10_6_noWiderCompositeExprAssignments($startNode: Joinpoint) { //unfinished for rets and params
323
+ Query.searchFrom($startNode, Expression).get().forEach(expr => {
324
+ const compositeExpr = Section10_EssentialTypeModel.isCompositeExpr(expr);
325
+ if (compositeExpr) {
326
+ const parent = expr.parent;
327
+ if (parent instanceof BinaryOp && parent.kind === "assign") {
328
+ if (Section10_EssentialTypeModel.compositeExprWidth(compositeExpr) < parent.left.bitWidth) {
329
+ this.logMISRAError(this.currentRule, compositeExpr, "A composite expression must not be assigned to a value with wider type.", new Fix(compositeExpr, op => {
330
+ if (op instanceof BinaryOp) {
331
+ Section10_EssentialTypeModel.transformBinaryOp(op, op.parent.type);
332
+ }
333
+ else if (op instanceof TernaryOp) {
334
+ op.replaceWith(ClavaJoinPoints.cStyleCast(op.parent.type, op));
335
+ }
336
+ }));
337
+ }
338
+ }
339
+ }
340
+ }, this);
341
+ /*Query.searchFrom($startNode, Op, {kind: /(add)|(sub)|(mul)|(div)|(rem)|(shl)|(shr)|(l_and)|(l_or)|(xor)/}).get().forEach(op => {
342
+ const parent = op.parent;
343
+ if (parent instanceof BinaryOp && parent.kind === "assign") {
344
+ if (Section10_EssentialTypeModel.compositeExprWidth(op) < parent.left.bitWidth) {
345
+ this.logMISRAError(op, "A composite expression must not be assigned to a value with wider type.", new Fix(op, op => {
346
+ const opJp = op as BinaryOp;
347
+ opJp.left.replaceWith(ClavaJoinPoints.cStyleCast(opJp.parent.type, opJp.left));
348
+ }));
349
+ }
350
+ }
351
+ }, this);*/
352
+ }
353
+
354
+ private r10_8_noWiderCompositeCasts($startNode: Joinpoint) {
355
+ Query.searchFrom($startNode, Cast).get().forEach(cast => {
356
+ const compositeExpr = Section10_EssentialTypeModel.isCompositeExpr(cast.subExpr);
357
+ if (compositeExpr) {
358
+ if (Section10_EssentialTypeModel.getEssentialType(cast.fromType) !== Section10_EssentialTypeModel.getEssentialType(cast.toType)) {
359
+ this.logMISRAError(this.currentRule, cast, `Composite expression ${cast.subExpr.code} cannot be cast to ${cast.toType.code}, since it has a different essential type category.`);
360
+ }
361
+ else if (cast.bitWidth > Section10_EssentialTypeModel.compositeExprWidth(compositeExpr)) {
362
+ this.logMISRAError(this.currentRule, compositeExpr, `Composite expression ${cast.subExpr.code} cannot be cast to ${cast.toType.code} since it is a wider type.`, new Fix(cast, cast => {
363
+ const castJp = cast as Cast;
364
+ const compositeExpr = Section10_EssentialTypeModel.isCompositeExpr(castJp.subExpr);
365
+ if (compositeExpr instanceof BinaryOp) {
366
+ compositeExpr.left.replaceWith(ClavaJoinPoints.cStyleCast(cast.type, compositeExpr.left));
367
+ cast.replaceWith(compositeExpr);
368
+ }
369
+ else if (compositeExpr instanceof TernaryOp) {
370
+ Section10_EssentialTypeModel.transformTernaryOp(compositeExpr, cast.type, cast.bitWidth);
371
+ }
372
+ }));
373
+ }
374
+ }
375
+ });
376
+ }
377
+ }
@@ -0,0 +1,104 @@
1
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
2
+ import { Program, FileJp, Cast, FunctionType, PointerType, BuiltinType, IntLiteral, Joinpoint, QualType } from "@specs-feup/clava/api/Joinpoints.js";
3
+ import MISRAAnalyser from "../MISRAAnalyser.js";
4
+ import Section10_EssentialTypeModel, { EssentialTypes } from "./Section10_EssentialTypeModel.js";
5
+
6
+ export default class Section11_PointerTypeConversions extends MISRAAnalyser {
7
+ ruleMapper: Map<string, (jp: Program | FileJp) => void>;
8
+
9
+ constructor(rules?: string[]) {
10
+ super(rules);
11
+ this.ruleMapper = new Map([
12
+ ["11.1", this.r11_1_noFunctionPointerConversions.bind(this)],
13
+ ["11.4", this.r11_4_noIntToPointer.bind(this)],
14
+ ["11.7", this.r11_7_noFloatConversions.bind(this)],
15
+ ["11.5", this.r11_5_noConversionFromVoid.bind(this)]
16
+ ]);
17
+ }
18
+
19
+ private static functionTypesMatch(t1: FunctionType, t2: FunctionType) {
20
+ //console.log(t1.returnType.kind, t2.returnType.kind);
21
+ if (t1.returnType != t2.returnType) {
22
+ return false;
23
+ }
24
+ if (t1.paramTypes.length !== t2.paramTypes.length) {
25
+ return false;
26
+ }
27
+ for (let i = 0; i < t1.paramTypes.length; i++) {
28
+ if (t1.paramTypes[i] != t2.paramTypes[i]) {
29
+ return false;
30
+ }
31
+ }
32
+ return true;
33
+ }
34
+
35
+ private r11_1_noFunctionPointerConversions($startNode: Joinpoint) { //type equality not working
36
+ Query.searchFrom($startNode, Cast).get().forEach(cast => {
37
+ const fromType = cast.fromType.desugarAll;
38
+ const toType = cast.toType.desugarAll;
39
+
40
+ if (fromType instanceof PointerType && toType instanceof PointerType && fromType.pointee.desugarAll instanceof FunctionType && toType.pointee.desugarAll instanceof FunctionType) {
41
+ if (!Section11_PointerTypeConversions.functionTypesMatch(fromType.pointee.desugarAll, toType.pointee.desugarAll)) {
42
+ this.logMISRAError(this.currentRule, cast, "A function pointer can only be converted into another function pointer if the types match.");
43
+
44
+ }
45
+ }
46
+ else if (fromType instanceof PointerType && fromType.pointee.desugarAll instanceof FunctionType) {
47
+ if (!(toType instanceof BuiltinType && toType.isVoid)) {
48
+ this.logMISRAError(this.currentRule, cast, "A function pointer can only be converted into another function pointer if the types match.");
49
+ }
50
+ }
51
+ else if (toType instanceof PointerType && toType.pointee.desugarAll instanceof FunctionType) {
52
+ if (!(cast.subExpr instanceof IntLiteral && Number(cast.subExpr.value) === 0)) {
53
+ this.logMISRAError(this.currentRule, cast, "Only null pointer constants can be converted into function pointers.");
54
+ }
55
+ }
56
+ });
57
+ }
58
+
59
+ private r11_4_noIntToPointer($startNode: Joinpoint) {
60
+ Query.searchFrom($startNode, Cast).get().forEach(cast => {
61
+ const fromType = cast.fromType.desugarAll;
62
+ const toType = cast.toType.desugarAll;
63
+ if (fromType.isPointer !== toType.isPointer) {
64
+ this.logMISRAError(this.currentRule, cast, "Integers should not be converted to pointers and vice-versa.");
65
+ }
66
+ })
67
+ }
68
+
69
+ private r11_5_noConversionFromVoid($startNode: Joinpoint) {
70
+ Query.searchFrom($startNode, Cast).get().forEach(cast => {
71
+ const fromType = cast.fromType.desugarAll;
72
+ const toType =cast.toType.desugarAll;
73
+ if (fromType instanceof PointerType && fromType.pointee instanceof BuiltinType && fromType.pointee.isVoid
74
+ && toType instanceof PointerType && !(toType.pointee instanceof BuiltinType && toType.pointee.isVoid)) {
75
+ this.logMISRAError(this.currentRule, cast, "Pointer to void should not be converted to pointer to object");
76
+ }
77
+ });
78
+ }
79
+
80
+ private r11_7_noFloatConversions($startNode: Joinpoint) {
81
+ Query.searchFrom($startNode, Cast).get().forEach(cast => {
82
+ let fromType = cast.fromType.desugarAll;
83
+ let toType = cast.fromType.desugarAll;
84
+
85
+ if (fromType instanceof QualType) {
86
+ fromType = fromType.unqualifiedType.desugarAll;
87
+ }
88
+ if (toType instanceof QualType) {
89
+ toType = toType.unqualifiedType.desugarAll;
90
+ }
91
+
92
+ if (fromType instanceof PointerType && !(toType instanceof PointerType)
93
+ && Section10_EssentialTypeModel.getEssentialType(toType) !== EssentialTypes.SIGNED
94
+ && Section10_EssentialTypeModel.getEssentialType(toType) !== EssentialTypes.UNSIGNED) {
95
+ this.logMISRAError(this.currentRule, cast, "A pointer to object cannot be cast to a non-integer arithmetic type.");
96
+ }
97
+ else if (toType instanceof PointerType && !(fromType instanceof PointerType)
98
+ && Section10_EssentialTypeModel.getEssentialType(fromType) !== EssentialTypes.SIGNED
99
+ && Section10_EssentialTypeModel.getEssentialType(fromType) !== EssentialTypes.UNSIGNED) {
100
+ this.logMISRAError(this.currentRule, cast, "A non-arithmetic integer value cannot be cast to a pointer to object.");
101
+ }
102
+ }, this);
103
+ }
104
+ }
@@ -5,13 +5,13 @@ import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
5
5
  import Fix from "@specs-feup/clava/api/clava/analysis/Fix.js";
6
6
 
7
7
  export default class Section12_Expressions extends MISRAAnalyser {
8
- ruleMapper: Map<number, (jp: Program | FileJp) => void>;
8
+ ruleMapper: Map<string, (jp: Program | FileJp) => void>;
9
9
 
10
- constructor(rules: number[]) {
10
+ constructor(rules?: string[]) {
11
11
  super(rules);
12
12
  this.ruleMapper = new Map([
13
- [1, this.r12_1_explicitPrecedence.bind(this)],
14
- [3, this.r12_3_noCommaOperator.bind(this)]
13
+ ["12.1", this.r12_1_explicitPrecedence.bind(this)],
14
+ ["12.3", this.r12_3_noCommaOperator.bind(this)]
15
15
  ]);
16
16
  }
17
17
 
@@ -55,7 +55,7 @@ export default class Section12_Expressions extends MISRAAnalyser {
55
55
  || (bOp.parent instanceof Op && Section12_Expressions.isSamePrecedence(bOp.kind, bOp.parent.kind))
56
56
  || (bOp.parent.instanceOf("parenExpr"))) continue;
57
57
 
58
- this.logMISRAError(bOp, `Operator precedence in expression ${bOp.code} is not explicit.`, new Fix(bOp, ($jp: Joinpoint) => {
58
+ this.logMISRAError(this.currentRule, bOp, `Operator precedence in expression ${bOp.code} is not explicit.`, new Fix(bOp, ($jp: Joinpoint) => {
59
59
  const parenExpr = ClavaJoinPoints.parenthesis($jp as Expression);
60
60
  bOp.replaceWith(parenExpr);
61
61
  }));
@@ -67,10 +67,10 @@ export default class Section12_Expressions extends MISRAAnalyser {
67
67
  const loopAncestor = op.getAncestor("loop");
68
68
  if (loopAncestor instanceof Loop && (loopAncestor?.step?.contains(op) || loopAncestor?.cond?.contains(op) || loopAncestor?.init?.contains(op))) {
69
69
  console.log(`Cannot eliminate comma operator in expression ${op.code} since it is at the head of a loop.`);
70
- this.logMISRAError(op, "Use of the comma operator is not allowed.");
70
+ this.logMISRAError(this.currentRule, op, "Use of the comma operator is not allowed.");
71
71
  }
72
72
  else {
73
- this.logMISRAError(op, "Use of the comma operator is not allowed.", new Fix(op, ($jp: Joinpoint) => {
73
+ this.logMISRAError(this.currentRule, op, "Use of the comma operator is not allowed.", new Fix(op, ($jp: Joinpoint) => {
74
74
  $jp.insertBefore(($jp as BinaryOp).left.stmt);
75
75
  $jp.replaceWith(($jp as BinaryOp).right);
76
76
  }));
@@ -6,32 +6,32 @@ import TraversalType from "@specs-feup/lara/api/weaver/TraversalType.js";
6
6
  import Fix from "@specs-feup/clava/api/clava/analysis/Fix.js";
7
7
 
8
8
  export default class Section13_SideEffects extends MISRAAnalyser {
9
- ruleMapper: Map<number, (jp: Program | FileJp) => void>;
9
+ ruleMapper: Map<string, (jp: Program | FileJp) => void>;
10
10
 
11
- constructor(rules: number[]) {
11
+ constructor(rules?: string[]) {
12
12
  super(rules);
13
13
  this.ruleMapper = new Map([
14
- [1, this.r13_1_initListSideEffects.bind(this)],
15
- [3, this.r13_3_noIncrementSideEffects.bind(this)],
16
- [4, this.r13_4_noUseOfAssignmentValue.bind(this)],
17
- [5, this.r13_5_shortCircuitSideEffects.bind(this)]
14
+ ["13.1", this.r13_1_initListSideEffects.bind(this)],
15
+ ["13.3", this.r13_3_noIncrementSideEffects.bind(this)],
16
+ ["13.4", this.r13_4_noUseOfAssignmentValue.bind(this)],
17
+ ["13.5", this.r13_5_shortCircuitSideEffects.bind(this)]
18
18
  ]);
19
19
  }
20
20
 
21
- private checkPotentialPersistentSideEffects<T>($startNode: Joinpoint, type: any, filters: any, name: string, childFun: ($jp: T) => Joinpoint) {
21
+ private checkPotentialPersistentSideEffects<T>(ruleID: string, $startNode: Joinpoint, type: any, filters: any, name: string, childFun: ($jp: T) => Joinpoint) {
22
22
  Query.searchFrom($startNode, type, filters).get().forEach(list => {
23
23
  Query.searchFromInclusive(childFun(list), Varref).get().forEach(ref => {
24
24
  if (ref.type instanceof QualType && ref.type.qualifiers?.includes("volatile")) {
25
- this.logMISRAError(list, `${name} ${list.code} contains persistent side effects: an access to volatile object ${ref.name}.`)
25
+ this.logMISRAError(ruleID, list, `${name} ${list.code} contains persistent side effects: an access to volatile object ${ref.name}.`)
26
26
  }
27
27
  }, this);
28
28
  Query.searchFromInclusive(childFun(list), Call).get().forEach(call => {
29
- this.logMISRAError(list, `${name} ${list.code} may contain persistent side effects in call to ${call.name}.`);
29
+ this.logMISRAError(ruleID, list, `${name} ${list.code} may contain persistent side effects in call to ${call.name}.`);
30
30
  }, this);
31
31
  Query.searchFromInclusive(childFun(list), UnaryOp, {kind: /(post_inc)|(post_dec)|(pre_inc)|(pre_dec)/}).get().forEach(op => { //use chain?
32
32
  Query.searchFrom(op, Varref).get().forEach(ref => {
33
33
  if (ref.declaration instanceof Vardecl && ref.declaration.isGlobal) {
34
- this.logMISRAError(list, `${name} ${list.code} may contain persistent side effects in expression ${op.code}.`)
34
+ this.logMISRAError(ruleID, list, `${name} ${list.code} may contain persistent side effects in expression ${op.code}.`)
35
35
  }
36
36
  });
37
37
  }, this);
@@ -39,7 +39,7 @@ export default class Section13_SideEffects extends MISRAAnalyser {
39
39
  }
40
40
 
41
41
  private r13_1_initListSideEffects($startNode: Joinpoint) {
42
- this.checkPotentialPersistentSideEffects<Joinpoint>($startNode, InitList, undefined, "Initializer list", jp => jp);
42
+ this.checkPotentialPersistentSideEffects<Joinpoint>(this.currentRule, $startNode, InitList, undefined, "Initializer list", jp => jp);
43
43
  }
44
44
 
45
45
  private static visitAllExprs(fun: ($jp: Joinpoint) => void, root: Joinpoint) {
@@ -61,7 +61,7 @@ export default class Section13_SideEffects extends MISRAAnalyser {
61
61
  const assignments = Query.searchFromInclusive(exprRoot, BinaryOp, {isAssignment: true}).get();
62
62
  if (jps.length + calls.length + assignments.length < 2) return;
63
63
 
64
- this.logMISRAError(exprRoot, `Expression ${exprRoot.code} contains a pre/post inc/decrement operator and other side effects.`, new Fix(exprRoot, ($jp: Joinpoint) => {
64
+ this.logMISRAError(this.currentRule, exprRoot, `Expression ${exprRoot.code} contains a pre/post inc/decrement operator and other side effects.`, new Fix(exprRoot, ($jp: Joinpoint) => {
65
65
  const jps = Query.searchFrom($jp, UnaryOp, {kind: /(post_inc)|(post_dec)|(pre_inc)|(pre_dec)/}, TraversalType.POSTORDER).get();
66
66
  const calls = Query.searchFromInclusive($jp, Call).get();
67
67
  const assignments = Query.searchFromInclusive($jp, BinaryOp, {isAssignment: true}).get();
@@ -76,7 +76,7 @@ export default class Section13_SideEffects extends MISRAAnalyser {
76
76
  else {
77
77
  $jp.insertBefore(jp.deepCopy());
78
78
  }
79
- console.log(jp);
79
+ //console.log(jp);
80
80
  jp.replaceWith(jp.operand);
81
81
  }
82
82
  }));
@@ -89,12 +89,12 @@ export default class Section13_SideEffects extends MISRAAnalyser {
89
89
  private r13_4_noUseOfAssignmentValue($startNode: Joinpoint) {
90
90
  for (const bOp of Query.searchFrom($startNode, BinaryOp, {isAssignment: true})) {
91
91
  if (!bOp.parent.instanceOf("exprStmt") && !(bOp.parent.instanceOf("parenExpr") && bOp.parent?.parent?.instanceOf("exprStmt"))) {
92
- this.logMISRAError(bOp, `Value of assignment expression ${bOp.code} should not be used.`);
92
+ this.logMISRAError(this.currentRule, bOp, `Value of assignment expression ${bOp.code} should not be used.`);
93
93
  }
94
94
  }
95
95
  }
96
96
 
97
97
  private r13_5_shortCircuitSideEffects($startNode: Joinpoint) {
98
- this.checkPotentialPersistentSideEffects<BinaryOp>($startNode, BinaryOp, {operator: /(\&\&|\|\|)/}, "RHS of && or || expression", jp => jp.right);
98
+ this.checkPotentialPersistentSideEffects<BinaryOp>(this.currentRule, $startNode, BinaryOp, {operator: /(\&\&|\|\|)/}, "RHS of && or || expression", jp => jp.right);
99
99
  }
100
100
  }
@@ -0,0 +1,27 @@
1
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
2
+ import { Program, FileJp, Loop, Joinpoint, If, ExprStmt } from "@specs-feup/clava/api/Joinpoints.js";
3
+ import MISRAAnalyser from "../MISRAAnalyser.js";
4
+
5
+ export default class Section14_ControlStmtExprs extends MISRAAnalyser {
6
+ ruleMapper: Map<string, (jp: Program | FileJp) => void>;
7
+
8
+ constructor(rules?: string[]) {
9
+ super(rules);
10
+ this.ruleMapper = new Map([
11
+ ["14.4", this.r14_4_essentiallyBooleanInControllingExpr.bind(this)]
12
+ ]);
13
+ }
14
+
15
+ private r14_4_essentiallyBooleanInControllingExpr($startNode: Joinpoint) { //better way?
16
+ Query.searchFrom($startNode, Loop).get().forEach(loop => {
17
+ if ((loop.cond as ExprStmt).expr.type.code !== "bool") {
18
+ this.logMISRAError(this.currentRule, loop, `Loop controlling expression ${(loop.cond as ExprStmt).expr.code} does not have essentially boolean type.`);
19
+ }
20
+ }, this);
21
+ Query.searchFrom($startNode, If).get().forEach(ifStmt => {
22
+ if (ifStmt.cond.type.code !== "bool") {
23
+ this.logMISRAError(this.currentRule, ifStmt, `Loop controlling expression ${ifStmt.cond.code} does not have essentially boolean type.`);
24
+ }
25
+ }, this);
26
+ }
27
+ }