diff --git a/change_notes/2024-06-21-misra-cpp-2023-support.md b/change_notes/2024-06-21-misra-cpp-2023-support.md new file mode 100644 index 0000000000..e314d447fa --- /dev/null +++ b/change_notes/2024-06-21-misra-cpp-2023-support.md @@ -0,0 +1,2 @@ +- `MISRA C++ 2023`: + - Extend the project structure and provide initial support for query writing. diff --git a/cpp/common/test/options b/cpp/common/test/options new file mode 100644 index 0000000000..59fc70d386 --- /dev/null +++ b/cpp/common/test/options @@ -0,0 +1 @@ +semmle-extractor-options:--clang -std=c++17 -nostdinc++ -I../../../../common/test/includes/standard-library -I../../../../common/test/includes/custom-library \ No newline at end of file diff --git a/cpp/misra/src/codeql-suites/misra-default.qls b/cpp/misra/src/codeql-suites/misra-default.qls new file mode 100644 index 0000000000..670b043caa --- /dev/null +++ b/cpp/misra/src/codeql-suites/misra-default.qls @@ -0,0 +1,10 @@ +- description: MISRA C++ 2023 (Default) +- qlpack: codeql/misra-cpp-coding-standards +- include: + kind: + - problem + - path-problem +- exclude: + tags contain: + - external/misra/audit + - external/misra/default-disabled diff --git a/cpp/misra/src/codeql-suites/misra-single-translation-unit.qls b/cpp/misra/src/codeql-suites/misra-single-translation-unit.qls new file mode 100644 index 0000000000..0782dd876d --- /dev/null +++ b/cpp/misra/src/codeql-suites/misra-single-translation-unit.qls @@ -0,0 +1,12 @@ +- description: MISRA C++ 2023 (Single Translation Unit) +- qlpack: codeql/misra-cpp-coding-standards +- include: + kind: + - problem + - path-problem + tags contain: + - scope/single-translation-unit +- exclude: + tags contain: + - external/misra/audit + - external/misra/default-disabled diff --git a/cpp/misra/src/codingstandards/cpp/misra.qll b/cpp/misra/src/codingstandards/cpp/misra.qll new file mode 100644 index 0000000000..ff308d4fd2 --- /dev/null +++ b/cpp/misra/src/codingstandards/cpp/misra.qll @@ -0,0 +1,4 @@ +import cpp +import misra.Customizations +import codingstandards.cpp.CodingStandards +import codingstandards.cpp.exclusions.cpp.RuleMetadata diff --git a/cpp/misra/src/codingstandards/cpp/misra/Customizations.qll b/cpp/misra/src/codingstandards/cpp/misra/Customizations.qll new file mode 100644 index 0000000000..b95d1bb3b3 --- /dev/null +++ b/cpp/misra/src/codingstandards/cpp/misra/Customizations.qll @@ -0,0 +1,8 @@ +/** + * Contains customizations to the MISRA C++ query rules. + * + * This module is imported by `misra.qll`, so any customizations defined here + * automatically apply to all MISRA C++ queries. + */ + +import cpp diff --git a/cpp/misra/src/qlpack.yml b/cpp/misra/src/qlpack.yml index 5a78931190..d177c9f651 100644 --- a/cpp/misra/src/qlpack.yml +++ b/cpp/misra/src/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/misra-cpp-coding-standards version: 2.33.0-dev -description: MISRA C++ 2008 +description: MISRA C++ 2023 suites: codeql-suites license: MIT dependencies: diff --git a/cpp/misra/test/options b/cpp/misra/test/options new file mode 100644 index 0000000000..59fc70d386 --- /dev/null +++ b/cpp/misra/test/options @@ -0,0 +1 @@ +semmle-extractor-options:--clang -std=c++17 -nostdinc++ -I../../../../common/test/includes/standard-library -I../../../../common/test/includes/custom-library \ No newline at end of file diff --git a/docs/design/guideline_recategorization.md b/docs/design/guideline_recategorization.md index f520869f39..e488cf88de 100644 --- a/docs/design/guideline_recategorization.md +++ b/docs/design/guideline_recategorization.md @@ -101,7 +101,7 @@ The *effective category* is the category whose policy is applied during the eval The policy of a category dictates if a result can be deviated from and implements the effect described in the design section. The existing exclusion mechanism implemented in the predicate `isExcluded` defined in the `Exclusions.qll` library will be updated to consider the applicable policy of a guideline. -Note: This changes the behavior of deviations which will no longer have an impact on Mandatory guidelines! However, this will only affect MISRA C rules because there are no MISRA C++ Guidelines with a Mandatory category. +Note: This changes the behavior of deviations which will no longer have an impact on Mandatory MISRA guidelines! ### Specification validation diff --git a/schemas/rule-package.schema.json b/schemas/rule-package.schema.json index 4d3c7f401a..daeb1ade51 100644 --- a/schemas/rule-package.schema.json +++ b/schemas/rule-package.schema.json @@ -220,6 +220,55 @@ "minProperties": 1 } } + }, + { + "properties": { + "MISRA-C++-2023": { + "description": "Rules part of the MISRA C++ 2023 standard", + "type": "object", + "patternProperties": { + "^RULE-\\d+-\\d+-\\d+": { + "description": "A coding standard rule", + "type": "object", + "properties": { + "properties": { + "type": "object", + "properties": { + "obligation": { + "type": "string", + "enum": [ + "required", + "advisory", + "mandatory" + ] + } + }, + "required": [ + "obligation" + ] + }, + "queries": { + "type": "array", + "uniqueItems": true, + "items": { + "$ref": "#/$defs/query" + } + }, + "title": { + "type": "string" + } + }, + "required": [ + "properties", + "queries", + "title" + ], + "additionalProperties": false + } + }, + "minProperties": 1 + } + } } ], "minProperties": 1, diff --git a/scripts/generate_rules/generate_package_description.py b/scripts/generate_rules/generate_package_description.py index 20c9adc065..bf993af574 100644 --- a/scripts/generate_rules/generate_package_description.py +++ b/scripts/generate_rules/generate_package_description.py @@ -110,6 +110,8 @@ def generate_short_name(title): print("Error: " + standard + " " + rule_id + " is marked as part of package " + package_name + " but is not marked as supportable.") sys.exit(1) + tags = [] + # Add the AUTOSAR obligation, enforcement and allocated target as query properties. properties = {} if obligation_level: @@ -117,7 +119,15 @@ def generate_short_name(title): if enforcement_level: properties["enforcement"] = enforcement_level.lower() if allocated_targets: - properties["allocated-target"] = [target.strip(' ').lower() for target in allocated_targets.split("/")] + if allocated_targets == "Single Translation Unit": + # MISRA C++ 2023 uses the allocated targets field for scope + tags.append("scope/single-translation-unit") + elif allocated_targets == "System": + # MISRA C++ 2023 uses the allocated targets field for scope + tags.append("scope/system") + else: + properties["allocated-target"] = [target.strip(' ').lower() for target in allocated_targets.split("/")] + if difficulty == "Audit": properties["audit"] = "" @@ -164,7 +174,7 @@ def generate_short_name(title): "severity" : severity, "description" : description, "kind" : "problem", - "tags" : [] + "tags" : tags } ] } diff --git a/scripts/generate_rules/generate_package_files.py b/scripts/generate_rules/generate_package_files.py index 6dabec0a92..ed8bb625bd 100644 --- a/scripts/generate_rules/generate_package_files.py +++ b/scripts/generate_rules/generate_package_files.py @@ -58,11 +58,15 @@ "MISRA-C-2012" : { "standard_title" : "MISRA-C:2012 Guidelines for the use of the C language in critical systems", "standard_url" : "https://www.misra.org.uk/" + }, + "MISRA-C++-2023" : { + "standard_title" : "MISRA C++:2023 Guidelines for the use C++:17 in critical systems", + "standard_url" : "https://misra.org.uk/product/misra-cpp2023/" } } # The help files of these standards cannot be distributed in our repository. -external_help_file_standards = ["AUTOSAR", "MISRA-C-2012"] +external_help_file_standards = ["AUTOSAR", "MISRA-C-2012", "MISRA-C++-2023"] # Mapping from the QL language to source file extension used to generate a help example file. ql_language_ext_mappings = { diff --git a/scripts/reports/utils.py b/scripts/reports/utils.py index 977826891c..6f5785808e 100644 --- a/scripts/reports/utils.py +++ b/scripts/reports/utils.py @@ -149,7 +149,7 @@ def __init__(self, sarif_results_file_path): if standard_rule_id in self.guideline_obligation_level[standard_short_name]: if not self.guideline_obligation_level[standard_short_name][standard_rule_id] == obligation_level: print( - f"WARNING: Rule { rule['id'] } specifies a conflicting obligation level of { obligation_level }, was previously specified as { guideline_obligation_level[standard_short_name][standard_rule_id] }.") + f"WARNING: Rule { rule['id'] } specifies a conflicting obligation level of { obligation_level }, was previously specified as { self.guideline_obligation_level[standard_short_name][standard_rule_id] }.") else: self.guideline_obligation_level[standard_short_name][standard_rule_id] = obligation_level # Add deviation counts for the rule