@specs-feup/clava-misra 1.0.2 → 1.0.4
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.
- package/.gitignore +8 -0
- package/README.md +53 -19
- package/dist/MISRA.d.ts +28 -10
- package/dist/MISRA.d.ts.map +1 -1
- package/dist/MISRA.js +30 -10
- package/dist/MISRA.js.map +1 -1
- package/dist/MISRAContext.d.ts +65 -11
- package/dist/MISRAContext.d.ts.map +1 -1
- package/dist/MISRAContext.js +131 -35
- package/dist/MISRAContext.js.map +1 -1
- package/dist/MISRARule.d.ts +38 -25
- package/dist/MISRARule.d.ts.map +1 -1
- package/dist/MISRARule.js +40 -18
- package/dist/MISRARule.js.map +1 -1
- package/dist/MISRATool.d.ts +46 -5
- package/dist/MISRATool.d.ts.map +1 -1
- package/dist/MISRATool.js +118 -45
- package/dist/MISRATool.js.map +1 -1
- package/dist/StandardGuideline.d.ts +22 -0
- package/dist/StandardGuideline.d.ts.map +1 -0
- package/dist/StandardGuideline.js +12 -0
- package/dist/StandardGuideline.js.map +1 -0
- package/dist/ast-visitor/Context.d.ts +11 -0
- package/dist/ast-visitor/Context.d.ts.map +1 -0
- package/dist/ast-visitor/Context.js +15 -0
- package/dist/ast-visitor/Context.js.map +1 -0
- package/dist/ast-visitor/Visit.d.ts +23 -0
- package/dist/ast-visitor/Visit.d.ts.map +1 -0
- package/dist/ast-visitor/Visit.js +18 -0
- package/dist/ast-visitor/Visit.js.map +1 -0
- package/dist/ast-visitor/VisitWithContext.d.ts +32 -0
- package/dist/ast-visitor/VisitWithContext.d.ts.map +1 -0
- package/dist/ast-visitor/VisitWithContext.js +26 -0
- package/dist/ast-visitor/VisitWithContext.js.map +1 -0
- package/dist/main.js +1 -2
- package/dist/main.js.map +1 -1
- package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts +27 -0
- package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.d.ts.map +1 -0
- package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js +98 -0
- package/dist/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.js.map +1 -0
- package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts +45 -6
- package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js +91 -8
- package/dist/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts +15 -5
- package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js +20 -6
- package/dist/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts +11 -5
- package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js +13 -10
- package/dist/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts +11 -6
- package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js +19 -11
- package/dist/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts +15 -5
- package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js +24 -10
- package/dist/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.js.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts +22 -6
- package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.d.ts.map +1 -1
- package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js +37 -10
- package/dist/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.js.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts +66 -0
- package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.d.ts.map +1 -0
- package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js +209 -0
- package/dist/rules/Section17_Functions/Rule_17_3_ImplicitFunction.js.map +1 -0
- package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts +37 -12
- package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.d.ts.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js +112 -39
- package/dist/rules/Section17_Functions/Rule_17_4_NonVoidReturn.js.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts +15 -5
- package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.d.ts.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js +21 -7
- package/dist/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.js.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts +11 -6
- package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.d.ts.map +1 -1
- package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js +17 -8
- package/dist/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.js.map +1 -1
- package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts +105 -0
- package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js +258 -0
- package/dist/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts +29 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js +31 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts +30 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js +32 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.js.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts +25 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.d.ts.map +1 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js +27 -0
- package/dist/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.js.map +1 -0
- package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts +6 -14
- package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.d.ts.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js +17 -27
- package/dist/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.js.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts +13 -7
- package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.d.ts.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js +31 -17
- package/dist/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.js.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts +26 -7
- package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.d.ts.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js +32 -14
- package/dist/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.js.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts +48 -6
- package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.d.ts.map +1 -1
- package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js +84 -34
- package/dist/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.js.map +1 -1
- package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts +24 -5
- package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.d.ts.map +1 -1
- package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js +27 -7
- package/dist/rules/Section3_Comments/Rule_3_1_CommentSequences.js.map +1 -1
- package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts +46 -0
- package/dist/rules/Section5_Identifiers/IdentifierRenameRule.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js +40 -0
- package/dist/rules/Section5_Identifiers/IdentifierRenameRule.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts +25 -0
- package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js +46 -0
- package/dist/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts +26 -0
- package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js +54 -0
- package/dist/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts +27 -0
- package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js +55 -0
- package/dist/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts +24 -0
- package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js +42 -0
- package/dist/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.js.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts +24 -0
- package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.d.ts.map +1 -0
- package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js +42 -0
- package/dist/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.js.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts +35 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.d.ts.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js +98 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.js.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts +35 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.d.ts.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js +76 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.js.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts +32 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.d.ts.map +1 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js +57 -0
- package/dist/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.js.map +1 -0
- package/dist/rules/UserConfigurableRule.d.ts +55 -0
- package/dist/rules/UserConfigurableRule.d.ts.map +1 -0
- package/dist/rules/UserConfigurableRule.js +16 -0
- package/dist/rules/UserConfigurableRule.js.map +1 -0
- package/dist/rules/index.d.ts +11 -18
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +47 -7
- package/dist/rules/index.js.map +1 -1
- package/dist/tests/Section17_Functions/misra_config.json +10 -0
- package/dist/tests/Section21-StandardLibraries/misra_config.json +88 -0
- package/dist/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
- package/dist/tests/utils.d.ts +6 -3
- package/dist/tests/utils.d.ts.map +1 -1
- package/dist/tests/utils.js +33 -7
- package/dist/tests/utils.js.map +1 -1
- package/dist/utils/CallUtils.d.ts +15 -0
- package/dist/utils/CallUtils.d.ts.map +1 -0
- package/dist/utils/CallUtils.js +34 -0
- package/dist/utils/CallUtils.js.map +1 -0
- package/dist/utils/CommentUtils.d.ts +21 -0
- package/dist/utils/CommentUtils.d.ts.map +1 -0
- package/dist/utils/CommentUtils.js +27 -0
- package/dist/utils/CommentUtils.js.map +1 -0
- package/dist/utils/FileUtils.d.ts +67 -0
- package/dist/utils/FileUtils.d.ts.map +1 -0
- package/dist/utils/FileUtils.js +144 -0
- package/dist/utils/FileUtils.js.map +1 -0
- package/dist/utils/FunctionUtils.d.ts +47 -0
- package/dist/utils/FunctionUtils.d.ts.map +1 -0
- package/dist/utils/FunctionUtils.js +87 -0
- package/dist/utils/FunctionUtils.js.map +1 -0
- package/dist/utils/IdentifierUtils.d.ts +63 -0
- package/dist/utils/IdentifierUtils.d.ts.map +1 -0
- package/dist/utils/IdentifierUtils.js +133 -0
- package/dist/utils/IdentifierUtils.js.map +1 -0
- package/dist/utils/JoinpointUtils.d.ts +36 -0
- package/dist/utils/JoinpointUtils.d.ts.map +1 -0
- package/dist/utils/JoinpointUtils.js +63 -0
- package/dist/utils/JoinpointUtils.js.map +1 -0
- package/dist/utils/ProgramUtils.d.ts +39 -0
- package/dist/utils/ProgramUtils.d.ts.map +1 -0
- package/dist/utils/ProgramUtils.js +97 -0
- package/dist/utils/ProgramUtils.js.map +1 -0
- package/dist/utils/SwitchUtils.d.ts +21 -0
- package/dist/utils/SwitchUtils.d.ts.map +1 -0
- package/dist/utils/SwitchUtils.js +47 -0
- package/dist/utils/SwitchUtils.js.map +1 -0
- package/dist/utils/TypeDeclUtils.d.ts +35 -0
- package/dist/utils/TypeDeclUtils.d.ts.map +1 -0
- package/dist/utils/TypeDeclUtils.js +78 -0
- package/dist/utils/TypeDeclUtils.js.map +1 -0
- package/dist/utils/VarUtils.d.ts +51 -0
- package/dist/utils/VarUtils.d.ts.map +1 -0
- package/dist/utils/VarUtils.js +91 -0
- package/dist/utils/VarUtils.js.map +1 -0
- package/package.json +16 -7
- package/src/MISRA.ts +33 -17
- package/src/MISRAContext.ts +128 -30
- package/src/MISRARule.ts +61 -29
- package/src/MISRATool.ts +126 -42
- package/src/StandardGuideline.ts +23 -0
- package/src/ast-visitor/Context.ts +16 -0
- package/src/ast-visitor/Visit.ts +26 -0
- package/src/ast-visitor/VisitWithContext.ts +42 -0
- package/src/main.ts +1 -4
- package/src/rules/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.ts +114 -0
- package/src/rules/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.ts +103 -13
- package/src/rules/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.ts +24 -10
- package/src/rules/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.ts +17 -8
- package/src/rules/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.ts +20 -12
- package/src/rules/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.ts +23 -12
- package/src/rules/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.ts +44 -13
- package/src/rules/Section17_Functions/Rule_17_3_ImplicitFunction.ts +153 -104
- package/src/rules/Section17_Functions/Rule_17_4_NonVoidReturn.ts +114 -44
- package/src/rules/Section17_Functions/Rule_17_6_StaticArraySizeParam.ts +27 -10
- package/src/rules/Section17_Functions/Rule_17_7_UnusedReturnValue.ts +20 -12
- package/src/rules/Section21-StandardLibraries/DisallowedStdLibFunctionRule.ts +317 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.ts +30 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.ts +35 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.ts +30 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.ts +30 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.ts +29 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.ts +36 -0
- package/src/rules/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.ts +30 -0
- package/src/rules/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.ts +14 -29
- package/src/rules/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.ts +33 -19
- package/src/rules/Section2_UnusedCode/Rule_2_6_UnusedLabels.ts +33 -20
- package/src/rules/Section2_UnusedCode/Rule_2_7_UnusedParameters.ts +90 -45
- package/src/rules/Section3_Comments/Rule_3_1_CommentSequences.ts +27 -8
- package/src/rules/Section5_Identifiers/IdentifierRenameRule.ts +63 -0
- package/src/rules/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.ts +52 -0
- package/src/rules/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.ts +62 -0
- package/src/rules/Section5_Identifiers/Rule_5_7_UniqueTagNames.ts +61 -0
- package/src/rules/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.ts +47 -0
- package/src/rules/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.ts +47 -0
- package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.ts +118 -0
- package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.ts +89 -0
- package/src/rules/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.ts +65 -0
- package/src/rules/UserConfigurableRule.ts +60 -0
- package/src/rules/index.ts +45 -7
- package/src/tests/Section13_SideEffects/Rule_13_6_SafeSizeOfOperand.test.ts +114 -0
- package/src/tests/Section16_SwitchStatements/Rule_16_2_TopLevelSwitch.test.ts +7 -5
- package/src/tests/Section16_SwitchStatements/Rule_16_3_UnconditionalBreak.test.ts +40 -13
- package/src/tests/Section16_SwitchStatements/Rule_16_4_SwitchHasDefault.test.ts +10 -12
- package/src/tests/Section16_SwitchStatements/Rule_16_5_DefaultFirstOrLast.test.ts +5 -5
- package/src/tests/Section16_SwitchStatements/Rule_16_6_SwitchMinTwoClauses.test.ts +5 -5
- package/src/tests/Section16_SwitchStatements/Rule_16_7_NonBooleanSwitchCondition.test.ts +5 -5
- package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions.test.ts +68 -40
- package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_MissingConfig.test.ts +98 -0
- package/src/tests/Section17_Functions/Rule_17_3_ImplicitFunctions_ProblematicConfig.test.ts +71 -0
- package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn.test.ts +103 -49
- package/src/tests/Section17_Functions/Rule_17_4_NonVoidReturn_MissingConfig.test.ts +7 -7
- package/src/tests/Section17_Functions/Rule_17_6_StaticArraySizeParam.test.ts +36 -7
- package/src/tests/Section17_Functions/Rule_17_7_UnusedReturnValue.test.ts +25 -21
- package/src/tests/Section17_Functions/misra_config.json +4 -3
- package/src/tests/Section21-StandardLibraries/Rule_21_10_NoTimeDateFunctions.test.ts +62 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_11_NoTgmathFunctions.test.ts +67 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory.test.ts +84 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_MissingConfig.test.ts +33 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_3_NoDynamicMemory_ProblematicConfig.test.ts +71 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_6_NoStdIOFunctions.test.ts +63 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_7_NoNumericStringConversions.test.ts +91 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_8_NoProcessControlFunctions.test.ts +65 -0
- package/src/tests/Section21-StandardLibraries/Rule_21_9_NoGenericSearchOrSort.test.ts +89 -0
- package/src/tests/Section21-StandardLibraries/misra_config.json +88 -0
- package/src/tests/Section21-StandardLibraries/problematic_misra_config.json +19 -0
- package/src/tests/Section2_UnusedCode/Rule_2_3_UnusedTypeDecl.test.ts +148 -113
- package/src/tests/Section2_UnusedCode/Rule_2_4_UnusedTagDecl.test.ts +243 -163
- package/src/tests/Section2_UnusedCode/Rule_2_6_UnusedLabels.test.ts +32 -20
- package/src/tests/Section2_UnusedCode/Rule_2_7_UnusedParameters.test.ts +36 -30
- package/src/tests/Section3_Comments/Rule_3_1_CommentSequences.test.ts +37 -8
- package/src/tests/Section5_Identifiers/Rule_5_1_DistinctExternalIdentifiers.test.ts +78 -0
- package/src/tests/Section5_Identifiers/Rule_5_6_UniqueTypedefNames.test.ts +120 -0
- package/src/tests/Section5_Identifiers/Rule_5_7_UniqueTagNames.test.ts +51 -0
- package/src/tests/Section5_Identifiers/Rule_5_8_UniqueExternalLinkIdentifiers.test.ts +73 -0
- package/src/tests/Section5_Identifiers/Rule_5_9_UniqueInternalLinkIdentifiers.test.ts +97 -0
- package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_6_SingleExternalDefinition.test.ts +160 -0
- package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_7_RestrictExternalLinkage.test.ts +46 -0
- package/src/tests/Section8_DeclarationsAndDefinitions/Rule_8_9_BlockScopeDefinition.test.ts +69 -0
- package/src/tests/utils.ts +32 -7
- package/src/utils/CallUtils.ts +37 -0
- package/src/utils/CommentUtils.ts +29 -0
- package/src/utils/FileUtils.ts +169 -0
- package/src/utils/FunctionUtils.ts +97 -0
- package/src/utils/IdentifierUtils.ts +142 -0
- package/src/utils/JoinpointUtils.ts +70 -0
- package/src/utils/ProgramUtils.ts +107 -0
- package/src/utils/SwitchUtils.ts +52 -0
- package/src/utils/TypeDeclUtils.ts +88 -0
- package/src/utils/VarUtils.ts +102 -0
- package/tsconfig.json +2 -1
- package/src/rules/Section20-PreprocessingDirectives/Rule_20_2_InvalidHeaderFileName.ts +0 -120
- package/src/rules/Section3_Comments/Rule_3_2_LineSplicing.ts +0 -36
- package/src/utils/utils.ts +0 -280
|
@@ -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
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import VisualizationTool from "@specs-feup/clava-visualization/api/VisualizationTool.js";
|
|
2
1
|
import MISRATool from "./MISRATool.js";
|
|
3
2
|
|
|
4
3
|
MISRATool.checkCompliance();
|
|
5
|
-
MISRATool.
|
|
6
|
-
|
|
7
|
-
//await VisualizationTool.visualize();
|
|
4
|
+
MISRATool.correctViolations();
|
|
@@ -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
|
+
}
|
|
@@ -1,21 +1,39 @@
|
|
|
1
|
-
import { Case, Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
|
|
1
|
+
import { Break, Case, Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
|
|
2
2
|
import MISRARule from "../../MISRARule.js";
|
|
3
|
-
import MISRAContext from "../../MISRAContext.js";
|
|
4
3
|
import Query from "@specs-feup/lara/api/weaver/Query.js";
|
|
5
|
-
import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
4
|
+
import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
|
-
* MISRA Rule 16.2: A switch label shall only be used when the most closely-enclosing
|
|
9
|
-
compound statement is the body of a switch statement
|
|
7
|
+
* MISRA-C Rule 16.2: A switch label shall only be used when the most closely-enclosing compound statement is the body of a switch statement
|
|
10
8
|
*/
|
|
11
|
-
export default class Rule_16_2_TopLevelSwitch extends MISRARule {
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
export default class Rule_16_2_TopLevelSwitch extends MISRARule {
|
|
10
|
+
/**
|
|
11
|
+
* Scope of analysis
|
|
12
|
+
*/
|
|
13
|
+
readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
|
|
17
|
+
*/
|
|
18
|
+
readonly priority = 4;
|
|
14
19
|
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
#misplacedCases: Case[] = [];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @returns Rule identifier according to MISRA-C:2012
|
|
24
|
+
*/
|
|
25
|
+
override get name(): string {
|
|
26
|
+
return "16.2";
|
|
17
27
|
}
|
|
18
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Checks if the given joinpoint is a switch statement with any misplaced case labels.
|
|
31
|
+
* A case label is considered misplaced if it is not a direct child of the switch body.
|
|
32
|
+
*
|
|
33
|
+
* @param $jp - Joinpoint to analyze
|
|
34
|
+
* @param logErrors - [logErrors=false] - Whether to log errors if a violation is detected
|
|
35
|
+
* @returns Returns true if the joinpoint violates the rule, false otherwise
|
|
36
|
+
*/
|
|
19
37
|
match($jp: Joinpoint, logErrors: boolean = false): boolean {
|
|
20
38
|
if (!($jp instanceof Switch)) return false;
|
|
21
39
|
|
|
@@ -30,12 +48,84 @@ export default class Rule_16_2_TopLevelSwitch extends MISRARule {
|
|
|
30
48
|
return this.#misplacedCases.length > 0;
|
|
31
49
|
}
|
|
32
50
|
|
|
33
|
-
|
|
34
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Transforms the joinpoint if it represents a switch with any misplaced case labels.
|
|
53
|
+
* For that, each case label is moved to a new location within the switch.
|
|
54
|
+
*
|
|
55
|
+
* @param $jp - Joinpoint to transform
|
|
56
|
+
* @returns Report detailing the transformation result
|
|
57
|
+
*/
|
|
58
|
+
apply($jp: Joinpoint): MISRATransformationReport {
|
|
59
|
+
if (!this.match($jp))
|
|
60
|
+
return new MISRATransformationReport(MISRATransformationType.NoChange);
|
|
35
61
|
|
|
36
62
|
for (const caseLabel of this.#misplacedCases) {
|
|
37
|
-
|
|
63
|
+
this.changeCaseLocation(caseLabel);
|
|
38
64
|
}
|
|
39
65
|
return new MISRATransformationReport(MISRATransformationType.DescendantChange);
|
|
40
66
|
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Relocates a inner case to a new position while preserving control flow.
|
|
71
|
+
* First, copies the instructions to be executed (direct siblings and fall-through code).
|
|
72
|
+
* Then, moves the case to the new position and finally appends the copied instructions after the case.
|
|
73
|
+
*
|
|
74
|
+
* @param caseLabel The inner case to relocate
|
|
75
|
+
*/
|
|
76
|
+
private changeCaseLocation(caseLabel: Case) {
|
|
77
|
+
// Collect instructions that follow the given case
|
|
78
|
+
const instructions = caseLabel.siblingsRight.map(sibling => sibling.deepCopy());
|
|
79
|
+
|
|
80
|
+
// If direct instruction do not have a break statement, find additional statements from higher scopes that will be executed
|
|
81
|
+
if (!instructions.some(instruction => instruction instanceof Break)) {
|
|
82
|
+
let lastScope: Joinpoint = caseLabel;
|
|
83
|
+
do {
|
|
84
|
+
lastScope = lastScope.parent;
|
|
85
|
+
const rightStmts = lastScope.siblingsRight;
|
|
86
|
+
for (const rightStmt of rightStmts) {
|
|
87
|
+
if (rightStmt.currentRegion instanceof Switch && rightStmt instanceof Case) {
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
instructions.push(rightStmt.deepCopy());
|
|
91
|
+
}
|
|
92
|
+
} while(!(lastScope.currentRegion instanceof Switch));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Locate target position
|
|
96
|
+
const caseAncestor = this.getCaseAncestor(caseLabel);
|
|
97
|
+
const caseAncestorRightSiblings = caseAncestor.siblingsRight;
|
|
98
|
+
const nextCaseIndex = caseAncestorRightSiblings.findIndex(jp => jp instanceof Case);
|
|
99
|
+
const targetStmt = nextCaseIndex != -1 ? caseAncestorRightSiblings[nextCaseIndex] : caseAncestorRightSiblings[caseAncestorRightSiblings.length - 1];
|
|
100
|
+
|
|
101
|
+
// Move case label to the new position
|
|
102
|
+
caseLabel.detach();
|
|
103
|
+
if (targetStmt instanceof Case) {
|
|
104
|
+
targetStmt.insertBefore(caseLabel);
|
|
105
|
+
} else {
|
|
106
|
+
targetStmt.insertAfter(caseLabel);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Add instructions after caseLabel
|
|
110
|
+
let lastStmt: Joinpoint = caseLabel;
|
|
111
|
+
for (const instruction of instructions) {
|
|
112
|
+
lastStmt.insertAfter(instruction);
|
|
113
|
+
lastStmt = instruction;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Retrieves the top-level case that contains a given inner case label.
|
|
119
|
+
*
|
|
120
|
+
* @param caseLabel - The inner case joinpoint
|
|
121
|
+
* @returns The ancestor case that contains the given inner case
|
|
122
|
+
*/
|
|
123
|
+
private getCaseAncestor(caseLabel: Case): Case {
|
|
124
|
+
let stmt: Joinpoint = caseLabel;
|
|
125
|
+
while (!(stmt.currentRegion instanceof Switch)) {
|
|
126
|
+
stmt = stmt.parent;
|
|
127
|
+
}
|
|
128
|
+
const caseAncestor = stmt.siblingsLeft.reverse().find(jp => jp instanceof Case);
|
|
129
|
+
return caseAncestor!;
|
|
130
|
+
}
|
|
41
131
|
}
|
|
@@ -1,19 +1,33 @@
|
|
|
1
|
-
import { Break, Joinpoint,
|
|
1
|
+
import { Break, Joinpoint, Switch, Case } from "@specs-feup/clava/api/Joinpoints.js";
|
|
2
2
|
import MISRARule from "../../MISRARule.js";
|
|
3
|
-
import
|
|
4
|
-
import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
5
|
-
import { getLastStmtOfCase } from "../../utils/utils.js";
|
|
3
|
+
import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
6
4
|
import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
|
|
5
|
+
import { getLastStmtOfCase } from "../../utils/SwitchUtils.js";
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
|
-
* MISRA Rule 16.3: An unconditional break statement shall terminate every switch-clause
|
|
8
|
+
* MISRA-C Rule 16.3: An unconditional break statement shall terminate every switch-clause
|
|
10
9
|
*/
|
|
11
10
|
export default class Rule_16_3_UnconditionalBreak extends MISRARule {
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Scope of analysis
|
|
13
|
+
*/
|
|
14
|
+
readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
|
|
18
|
+
*/
|
|
19
|
+
readonly priority = 3;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* List of statements that require a `break` statement as their last sibling
|
|
23
|
+
*/
|
|
24
|
+
#statementsNeedingBreakAfter: Joinpoint[] = [];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @returns Rule identifier according to MISRA-C:2012
|
|
28
|
+
*/
|
|
29
|
+
override get name(): string {
|
|
30
|
+
return "16.3";
|
|
17
31
|
}
|
|
18
32
|
|
|
19
33
|
match($jp: Joinpoint, logErrors: boolean = false): boolean {
|
|
@@ -54,7 +68,7 @@ export default class Rule_16_3_UnconditionalBreak extends MISRARule {
|
|
|
54
68
|
lastStmt.insertAfter(ClavaJoinPoints.breakStmt());
|
|
55
69
|
}
|
|
56
70
|
|
|
57
|
-
|
|
71
|
+
apply($jp: Joinpoint): MISRATransformationReport {
|
|
58
72
|
if (!this.match($jp))
|
|
59
73
|
return new MISRATransformationReport(MISRATransformationType.NoChange);
|
|
60
74
|
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
|
|
2
2
|
import MISRARule from "../../MISRARule.js";
|
|
3
|
-
import
|
|
4
|
-
import { MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
3
|
+
import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
5
4
|
import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
|
|
6
|
-
import { getNumOfSwitchClauses, switchHasBooleanCondition, switchHasConditionalBreak } from "../../utils/utils.js";
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
|
-
* MISRA Rule 16.4: Every switch statement shall have a default label
|
|
7
|
+
* MISRA-C Rule 16.4: Every switch statement shall have a default label
|
|
10
8
|
*/
|
|
11
9
|
export default class Rule_16_4_SwitchHasDefault extends MISRARule {
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Scope of analysis
|
|
12
|
+
*/
|
|
13
|
+
readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @returns Rule identifier according to MISRA-C:2012
|
|
17
|
+
*/
|
|
18
|
+
override get name(): string {
|
|
19
|
+
return "16.4";
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
/**
|
|
@@ -29,13 +35,16 @@ export default class Rule_16_4_SwitchHasDefault extends MISRARule {
|
|
|
29
35
|
return noDefaultCase;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
if (!this.match($jp))
|
|
38
|
+
apply($jp: Joinpoint): MISRATransformationReport {
|
|
39
|
+
if (!this.match($jp))
|
|
40
|
+
return new MISRATransformationReport(MISRATransformationType.NoChange);
|
|
34
41
|
|
|
35
42
|
$jp.children[1].lastChild
|
|
36
43
|
.insertAfter(ClavaJoinPoints.defaultStmt())
|
|
37
44
|
.insertAfter(ClavaJoinPoints.emptyStmt())
|
|
38
45
|
.insertAfter(ClavaJoinPoints.breakStmt());
|
|
46
|
+
|
|
47
|
+
this.context.addRuleResult(this.ruleID, $jp, MISRATransformationType.DescendantChange);
|
|
39
48
|
return new MISRATransformationReport(MISRATransformationType.DescendantChange);
|
|
40
49
|
}
|
|
41
50
|
}
|
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
import {Case,
|
|
1
|
+
import {Case, Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
|
|
2
2
|
import MISRARule from "../../MISRARule.js";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { isCommentStmt } from "../../utils/utils.js";
|
|
3
|
+
import { AnalysisType, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
4
|
+
import { isCommentStmt } from "../../utils/CommentUtils.js";
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
|
-
* MISRA Rule 16.5: A default label shall appear as either the first or the last switch label of
|
|
9
|
-
a switch statement
|
|
7
|
+
* MISRA-C Rule 16.5: A default label shall appear as either the first or the last switch label of a switch statement
|
|
10
8
|
*/
|
|
11
9
|
export default class Rule_16_5_DefaultFirstOrLast extends MISRARule {
|
|
10
|
+
/**
|
|
11
|
+
* Scope of analysis
|
|
12
|
+
*/
|
|
13
|
+
readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
/**
|
|
16
|
+
* @returns Rule identifier according to MISRA-C:2012
|
|
17
|
+
*/
|
|
18
|
+
override get name(): string {
|
|
19
|
+
return "16.5";
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
/**
|
|
@@ -24,7 +29,7 @@ export default class Rule_16_5_DefaultFirstOrLast extends MISRARule {
|
|
|
24
29
|
private getConsecutiveRightCases($jp: Case): Joinpoint[] {
|
|
25
30
|
const cases = [];
|
|
26
31
|
for (const stmt of $jp.siblingsRight) {
|
|
27
|
-
if (!(stmt instanceof Case || isCommentStmt(
|
|
32
|
+
if (!(stmt instanceof Case || isCommentStmt(stmt)))
|
|
28
33
|
break;
|
|
29
34
|
cases.push(stmt);
|
|
30
35
|
}
|
|
@@ -67,7 +72,7 @@ export default class Rule_16_5_DefaultFirstOrLast extends MISRARule {
|
|
|
67
72
|
return false;
|
|
68
73
|
}
|
|
69
74
|
if (logErrors) {
|
|
70
|
-
this.logMISRAError(
|
|
75
|
+
this.logMISRAError(currentCase, "The default case of a switch statement must be the first or last label.")
|
|
71
76
|
}
|
|
72
77
|
return true;
|
|
73
78
|
}
|
|
@@ -82,8 +87,11 @@ export default class Rule_16_5_DefaultFirstOrLast extends MISRARule {
|
|
|
82
87
|
* @param $jp - Joinpoint to transform
|
|
83
88
|
* @returns Report detailing the transformation result
|
|
84
89
|
*/
|
|
85
|
-
|
|
86
|
-
|
|
90
|
+
apply($jp: Joinpoint): MISRATransformationReport {
|
|
91
|
+
const previousResult = $jp instanceof Switch ? this.context.getRuleResult("16.4", $jp) : undefined;
|
|
92
|
+
if (previousResult === MISRATransformationType.DescendantChange || !this.match($jp)) {
|
|
93
|
+
return new MISRATransformationReport(MISRATransformationType.NoChange);
|
|
94
|
+
}
|
|
87
95
|
|
|
88
96
|
const defaultCase = ($jp as Switch).getDefaultCase;
|
|
89
97
|
const rightStatements = defaultCase.siblingsRight.filter(sibling => !isCommentStmt(sibling));
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
|
|
2
2
|
import MISRARule from "../../MISRARule.js";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import { getNumOfSwitchClauses, switchHasConditionalBreak } from "../../utils/utils.js";
|
|
3
|
+
import { AnalysisType, MISRASwitchConverter, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
4
|
+
import { countSwitchClauses, hasConditionalBreak } from "../../utils/SwitchUtils.js";
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
|
-
* MISRA Rule 16.6: Every switch statement shall have at least two switch-clauses.
|
|
7
|
+
* MISRA-C Rule 16.6: Every switch statement shall have at least two switch-clauses.
|
|
9
8
|
*/
|
|
10
9
|
export default class Rule_16_6_SwitchMinTwoClauses extends MISRARule {
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
|
|
12
|
+
*/
|
|
13
|
+
readonly priority = 5;
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Scope of analysis
|
|
17
|
+
*/
|
|
18
|
+
readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @returns Rule identifier according to MISRA-C:2012
|
|
22
|
+
*/
|
|
23
|
+
override get name(): string {
|
|
24
|
+
return "16.6";
|
|
15
25
|
}
|
|
16
26
|
|
|
17
27
|
/**
|
|
@@ -23,7 +33,7 @@ export default class Rule_16_6_SwitchMinTwoClauses extends MISRARule {
|
|
|
23
33
|
match($jp: Joinpoint, logErrors: boolean = false): boolean {
|
|
24
34
|
if (!($jp instanceof Switch)) return false;
|
|
25
35
|
|
|
26
|
-
const nonCompliant =
|
|
36
|
+
const nonCompliant = countSwitchClauses($jp) < 2;
|
|
27
37
|
if (nonCompliant && logErrors) {
|
|
28
38
|
this.logMISRAError($jp, "Switch statements should have at least two clauses.")
|
|
29
39
|
}
|
|
@@ -37,11 +47,12 @@ export default class Rule_16_6_SwitchMinTwoClauses extends MISRARule {
|
|
|
37
47
|
* @param $jp - Joinpoint to transform
|
|
38
48
|
* @returns Report detailing the transformation result
|
|
39
49
|
*/
|
|
40
|
-
|
|
41
|
-
if (!this.match($jp))
|
|
50
|
+
apply($jp: Joinpoint): MISRATransformationReport {
|
|
51
|
+
if (!this.match($jp))
|
|
52
|
+
return new MISRATransformationReport(MISRATransformationType.NoChange);
|
|
42
53
|
|
|
43
54
|
const switchJp = $jp as Switch;
|
|
44
|
-
if (
|
|
55
|
+
if (hasConditionalBreak(switchJp)) {
|
|
45
56
|
if (switchJp.hasDefaultCase) {
|
|
46
57
|
this.logMISRAError($jp, "Switch statement must have at least two clauses and cannot be transformed due to a conditional break statement.")
|
|
47
58
|
}
|
|
@@ -1,16 +1,46 @@
|
|
|
1
|
-
import { BuiltinType, Joinpoint, Switch } from "@specs-feup/clava/api/Joinpoints.js";
|
|
1
|
+
import { BinaryOp, BuiltinType, Joinpoint, Switch, UnaryOp } from "@specs-feup/clava/api/Joinpoints.js";
|
|
2
2
|
import MISRARule from "../../MISRARule.js";
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { AnalysisType, MISRASwitchConverter, MISRATransformationReport, MISRATransformationType } from "../../MISRA.js";
|
|
4
|
+
import { hasConditionalBreak } from "../../utils/SwitchUtils.js";
|
|
5
|
+
import { hasDefinedType } from "../../utils/JoinpointUtils.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* MISRA Rule 16.7: A switch-expression shall not have essentially Boolean type.
|
|
8
|
+
* MISRA-C Rule 16.7: A switch-expression shall not have essentially Boolean type.
|
|
9
9
|
*/
|
|
10
10
|
export default class Rule_16_7_NonBooleanSwitchCondition extends MISRARule {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
/**
|
|
12
|
+
* A positive integer starting from 1 that indicates the rule's priority, determining the order in which rules are applied.
|
|
13
|
+
*/
|
|
14
|
+
readonly priority = 5;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Scope of analysis
|
|
18
|
+
*/
|
|
19
|
+
readonly analysisType = AnalysisType.SINGLE_TRANSLATION_UNIT;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @returns Rule identifier according to MISRA-C:2012
|
|
23
|
+
*/
|
|
24
|
+
override get name(): string {
|
|
25
|
+
return "16.7";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Checks if the provided switch statement has a Boolean condition
|
|
30
|
+
* @param switchStmt The switch statement to check
|
|
31
|
+
* @returns Returns true if the switch statement has a Boolean condition, otherwise false
|
|
32
|
+
*/
|
|
33
|
+
switchHasBooleanCondition(switchStmt: Switch): boolean {
|
|
34
|
+
const switchCondition = switchStmt.condition;
|
|
35
|
+
|
|
36
|
+
if (switchCondition instanceof BinaryOp || switchCondition instanceof UnaryOp) {
|
|
37
|
+
const logicalOps = new Set(["lt", "gt", "le", "ge", "eq", "ne", "not", "l_not", "and", "or"]);
|
|
38
|
+
return logicalOps.has(switchCondition.kind);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return hasDefinedType(switchCondition) &&
|
|
42
|
+
switchCondition.type instanceof BuiltinType &&
|
|
43
|
+
switchCondition.type.builtinKind === "Bool";
|
|
14
44
|
}
|
|
15
45
|
|
|
16
46
|
/**
|
|
@@ -22,9 +52,9 @@ export default class Rule_16_7_NonBooleanSwitchCondition extends MISRARule {
|
|
|
22
52
|
match($jp: Joinpoint, logErrors: boolean = false): boolean {
|
|
23
53
|
if (!($jp instanceof Switch)) return false;
|
|
24
54
|
|
|
25
|
-
const booleanCondition = switchHasBooleanCondition($jp);
|
|
55
|
+
const booleanCondition = this.switchHasBooleanCondition($jp);
|
|
26
56
|
if (booleanCondition && logErrors) {
|
|
27
|
-
this.logMISRAError($jp, `Switch statement controlling expression ${$jp.condition.code} must not have essentially boolean type.`)
|
|
57
|
+
this.logMISRAError($jp, `Switch statement controlling expression '${$jp.condition.code}' must not have essentially boolean type.`)
|
|
28
58
|
}
|
|
29
59
|
return booleanCondition;
|
|
30
60
|
}
|
|
@@ -36,10 +66,11 @@ export default class Rule_16_7_NonBooleanSwitchCondition extends MISRARule {
|
|
|
36
66
|
* @param $jp - Joinpoint to transform
|
|
37
67
|
* @returns Report detailing the transformation result
|
|
38
68
|
*/
|
|
39
|
-
|
|
40
|
-
if (!this.match($jp))
|
|
69
|
+
apply($jp: Joinpoint): MISRATransformationReport {
|
|
70
|
+
if (!this.match($jp))
|
|
71
|
+
return new MISRATransformationReport(MISRATransformationType.NoChange);
|
|
41
72
|
|
|
42
|
-
if (
|
|
73
|
+
if (hasConditionalBreak($jp as Switch)) {
|
|
43
74
|
this.logMISRAError($jp, `The switch statement's controlling expression ${($jp as Switch).condition.code} must not be of a boolean type and cannot be transformed due to a conditional break statement.`)
|
|
44
75
|
return new MISRATransformationReport(MISRATransformationType.NoChange);
|
|
45
76
|
}
|