diff --git a/.github/actions/check-permissions/action.yml b/.github/actions/check-permissions/action.yml
new file mode 100644
index 0000000000..b47466d080
--- /dev/null
+++ b/.github/actions/check-permissions/action.yml
@@ -0,0 +1,49 @@
+name: Check current actor permissions
+description: |
+ Checks whether the current actor has the specified permssions
+inputs:
+ minimum-permission:
+ description: |
+ The minimum required permission. One of: read, write, admin
+ required: true
+outputs:
+ has-permission:
+ description: "Whether the actor had the minimum required permission"
+ value: ${{ steps.check-permission.outputs.has-permission }}
+
+runs:
+ using: composite
+ steps:
+ - uses: actions/github-script@v7
+ id: check-permission
+ env:
+ INPUT_MINIMUM-PERMISSION: ${{ inputs.minimum-permission }}
+ with:
+ script: |
+ // Valid permissions are none, read, write, admin (legacy base permissions)
+ const permissionsRanking = ["none", "read", "write", "admin"];
+
+ // Note: core.getInput doesn't work by default in a composite action - in this case
+ // it would try to fetch the input to the github-script instead of the action
+ // itself. Instead, we set the appropriate magic env var with the actions input.
+ // See: https://github.com/actions/runner/issues/665
+ const minimumPermission = core.getInput('minimum-permission');
+ if (!permissionsRanking.includes(minimumPermission)) {
+ core.setFailed(`Invalid minimum permission: ${minimumPermission}`);
+ return;
+ }
+
+ const { data : { permission : actorPermission } } = await github.rest.repos.getCollaboratorPermissionLevel({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ username: context.actor
+ });
+
+ // Confirm whether the actor permission is at least the selected permission
+ const hasPermission = permissionsRanking.indexOf(minimumPermission) <= permissionsRanking.indexOf(actorPermission) ? "1" : "";
+ core.setOutput('has-permission', hasPermission);
+ if (!hasPermission) {
+ core.info(`Current actor (${context.actor}) does not have the minimum required permission '${minimumPermission}' (has '${actorPermission}')`);
+ } else {
+ core.info(`Current actor (${context.actor}) has the minimum required permission '${minimumPermission}' (has '${actorPermission}')`);
+ }
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000000..73f11c1f47
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,8 @@
+version: 2
+updates:
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ # Check for updates to GitHub Actions every week
+ interval: "weekly"
\ No newline at end of file
diff --git a/.github/workflows/code-scanning-pack-gen.yml b/.github/workflows/code-scanning-pack-gen.yml
index 1fd57cf755..c88dae52cd 100644
--- a/.github/workflows/code-scanning-pack-gen.yml
+++ b/.github/workflows/code-scanning-pack-gen.yml
@@ -8,7 +8,6 @@ on:
- main
- next
- "rc/**"
-
push:
branches:
- main
@@ -47,7 +46,7 @@ jobs:
- name: Cache CodeQL
id: cache-codeql
- uses: actions/cache@v2.1.3
+ uses: actions/cache@v4
with:
path: ${{ github.workspace }}/codeql_home
key: codeql-home-${{ matrix.os }}-${{ matrix.codeql_cli }}-${{ matrix.codeql_standard_library }}
@@ -98,15 +97,36 @@ jobs:
CODEQL_HOME: ${{ github.workspace }}/codeql_home
run: |
PATH=$PATH:$CODEQL_HOME/codeql
-
- codeql query compile --precompile --threads 0 cpp
- codeql query compile --precompile --threads 0 c
+ # Precompile all queries, and use a compilation cache larger than default
+ # to ensure we cache all the queries for later steps
+ codeql query compile --precompile --threads 0 --compilation-cache-size=1024 cpp c
cd ..
- zip -r codeql-coding-standards/code-scanning-cpp-query-pack.zip codeql-coding-standards/c/ codeql-coding-standards/cpp/ codeql-coding-standards/.codeqlmanifest.json codeql-coding-standards/supported_codeql_configs.json codeql-coding-standards/scripts/configuration codeql-coding-standards/scripts/reports codeql-coding-standards/scripts/shared codeql-coding-standards/scripts/guideline_recategorization codeql-coding-standards/scripts/shared codeql-coding-standards/scripts/schemas
+ zip -r codeql-coding-standards/code-scanning-cpp-query-pack.zip codeql-coding-standards/c/ codeql-coding-standards/cpp/ codeql-coding-standards/.codeqlmanifest.json codeql-coding-standards/supported_codeql_configs.json codeql-coding-standards/scripts/configuration codeql-coding-standards/scripts/reports codeql-coding-standards/scripts/shared codeql-coding-standards/scripts/guideline_recategorization codeql-coding-standards/schemas
- name: Upload GHAS Query Pack
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: code-scanning-cpp-query-pack.zip
path: code-scanning-cpp-query-pack.zip
+
+ - name: Create qlpack bundles
+ env:
+ CODEQL_HOME: ${{ github.workspace }}/codeql_home
+ run: |
+ PATH=$PATH:$CODEQL_HOME/codeql
+
+ codeql pack bundle --output=common-cpp-coding-standards.tgz cpp/common/src
+ codeql pack bundle --output=common-c-coding-standards.tgz c/common/src
+ codeql pack bundle --output=misra-c-coding-standards.tgz c/misra/src
+ codeql pack bundle --output=cert-c-coding-standards.tgz c/cert/src
+ codeql pack bundle --output=cert-cpp-coding-standards.tgz cpp/cert/src
+ codeql pack bundle --output=autosar-cpp-coding-standards.tgz cpp/autosar/src
+ codeql pack bundle --output=misra-cpp-coding-standards.tgz cpp/misra/src
+ codeql pack bundle --output=report-coding-standards.tgz cpp/report/src
+
+ - name: Upload qlpack bundles
+ uses: actions/upload-artifact@v4
+ with:
+ name: coding-standards-codeql-packs
+ path: '*-coding-standards.tgz'
\ No newline at end of file
diff --git a/.github/workflows/codeql_unit_tests.yml b/.github/workflows/codeql_unit_tests.yml
index 62660d973d..2c771b4575 100644
--- a/.github/workflows/codeql_unit_tests.yml
+++ b/.github/workflows/codeql_unit_tests.yml
@@ -48,7 +48,7 @@ jobs:
uses: actions/checkout@v4
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
@@ -57,7 +57,7 @@ jobs:
- name: Cache CodeQL
id: cache-codeql
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
# A list of files, directories, and wildcard patterns to cache and restore
path: ${{github.workspace}}/codeql_home
@@ -151,7 +151,7 @@ jobs:
file.close()
- name: Upload test results
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: ${{ matrix.language }}-test-results-${{ runner.os }}-${{ matrix.codeql_cli }}-${{ matrix.codeql_standard_library_ident }}
path: |
@@ -160,11 +160,18 @@ jobs:
validate-test-results:
name: Validate test results
+ if: ${{ always() }}
needs: run-test-suites
runs-on: ubuntu-22.04
steps:
+ - name: Check if run-test-suites job failed to complete, if so fail
+ if: ${{ needs.run-test-suites.result == 'failure' }}
+ uses: actions/github-script@v3
+ with:
+ script: |
+ core.setFailed('Test run job failed')
- name: Collect test results
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
- name: Validate test results
run: |
diff --git a/.github/workflows/dispatch-matrix-check.yml b/.github/workflows/dispatch-matrix-check.yml
deleted file mode 100644
index 350f2fb73f..0000000000
--- a/.github/workflows/dispatch-matrix-check.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-name: 🤖 Run Matrix Check
-
-on:
- pull_request_target:
- types: [synchronize,opened]
- branches:
- - "matrix/**"
- workflow_dispatch:
-
-jobs:
- dispatch-matrix-check:
- runs-on: ubuntu-22.04
- steps:
-
- - name: Test Variables
- shell: pwsh
- run: |
- Write-Host "Running as: ${{github.actor}}"
-
- - name: Dispatch Matrix Testing Job
- if: ${{ contains(fromJSON('["jsinglet", "mbaluda", "lcartey", "rvermeulen", "ravikprasad", "jeongsoolee09", "hohn", "knewbury01", "kraiouchkine"]'), github.actor) }}
- uses: peter-evans/repository-dispatch@v2
- with:
- token: ${{ secrets.RELEASE_ENGINEERING_TOKEN }}
- repository: github/codeql-coding-standards-release-engineering
- event-type: matrix-test
- client-payload: '{"pr": "${{ github.event.number }}"}'
-
-
- - uses: actions/github-script@v6
- if: ${{ contains(fromJSON('["jsinglet", "mbaluda", "lcartey", "rvermeulen", "ravikprasad", "jeongsoolee09", "hohn", "knewbury01", "kraiouchkine"]'), github.actor) }}
- with:
- script: |
- github.rest.issues.createComment({
- issue_number: context.issue.number,
- owner: context.repo.owner,
- repo: context.repo.repo,
- body: '🤖 Beep Boop! Matrix Testing for this PR has been initiated. Please check back later for results.
:bulb: If you do not hear back from me please check my status! **I will report even if this PR does not contain files eligible for matrix testing.**'
- })
\ No newline at end of file
diff --git a/.github/workflows/dispatch-matrix-test-on-comment.yml b/.github/workflows/dispatch-matrix-test-on-comment.yml
index bef0ba7232..297b6fbc7e 100644
--- a/.github/workflows/dispatch-matrix-test-on-comment.yml
+++ b/.github/workflows/dispatch-matrix-test-on-comment.yml
@@ -3,42 +3,45 @@ name: 🤖 Run Matrix Check (On Comment)
on:
issue_comment:
types: [created]
- branches:
- - main
- - "rc/**"
- - next
-
jobs:
dispatch-matrix-check:
runs-on: ubuntu-22.04
steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
- - name: Test Variables
- shell: pwsh
- run: |
- Write-Host "Running as: ${{github.actor}}"
-
- $actor = "${{github.actor}}"
-
- $acl = @("jsinglet","mbaluda", "lcartey", "rvermeulen", "ravikprasad", "jeongsoolee09", "hohn", "knewbury01", "kraiouchkine")
-
- if(-not ($actor -in $acl)){
- throw "Refusing to run workflow for user not in acl."
- }
-
+ - name: Check permission
+ id: check-write-permission
+ uses: ./.github/actions/check-permissions
+ with:
+ minimum-permission: "write"
- - name: Dispatch Matrix Testing Job
- if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-matrix') }}
- uses: peter-evans/repository-dispatch@v2
+ - name: Generate token
+ id: generate-token
+ uses: actions/create-github-app-token@v1
with:
- token: ${{ secrets.RELEASE_ENGINEERING_TOKEN }}
- repository: github/codeql-coding-standards-release-engineering
- event-type: matrix-test
- client-payload: '{"pr": "${{ github.event.issue.number }}"}'
+ app-id: ${{ vars.AUTOMATION_APP_ID }}
+ private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
+ owner: ${{ github.repository_owner }}
+ repositories: "codeql-coding-standards-release-engineering"
+
+ - name: Invoke matrix testing job
+ if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-matrix') && steps.check-write-permission.outputs.has-permission }}
+ env:
+ ISSUE_NR: ${{ github.event.issue.number }}
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ run: |
+ jq -n \
+ --arg issue_nr "$ISSUE_NR" \
+ '{"issue-nr": $issue_nr}' \
+ | \
+ gh workflow run pr-compiler-validation.yml \
+ --json \
+ -R github/codeql-coding-standards-release-engineering
- uses: actions/github-script@v6
- if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-matrix') }}
+ if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-matrix') && steps.check-write-permission.outputs.has-permission }}
with:
script: |
github.rest.issues.createComment({
diff --git a/.github/workflows/dispatch-release-performance-check.yml b/.github/workflows/dispatch-release-performance-check.yml
index 0858527721..260846185a 100644
--- a/.github/workflows/dispatch-release-performance-check.yml
+++ b/.github/workflows/dispatch-release-performance-check.yml
@@ -3,41 +3,45 @@ name: 🏁 Run Release Performance Check
on:
issue_comment:
types: [created]
- branches:
- - main
- - "rc/**"
- - next
jobs:
dispatch-matrix-check:
runs-on: ubuntu-22.04
steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
- - name: Test Variables
- shell: pwsh
- run: |
- Write-Host "Running as: ${{github.actor}}"
-
- $actor = "${{github.actor}}"
-
- $acl = @("jsinglet","mbaluda", "lcartey", "rvermeulen", "ravikprasad", "jeongsoolee09", "hohn", "knewbury01", "kraiouchkine")
-
- if(-not ($actor -in $acl)){
- throw "Refusing to run workflow for user not in acl."
- }
-
- - name: Dispatch Performance Testing Job
- if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-performance') }}
- uses: peter-evans/repository-dispatch@v2
+ - name: Check permission
+ id: check-write-permission
+ uses: ./.github/actions/check-permissions
with:
- token: ${{ secrets.RELEASE_ENGINEERING_TOKEN }}
- repository: github/codeql-coding-standards-release-engineering
- event-type: performance-test
- client-payload: '{"pr": "${{ github.event.issue.number }}"}'
+ minimum-permission: "write"
+ - name: Generate token
+ id: generate-token
+ uses: actions/create-github-app-token@v1
+ with:
+ app-id: ${{ vars.AUTOMATION_APP_ID }}
+ private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
+ owner: ${{ github.repository_owner }}
+ repositories: "codeql-coding-standards-release-engineering"
+
+ - name: Invoke performance test
+ if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-performance') && steps.check-write-permission.outputs.has-permission }}
+ env:
+ ISSUE_NR: ${{ github.event.issue.number }}
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ run: |
+ jq -n \
+ --arg issue_nr "$ISSUE_NR" \
+ '{"issue-nr": $issue_nr}' \
+ | \
+ gh workflow run pr-performance-testing.yml \
+ --json \
+ -R github/codeql-coding-standards-release-engineering
- uses: actions/github-script@v6
- if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-performance') }}
+ if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-performance') && steps.check-write-permission.outputs.has-permission }}
with:
script: |
github.rest.issues.createComment({
@@ -45,4 +49,4 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
body: '🏁 Beep Boop! Performance testing for this PR has been initiated. Please check back later for results. Note that the query package generation step must complete before testing will start so it might be a minute.
:bulb: If you do not hear back from me please check my status! **I will report even if I fail!**'
- })
\ No newline at end of file
+ })
diff --git a/.github/workflows/extra-rule-validation.yml b/.github/workflows/extra-rule-validation.yml
index a18f47c65d..02d37f92b2 100644
--- a/.github/workflows/extra-rule-validation.yml
+++ b/.github/workflows/extra-rule-validation.yml
@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Check Rules
shell: pwsh
@@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Ensure CPP Shared Rules Have Valid Structure
shell: pwsh
@@ -44,13 +44,13 @@ jobs:
run: scripts/util/Test-SharedImplementationsHaveTestCases.ps1 -Language c -CIMode
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
if: failure()
with:
name: missing-test-report.csv
path: MissingTestReport*.csv
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
if: failure()
with:
name: test-report.csv
diff --git a/.github/workflows/finalize-release.yml b/.github/workflows/finalize-release.yml
index d3f511caba..a7ccc0375e 100644
--- a/.github/workflows/finalize-release.yml
+++ b/.github/workflows/finalize-release.yml
@@ -52,7 +52,7 @@ jobs:
path: tooling
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
@@ -103,7 +103,7 @@ jobs:
- name: Generate token
if: env.HOTFIX_RELEASE == 'false'
id: generate-token
- uses: actions/create-github-app-token@eaddb9eb7e4226c68cf4b39f167c83e5bd132b3e
+ uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
diff --git a/.github/workflows/generate-html-docs.yml b/.github/workflows/generate-html-docs.yml
index f8e3d6d30c..d63f631421 100644
--- a/.github/workflows/generate-html-docs.yml
+++ b/.github/workflows/generate-html-docs.yml
@@ -20,10 +20,10 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
@@ -35,7 +35,7 @@ jobs:
python scripts/documentation/generate_iso26262_docs.py coding-standards-html-docs
- name: Upload HTML documentation
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: coding-standards-docs-${{ github.sha }}
path: coding-standards-html-docs/
diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml
index 9bbd27ce26..19dbe1adbd 100644
--- a/.github/workflows/prepare-release.yml
+++ b/.github/workflows/prepare-release.yml
@@ -34,12 +34,12 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
@@ -143,7 +143,7 @@ jobs:
- name: Generate token
id: generate-token
- uses: actions/create-github-app-token@eaddb9eb7e4226c68cf4b39f167c83e5bd132b3e
+ uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
diff --git a/.github/workflows/standard_library_upgrade_tests.yml b/.github/workflows/standard_library_upgrade_tests.yml
index aac2fd1e0e..a401150b07 100644
--- a/.github/workflows/standard_library_upgrade_tests.yml
+++ b/.github/workflows/standard_library_upgrade_tests.yml
@@ -19,7 +19,7 @@ jobs:
matrix: ${{ steps.export-unit-test-matrix.outputs.matrix }}
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Export unit test matrix
id: export-unit-test-matrix
@@ -41,16 +41,16 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Setup Python 3
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Cache CodeQL
id: cache-codeql
- uses: actions/cache@v2.1.3
+ uses: actions/cache@v4
with:
# A list of files, directories, and wildcard patterns to cache and restore
path: ${{github.workspace}}/codeql_home
@@ -143,7 +143,7 @@ jobs:
}, test_summary_file)
- name: Upload test results
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: test-results-${{runner.os}}-${{matrix.codeql_cli}}-${{matrix.codeql_standard_library_ident}}
path: |
@@ -157,12 +157,12 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
- name: Collect test results
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v4
- name: Validate test results
shell: python
diff --git a/.github/workflows/tooling-unit-tests.yml b/.github/workflows/tooling-unit-tests.yml
index 490d399e8b..3f4fde932d 100644
--- a/.github/workflows/tooling-unit-tests.yml
+++ b/.github/workflows/tooling-unit-tests.yml
@@ -22,7 +22,7 @@ jobs:
matrix: ${{ steps.export-supported-codeql-env-matrix.outputs.matrix }}
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Export supported CodeQL environment matrix
id: export-supported-codeql-env-matrix
@@ -40,10 +40,10 @@ jobs:
matrix: ${{ fromJSON(needs.prepare-supported-codeql-env-matrix.outputs.matrix) }}
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
@@ -52,7 +52,7 @@ jobs:
- name: Cache CodeQL
id: cache-codeql
- uses: actions/cache@v2.1.3
+ uses: actions/cache@v4
with:
path: ${{ github.workspace }}/codeql_home
key: codeql-home-${{ matrix.os }}-${{ matrix.codeql_cli }}-${{ matrix.codeql_standard_library }}
@@ -83,10 +83,10 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
@@ -102,10 +102,10 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
diff --git a/.github/workflows/update-release.yml b/.github/workflows/update-release.yml
index 21838c1d9f..4f779d0841 100644
--- a/.github/workflows/update-release.yml
+++ b/.github/workflows/update-release.yml
@@ -34,7 +34,7 @@ jobs:
ref: ${{ inputs.head-sha }}
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
@@ -43,7 +43,7 @@ jobs:
- name: Generate token
id: generate-token
- uses: actions/create-github-app-token@eaddb9eb7e4226c68cf4b39f167c83e5bd132b3e
+ uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
diff --git a/.github/workflows/upgrade_codeql_dependencies.yml b/.github/workflows/upgrade_codeql_dependencies.yml
index 73721d5581..841b78fcd6 100644
--- a/.github/workflows/upgrade_codeql_dependencies.yml
+++ b/.github/workflows/upgrade_codeql_dependencies.yml
@@ -18,10 +18,20 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
+
+ - name: Fetch CodeQL
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ RUNNER_TEMP: ${{ runner.temp }}
+ run: |
+ cd $RUNNER_TEMP
+ gh release download "v${CODEQL_CLI_VERSION}" --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip
+ unzip -q codeql-linux64.zip
+ echo "$RUNNER_TEMP/codeql/" >> $GITHUB_PATH
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
@@ -35,27 +45,27 @@ jobs:
run: |
python3 scripts/upgrade-codeql-dependencies/upgrade-codeql-dependencies.py --cli-version "$CODEQL_CLI_VERSION"
- - name: Fetch CodeQL
- env:
- GITHUB_TOKEN: ${{ github.token }}
- RUNNER_TEMP: ${{ runner.temp }}
- run: |
- cd $RUNNER_TEMP
- gh release download "v${CODEQL_CLI_VERSION}" --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip
- unzip -q codeql-linux64.zip
-
- name: Update CodeQL formatting based on new CLI version
env:
RUNNER_TEMP: ${{ runner.temp }}
run: |
- find cpp \( -name '*.ql' -or -name '*.qll' \) -print0 | xargs -0 --max-procs "$XARGS_MAX_PROCS" $RUNNER_TEMP/codeql/codeql query format --in-place
- find c \( -name '*.ql' -or -name '*.qll' \) -print0 | xargs -0 --max-procs "$XARGS_MAX_PROCS" $RUNNER_TEMP/codeql/codeql query format --in-place
+ find cpp \( -name '*.ql' -or -name '*.qll' \) -print0 | xargs -0 --max-procs "$XARGS_MAX_PROCS" codeql query format --in-place
+ find c \( -name '*.ql' -or -name '*.qll' \) -print0 | xargs -0 --max-procs "$XARGS_MAX_PROCS" codeql query format --in-place
- name: Create Pull Request
- uses: peter-evans/create-pull-request@v3
+ uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
with:
- title: "Upgrading `github/codeql` dependency to ${{ github.event.inputs.codeql_cli_version }}"
- body: "This PR upgrades the CodeQL CLI version to ${{ github.event.inputs.codeql_cli_version }}."
+ title: "Upgrade `github/codeql` dependency to ${{ github.event.inputs.codeql_cli_version }}"
+ body: |
+ This PR upgrades the CodeQL CLI version to ${{ github.event.inputs.codeql_cli_version }}.
+
+ ## CodeQL dependency upgrade checklist:
+
+ - [ ] Confirm the code has been correctly reformatted according to the new CodeQL CLI.
+ - [ ] Identify any CodeQL compiler warnings and errors, and update queries as required.
+ - [ ] Validate that the `github/codeql` test cases succeed.
+ - [ ] Address any CodeQL test failures in the `github/codeql-coding-standards` repository.
+ - [ ] Validate performance vs pre-upgrade, using /test-performance
commit-message: "Upgrading `github/codeql` dependency to ${{ github.event.inputs.codeql_cli_version }}"
delete-branch: true
branch: "codeql/upgrade-to-${{ github.event.inputs.codeql_cli_version }}"
diff --git a/.github/workflows/validate-package-files.yml b/.github/workflows/validate-package-files.yml
index 0573b00590..a716921053 100644
--- a/.github/workflows/validate-package-files.yml
+++ b/.github/workflows/validate-package-files.yml
@@ -16,12 +16,12 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
- name: Install Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
@@ -56,4 +56,10 @@ jobs:
find rule_packages/$LANGUAGE -name \*.json -exec basename {} .json \; | xargs python scripts/generate_rules/generate_package_files.py $LANGUAGE
git diff
git diff --compact-summary
- git diff --quiet
\ No newline at end of file
+ git diff --quiet
+
+ - name: Validate Amendments
+ env:
+ LANGUAGE: ${{ matrix.language }}
+ run: |
+ python scripts/validate-amendments-csv.py $LANGUAGE
\ No newline at end of file
diff --git a/.github/workflows/validate-query-formatting.yml b/.github/workflows/validate-query-formatting.yml
index e4c6871ad5..88b4c0d438 100644
--- a/.github/workflows/validate-query-formatting.yml
+++ b/.github/workflows/validate-query-formatting.yml
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
diff --git a/.github/workflows/validate-query-help.yml b/.github/workflows/validate-query-help.yml
index d99144fc7f..90f0d16dbc 100644
--- a/.github/workflows/validate-query-help.yml
+++ b/.github/workflows/validate-query-help.yml
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
diff --git a/.github/workflows/validate-query-test-case-formatting.yml b/.github/workflows/validate-query-test-case-formatting.yml
index 7b95484376..879c1c9058 100644
--- a/.github/workflows/validate-query-test-case-formatting.yml
+++ b/.github/workflows/validate-query-test-case-formatting.yml
@@ -20,7 +20,7 @@ jobs:
fail-fast: false
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
diff --git a/.github/workflows/validate-release.yml b/.github/workflows/validate-release.yml
index 5f5382f5dd..63aa9e90e3 100644
--- a/.github/workflows/validate-release.yml
+++ b/.github/workflows/validate-release.yml
@@ -40,7 +40,7 @@ jobs:
steps:
- name: Generate token
id: generate-token
- uses: actions/create-github-app-token@eaddb9eb7e4226c68cf4b39f167c83e5bd132b3e
+ uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
@@ -108,7 +108,7 @@ jobs:
steps:
- name: Generate token
id: generate-token
- uses: actions/create-github-app-token@eaddb9eb7e4226c68cf4b39f167c83e5bd132b3e
+ uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
diff --git a/.github/workflows/verify-standard-library-dependencies.yml b/.github/workflows/verify-standard-library-dependencies.yml
index cd5d35248d..06ab4d23e2 100644
--- a/.github/workflows/verify-standard-library-dependencies.yml
+++ b/.github/workflows/verify-standard-library-dependencies.yml
@@ -22,7 +22,7 @@ jobs:
matrix: ${{ steps.export-matrix.outputs.matrix }}
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Export unit test matrix
id: export-matrix
@@ -44,16 +44,16 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Setup Python 3
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.9"
- name: Cache CodeQL
id: cache-codeql
- uses: actions/cache@v2.1.3
+ uses: actions/cache@v4
with:
# A list of files, directories, and wildcard patterns to cache and restore
path: ${{github.workspace}}/codeql_home
diff --git a/README.md b/README.md
index d1de9b6372..0f24587afe 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,11 @@ The following coding standards are supported:
## :construction: Standards under development :construction:
-- [MISRA C++ 2023](https://misra.org.uk/product/misra-cpp2023/) - under development _scheduled for release 2024 Q4_.
+The following standards are under active development:
+
+- [MISRA C++ 2023](https://misra.org.uk/product/misra-cpp2023/) - under development - _scheduled for release 2025 Q1_
+- [MISRA C 2023](https://misra.org.uk/product/misra-c2023/) - under development - _scheduled for release 2025 Q1_
+ - This includes the development of [MISRA C 2012 Amendment 3](https://misra.org.uk/app/uploads/2021/06/MISRA-C-2012-AMD3.pdf) and [MISRA C 2012 Amendment 4](https://misra.org.uk/app/uploads/2021/06/MISRA-C-2012-AMD4.pdf), which are incorporated into MISRA C 2023.
## How do I use the CodeQL Coding Standards Queries?
diff --git a/amendments.csv b/amendments.csv
new file mode 100644
index 0000000000..cd0085493e
--- /dev/null
+++ b/amendments.csv
@@ -0,0 +1,49 @@
+language,standard,amendment,rule_id,supportable,implementation_category,implemented,difficulty
+c,MISRA-C-2012,Amendment3,DIR-4-6,Yes,Expand,No,Easy
+c,MISRA-C-2012,Amendment3,DIR-4-9,Yes,Refine,No,Easy
+c,MISRA-C-2012,Amendment3,DIR-4-11,Yes,Refine,No,Import
+c,MISRA-C-2012,Amendment3,RULE-1-4,Yes,Replace,No,Easy
+c,MISRA-C-2012,Amendment3,RULE-10-1,Yes,Replace,No,Easy
+c,MISRA-C-2012,Amendment3,RULE-10-3,Yes,Refine,No,Easy
+c,MISRA-C-2012,Amendment3,RULE-10-4,Yes,Refine,No,Import
+c,MISRA-C-2012,Amendment3,RULE-10-5,Yes,Expand,No,Easy
+c,MISRA-C-2012,Amendment3,RULE-10-7,Yes,Refine,No,Import
+c,MISRA-C-2012,Amendment3,RULE-10-8,Yes,Refine,No,Import
+c,MISRA-C-2012,Amendment3,RULE-21-11,Yes,Clarification,No,Import
+c,MISRA-C-2012,Amendment3,RULE-21-12,Yes,Replace,No,Easy
+c,MISRA-C-2012,Amendment4,RULE-11-3,Yes,Expand,No,Easy
+c,MISRA-C-2012,Amendment4,RULE-11-8,Yes,Expand,No,Easy
+c,MISRA-C-2012,Amendment4,RULE-13-2,Yes,Expand,No,Very Hard
+c,MISRA-C-2012,Amendment4,RULE-18-6,Yes,Expand,No,Medium
+c,MISRA-C-2012,Amendment4,RULE-18-8,Yes,Split,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-2-2,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-2-7,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-3-1,Yes,Refine,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-8-6,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-8-9,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-9-4,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-10-1,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-18-3,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-1-4,Yes,Replace,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-9-1,Yes,Refine,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-9-2,Yes,Refine,No,Import
+c,MISRA-C-2012,Corrigendum2,DIR-4-10,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-7-4,Yes,Refine,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-8-2,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-8-3,Yes,Refine,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-8-7,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-10-2,Yes,Refine,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-10-3,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-11-3,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-11-6,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-13-2,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-13-6,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-14-3,Yes,Refine,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-15-7,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-17-4,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-17-5,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-18-1,Yes,Refine,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-20-14,No,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-21-19,Yes,Clarification,No,Import
+c,MISRA-C-2012,Corrigendum2,RULE-21-20,Yes,Refine,No,Easy
+c,MISRA-C-2012,Corrigendum2,RULE-22-9,Yes,Clarification,No,Import
\ No newline at end of file
diff --git a/apply-configuration/action.yml b/apply-configuration/action.yml
new file mode 100644
index 0000000000..89a702b72a
--- /dev/null
+++ b/apply-configuration/action.yml
@@ -0,0 +1,24 @@
+name: Applies Coding Standard configuration files in the repository
+description: |
+ Installs Python and indexes the CodeQL Coding Standard configuration files in the repository
+
+runs:
+ using: composite
+ steps:
+ - name: Install Python
+ id: cs-install-python
+ uses: actions/setup-python@v5
+ with:
+ python-version: 3.9
+ update-environment: false
+ - name: Install dependencies and process files
+ shell: bash
+ run: |
+ install_dir=$(dirname $(dirname "${{ steps.cs-install-python.outputs.python-path }}"))
+ if [[ -z "$LD_LIBRARY_PATH" ]]; then
+ export LD_LIBRARY_PATH="$install_dir/lib"
+ else
+ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$install_dir/lib"
+ fi
+ ${{ steps.cs-install-python.outputs.python-path }} -m pip install -r ${GITHUB_ACTION_PATH}/../scripts/configuration/requirements.txt
+ ${{ steps.cs-install-python.outputs.python-path }} ${GITHUB_ACTION_PATH}/../scripts/configuration/process_coding_standards_config.py
\ No newline at end of file
diff --git a/c/cert/src/codeql-pack.lock.yml b/c/cert/src/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/c/cert/src/codeql-pack.lock.yml
+++ b/c/cert/src/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/c/cert/src/qlpack.yml b/c/cert/src/qlpack.yml
index fbae0e71e0..db08fb3ebe 100644
--- a/c/cert/src/qlpack.yml
+++ b/c/cert/src/qlpack.yml
@@ -1,8 +1,8 @@
name: codeql/cert-c-coding-standards
-version: 2.33.0-dev
+version: 2.38.0-dev
description: CERT C 2016
suites: codeql-suites
license: MIT
dependencies:
codeql/common-c-coding-standards: '*'
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 0.12.9
diff --git a/c/cert/src/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.ql b/c/cert/src/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.ql
index c641c17124..ff1517c5b1 100644
--- a/c/cert/src/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.ql
+++ b/c/cert/src/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.c.cert
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
import codingstandards.cpp.dataflow.TaintTracking
import ScaledIntegerPointerArithmeticFlow::PathGraph
diff --git a/c/cert/src/rules/DCL40-C/IncompatibleFunctionDeclarations.ql b/c/cert/src/rules/DCL40-C/IncompatibleFunctionDeclarations.ql
index 4660e69b68..20b6e5e59e 100644
--- a/c/cert/src/rules/DCL40-C/IncompatibleFunctionDeclarations.ql
+++ b/c/cert/src/rules/DCL40-C/IncompatibleFunctionDeclarations.ql
@@ -16,30 +16,32 @@
import cpp
import codingstandards.c.cert
+import codingstandards.cpp.Compatible
import ExternalIdentifiers
-//checks if they are incompatible based on return type, number of parameters and parameter types
-predicate checkMatchingFunction(FunctionDeclarationEntry d, FunctionDeclarationEntry d2) {
- not d.getType() = d2.getType()
- or
- not d.getNumberOfParameters() = d2.getNumberOfParameters()
- or
- exists(ParameterDeclarationEntry p, ParameterDeclarationEntry p2, int i |
- d.getParameterDeclarationEntry(i) = p and
- d2.getParameterDeclarationEntry(i) = p2 and
- not p.getType() = p2.getType()
- )
-}
-
from ExternalIdentifiers d, FunctionDeclarationEntry f1, FunctionDeclarationEntry f2
where
not isExcluded(f1, Declarations2Package::incompatibleFunctionDeclarationsQuery()) and
not isExcluded(f2, Declarations2Package::incompatibleFunctionDeclarationsQuery()) and
- f1 = d.getADeclarationEntry() and
- f2 = d.getADeclarationEntry() and
not f1 = f2 and
- f1.getLocation().getStartLine() >= f2.getLocation().getStartLine() and
+ f1.getDeclaration() = d and
+ f2.getDeclaration() = d and
f1.getName() = f2.getName() and
- checkMatchingFunction(f1, f2)
+ (
+ //return type check
+ not typesCompatible(f1.getType(), f2.getType())
+ or
+ //parameter type check
+ parameterTypesIncompatible(f1, f2)
+ or
+ not f1.getNumberOfParameters() = f2.getNumberOfParameters()
+ ) and
+ // Apply ordering on start line, trying to avoid the optimiser applying this join too early
+ // in the pipeline
+ exists(int f1Line, int f2Line |
+ f1.getLocation().hasLocationInfo(_, f1Line, _, _, _) and
+ f2.getLocation().hasLocationInfo(_, f2Line, _, _, _) and
+ f1Line >= f2Line
+ )
select f1, "The object $@ is not compatible with re-declaration $@", f1, f1.getName(), f2,
f2.getName()
diff --git a/c/cert/src/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql b/c/cert/src/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql
index a4cc4e8944..08121f8c2b 100644
--- a/c/cert/src/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql
+++ b/c/cert/src/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql
@@ -12,177 +12,11 @@
import cpp
import codingstandards.c.cert
-import codingstandards.c.Pointers
-import codingstandards.c.Variable
-import codingstandards.cpp.dataflow.DataFlow
-import semmle.code.cpp.pointsto.PointsTo
-import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
+import codingstandards.cpp.rules.donotpassaliasedpointertorestrictqualifiedparamshared.DoNotPassAliasedPointerToRestrictQualifiedParamShared
-/**
- * A function that has a parameter with a restrict-qualified pointer type.
- */
-class FunctionWithRestrictParameters extends Function {
- Parameter restrictPtrParam;
-
- FunctionWithRestrictParameters() {
- restrictPtrParam.getUnspecifiedType() instanceof PointerOrArrayType and
- (
- restrictPtrParam.getType().hasSpecifier(["restrict"]) and
- restrictPtrParam = this.getAParameter()
- or
- this.hasGlobalName(["strcpy", "strncpy", "strcat", "strncat", "memcpy"]) and
- restrictPtrParam = this.getParameter([0, 1])
- or
- this.hasGlobalName(["strcpy_s", "strncpy_s", "strcat_s", "strncat_s", "memcpy_s"]) and
- restrictPtrParam = this.getParameter([0, 2])
- or
- this.hasGlobalName(["strtok_s"]) and
- restrictPtrParam = this.getAParameter()
- or
- this.hasGlobalName(["printf", "printf_s", "scanf", "scanf_s"]) and
- restrictPtrParam = this.getParameter(0)
- or
- this.hasGlobalName(["sprintf", "sprintf_s", "snprintf", "snprintf_s"]) and
- restrictPtrParam = this.getParameter(3)
- )
- }
-
- Parameter getARestrictPtrParam() { result = restrictPtrParam }
-}
-
-/**
- * A call to a function that has a parameter with a restrict-qualified pointer type.
- */
-class CallToFunctionWithRestrictParameters extends FunctionCall {
- CallToFunctionWithRestrictParameters() {
- this.getTarget() instanceof FunctionWithRestrictParameters
- }
-
- Expr getARestrictPtrArg() {
- result =
- this.getArgument(this.getTarget()
- .(FunctionWithRestrictParameters)
- .getARestrictPtrParam()
- .getIndex())
- }
-
- Expr getAPtrArg(int index) {
- result = this.getArgument(index) and
- pointerValue(result)
- }
-
- Expr getAPossibleSizeArg() {
- exists(Parameter param |
- param = this.getTarget().(FunctionWithRestrictParameters).getAParameter() and
- param.getUnderlyingType() instanceof IntegralType and
- // exclude __builtin_object_size
- not result.(FunctionCall).getTarget() instanceof BuiltInFunction and
- result = this.getArgument(param.getIndex())
- )
- }
-}
-
-/**
- * A `PointsToExpr` that is an argument of a pointer-type in a `CallToFunctionWithRestrictParameters`
- */
-class CallToFunctionWithRestrictParametersArgExpr extends Expr {
- int paramIndex;
-
- CallToFunctionWithRestrictParametersArgExpr() {
- this = any(CallToFunctionWithRestrictParameters call).getAPtrArg(paramIndex)
+class DoNotPassAliasedPointerToRestrictQualifiedParamQuery extends DoNotPassAliasedPointerToRestrictQualifiedParamSharedSharedQuery
+{
+ DoNotPassAliasedPointerToRestrictQualifiedParamQuery() {
+ this = Pointers3Package::doNotPassAliasedPointerToRestrictQualifiedParamQuery()
}
-
- int getParamIndex() { result = paramIndex }
-}
-
-int getStatedValue(Expr e) {
- // `upperBound(e)` defaults to `exprMaxVal(e)` when `e` isn't analyzable. So to get a meaningful
- // result in this case we pick the minimum value obtainable from dataflow and range analysis.
- result =
- upperBound(e)
- .minimum(min(Expr source | DataFlow::localExprFlow(source, e) | source.getValue().toInt()))
-}
-
-int getPointerArithmeticOperandStatedValue(CallToFunctionWithRestrictParametersArgExpr expr) {
- result = getStatedValue(expr.(PointerArithmeticExpr).getOperand())
- or
- // edge-case: &(array[index]) expressions
- result = getStatedValue(expr.(AddressOfExpr).getOperand().(PointerArithmeticExpr).getOperand())
- or
- // fall-back if `expr` is not a pointer arithmetic expression
- not expr instanceof PointerArithmeticExpr and
- not expr.(AddressOfExpr).getOperand() instanceof PointerArithmeticExpr and
- result = 0
}
-
-module PointerValueToRestrictArgConfig implements DataFlow::ConfigSig {
- predicate isSource(DataFlow::Node source) { pointerValue(source.asExpr()) }
-
- predicate isSink(DataFlow::Node sink) {
- exists(CallToFunctionWithRestrictParameters call |
- sink.asExpr() = call.getAPtrArg(_).getAChild*()
- )
- }
-
- predicate isBarrierIn(DataFlow::Node node) {
- exists(AddressOfExpr a | node.asExpr() = a.getOperand().getAChild*())
- }
-}
-
-module PointerValueToRestrictArgFlow = DataFlow::Global;
-
-from
- CallToFunctionWithRestrictParameters call, CallToFunctionWithRestrictParametersArgExpr arg1,
- CallToFunctionWithRestrictParametersArgExpr arg2, int argOffset1, int argOffset2, Expr source1,
- Expr source2, string sourceMessage1, string sourceMessage2
-where
- not isExcluded(call, Pointers3Package::doNotPassAliasedPointerToRestrictQualifiedParamQuery()) and
- arg1 = call.getARestrictPtrArg() and
- arg2 = call.getAPtrArg(_) and
- // enforce ordering to remove permutations if multiple restrict-qualified args exist
- (not arg2 = call.getARestrictPtrArg() or arg2.getParamIndex() > arg1.getParamIndex()) and
- (
- // check if two pointers address the same object
- PointerValueToRestrictArgFlow::flow(DataFlow::exprNode(source1),
- DataFlow::exprNode(arg1.getAChild*())) and
- (
- // one pointer value flows to both args
- PointerValueToRestrictArgFlow::flow(DataFlow::exprNode(source1),
- DataFlow::exprNode(arg2.getAChild*())) and
- sourceMessage1 = "$@" and
- sourceMessage2 = "source" and
- source1 = source2
- or
- // there are two separate values that flow from an AddressOfExpr of the same target
- getAddressOfExprTargetBase(source1) = getAddressOfExprTargetBase(source2) and
- PointerValueToRestrictArgFlow::flow(DataFlow::exprNode(source2),
- DataFlow::exprNode(arg2.getAChild*())) and
- sourceMessage1 = "a pair of address-of expressions ($@, $@)" and
- sourceMessage2 = "addressof1" and
- not source1 = source2
- )
- ) and
- // get the offset of the pointer arithmetic operand (or '0' if there is none)
- argOffset1 = getPointerArithmeticOperandStatedValue(arg1) and
- argOffset2 = getPointerArithmeticOperandStatedValue(arg2) and
- (
- // case 1: the pointer args are the same.
- // (definite aliasing)
- argOffset1 = argOffset2
- or
- // case 2: the pointer args are different, a size arg exists,
- // and the size arg is greater than the difference between the offsets.
- // (potential aliasing)
- exists(Expr sizeArg |
- sizeArg = call.getAPossibleSizeArg() and
- getStatedValue(sizeArg) > (argOffset1 - argOffset2).abs()
- )
- or
- // case 3: the pointer args are different, and a size arg does not exist
- // (potential aliasing)
- not exists(call.getAPossibleSizeArg())
- )
-select call,
- "Call to '" + call.getTarget().getName() + "' passes an $@ to a $@ (pointer value derived from " +
- sourceMessage1 + ".", arg2, "aliased pointer", arg1, "restrict-qualified parameter", source1,
- sourceMessage2, source2, "addressof2"
diff --git a/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql b/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql
index bbe41259b8..eac0f8826c 100644
--- a/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql
+++ b/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql
@@ -14,7 +14,7 @@ import cpp
import codingstandards.cpp.dataflow.DataFlow
import semmle.code.cpp.controlflow.Dominance
import codingstandards.c.cert
-import codingstandards.c.Variable
+import codingstandards.cpp.Variable
/**
* An `Expr` that is an assignment or initialization to a restrict-qualified pointer-type variable.
diff --git a/c/cert/src/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql b/c/cert/src/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql
index 821b79c8e4..2fc334ba50 100644
--- a/c/cert/src/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql
+++ b/c/cert/src/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql
@@ -71,12 +71,19 @@ predicate sameSource(VaAccess e1, VaAccess e2) {
)
}
+/**
+ * Extracted to avoid poor magic join ordering on the `isExcluded` predicate.
+ */
+predicate query(VaAccess va_acc, VaArgArg va_arg, FunctionCall fc) {
+ sameSource(va_acc, va_arg) and
+ fc = preceedsFC(va_acc) and
+ fc.getTarget().calls*(va_arg.getEnclosingFunction())
+}
+
from VaAccess va_acc, VaArgArg va_arg, FunctionCall fc
where
not isExcluded(va_acc,
Contracts7Package::doNotCallVaArgOnAVaListThatHasAnIndeterminateValueQuery()) and
- sameSource(va_acc, va_arg) and
- fc = preceedsFC(va_acc) and
- fc.getTarget().calls*(va_arg.getEnclosingFunction())
+ query(va_acc, va_arg, fc)
select va_acc, "The value of " + va_acc.toString() + " is indeterminate after the $@.", fc,
fc.toString()
diff --git a/c/cert/src/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.ql b/c/cert/src/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.ql
index c323c2d31f..9680bea813 100644
--- a/c/cert/src/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.ql
+++ b/c/cert/src/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.ql
@@ -32,11 +32,38 @@ predicate isFunctionSuccessorLocation(ControlFlowNode node, File f, int endline)
PreprocessorDirective isLocatedInAFunctionInvocation(FunctionCall c) {
exists(PreprocessorDirective p, File f, int startCall, int endCall |
isFunctionInvocationLocation(c, f, startCall, endCall) and
- exists(int startLine, int endLine | isPreprocDirectiveLine(p, f, startLine, endLine) |
- startCall < startLine and
- startCall < endLine and
- endLine <= endCall and
- endLine <= endCall
+ exists(Expr arg, int preprocStartLine, int preprocEndLine |
+ c.getAnArgument() = arg and
+ isPreprocDirectiveLine(p, f, preprocStartLine, preprocEndLine) and
+ // function call begins before preprocessor directive
+ startCall < preprocStartLine and
+ (
+ // argument's location is after the preprocessor directive
+ arg.getLocation().getStartLine() > preprocStartLine
+ or
+ // arg's location is before an endif token that is part of a
+ // preprocessor directive defined before the argument.
+ // E.g.
+ // memcpy(dest, src,
+ // #ifdef SOMEMACRO
+ // 12
+ // #else
+ // 24 // 'arg' exists here
+ // #endif // endif after 'arg', but part of a preproc. branch before 'arg'
+ // );
+ p instanceof PreprocessorEndif and
+ // exists a preprocessor branch of which this is the endif
+ // and that preprocessor directive exists before
+ // the argument and after the function call begins.
+ exists(PreprocessorBranchDirective another |
+ another.getEndIf() = p and
+ another.getLocation().getFile() = f and
+ startCall < another.getLocation().getStartLine() and
+ arg.getLocation().getStartLine() > another.getLocation().getStartLine()
+ )
+ ) and
+ // function call ends after preprocessor directive
+ endCall > preprocEndLine
) and
result = p
)
diff --git a/c/cert/src/rules/SIG31-C/DoNotAccessSharedObjectsInSignalHandlers.ql b/c/cert/src/rules/SIG31-C/DoNotAccessSharedObjectsInSignalHandlers.ql
index 8f9e907019..2a7a6a77f2 100644
--- a/c/cert/src/rules/SIG31-C/DoNotAccessSharedObjectsInSignalHandlers.ql
+++ b/c/cert/src/rules/SIG31-C/DoNotAccessSharedObjectsInSignalHandlers.ql
@@ -21,18 +21,19 @@ import codingstandards.c.Signal
*/
class UnsafeSharedVariableAccess extends VariableAccess {
UnsafeSharedVariableAccess() {
- // static or thread local storage duration
- (
- this.getTarget() instanceof StaticStorageDurationVariable or
- this.getTarget().isThreadLocal()
- ) and
// excluding `volatile sig_atomic_t` type
not this.getType().(SigAtomicType).isVolatile() and
- // excluding lock-free atomic objects
- not exists(MacroInvocation mi, VariableAccess va |
- mi.getMacroName() = "atomic_is_lock_free" and
- mi.getExpr().getChild(0) = va.getEnclosingElement*() and
- va.getTarget() = this.getTarget()
+ exists(Variable target | target = this.getTarget() |
+ // static or thread local storage duration
+ (
+ target instanceof StaticStorageDurationVariable or
+ target.isThreadLocal()
+ ) and
+ // excluding lock-free atomic objects
+ not exists(MacroInvocation mi, VariableAccess va | va.getTarget() = target |
+ mi.getMacroName() = "atomic_is_lock_free" and
+ mi.getExpr().getChild(0) = va.getEnclosingElement*()
+ )
)
}
}
diff --git a/c/cert/test/codeql-pack.lock.yml b/c/cert/test/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/c/cert/test/codeql-pack.lock.yml
+++ b/c/cert/test/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/c/cert/test/qlpack.yml b/c/cert/test/qlpack.yml
index 9b878b7b5c..0242ecdd10 100644
--- a/c/cert/test/qlpack.yml
+++ b/c/cert/test/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cert-c-coding-standards-tests
-version: 2.33.0-dev
+version: 2.38.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/c/cert/test/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.expected b/c/cert/test/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.expected
index 8a7bfe553b..e5e0252e3a 100644
--- a/c/cert/test/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.expected
+++ b/c/cert/test/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.expected
@@ -1,13 +1,13 @@
edges
-| test.c:14:38:14:39 | p1 | test.c:18:10:18:11 | v1 |
-| test.c:14:38:14:39 | p1 | test.c:19:10:19:11 | v2 |
-| test.c:14:38:14:39 | p1 | test.c:20:10:20:11 | p1 |
-| test.c:14:38:14:39 | p1 | test.c:21:10:21:11 | p1 |
-| test.c:14:38:14:39 | p1 | test.c:22:9:22:10 | p1 |
-| test.c:14:38:14:39 | p1 | test.c:23:13:23:14 | p1 |
-| test.c:14:38:14:39 | p1 | test.c:24:9:24:10 | p1 |
-| test.c:14:38:14:39 | p1 | test.c:25:9:25:10 | p1 |
-| test.c:51:30:51:38 | & ... | test.c:14:38:14:39 | p1 |
+| test.c:14:38:14:39 | p1 | test.c:18:10:18:11 | v1 | provenance | |
+| test.c:14:38:14:39 | p1 | test.c:19:10:19:11 | v2 | provenance | |
+| test.c:14:38:14:39 | p1 | test.c:20:10:20:11 | p1 | provenance | |
+| test.c:14:38:14:39 | p1 | test.c:21:10:21:11 | p1 | provenance | |
+| test.c:14:38:14:39 | p1 | test.c:22:9:22:10 | p1 | provenance | |
+| test.c:14:38:14:39 | p1 | test.c:23:13:23:14 | p1 | provenance | |
+| test.c:14:38:14:39 | p1 | test.c:24:9:24:10 | p1 | provenance | |
+| test.c:14:38:14:39 | p1 | test.c:25:9:25:10 | p1 | provenance | |
+| test.c:51:30:51:38 | & ... | test.c:14:38:14:39 | p1 | provenance | |
nodes
| test.c:14:38:14:39 | p1 | semmle.label | p1 |
| test.c:18:10:18:11 | v1 | semmle.label | v1 |
diff --git a/c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected b/c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected
index 1d3f5dcf13..bfd6b23128 100644
--- a/c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected
+++ b/c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected
@@ -1,9 +1,9 @@
edges
-| test.c:7:13:7:14 | p1 | test.c:9:9:9:10 | p1 |
-| test.c:16:19:16:41 | ... - ... | test.c:18:26:18:31 | offset |
-| test.c:16:19:16:41 | ... - ... | test.c:29:6:29:11 | offset |
-| test.c:17:17:17:26 | sizeof() | test.c:23:9:23:12 | size |
-| test.c:29:6:29:11 | offset | test.c:7:13:7:14 | p1 |
+| test.c:7:13:7:14 | p1 | test.c:9:9:9:10 | p1 | provenance | |
+| test.c:16:19:16:41 | ... - ... | test.c:18:26:18:31 | offset | provenance | |
+| test.c:16:19:16:41 | ... - ... | test.c:29:6:29:11 | offset | provenance | |
+| test.c:17:17:17:26 | sizeof() | test.c:23:9:23:12 | size | provenance | |
+| test.c:29:6:29:11 | offset | test.c:7:13:7:14 | p1 | provenance | |
nodes
| test.c:7:13:7:14 | p1 | semmle.label | p1 |
| test.c:9:9:9:10 | p1 | semmle.label | p1 |
diff --git a/c/cert/test/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.expected b/c/cert/test/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.expected
index a1c9a14fa2..c4bc63cc94 100644
--- a/c/cert/test/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.expected
+++ b/c/cert/test/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.expected
@@ -1,67 +1,67 @@
edges
-| test.c:75:14:75:16 | & ... | test.c:76:11:76:12 | v1 |
-| test.c:75:14:75:16 | & ... | test.c:77:12:77:13 | v1 |
-| test.c:75:14:75:16 | & ... | test.c:78:10:78:11 | v1 |
-| test.c:75:14:75:16 | & ... | test.c:79:12:79:13 | v1 |
-| test.c:75:14:75:16 | & ... | test.c:80:11:80:12 | v1 |
-| test.c:75:14:75:16 | & ... | test.c:81:13:81:14 | v1 |
-| test.c:84:14:84:16 | & ... | test.c:85:11:85:12 | v2 |
-| test.c:84:14:84:16 | & ... | test.c:86:12:86:13 | v2 |
-| test.c:84:14:84:16 | & ... | test.c:87:10:87:11 | v2 |
-| test.c:84:14:84:16 | & ... | test.c:88:12:88:13 | v2 |
-| test.c:84:14:84:16 | & ... | test.c:89:11:89:12 | v2 |
-| test.c:84:14:84:16 | & ... | test.c:90:13:90:14 | v2 |
-| test.c:93:14:93:16 | & ... | test.c:94:11:94:12 | v3 |
-| test.c:93:14:93:16 | & ... | test.c:95:12:95:13 | v3 |
-| test.c:93:14:93:16 | & ... | test.c:96:10:96:11 | v3 |
-| test.c:93:14:93:16 | & ... | test.c:97:12:97:13 | v3 |
-| test.c:93:14:93:16 | & ... | test.c:98:11:98:12 | v3 |
-| test.c:93:14:93:16 | & ... | test.c:99:13:99:14 | v3 |
-| test.c:102:14:102:16 | & ... | test.c:103:11:103:12 | v4 |
-| test.c:102:14:102:16 | & ... | test.c:104:12:104:13 | v4 |
-| test.c:102:14:102:16 | & ... | test.c:105:10:105:11 | v4 |
-| test.c:102:14:102:16 | & ... | test.c:106:12:106:13 | v4 |
-| test.c:102:14:102:16 | & ... | test.c:107:11:107:12 | v4 |
-| test.c:102:14:102:16 | & ... | test.c:108:13:108:14 | v4 |
-| test.c:111:14:111:16 | & ... | test.c:112:11:112:12 | v5 |
-| test.c:111:14:111:16 | & ... | test.c:113:12:113:13 | v5 |
-| test.c:111:14:111:16 | & ... | test.c:114:10:114:11 | v5 |
-| test.c:111:14:111:16 | & ... | test.c:115:12:115:13 | v5 |
-| test.c:111:14:111:16 | & ... | test.c:116:11:116:12 | v5 |
-| test.c:111:14:111:16 | & ... | test.c:117:13:117:14 | v5 |
-| test.c:120:14:120:16 | & ... | test.c:121:11:121:12 | v6 |
-| test.c:120:14:120:16 | & ... | test.c:122:12:122:13 | v6 |
-| test.c:120:14:120:16 | & ... | test.c:123:10:123:11 | v6 |
-| test.c:120:14:120:16 | & ... | test.c:124:12:124:13 | v6 |
-| test.c:120:14:120:16 | & ... | test.c:125:11:125:12 | v6 |
-| test.c:120:14:120:16 | & ... | test.c:126:13:126:14 | v6 |
-| test.c:129:22:129:22 | v | test.c:130:17:130:17 | v |
-| test.c:135:21:135:23 | & ... | test.c:129:22:129:22 | v |
-| test.c:138:21:138:23 | & ... | test.c:129:22:129:22 | v |
-| test.c:166:24:166:29 | call to malloc | test.c:167:13:167:15 | & ... |
-| test.c:166:24:166:29 | call to malloc | test.c:168:16:168:17 | s1 |
-| test.c:166:24:166:29 | call to malloc | test.c:169:13:169:14 | s1 |
-| test.c:166:24:166:29 | call to malloc | test.c:169:13:169:14 | s1 |
-| test.c:169:13:169:14 | s1 | test.c:129:22:129:22 | v |
-| test.c:174:13:174:14 | s2 | test.c:129:22:129:22 | v |
-| test.c:179:13:179:14 | s3 | test.c:129:22:129:22 | v |
-| test.c:183:14:183:26 | call to aligned_alloc | test.c:184:11:184:12 | v1 |
-| test.c:183:14:183:26 | call to aligned_alloc | test.c:185:10:185:11 | v1 |
-| test.c:183:14:183:26 | call to aligned_alloc | test.c:186:13:186:14 | v1 |
-| test.c:183:14:183:26 | call to aligned_alloc | test.c:187:13:187:14 | v1 |
-| test.c:187:13:187:14 | v1 | test.c:129:22:129:22 | v |
-| test.c:189:14:189:26 | call to aligned_alloc | test.c:190:13:190:14 | v2 |
-| test.c:190:13:190:14 | v2 | test.c:129:22:129:22 | v |
-| test.c:222:8:222:9 | p2 | test.c:223:11:223:12 | v1 |
-| test.c:222:8:222:9 | p2 | test.c:224:12:224:13 | v1 |
-| test.c:222:8:222:9 | p2 | test.c:225:10:225:11 | v1 |
-| test.c:222:8:222:9 | p2 | test.c:226:12:226:13 | v1 |
-| test.c:222:8:222:9 | p2 | test.c:227:11:227:12 | v1 |
-| test.c:222:8:222:9 | p2 | test.c:228:13:228:14 | v1 |
-| test.c:238:13:238:14 | & ... | test.c:244:12:244:13 | ip |
-| test.c:241:15:241:18 | & ... | test.c:247:9:247:12 | & ... |
-| test.c:252:16:252:18 | & ... | test.c:254:11:254:13 | ps1 |
-| test.c:252:16:252:18 | & ... | test.c:256:10:256:12 | ps1 |
+| test.c:75:14:75:16 | & ... | test.c:76:11:76:12 | v1 | provenance | |
+| test.c:75:14:75:16 | & ... | test.c:77:12:77:13 | v1 | provenance | |
+| test.c:75:14:75:16 | & ... | test.c:78:10:78:11 | v1 | provenance | |
+| test.c:75:14:75:16 | & ... | test.c:79:12:79:13 | v1 | provenance | |
+| test.c:75:14:75:16 | & ... | test.c:80:11:80:12 | v1 | provenance | |
+| test.c:75:14:75:16 | & ... | test.c:81:13:81:14 | v1 | provenance | |
+| test.c:84:14:84:16 | & ... | test.c:85:11:85:12 | v2 | provenance | |
+| test.c:84:14:84:16 | & ... | test.c:86:12:86:13 | v2 | provenance | |
+| test.c:84:14:84:16 | & ... | test.c:87:10:87:11 | v2 | provenance | |
+| test.c:84:14:84:16 | & ... | test.c:88:12:88:13 | v2 | provenance | |
+| test.c:84:14:84:16 | & ... | test.c:89:11:89:12 | v2 | provenance | |
+| test.c:84:14:84:16 | & ... | test.c:90:13:90:14 | v2 | provenance | |
+| test.c:93:14:93:16 | & ... | test.c:94:11:94:12 | v3 | provenance | |
+| test.c:93:14:93:16 | & ... | test.c:95:12:95:13 | v3 | provenance | |
+| test.c:93:14:93:16 | & ... | test.c:96:10:96:11 | v3 | provenance | |
+| test.c:93:14:93:16 | & ... | test.c:97:12:97:13 | v3 | provenance | |
+| test.c:93:14:93:16 | & ... | test.c:98:11:98:12 | v3 | provenance | |
+| test.c:93:14:93:16 | & ... | test.c:99:13:99:14 | v3 | provenance | |
+| test.c:102:14:102:16 | & ... | test.c:103:11:103:12 | v4 | provenance | |
+| test.c:102:14:102:16 | & ... | test.c:104:12:104:13 | v4 | provenance | |
+| test.c:102:14:102:16 | & ... | test.c:105:10:105:11 | v4 | provenance | |
+| test.c:102:14:102:16 | & ... | test.c:106:12:106:13 | v4 | provenance | |
+| test.c:102:14:102:16 | & ... | test.c:107:11:107:12 | v4 | provenance | |
+| test.c:102:14:102:16 | & ... | test.c:108:13:108:14 | v4 | provenance | |
+| test.c:111:14:111:16 | & ... | test.c:112:11:112:12 | v5 | provenance | |
+| test.c:111:14:111:16 | & ... | test.c:113:12:113:13 | v5 | provenance | |
+| test.c:111:14:111:16 | & ... | test.c:114:10:114:11 | v5 | provenance | |
+| test.c:111:14:111:16 | & ... | test.c:115:12:115:13 | v5 | provenance | |
+| test.c:111:14:111:16 | & ... | test.c:116:11:116:12 | v5 | provenance | |
+| test.c:111:14:111:16 | & ... | test.c:117:13:117:14 | v5 | provenance | |
+| test.c:120:14:120:16 | & ... | test.c:121:11:121:12 | v6 | provenance | |
+| test.c:120:14:120:16 | & ... | test.c:122:12:122:13 | v6 | provenance | |
+| test.c:120:14:120:16 | & ... | test.c:123:10:123:11 | v6 | provenance | |
+| test.c:120:14:120:16 | & ... | test.c:124:12:124:13 | v6 | provenance | |
+| test.c:120:14:120:16 | & ... | test.c:125:11:125:12 | v6 | provenance | |
+| test.c:120:14:120:16 | & ... | test.c:126:13:126:14 | v6 | provenance | |
+| test.c:129:22:129:22 | v | test.c:130:17:130:17 | v | provenance | |
+| test.c:135:21:135:23 | & ... | test.c:129:22:129:22 | v | provenance | |
+| test.c:138:21:138:23 | & ... | test.c:129:22:129:22 | v | provenance | |
+| test.c:166:24:166:29 | call to malloc | test.c:167:13:167:15 | & ... | provenance | |
+| test.c:166:24:166:29 | call to malloc | test.c:168:16:168:17 | s1 | provenance | |
+| test.c:166:24:166:29 | call to malloc | test.c:169:13:169:14 | s1 | provenance | |
+| test.c:166:24:166:29 | call to malloc | test.c:169:13:169:14 | s1 | provenance | |
+| test.c:169:13:169:14 | s1 | test.c:129:22:129:22 | v | provenance | |
+| test.c:174:13:174:14 | s2 | test.c:129:22:129:22 | v | provenance | |
+| test.c:179:13:179:14 | s3 | test.c:129:22:129:22 | v | provenance | |
+| test.c:183:14:183:26 | call to aligned_alloc | test.c:184:11:184:12 | v1 | provenance | |
+| test.c:183:14:183:26 | call to aligned_alloc | test.c:185:10:185:11 | v1 | provenance | |
+| test.c:183:14:183:26 | call to aligned_alloc | test.c:186:13:186:14 | v1 | provenance | |
+| test.c:183:14:183:26 | call to aligned_alloc | test.c:187:13:187:14 | v1 | provenance | |
+| test.c:187:13:187:14 | v1 | test.c:129:22:129:22 | v | provenance | |
+| test.c:189:14:189:26 | call to aligned_alloc | test.c:190:13:190:14 | v2 | provenance | |
+| test.c:190:13:190:14 | v2 | test.c:129:22:129:22 | v | provenance | |
+| test.c:222:8:222:9 | p2 | test.c:223:11:223:12 | v1 | provenance | |
+| test.c:222:8:222:9 | p2 | test.c:224:12:224:13 | v1 | provenance | |
+| test.c:222:8:222:9 | p2 | test.c:225:10:225:11 | v1 | provenance | |
+| test.c:222:8:222:9 | p2 | test.c:226:12:226:13 | v1 | provenance | |
+| test.c:222:8:222:9 | p2 | test.c:227:11:227:12 | v1 | provenance | |
+| test.c:222:8:222:9 | p2 | test.c:228:13:228:14 | v1 | provenance | |
+| test.c:238:13:238:14 | & ... | test.c:244:12:244:13 | ip | provenance | |
+| test.c:241:15:241:18 | & ... | test.c:247:9:247:12 | & ... | provenance | |
+| test.c:252:16:252:18 | & ... | test.c:254:11:254:13 | ps1 | provenance | |
+| test.c:252:16:252:18 | & ... | test.c:256:10:256:12 | ps1 | provenance | |
nodes
| test.c:7:11:7:13 | & ... | semmle.label | & ... |
| test.c:8:12:8:14 | & ... | semmle.label | & ... |
diff --git a/c/cert/test/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.expected b/c/cert/test/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.expected
index 4c18bb2672..546c753ebb 100644
--- a/c/cert/test/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.expected
+++ b/c/cert/test/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.expected
@@ -1,11 +1,11 @@
edges
-| test.c:48:68:48:70 | fns [f1] | test.c:49:3:49:5 | fns [f1] |
-| test.c:49:3:49:5 | fns [f1] | test.c:49:8:49:9 | f1 |
-| test.c:61:28:61:29 | f2 | test.c:62:3:62:11 | v1_called |
-| test.c:73:3:73:5 | fns [post update] [f1] | test.c:75:45:75:48 | & ... [f1] |
-| test.c:73:3:73:13 | ... = ... | test.c:73:3:73:5 | fns [post update] [f1] |
-| test.c:73:12:73:13 | v2 | test.c:73:3:73:13 | ... = ... |
-| test.c:75:45:75:48 | & ... [f1] | test.c:48:68:48:70 | fns [f1] |
+| test.c:48:68:48:70 | fns [f1] | test.c:49:3:49:5 | fns [f1] | provenance | |
+| test.c:49:3:49:5 | fns [f1] | test.c:49:8:49:9 | f1 | provenance | |
+| test.c:61:28:61:29 | f2 | test.c:62:3:62:11 | v1_called | provenance | |
+| test.c:73:3:73:5 | fns [post update] [f1] | test.c:75:45:75:48 | & ... [f1] | provenance | |
+| test.c:73:3:73:13 | ... = ... | test.c:73:3:73:5 | fns [post update] [f1] | provenance | |
+| test.c:73:12:73:13 | v2 | test.c:73:3:73:13 | ... = ... | provenance | |
+| test.c:75:45:75:48 | & ... [f1] | test.c:48:68:48:70 | fns [f1] | provenance | |
nodes
| test.c:48:68:48:70 | fns [f1] | semmle.label | fns [f1] |
| test.c:49:3:49:5 | fns [f1] | semmle.label | fns [f1] |
diff --git a/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected b/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected
index e42f003f0f..137017d53a 100644
--- a/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected
+++ b/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected
@@ -1,15 +1,15 @@
edges
-| test.c:49:8:49:9 | s3 | test.c:50:8:50:9 | s1 |
-| test.c:60:16:60:18 | E1A | test.c:61:16:61:17 | e1 |
-| test.c:60:16:60:18 | E1A | test.c:65:10:65:12 | & ... |
-| test.c:68:22:68:22 | v | test.c:68:41:68:41 | v |
-| test.c:72:13:72:15 | & ... | test.c:68:22:68:22 | v |
-| test.c:74:13:74:15 | & ... | test.c:68:22:68:22 | v |
-| test.c:97:32:97:37 | call to malloc | test.c:98:40:98:41 | s2 |
-| test.c:97:32:97:37 | call to malloc | test.c:98:40:98:41 | s2 |
-| test.c:98:32:98:38 | call to realloc | test.c:99:3:99:4 | s3 |
-| test.c:98:32:98:38 | call to realloc | test.c:100:10:100:11 | s3 |
-| test.c:98:40:98:41 | s2 | test.c:98:32:98:38 | call to realloc |
+| test.c:49:8:49:9 | s3 | test.c:50:8:50:9 | s1 | provenance | |
+| test.c:60:16:60:18 | E1A | test.c:61:16:61:17 | e1 | provenance | |
+| test.c:60:16:60:18 | E1A | test.c:65:10:65:12 | & ... | provenance | |
+| test.c:68:22:68:22 | v | test.c:68:41:68:41 | v | provenance | |
+| test.c:72:13:72:15 | & ... | test.c:68:22:68:22 | v | provenance | |
+| test.c:74:13:74:15 | & ... | test.c:68:22:68:22 | v | provenance | |
+| test.c:97:32:97:37 | call to malloc | test.c:98:40:98:41 | s2 | provenance | |
+| test.c:97:32:97:37 | call to malloc | test.c:98:40:98:41 | s2 | provenance | |
+| test.c:98:32:98:38 | call to realloc | test.c:99:3:99:4 | s3 | provenance | |
+| test.c:98:32:98:38 | call to realloc | test.c:100:10:100:11 | s3 | provenance | |
+| test.c:98:40:98:41 | s2 | test.c:98:32:98:38 | call to realloc | provenance | |
nodes
| test.c:6:19:6:20 | & ... | semmle.label | & ... |
| test.c:11:10:11:11 | & ... | semmle.label | & ... |
diff --git a/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected b/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected
index 3211c4fab1..bef45f3841 100644
--- a/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected
+++ b/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected
@@ -1,11 +1,11 @@
edges
-| test.c:5:8:5:9 | & ... | test.c:6:4:6:5 | aa |
-| test.c:26:15:26:15 | a | test.c:27:4:27:4 | a |
-| test.c:34:13:34:14 | & ... | test.c:39:7:39:8 | p1 |
-| test.c:39:7:39:8 | p1 | test.c:26:15:26:15 | a |
-| test.c:40:7:40:9 | * ... | test.c:26:15:26:15 | a |
-| test.c:59:7:59:8 | & ... | test.c:60:4:60:4 | p |
-| test.c:79:11:79:16 | call to strchr | test.c:81:6:81:12 | ... ++ |
+| test.c:5:8:5:9 | & ... | test.c:6:4:6:5 | aa | provenance | |
+| test.c:26:15:26:15 | a | test.c:27:4:27:4 | a | provenance | |
+| test.c:34:13:34:14 | & ... | test.c:39:7:39:8 | p1 | provenance | |
+| test.c:39:7:39:8 | p1 | test.c:26:15:26:15 | a | provenance | |
+| test.c:40:7:40:9 | * ... | test.c:26:15:26:15 | a | provenance | |
+| test.c:59:7:59:8 | & ... | test.c:60:4:60:4 | p | provenance | |
+| test.c:79:11:79:16 | call to strchr | test.c:81:6:81:12 | ... ++ | provenance | |
nodes
| test.c:5:8:5:9 | & ... | semmle.label | & ... |
| test.c:6:4:6:5 | aa | semmle.label | aa |
diff --git a/c/cert/test/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.qlref b/c/cert/test/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.qlref
deleted file mode 100644
index 6121235f17..0000000000
--- a/c/cert/test/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.ql
\ No newline at end of file
diff --git a/c/cert/test/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.testref b/c/cert/test/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.testref
new file mode 100644
index 0000000000..ef17bca58a
--- /dev/null
+++ b/c/cert/test/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.testref
@@ -0,0 +1 @@
+c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.ql
\ No newline at end of file
diff --git a/c/cert/test/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.expected b/c/cert/test/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.expected
index 06bf56cf8a..93d6de6b8a 100644
--- a/c/cert/test/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.expected
+++ b/c/cert/test/rules/FIO32-C/DoNotPerformFileOperationsOnDevices.expected
@@ -1,12 +1,12 @@
edges
-| test.c:20:15:20:23 | scanf output argument | test.c:21:8:21:16 | file_name indirection |
-| test.c:45:15:45:23 | scanf output argument | test.c:46:29:46:37 | file_name indirection |
+| test.c:20:15:20:23 | scanf output argument | test.c:21:8:21:16 | *file_name | provenance | |
+| test.c:45:15:45:23 | scanf output argument | test.c:46:29:46:37 | *file_name | provenance | |
nodes
| test.c:20:15:20:23 | scanf output argument | semmle.label | scanf output argument |
-| test.c:21:8:21:16 | file_name indirection | semmle.label | file_name indirection |
+| test.c:21:8:21:16 | *file_name | semmle.label | *file_name |
| test.c:45:15:45:23 | scanf output argument | semmle.label | scanf output argument |
-| test.c:46:29:46:37 | file_name indirection | semmle.label | file_name indirection |
+| test.c:46:29:46:37 | *file_name | semmle.label | *file_name |
subpaths
#select
-| test.c:21:8:21:16 | file_name | test.c:20:15:20:23 | scanf output argument | test.c:21:8:21:16 | file_name indirection | This argument to a file access function is derived from $@ and then passed to func(file_name), which calls fopen((unnamed parameter 0)). | test.c:20:15:20:23 | scanf output argument | user input (value read by scanf) |
-| test.c:46:29:46:37 | file_name | test.c:45:15:45:23 | scanf output argument | test.c:46:29:46:37 | file_name indirection | This argument to a file access function is derived from $@ and then passed to CreateFile(lpFileName). | test.c:45:15:45:23 | scanf output argument | user input (value read by scanf) |
+| test.c:21:8:21:16 | file_name | test.c:20:15:20:23 | scanf output argument | test.c:21:8:21:16 | *file_name | This argument to a file access function is derived from $@ and then passed to func(file_name), which calls fopen((unnamed parameter 0)). | test.c:20:15:20:23 | scanf output argument | user input (value read by scanf) |
+| test.c:46:29:46:37 | file_name | test.c:45:15:45:23 | scanf output argument | test.c:46:29:46:37 | *file_name | This argument to a file access function is derived from $@ and then passed to CreateFile(lpFileName). | test.c:45:15:45:23 | scanf output argument | user input (value read by scanf) |
diff --git a/c/cert/test/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.expected b/c/cert/test/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.expected
index 0592cb038d..0ae87f2ee8 100644
--- a/c/cert/test/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.expected
+++ b/c/cert/test/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.expected
@@ -1,9 +1,9 @@
edges
-| test.c:5:10:5:22 | call to aligned_alloc | test.c:15:8:15:28 | call to aligned_alloc_wrapper |
-| test.c:8:29:8:31 | ptr | test.c:8:64:8:66 | ptr |
-| test.c:15:8:15:28 | call to aligned_alloc_wrapper | test.c:16:24:16:25 | v1 |
-| test.c:16:24:16:25 | v1 | test.c:8:29:8:31 | ptr |
-| test.c:22:8:22:20 | call to aligned_alloc | test.c:23:16:23:17 | v3 |
+| test.c:5:10:5:22 | call to aligned_alloc | test.c:15:8:15:28 | call to aligned_alloc_wrapper | provenance | |
+| test.c:8:29:8:31 | ptr | test.c:8:64:8:66 | ptr | provenance | |
+| test.c:15:8:15:28 | call to aligned_alloc_wrapper | test.c:16:24:16:25 | v1 | provenance | |
+| test.c:16:24:16:25 | v1 | test.c:8:29:8:31 | ptr | provenance | |
+| test.c:22:8:22:20 | call to aligned_alloc | test.c:23:16:23:17 | v3 | provenance | |
nodes
| test.c:5:10:5:22 | call to aligned_alloc | semmle.label | call to aligned_alloc |
| test.c:8:29:8:31 | ptr | semmle.label | ptr |
diff --git a/c/cert/test/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.expected b/c/cert/test/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.expected
index f25c7ea0e0..efbf021972 100644
--- a/c/cert/test/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.expected
+++ b/c/cert/test/rules/PRE32-C/MacroOrFunctionArgsContainHashToken.expected
@@ -4,5 +4,3 @@
| test.c:20:1:20:16 | #ifdef SOMEMACRO | Invocation of function memcpy includes a token "#ifdef SOMEMACRO" that could be confused for an argument preprocessor directive. |
| test.c:22:1:22:5 | #else | Invocation of function memcpy includes a token "#else" that could be confused for an argument preprocessor directive. |
| test.c:24:1:24:6 | #endif | Invocation of function memcpy includes a token "#endif" that could be confused for an argument preprocessor directive. |
-| test.c:27:1:27:8 | #if TEST | Invocation of function memcpy includes a token "#if TEST" that could be confused for an argument preprocessor directive. |
-| test.c:28:1:28:6 | #endif | Invocation of function memcpy includes a token "#endif" that could be confused for an argument preprocessor directive. |
diff --git a/c/cert/test/rules/PRE32-C/test.c b/c/cert/test/rules/PRE32-C/test.c
index af3606f24c..bf07beecb5 100644
--- a/c/cert/test/rules/PRE32-C/test.c
+++ b/c/cert/test/rules/PRE32-C/test.c
@@ -24,6 +24,6 @@ void func(const char *src) {
#endif // NON_COMPLIANT
);
-#if TEST // COMPLIANT[FALSE_POSITIVE]
-#endif // COMPLIANT[FALSE_POSITIVE]
-}
\ No newline at end of file
+#if TEST // COMPLIANT
+#endif // COMPLIANT
+}
diff --git a/c/common/src/codeql-pack.lock.yml b/c/common/src/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/c/common/src/codeql-pack.lock.yml
+++ b/c/common/src/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/c/common/src/codingstandards/c/Extensions.qll b/c/common/src/codingstandards/c/Extensions.qll
index 018359586e..4f16a1f09a 100644
--- a/c/common/src/codingstandards/c/Extensions.qll
+++ b/c/common/src/codingstandards/c/Extensions.qll
@@ -4,21 +4,28 @@ import codingstandards.cpp.Extensions
/**
* Common base class for modeling compiler extensions.
*/
-abstract class CCompilerExtension extends CompilerExtension { }
+abstract class CCompilerExtension extends CompilerExtension {
+ abstract string getMessage();
+}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins
abstract class CConditionalDefineExtension extends CCompilerExtension, PreprocessorIfdef {
+ string feature;
+
CConditionalDefineExtension() {
- exists(toString().indexOf("__has_builtin")) or
- exists(toString().indexOf("__has_constexpr_builtin")) or
- exists(toString().indexOf("__has_feature")) or
- exists(toString().indexOf("__has_extension")) or
- exists(toString().indexOf("__has_attribute")) or
- exists(toString().indexOf("__has_declspec_attribute")) or
- exists(toString().indexOf("__is_identifier")) or
- exists(toString().indexOf("__has_include")) or
- exists(toString().indexOf("__has_include_next")) or
- exists(toString().indexOf("__has_warning"))
+ feature =
+ [
+ "__has_builtin", "__has_constexpr_builtin", "__has_feature", "__has_extension",
+ "__has_attribute", "__has_declspec_attribute", "__is_identifier", "__has_include",
+ "__has_include_next", "__has_warning"
+ ] and
+ exists(toString().indexOf(feature))
+ }
+
+ override string getMessage() {
+ result =
+ "Call to builtin function '" + feature +
+ "' is a compiler extension and is not portable to other compilers."
}
}
@@ -31,6 +38,12 @@ class CMacroBasedExtension extends CCompilerExtension, Macro {
"__clang_version__", "__clang_literal_encoding__", "__clang_wide_literal_encoding__"
]
}
+
+ override string getMessage() {
+ result =
+ "Use of builtin macro '" + getBody() +
+ "' is a compiler extension and is not portable to other compilers."
+ }
}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes
@@ -41,6 +54,12 @@ class CAttributeExtension extends CCompilerExtension, Attribute {
"fallthrough", "read_only", "alias"
]
}
+
+ override string getMessage() {
+ result =
+ "Use of attribute '" + getName() +
+ "' is a compiler extension and is not portable to other compilers."
+ }
}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins
@@ -61,21 +80,41 @@ class CFunctionExtension extends CCompilerExtension, FunctionCall {
// the built-in extensions
getTarget().getName().indexOf("__builtin_") = 0
}
+
+ override string getMessage() {
+ result =
+ "Call to builtin function '" + getTarget().getName() +
+ "' is a compiler extension and is not portable to other compilers."
+ }
}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment
class CFunctionLikeExtension extends CCompilerExtension, AlignofExprOperator {
CFunctionLikeExtension() { exists(getValueText().indexOf("__alignof__")) }
+
+ override string getMessage() {
+ result = "'__alignof__' is a compiler extension and is not portable to other compilers."
+ }
}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs
-class CStmtExprExtension extends CCompilerExtension, StmtExpr { }
+class CStmtExprExtension extends CCompilerExtension, StmtExpr {
+ override string getMessage() {
+ result =
+ "Statement expressions are a compiler extension and are not portable to other compilers."
+ }
+}
// Use of ternary like the following: `int a = 0 ?: 0;` where the
// one of the branches is omitted
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals
class CTerseTernaryExtension extends CCompilerExtension, ConditionalExpr {
CTerseTernaryExtension() { getCondition() = getElse() or getCondition() = getThen() }
+
+ override string getMessage() {
+ result =
+ "Ternaries with omitted middle operands are a compiler extension and is not portable to other compilers."
+ }
}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128
@@ -87,31 +126,63 @@ class CRealTypeExtensionExtension extends CCompilerExtension, DeclarationEntry {
getType() instanceof Decimal64Type or
getType() instanceof Float128Type
}
+
+ override string getMessage() {
+ result = "Decimal floats are a compiler extension and are not portable to other compilers."
+ }
}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128
class CIntegerTypeExtension extends CCompilerExtension, DeclarationEntry {
CIntegerTypeExtension() { getType() instanceof Int128Type }
+
+ override string getMessage() {
+ result = "128-bit integers are a compiler extension and are not portable to other compilers."
+ }
}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Long-Long.html#Long-Long
class CLongLongType extends CCompilerExtension, DeclarationEntry {
CLongLongType() { getType() instanceof LongLongType }
+
+ override string getMessage() {
+ result =
+ "Double-Word integers are a compiler extension and are not portable to other compilers."
+ }
}
class CZeroLengthArraysExtension extends CCompilerExtension, DeclarationEntry {
CZeroLengthArraysExtension() { getType().(ArrayType).getArraySize() = 0 }
+
+ override string getMessage() {
+ result = "Zero length arrays are a compiler extension and are not portable to other compilers."
+ }
}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html#Empty-Structures
class CEmptyStructExtension extends CCompilerExtension, Struct {
CEmptyStructExtension() { not exists(getAMember(_)) }
+
+ override string getMessage() {
+ result = "Empty structures are a compiler extension and are not portable to other compilers."
+ }
}
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length
-class CVariableLengthArraysExtension extends CCompilerExtension, DeclarationEntry {
+class CVariableLengthArraysExtension extends CCompilerExtension, Field {
CVariableLengthArraysExtension() {
getType() instanceof ArrayType and
- not getType().(ArrayType).hasArraySize()
+ not getType().(ArrayType).hasArraySize() and
+ // Not the final member of the struct, which is allowed to be variably sized
+ not exists(int lastIndex, Class declaringStruct |
+ declaringStruct = getDeclaringType() and
+ lastIndex = count(declaringStruct.getACanonicalMember()) - 1 and
+ this = declaringStruct.getCanonicalMember(lastIndex)
+ )
+ }
+
+ override string getMessage() {
+ result =
+ "Variable length arrays are a compiler extension and are not portable to other compilers."
}
}
diff --git a/c/common/src/codingstandards/c/OutOfBounds.qll b/c/common/src/codingstandards/c/OutOfBounds.qll
index 87c7c17870..21255827dd 100644
--- a/c/common/src/codingstandards/c/OutOfBounds.qll
+++ b/c/common/src/codingstandards/c/OutOfBounds.qll
@@ -5,7 +5,7 @@
*/
import cpp
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
import codingstandards.c.Variable
import codingstandards.cpp.Allocations
import codingstandards.cpp.Overflow
diff --git a/c/common/src/codingstandards/c/UndefinedBehavior.qll b/c/common/src/codingstandards/c/UndefinedBehavior.qll
index 5c9dc230d8..6a72cb6eb7 100644
--- a/c/common/src/codingstandards/c/UndefinedBehavior.qll
+++ b/c/common/src/codingstandards/c/UndefinedBehavior.qll
@@ -1,4 +1,5 @@
import cpp
+import codingstandards.cpp.Pointers
import codingstandards.cpp.UndefinedBehavior
/**
@@ -6,28 +7,38 @@ import codingstandards.cpp.UndefinedBehavior
*/
abstract class CUndefinedBehavior extends UndefinedBehavior { }
+/**
+ * A function which has the signature - but not the name - of a main function.
+ */
class C99MainFunction extends Function {
C99MainFunction() {
this.getNumberOfParameters() = 2 and
- this.getType() instanceof IntType and
- this.getParameter(0).getType() instanceof IntType and
- this.getParameter(1).getType().(PointerType).getBaseType().(PointerType).getBaseType()
- instanceof CharType
+ this.getType().getUnderlyingType() instanceof IntType and
+ this.getParameter(0).getType().getUnderlyingType() instanceof IntType and
+ this.getParameter(1)
+ .getType()
+ .getUnderlyingType()
+ .(UnspecifiedPointerOrArrayType)
+ .getBaseType()
+ .(UnspecifiedPointerOrArrayType)
+ .getBaseType() instanceof CharType
or
this.getNumberOfParameters() = 0 and
- this.getType() instanceof VoidType
+ // Must be explicitly declared as `int main(void)`.
+ this.getADeclarationEntry().hasVoidParamList() and
+ this.getType().getUnderlyingType() instanceof IntType
}
}
class CUndefinedMainDefinition extends CUndefinedBehavior, Function {
CUndefinedMainDefinition() {
// for testing purposes, we use the prefix ____codeql_coding_standards`
- (this.getName() = "main" or this.getName().indexOf("____codeql_coding_standards") = 0) and
+ (this.getName() = "main" or this.getName().indexOf("____codeql_coding_standards_main") = 0) and
not this instanceof C99MainFunction
}
override string getReason() {
result =
- "The behavior of the program is undefined because the main function is not defined according to the C standard."
+ "main function may trigger undefined behavior because it is not in one of the formats specified by the C standard."
}
}
diff --git a/c/common/src/codingstandards/c/Variable.qll b/c/common/src/codingstandards/c/Variable.qll
index adf2f08ad9..09d86e0e25 100644
--- a/c/common/src/codingstandards/c/Variable.qll
+++ b/c/common/src/codingstandards/c/Variable.qll
@@ -39,20 +39,6 @@ class FlexibleArrayMemberCandidate extends MemberVariable {
}
}
-/**
- * Returns the target variable of a `VariableAccess`.
- * If the access is a field access, then the target is the `Variable` of the qualifier.
- * If the access is an array access, then the target is the array base.
- */
-Variable getAddressOfExprTargetBase(AddressOfExpr expr) {
- result = expr.getOperand().(ValueFieldAccess).getQualifier().(VariableAccess).getTarget()
- or
- not expr.getOperand() instanceof ValueFieldAccess and
- result = expr.getOperand().(VariableAccess).getTarget()
- or
- result = expr.getOperand().(ArrayExpr).getArrayBase().(VariableAccess).getTarget()
-}
-
/**
* A struct that contains a flexible array member
*/
diff --git a/c/common/src/qlpack.yml b/c/common/src/qlpack.yml
index 474bb3bed7..9d05e536fd 100644
--- a/c/common/src/qlpack.yml
+++ b/c/common/src/qlpack.yml
@@ -1,6 +1,6 @@
name: codeql/common-c-coding-standards
-version: 2.33.0-dev
+version: 2.38.0-dev
license: MIT
dependencies:
codeql/common-cpp-coding-standards: '*'
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 0.12.9
diff --git a/c/common/test/codeql-pack.lock.yml b/c/common/test/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/c/common/test/codeql-pack.lock.yml
+++ b/c/common/test/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/c/common/test/qlpack.yml b/c/common/test/qlpack.yml
index c83d53ae3f..e19cb371e8 100644
--- a/c/common/test/qlpack.yml
+++ b/c/common/test/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/common-c-coding-standards-tests
-version: 2.33.0-dev
+version: 2.38.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/c/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected b/c/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
index 99d91f7575..d7dfc6c13f 100644
--- a/c/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
+++ b/c/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
@@ -3,11 +3,11 @@ problems
| test.c:67:5:67:9 | conv4 | test.c:64:11:64:20 | call to localeconv | test.c:67:5:67:9 | conv4 | The object returned by the function localeconv should not be modified. |
| test.c:76:5:76:8 | conv | test.c:72:25:72:34 | call to localeconv | test.c:76:5:76:8 | conv | The object returned by the function localeconv should not be modified. |
edges
-| test.c:8:18:8:22 | c_str | test.c:11:8:11:12 | c_str |
-| test.c:18:16:18:21 | call to getenv | test.c:24:9:24:12 | env1 |
-| test.c:24:9:24:12 | env1 | test.c:8:18:8:22 | c_str |
-| test.c:64:11:64:20 | call to localeconv | test.c:67:5:67:9 | conv4 |
-| test.c:72:25:72:34 | call to localeconv | test.c:76:5:76:8 | conv |
+| test.c:8:18:8:22 | c_str | test.c:11:8:11:12 | c_str | provenance | |
+| test.c:18:16:18:21 | call to getenv | test.c:24:9:24:12 | env1 | provenance | |
+| test.c:24:9:24:12 | env1 | test.c:8:18:8:22 | c_str | provenance | |
+| test.c:64:11:64:20 | call to localeconv | test.c:67:5:67:9 | conv4 | provenance | |
+| test.c:72:25:72:34 | call to localeconv | test.c:76:5:76:8 | conv | provenance | |
nodes
| test.c:8:18:8:22 | c_str | semmle.label | c_str |
| test.c:11:8:11:12 | c_str | semmle.label | c_str |
diff --git a/c/cert/test/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.expected b/c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.expected
similarity index 100%
rename from c/cert/test/rules/EXP43-C/DoNotPassAliasedPointerToRestrictQualifiedParam.expected
rename to c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.expected
diff --git a/c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.ql b/c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.ql
new file mode 100644
index 0000000000..dc3a521edf
--- /dev/null
+++ b/c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.ql
@@ -0,0 +1,6 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.donotpassaliasedpointertorestrictqualifiedparamshared.DoNotPassAliasedPointerToRestrictQualifiedParamShared
+
+class TestFileQuery extends DoNotPassAliasedPointerToRestrictQualifiedParamSharedSharedQuery,
+ TestQuery
+{ }
diff --git a/c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/test.c b/c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/test.c
new file mode 100644
index 0000000000..3bf7cfa490
--- /dev/null
+++ b/c/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/test.c
@@ -0,0 +1,100 @@
+#include
+#include
+#include
+
+int *restrict g1;
+int *restrict g2;
+int *restrict g1_1;
+int *g2_1;
+
+struct s1 {
+ int x, y, z;
+};
+struct s1 v1;
+
+void test_global_local() {
+ int *restrict i1 = g1; // COMPLIANT
+ int *restrict i2 = g2; // COMPLIANT
+ int *restrict i3 = i2; // NON_COMPLIANT
+ g1 = g2; // NON_COMPLIANT
+ i1 = i2; // NON_COMPLIANT
+ {
+ int *restrict i4;
+ int *restrict i5;
+ int *restrict i6;
+ i4 = g1; // COMPLIANT
+ i4 = (void *)0; // COMPLIANT
+ i5 = g1; // NON_COMPLIANT - block rather than statement scope matters
+ i4 = g1; // NON_COMPLIANT
+ i6 = g2; // COMPLIANT
+ }
+}
+
+void test_global_local_1() {
+ g1_1 = g2_1; // COMPLIANT
+}
+
+void test_structs() {
+ struct s1 *restrict p1 = &v1;
+ int *restrict px = &v1.x; // NON_COMPLIANT
+ {
+ int *restrict py;
+ int *restrict pz;
+ py = &v1.y; // COMPLIANT
+ py = (int *)0;
+ pz = &v1.z; // NON_COMPLIANT - block rather than statement scope matters
+ py = &v1.y; // NON_COMPLIANT
+ }
+}
+
+void copy(int *restrict p1, int *restrict p2, size_t s) {
+ for (size_t i = 0; i < s; ++i) {
+ p2[i] = p1[i];
+ }
+}
+
+void test_restrict_params() {
+ int i1 = 1;
+ int i2 = 2;
+ copy(&i1, &i1, 1); // NON_COMPLIANT
+ copy(&i1, &i2, 1); // COMPLIANT
+
+ int x[10];
+ int *px = &x[0];
+ copy(&x[0], &x[1], 1); // COMPLIANT - non overlapping
+ copy(&x[0], &x[1], 2); // NON_COMPLIANT - overlapping
+ copy(&x[0], (int *)x[0], 1); // COMPLIANT - non overlapping
+ copy(&x[0], px, 1); // NON_COMPLIANT - overlapping
+}
+
+void test_strcpy() {
+ char s1[] = "my test string";
+ char s2[] = "my other string";
+ strcpy(&s1, &s1 + 3); // NON_COMPLIANT
+ strcpy(&s2, &s1); // COMPLIANT
+}
+
+void test_memcpy() {
+ char s1[] = "my test string";
+ char s2[] = "my other string";
+ memcpy(&s1, &s1 + 3, 5); // NON_COMPLIANT
+ memcpy(&s2, &s1 + 3, 5); // COMPLIANT
+}
+
+void test_memmove() {
+ char s1[] = "my test string";
+ char s2[] = "my other string";
+ memmove(&s1, &s1 + 3, 5); // COMPLIANT - memmove is allowed to overlap
+ memmove(&s2, &s1 + 3, 5); // COMPLIANT
+}
+
+void test_scanf() {
+ char s1[200] = "%10s";
+ scanf(&s1, &s1 + 4); // NON_COMPLIANT
+}
+
+// TODO also consider the following:
+// strncpy(), strncpy_s()
+// strcat(), strcat_s()
+// strncat(), strncat_s()
+// strtok_s()
\ No newline at end of file
diff --git a/c/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected b/c/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected
index d0ba3bdb5c..c595e7e5f7 100644
--- a/c/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected
+++ b/c/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected
@@ -4,14 +4,14 @@ problems
| test.c:13:10:13:11 | p4 | test.c:5:14:5:15 | l2 | test.c:13:10:13:11 | p4 | Subtraction between left operand pointing to array $@ and other operand pointing to array $@. | test.c:3:7:3:8 | l2 | l2 | test.c:2:7:2:8 | l1 | l1 |
| test.c:13:15:13:16 | l1 | test.c:13:15:13:16 | l1 | test.c:13:15:13:16 | l1 | Subtraction between right operand pointing to array $@ and other operand pointing to array $@. | test.c:2:7:2:8 | l1 | l1 | test.c:3:7:3:8 | l2 | l2 |
edges
-| test.c:4:14:4:15 | l1 | test.c:4:14:4:18 | access to array |
-| test.c:4:14:4:18 | access to array | test.c:10:10:10:11 | p1 |
-| test.c:4:14:4:18 | access to array | test.c:12:10:12:11 | p1 |
-| test.c:5:14:5:15 | l2 | test.c:5:14:5:19 | access to array |
-| test.c:5:14:5:19 | access to array | test.c:11:10:11:11 | p2 |
-| test.c:5:14:5:19 | access to array | test.c:12:15:12:16 | p2 |
-| test.c:5:14:5:19 | access to array | test.c:13:10:13:11 | p4 |
-| test.c:5:14:5:19 | access to array | test.c:14:10:14:11 | p4 |
+| test.c:4:14:4:15 | l1 | test.c:4:14:4:18 | access to array | provenance | |
+| test.c:4:14:4:18 | access to array | test.c:10:10:10:11 | p1 | provenance | |
+| test.c:4:14:4:18 | access to array | test.c:12:10:12:11 | p1 | provenance | |
+| test.c:5:14:5:15 | l2 | test.c:5:14:5:19 | access to array | provenance | |
+| test.c:5:14:5:19 | access to array | test.c:11:10:11:11 | p2 | provenance | |
+| test.c:5:14:5:19 | access to array | test.c:12:15:12:16 | p2 | provenance | |
+| test.c:5:14:5:19 | access to array | test.c:13:10:13:11 | p4 | provenance | |
+| test.c:5:14:5:19 | access to array | test.c:14:10:14:11 | p4 | provenance | |
nodes
| test.c:4:14:4:15 | l1 | semmle.label | l1 |
| test.c:4:14:4:18 | access to array | semmle.label | access to array |
diff --git a/c/common/test/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.expected b/c/common/test/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.expected
index 8db569a98d..05c0ed4ca0 100644
--- a/c/common/test/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.expected
+++ b/c/common/test/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.expected
@@ -10,19 +10,19 @@ problems
| test.c:25:7:25:14 | ... >= ... | test.c:7:14:7:15 | l1 | test.c:25:7:25:8 | p1 | Compare operation >= comparing left operand pointing to array $@ and other operand pointing to array $@. | test.c:2:7:2:8 | l1 | l1 | test.c:4:7:4:8 | l3 | l3 |
| test.c:25:7:25:14 | ... >= ... | test.c:25:13:25:14 | l3 | test.c:25:13:25:14 | l3 | Compare operation >= comparing right operand pointing to array $@ and other operand pointing to array $@. | test.c:4:7:4:8 | l3 | l3 | test.c:2:7:2:8 | l1 | l1 |
edges
-| test.c:6:13:6:14 | l1 | test.c:13:12:13:13 | p0 |
-| test.c:7:14:7:15 | l1 | test.c:7:14:7:18 | access to array |
-| test.c:7:14:7:18 | access to array | test.c:11:7:11:8 | p1 |
-| test.c:7:14:7:18 | access to array | test.c:13:7:13:8 | p1 |
-| test.c:7:14:7:18 | access to array | test.c:15:13:15:14 | p1 |
-| test.c:7:14:7:18 | access to array | test.c:17:7:17:8 | p1 |
-| test.c:7:14:7:18 | access to array | test.c:23:13:23:14 | p1 |
-| test.c:7:14:7:18 | access to array | test.c:25:7:25:8 | p1 |
-| test.c:8:14:8:15 | l1 | test.c:8:14:8:18 | access to array |
-| test.c:8:14:8:18 | access to array | test.c:11:12:11:13 | p2 |
-| test.c:8:14:8:18 | access to array | test.c:21:7:21:8 | p2 |
-| test.c:9:14:9:15 | l2 | test.c:9:14:9:18 | access to array |
-| test.c:9:14:9:18 | access to array | test.c:21:12:21:13 | p3 |
+| test.c:6:13:6:14 | l1 | test.c:13:12:13:13 | p0 | provenance | |
+| test.c:7:14:7:15 | l1 | test.c:7:14:7:18 | access to array | provenance | |
+| test.c:7:14:7:18 | access to array | test.c:11:7:11:8 | p1 | provenance | |
+| test.c:7:14:7:18 | access to array | test.c:13:7:13:8 | p1 | provenance | |
+| test.c:7:14:7:18 | access to array | test.c:15:13:15:14 | p1 | provenance | |
+| test.c:7:14:7:18 | access to array | test.c:17:7:17:8 | p1 | provenance | |
+| test.c:7:14:7:18 | access to array | test.c:23:13:23:14 | p1 | provenance | |
+| test.c:7:14:7:18 | access to array | test.c:25:7:25:8 | p1 | provenance | |
+| test.c:8:14:8:15 | l1 | test.c:8:14:8:18 | access to array | provenance | |
+| test.c:8:14:8:18 | access to array | test.c:11:12:11:13 | p2 | provenance | |
+| test.c:8:14:8:18 | access to array | test.c:21:7:21:8 | p2 | provenance | |
+| test.c:9:14:9:15 | l2 | test.c:9:14:9:18 | access to array | provenance | |
+| test.c:9:14:9:18 | access to array | test.c:21:12:21:13 | p3 | provenance | |
nodes
| test.c:6:13:6:14 | l1 | semmle.label | l1 |
| test.c:7:14:7:15 | l1 | semmle.label | l1 |
diff --git a/c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.expected b/c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.expected
new file mode 100644
index 0000000000..5aede0a5ba
--- /dev/null
+++ b/c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.expected
@@ -0,0 +1,3 @@
+| test.c:9:16:9:31 | test_noreturn_f2 | The function test_noreturn_f2 declared with attribute _Noreturn returns a value. |
+| test.c:34:16:34:31 | test_noreturn_f5 | The function test_noreturn_f5 declared with attribute _Noreturn returns a value. |
+| test.c:49:32:49:47 | test_noreturn_f7 | The function test_noreturn_f7 declared with attribute _Noreturn returns a value. |
diff --git a/c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.ql b/c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.ql
new file mode 100644
index 0000000000..4af4aeceaf
--- /dev/null
+++ b/c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.functionnoreturnattributecondition.FunctionNoReturnAttributeCondition
+
+class TestFileQuery extends FunctionNoReturnAttributeConditionSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/functionnoreturnattributecondition/test.c b/c/common/test/rules/functionnoreturnattributecondition/test.c
new file mode 100644
index 0000000000..1b0ba759e1
--- /dev/null
+++ b/c/common/test/rules/functionnoreturnattributecondition/test.c
@@ -0,0 +1,88 @@
+#include "setjmp.h"
+#include "stdlib.h"
+#include "threads.h"
+
+_Noreturn void test_noreturn_f1(int i) { // COMPLIANT
+ abort();
+}
+
+_Noreturn void test_noreturn_f2(int i) { // NON_COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+ if (i < 0) {
+ abort();
+ }
+}
+
+_Noreturn void test_noreturn_f3(int i) { // COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+ exit(1);
+}
+
+void test_noreturn_f4(int i) { // COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+ if (i < 0) {
+ abort();
+ }
+}
+
+_Noreturn void test_noreturn_f5(int i) { // NON_COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+}
+
+_Noreturn void test_noreturn_f6(int i) { // COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+ while (1) {
+ i = 5;
+ }
+}
+
+__attribute__((noreturn)) void test_noreturn_f7(int i) { // NON_COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+}
+
+__attribute__((noreturn)) void test_noreturn_f8(int i) { // COMPLIANT
+ abort();
+}
+
+_Noreturn void test_noreturn_f9(int i) { // COMPLIANT
+ test_noreturn_f1(i);
+}
+
+_Noreturn void test_noreturn_f10(int i) { // COMPLIANT
+ switch (i) {
+ case 0:
+ abort();
+ break;
+ case 1:
+ exit(0);
+ break;
+ case 2:
+ _Exit(0);
+ break;
+ case 3:
+ quick_exit(0);
+ break;
+ case 4:
+ thrd_exit(0);
+ break;
+ default:
+ jmp_buf jb;
+ longjmp(jb, 0);
+ }
+}
+
+_Noreturn void test_noreturn_f11(int i) { // COMPLIANT
+ return test_noreturn_f11(i);
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected b/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected
similarity index 100%
rename from c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected
rename to c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected
diff --git a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected.clang b/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected.clang
similarity index 100%
rename from c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected.clang
rename to c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected.clang
diff --git a/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql b/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql
new file mode 100644
index 0000000000..25d273354d
--- /dev/null
+++ b/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared
+
+class TestFileQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-8-2/test.c b/c/common/test/rules/functiontypesnotinprototypeformshared/test.c
similarity index 100%
rename from c/misra/test/rules/RULE-8-2/test.c
rename to c/common/test/rules/functiontypesnotinprototypeformshared/test.c
diff --git a/c/misra/test/rules/RULE-8-2/test.c.clang b/c/common/test/rules/functiontypesnotinprototypeformshared/test.c.clang
similarity index 100%
rename from c/misra/test/rules/RULE-8-2/test.c.clang
rename to c/common/test/rules/functiontypesnotinprototypeformshared/test.c.clang
diff --git a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.expected
similarity index 100%
rename from c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected
rename to c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.expected
diff --git a/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql
new file mode 100644
index 0000000000..3d6d2019fb
--- /dev/null
+++ b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql
@@ -0,0 +1,5 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared
+
+class TestFileQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery, TestQuery {
+}
diff --git a/c/misra/test/rules/RULE-8-8/test.c b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/test.c
similarity index 100%
rename from c/misra/test/rules/RULE-8-8/test.c
rename to c/common/test/rules/missingstaticspecifierobjectredeclarationshared/test.c
diff --git a/c/common/test/rules/onlyfreememoryallocateddynamicallyshared/OnlyFreeMemoryAllocatedDynamicallyShared.expected b/c/common/test/rules/onlyfreememoryallocateddynamicallyshared/OnlyFreeMemoryAllocatedDynamicallyShared.expected
index 5881d5e78f..a6c41a6d75 100644
--- a/c/common/test/rules/onlyfreememoryallocateddynamicallyshared/OnlyFreeMemoryAllocatedDynamicallyShared.expected
+++ b/c/common/test/rules/onlyfreememoryallocateddynamicallyshared/OnlyFreeMemoryAllocatedDynamicallyShared.expected
@@ -6,10 +6,10 @@ problems
| test.c:18:36:18:38 | ptr | test.c:27:7:27:8 | & ... | test.c:18:36:18:38 | ptr | Free expression frees memory which was not dynamically allocated. |
| test.c:26:8:26:8 | p | test.c:25:13:25:14 | & ... | test.c:26:8:26:8 | p | Free expression frees memory which was not dynamically allocated. |
edges
-| test.c:18:24:18:26 | ptr | test.c:18:36:18:38 | ptr |
-| test.c:25:13:25:14 | & ... | test.c:26:8:26:8 | p |
-| test.c:27:7:27:8 | & ... | test.c:28:15:28:15 | p |
-| test.c:28:15:28:15 | p | test.c:18:24:18:26 | ptr |
+| test.c:18:24:18:26 | ptr | test.c:18:36:18:38 | ptr | provenance | |
+| test.c:25:13:25:14 | & ... | test.c:26:8:26:8 | p | provenance | |
+| test.c:27:7:27:8 | & ... | test.c:28:15:28:15 | p | provenance | |
+| test.c:28:15:28:15 | p | test.c:18:24:18:26 | ptr | provenance | |
nodes
| test.c:8:8:8:10 | g_p | semmle.label | g_p |
| test.c:10:8:10:10 | g_p | semmle.label | g_p |
diff --git a/c/misra/src/codeql-pack.lock.yml b/c/misra/src/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/c/misra/src/codeql-pack.lock.yml
+++ b/c/misra/src/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/c/misra/src/codeql-suites/misra-c-2012-third-edition-with-amendment-2.qls b/c/misra/src/codeql-suites/misra-c-2012-third-edition-with-amendment-2.qls
new file mode 100644
index 0000000000..8d06e7c2c8
--- /dev/null
+++ b/c/misra/src/codeql-suites/misra-c-2012-third-edition-with-amendment-2.qls
@@ -0,0 +1,13 @@
+- description: MISRA C 2012 - Third Edition, First Revision including Amendment 2
+- qlpack: codeql/misra-c-coding-standards
+- include:
+ kind:
+ - problem
+ - path-problem
+ tags contain:
+ - external/misra/c/2012/third-edition-first-revision
+ - external/misra/c/2012/amendment2
+- exclude:
+ tags contain:
+ - external/misra/audit
+ - external/misra/default-disabled
diff --git a/c/misra/src/codeql-suites/misra-c-advisory.qls b/c/misra/src/codeql-suites/misra-c-advisory.qls
new file mode 100644
index 0000000000..517f449b13
--- /dev/null
+++ b/c/misra/src/codeql-suites/misra-c-advisory.qls
@@ -0,0 +1,12 @@
+- description: MISRA C 2012 (Advisory)
+- qlpack: codeql/misra-c-coding-standards
+- include:
+ kind:
+ - problem
+ - path-problem
+ tags contain:
+ - external/misra/obligation/advisory
+- exclude:
+ tags contain:
+ - external/misra/audit
+ - external/misra/default-disabled
diff --git a/c/misra/src/codeql-suites/misra-c-default.qls b/c/misra/src/codeql-suites/misra-c-default.qls
new file mode 100644
index 0000000000..343379a2b3
--- /dev/null
+++ b/c/misra/src/codeql-suites/misra-c-default.qls
@@ -0,0 +1,10 @@
+- description: MISRA C 2012 (Default)
+- qlpack: codeql/misra-c-coding-standards
+- include:
+ kind:
+ - problem
+ - path-problem
+- exclude:
+ tags contain:
+ - external/misra/audit
+ - external/misra/default-disabled
diff --git a/c/misra/src/codeql-suites/misra-c-mandatory.qls b/c/misra/src/codeql-suites/misra-c-mandatory.qls
new file mode 100644
index 0000000000..454b8487ab
--- /dev/null
+++ b/c/misra/src/codeql-suites/misra-c-mandatory.qls
@@ -0,0 +1,12 @@
+- description: MISRA C 2012 (Advisory)
+- qlpack: codeql/misra-c-coding-standards
+- include:
+ kind:
+ - problem
+ - path-problem
+ tags contain:
+ - external/misra/obligation/mandatory
+- exclude:
+ tags contain:
+ - external/misra/audit
+ - external/misra/default-disabled
diff --git a/c/misra/src/codeql-suites/misra-c-required.qls b/c/misra/src/codeql-suites/misra-c-required.qls
new file mode 100644
index 0000000000..ca32b9ca97
--- /dev/null
+++ b/c/misra/src/codeql-suites/misra-c-required.qls
@@ -0,0 +1,12 @@
+- description: MISRA C 2012 (Required)
+- qlpack: codeql/misra-c-coding-standards
+- include:
+ kind:
+ - problem
+ - path-problem
+ tags contain:
+ - external/misra/obligation/required
+- exclude:
+ tags contain:
+ - external/misra/audit
+ - external/misra/default-disabled
diff --git a/c/misra/src/codeql-suites/misra-default.qls b/c/misra/src/codeql-suites/misra-default.qls
index 343379a2b3..e645bb1545 100644
--- a/c/misra/src/codeql-suites/misra-default.qls
+++ b/c/misra/src/codeql-suites/misra-default.qls
@@ -1,10 +1,2 @@
-- description: MISRA C 2012 (Default)
-- qlpack: codeql/misra-c-coding-standards
-- include:
- kind:
- - problem
- - path-problem
-- exclude:
- tags contain:
- - external/misra/audit
- - external/misra/default-disabled
+- description: "DEPRECATED - MISRA C 2012 - use misra-c-default.qls instead"
+- import: codeql-suites/misra-c-default.qls
diff --git a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll
index a1b8d6fdb0..4783547ed2 100644
--- a/c/misra/src/codingstandards/c/misra/EssentialTypes.qll
+++ b/c/misra/src/codingstandards/c/misra/EssentialTypes.qll
@@ -130,12 +130,17 @@ EssentialTypeCategory getEssentialTypeCategory(Type type) {
essentialType.(IntegralType).isSigned() and
not essentialType instanceof PlainCharType
or
+ // Anonymous enums are considered to be signed
+ result = EssentiallySignedType() and
+ essentialType instanceof AnonymousEnumType and
+ not essentialType instanceof MisraBoolType
+ or
result = EssentiallyUnsignedType() and
essentialType.(IntegralType).isUnsigned() and
not essentialType instanceof PlainCharType
or
result = EssentiallyEnumType() and
- essentialType instanceof Enum and
+ essentialType instanceof NamedEnumType and
not essentialType instanceof MisraBoolType
or
result = EssentiallyFloatingType() and
@@ -179,6 +184,10 @@ class EssentialBinaryLogicalOperationExpr extends EssentialExpr, BinaryLogicalOp
override Type getEssentialType() { result instanceof BoolType }
}
+class EssentialUnaryLogicalOperationExpr extends EssentialExpr, UnaryLogicalOperation {
+ override Type getEssentialType() { result instanceof BoolType }
+}
+
class EssentialEqualityOperationExpr extends EssentialExpr, EqualityOperation {
override Type getEssentialType() { result instanceof BoolType }
}
@@ -344,24 +353,63 @@ class EssentialBinaryArithmeticExpr extends EssentialExpr, BinaryArithmeticOpera
}
}
+/**
+ * A named Enum type, as per D.5.
+ */
+class NamedEnumType extends Enum {
+ NamedEnumType() {
+ not isAnonymous()
+ or
+ exists(Type useOfEnum | this = useOfEnum.stripType() |
+ exists(TypedefType t | t.getBaseType() = useOfEnum)
+ or
+ exists(Function f | f.getType() = useOfEnum or f.getAParameter().getType() = useOfEnum)
+ or
+ exists(Struct s | s.getAField().getType() = useOfEnum)
+ or
+ exists(Variable v | v.getType() = useOfEnum)
+ )
+ }
+}
+
+/**
+ * An anonymous Enum type, as per D.5.
+ */
+class AnonymousEnumType extends Enum {
+ AnonymousEnumType() { not this instanceof NamedEnumType }
+}
+
+/**
+ * The EssentialType of an EnumConstantAccess, which may be essentially enum or essentially signed.
+ */
class EssentialEnumConstantAccess extends EssentialExpr, EnumConstantAccess {
- override Type getEssentialType() { result = getTarget().getDeclaringEnum() }
+ override Type getEssentialType() {
+ exists(Enum e | e = getTarget().getDeclaringEnum() |
+ if e instanceof NamedEnumType then result = e else result = stlr(this)
+ )
+ }
}
class EssentialLiteral extends EssentialExpr, Literal {
override Type getEssentialType() {
if this instanceof BooleanLiteral
- then result instanceof MisraBoolType
+ then
+ // This returns a multitude of types - not sure if we really want that
+ result instanceof MisraBoolType
else (
- if this.(CharLiteral).getCharacter().length() = 1
+ if this instanceof CharLiteral
then result instanceof PlainCharType
- else (
- getStandardType().(IntegralType).isSigned() and
- result = stlr(this)
- or
- not getStandardType().(IntegralType).isSigned() and
- result = utlr(this)
- )
+ else
+ exists(Type underlyingStandardType |
+ underlyingStandardType = getStandardType().getUnderlyingType()
+ |
+ if underlyingStandardType instanceof IntType
+ then
+ if underlyingStandardType.(IntType).isSigned()
+ then result = stlr(this)
+ else result = utlr(this)
+ else result = underlyingStandardType
+ )
)
}
}
diff --git a/c/misra/src/qlpack.yml b/c/misra/src/qlpack.yml
index bfb3a8e8a5..0c78ad44b6 100644
--- a/c/misra/src/qlpack.yml
+++ b/c/misra/src/qlpack.yml
@@ -1,8 +1,9 @@
name: codeql/misra-c-coding-standards
-version: 2.33.0-dev
+version: 2.38.0-dev
description: MISRA C 2012
suites: codeql-suites
license: MIT
+default-suite-file: codeql-suites/misra-c-default.qls
dependencies:
codeql/common-c-coding-standards: '*'
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 0.12.9
diff --git a/c/misra/src/rules/DIR-4-10/PrecautionIncludeGuardsNotProvided.ql b/c/misra/src/rules/DIR-4-10/PrecautionIncludeGuardsNotProvided.ql
index 58ec5c80a9..338437b5b2 100644
--- a/c/misra/src/rules/DIR-4-10/PrecautionIncludeGuardsNotProvided.ql
+++ b/c/misra/src/rules/DIR-4-10/PrecautionIncludeGuardsNotProvided.ql
@@ -10,6 +10,7 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/DIR-4-12/StdLibDynamicMemoryAllocationUsed.ql b/c/misra/src/rules/DIR-4-12/StdLibDynamicMemoryAllocationUsed.ql
index dc1e21c97a..5c70bec761 100644
--- a/c/misra/src/rules/DIR-4-12/StdLibDynamicMemoryAllocationUsed.ql
+++ b/c/misra/src/rules/DIR-4-12/StdLibDynamicMemoryAllocationUsed.ql
@@ -11,6 +11,7 @@
* security
* correctness
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/DIR-4-2/UsageOfAssemblyLanguageShouldBeDocumented.ql b/c/misra/src/rules/DIR-4-2/UsageOfAssemblyLanguageShouldBeDocumented.ql
index 9503024671..1afd57913e 100644
--- a/c/misra/src/rules/DIR-4-2/UsageOfAssemblyLanguageShouldBeDocumented.ql
+++ b/c/misra/src/rules/DIR-4-2/UsageOfAssemblyLanguageShouldBeDocumented.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/dir-4-2
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/DIR-4-3/LanguageNotEncapsulatedAndIsolated.ql b/c/misra/src/rules/DIR-4-3/LanguageNotEncapsulatedAndIsolated.ql
index fb9f00e9c4..698cbabf01 100644
--- a/c/misra/src/rules/DIR-4-3/LanguageNotEncapsulatedAndIsolated.ql
+++ b/c/misra/src/rules/DIR-4-3/LanguageNotEncapsulatedAndIsolated.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/dir-4-3
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/DIR-4-4/SectionsOfCodeShallNotBeCommentedOut.ql b/c/misra/src/rules/DIR-4-4/SectionsOfCodeShallNotBeCommentedOut.ql
index d0af758699..272a411f0e 100644
--- a/c/misra/src/rules/DIR-4-4/SectionsOfCodeShallNotBeCommentedOut.ql
+++ b/c/misra/src/rules/DIR-4-4/SectionsOfCodeShallNotBeCommentedOut.ql
@@ -9,6 +9,7 @@
* maintainability
* readability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/DIR-4-5/IdentifiersInTheSameNameSpaceUnambiguous.ql b/c/misra/src/rules/DIR-4-5/IdentifiersInTheSameNameSpaceUnambiguous.ql
index ced5bce28f..5dd78fc340 100644
--- a/c/misra/src/rules/DIR-4-5/IdentifiersInTheSameNameSpaceUnambiguous.ql
+++ b/c/misra/src/rules/DIR-4-5/IdentifiersInTheSameNameSpaceUnambiguous.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/dir-4-5
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/DIR-4-6/PlainNumericalTypeUsedOverExplicitTypedef.ql b/c/misra/src/rules/DIR-4-6/PlainNumericalTypeUsedOverExplicitTypedef.ql
index c3ea6dfdbd..3891d8c99f 100644
--- a/c/misra/src/rules/DIR-4-6/PlainNumericalTypeUsedOverExplicitTypedef.ql
+++ b/c/misra/src/rules/DIR-4-6/PlainNumericalTypeUsedOverExplicitTypedef.ql
@@ -7,6 +7,7 @@
* @precision high
* @problem.severity error
* @tags external/misra/id/dir-4-6
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/DIR-4-8/ObjectWithNoPointerDereferenceShouldBeOpaque.ql b/c/misra/src/rules/DIR-4-8/ObjectWithNoPointerDereferenceShouldBeOpaque.ql
index 56f2dd785d..b32a0a4aee 100644
--- a/c/misra/src/rules/DIR-4-8/ObjectWithNoPointerDereferenceShouldBeOpaque.ql
+++ b/c/misra/src/rules/DIR-4-8/ObjectWithNoPointerDereferenceShouldBeOpaque.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/dir-4-8
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/DIR-4-9/FunctionOverFunctionLikeMacro.ql b/c/misra/src/rules/DIR-4-9/FunctionOverFunctionLikeMacro.ql
index 3d8a51f219..582715e34f 100644
--- a/c/misra/src/rules/DIR-4-9/FunctionOverFunctionLikeMacro.ql
+++ b/c/misra/src/rules/DIR-4-9/FunctionOverFunctionLikeMacro.ql
@@ -10,6 +10,7 @@
* external/misra/audit
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql b/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql
index f38e41a1b6..34a0f40fb6 100644
--- a/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql
+++ b/c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql
@@ -8,13 +8,15 @@
* @tags external/misra/id/rule-1-2
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.AlertReporting
import codingstandards.c.Extensions
from CCompilerExtension e
where not isExcluded(e, Language3Package::languageExtensionsShouldNotBeUsedQuery())
-select e, "Is a compiler extension and is not portable to other compilers."
+select MacroUnwrapper::unwrapElement(e), e.getMessage()
diff --git a/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql b/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql
index f6b295bd32..00ef875985 100644
--- a/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql
+++ b/c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-1-3
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
@@ -17,4 +18,4 @@ import codingstandards.c.UndefinedBehavior
from CUndefinedBehavior c
where not isExcluded(c, Language3Package::occurrenceOfUndefinedBehaviorQuery())
-select c, "May result in undefined behavior."
+select c, c.getReason()
diff --git a/c/misra/src/rules/RULE-1-4/EmergentLanguageFeaturesUsed.ql b/c/misra/src/rules/RULE-1-4/EmergentLanguageFeaturesUsed.ql
index 56ab349a11..a413b1c29a 100644
--- a/c/misra/src/rules/RULE-1-4/EmergentLanguageFeaturesUsed.ql
+++ b/c/misra/src/rules/RULE-1-4/EmergentLanguageFeaturesUsed.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-1-4
* maintainability
* readability
+ * external/misra/c/2012/amendment2
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-1-5/CallToObsolescentFunctionGets.ql b/c/misra/src/rules/RULE-1-5/CallToObsolescentFunctionGets.ql
new file mode 100644
index 0000000000..4994c4ea6e
--- /dev/null
+++ b/c/misra/src/rules/RULE-1-5/CallToObsolescentFunctionGets.ql
@@ -0,0 +1,22 @@
+/**
+ * @id c/misra/call-to-obsolescent-function-gets
+ * @name RULE-1-5: Disallowed usage of obsolescent function 'gets'
+ * @description The function 'gets' is an obsolescent language feature which was removed in C11.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-1-5
+ * external/misra/c/2012/amendment3
+ * security
+ * maintainability
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+
+from FunctionCall fc
+where
+ not isExcluded(fc, Language4Package::callToObsolescentFunctionGetsQuery()) and
+ fc.getTarget().hasGlobalOrStdName("gets")
+select fc, "Call to obsolescent function 'gets'."
diff --git a/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql b/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql
new file mode 100644
index 0000000000..645285f438
--- /dev/null
+++ b/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql
@@ -0,0 +1,24 @@
+/**
+ * @id c/misra/function-types-not-in-prototype-form-obsolete
+ * @name RULE-1-5: Function types shall be in prototype form with named parameters
+ * @description The use of non-prototype format parameter type declarators is an obsolescent
+ * language feature.
+ * @kind problem
+ * @precision medium
+ * @problem.severity error
+ * @tags external/misra/id/rule-1-5
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared
+
+class FunctionTypesNotInPrototypeFormObsoleteQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery
+{
+ FunctionTypesNotInPrototypeFormObsoleteQuery() {
+ this = Language4Package::functionTypesNotInPrototypeFormObsoleteQuery()
+ }
+}
diff --git a/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql b/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql
new file mode 100644
index 0000000000..9d10522ecf
--- /dev/null
+++ b/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql
@@ -0,0 +1,32 @@
+/**
+ * @id c/misra/invalid-define-or-undef-of-std-bool-macro
+ * @name RULE-1-5: Programs may not undefine or redefine the macros bool, true, or false
+ * @description Directives that undefine and/or redefine the standard boolean macros has been
+ * declared an obsolescent language feature since C99.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-1-5
+ * maintainability
+ * readability
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+
+string getABoolMacroName() { result = ["true", "false", "bool"] }
+
+from PreprocessorDirective directive, string opString, string macroName
+where
+ not isExcluded(directive, Language4Package::invalidDefineOrUndefOfStdBoolMacroQuery()) and
+ macroName = getABoolMacroName() and
+ (
+ macroName = directive.(Macro).getName() and
+ opString = "define"
+ or
+ macroName = directive.(PreprocessorUndef).getName() and
+ opString = "undefine"
+ )
+select directive, "Invalid " + opString + " of boolean standard macro '" + macroName + "'."
diff --git a/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql
new file mode 100644
index 0000000000..ba800885ef
--- /dev/null
+++ b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql
@@ -0,0 +1,24 @@
+/**
+ * @id c/misra/missing-static-specifier-func-redeclaration-obsolete
+ * @name RULE-1-5: If a function has internal linkage then all re-declarations shall include the static storage class
+ * @description Declaring a function with internal linkage without the static storage class
+ * specifier is an obselescent feature.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-1-5
+ * readability
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.rules.missingstaticspecifierfunctionredeclarationshared.MissingStaticSpecifierFunctionRedeclarationShared
+
+class MissingStaticSpecifierFuncRedeclarationObsoleteQuery extends MissingStaticSpecifierFunctionRedeclarationSharedSharedQuery
+{
+ MissingStaticSpecifierFuncRedeclarationObsoleteQuery() {
+ this = Language4Package::missingStaticSpecifierFuncRedeclarationObsoleteQuery()
+ }
+}
diff --git a/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql
new file mode 100644
index 0000000000..9f9953aa6f
--- /dev/null
+++ b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql
@@ -0,0 +1,24 @@
+/**
+ * @id c/misra/missing-static-specifier-object-redeclaration-obsolete
+ * @name RULE-1-5: If an object has internal linkage then all re-declarations shall include the static storage class
+ * @description Declaring an identifier with internal linkage without the static storage class
+ * specifier is an obselescent feature.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-1-5
+ * readability
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared
+
+class MissingStaticSpecifierObjectRedeclarationObsoleteQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery
+{
+ MissingStaticSpecifierObjectRedeclarationObsoleteQuery() {
+ this = Language4Package::missingStaticSpecifierObjectRedeclarationObsoleteQuery()
+ }
+}
diff --git a/c/misra/src/rules/RULE-1-5/SizeInReallocCallIsZero.ql b/c/misra/src/rules/RULE-1-5/SizeInReallocCallIsZero.ql
new file mode 100644
index 0000000000..2b5cdaa851
--- /dev/null
+++ b/c/misra/src/rules/RULE-1-5/SizeInReallocCallIsZero.ql
@@ -0,0 +1,26 @@
+/**
+ * @id c/misra/size-in-realloc-call-is-zero
+ * @name RULE-1-5: Size argument value in realloc call is equal zero
+ * @description Invoking realloc with a size argument set to zero is implementation-defined behavior
+ * and declared as an obsolete feature in C18.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-1-5
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import semmle.code.cpp.rangeanalysis.new.RangeAnalysis
+import codingstandards.cpp.Realloc
+
+from ReallocCall call
+where
+ not isExcluded(call, Language4Package::sizeInReallocCallIsZeroQuery()) and
+ call.sizeIsExactlyZero()
+select call,
+ "Size argument '$@' may equal zero in realloc call, resulting in obsolescent and/or implementation-defined behavior.",
+ call.getSizeArgument(), call.getSizeArgument().toString()
diff --git a/c/misra/src/rules/RULE-1-5/SizeInReallocCallMayBeZero.ql b/c/misra/src/rules/RULE-1-5/SizeInReallocCallMayBeZero.ql
new file mode 100644
index 0000000000..3e883e45f4
--- /dev/null
+++ b/c/misra/src/rules/RULE-1-5/SizeInReallocCallMayBeZero.ql
@@ -0,0 +1,26 @@
+/**
+ * @id c/misra/size-in-realloc-call-may-be-zero
+ * @name RULE-1-5: Size argument value in realloc call may equal zero
+ * @description Invoking realloc with a size argument set to zero is implementation-defined behavior
+ * and declared as an obsolete feature in C18.
+ * @kind problem
+ * @precision medium
+ * @problem.severity error
+ * @tags external/misra/id/rule-1-5
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.Realloc
+
+from ReallocCall call
+where
+ not isExcluded(call, Language4Package::sizeInReallocCallMayBeZeroQuery()) and
+ call.sizeMayBeZero() and
+ not call.sizeIsExactlyZero()
+select call,
+ "Size argument '$@' equals zero in realloc call, resulting in obsolescent and/or implementation-defined behavior.",
+ call.getSizeArgument(), call.getSizeArgument().toString()
diff --git a/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql b/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql
new file mode 100644
index 0000000000..6a10c94030
--- /dev/null
+++ b/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql
@@ -0,0 +1,81 @@
+/**
+ * @id c/misra/ungetc-call-on-stream-position-zero
+ * @name RULE-1-5: Disallowed obsolescent usage of 'ungetc' on a file stream at position zero
+ * @description Calling the function 'ungetc' on a file stream with a position of zero is an
+ * obsolescent language feature.
+ * @kind path-problem
+ * @precision high
+ * @problem.severity error
+ * @tags external/misra/id/rule-1-5
+ * external/misra/c/2012/amendment3
+ * security
+ * maintainability
+ * external/misra/obligation/required
+ */
+
+import cpp
+import semmle.code.cpp.dataflow.new.DataFlow
+import semmle.code.cpp.controlflow.Dominance
+import codingstandards.c.misra
+
+/**
+ * This is an inconclusive list, which is adequate, as RULE-21-3 provides
+ * assurance we won't have false negatives, or care too much about false
+ * positives.
+ */
+class MoveStreamPositionCall extends FunctionCall {
+ Expr streamArgument;
+
+ MoveStreamPositionCall() {
+ getTarget().hasGlobalOrStdName("fgetc") and
+ streamArgument = getArgument(0)
+ or
+ getTarget().hasGlobalOrStdName("getc") and
+ streamArgument = getArgument(0)
+ or
+ getTarget().hasGlobalOrStdName("fget") and
+ streamArgument = getArgument(2)
+ or
+ getTarget().hasGlobalOrStdName("fscanf") and
+ streamArgument = getArgument(0)
+ or
+ getTarget().hasGlobalOrStdName("fsetpos") and
+ streamArgument = getArgument(0)
+ or
+ getTarget().hasGlobalOrStdName("fseek") and
+ streamArgument = getArgument(0)
+ or
+ getTarget().hasGlobalOrStdName("fread") and
+ streamArgument = getArgument(3)
+ }
+
+ Expr getStreamArgument() { result = streamArgument }
+}
+
+module FilePositionZeroFlowConfig implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node node) {
+ node.asIndirectExpr().(FunctionCall).getTarget().hasGlobalOrStdName("fopen")
+ }
+
+ predicate isSink(DataFlow::Node node) {
+ exists(FunctionCall fc |
+ fc.getTarget().hasGlobalOrStdName("ungetc") and
+ node.asIndirectExpr() = fc.getArgument(1)
+ )
+ }
+
+ predicate isBarrierIn(DataFlow::Node node) {
+ exists(MoveStreamPositionCall fc | node.asIndirectExpr() = fc.getStreamArgument())
+ }
+}
+
+module FilePositionZeroFlow = DataFlow::Global;
+
+import FilePositionZeroFlow::PathGraph
+
+from FilePositionZeroFlow::PathNode sink, FilePositionZeroFlow::PathNode source
+where
+ not isExcluded(sink.getNode().asExpr(), Language4Package::ungetcCallOnStreamPositionZeroQuery()) and
+ FilePositionZeroFlow::flowPath(source, sink)
+select sink.getNode(), source, sink,
+ "Obsolescent call to ungetc on file stream $@ at position zero.", source, source.toString()
diff --git a/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql
new file mode 100644
index 0000000000..e8abf1bbfb
--- /dev/null
+++ b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql
@@ -0,0 +1,24 @@
+/**
+ * @id c/misra/use-of-obsolete-macro-atomic-var-init
+ * @name RULE-1-5: Disallowed usage of obsolete macro ATOMIC_VAR_INIT compiled as C18
+ * @description The macro ATOMIC_VAR_INIT is has been declared an obsolescent language feature since
+ * C18.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity recommendation
+ * @tags external/misra/id/rule-1-5
+ * maintainability
+ * readability
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+
+from MacroInvocation invoke
+where
+ not isExcluded(invoke, Language4Package::useOfObsoleteMacroAtomicVarInitQuery()) and
+ invoke.getMacroName() = "ATOMIC_VAR_INIT"
+select invoke,
+ "Usage of macro ATOMIC_VAR_INIT() is declared obscelescent in C18, and discouraged in earlier C versions."
diff --git a/c/misra/src/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.ql b/c/misra/src/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.ql
index 6fdde80119..10b24b8c8a 100644
--- a/c/misra/src/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.ql
+++ b/c/misra/src/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.ql
@@ -8,13 +8,13 @@
* @problem.severity warning
* @tags external/misra/id/rule-10-1
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
import codingstandards.c.misra.EssentialTypes
-import codingstandards.cpp.Bitwise
/**
* Holds if the operator `operator` has an operand `child` that is of an inappropriate essential type
@@ -178,7 +178,7 @@ predicate isInappropriateEssentialType(
child =
[
operator.(BinaryBitwiseOperation).getAnOperand(),
- operator.(Bitwise::AssignBitwiseOperation).getAnOperand()
+ operator.(AssignBitwiseOperation).getAnOperand(), operator.(ComplementExpr).getAnOperand()
] and
not operator instanceof LShiftExpr and
not operator instanceof RShiftExpr and
@@ -240,7 +240,7 @@ string getRationaleMessage(int rationaleId, EssentialTypeCategory etc) {
result = "Bitwise operator applied to operand of " + etc + " and not essentially unsigned."
or
rationaleId = 7 and
- result = "Right hand operatand of shift operator is " + etc + " and not not essentially unsigned."
+ result = "Right hand operand of shift operator is " + etc + " and not not essentially unsigned."
or
rationaleId = 8 and
result =
@@ -251,4 +251,4 @@ from Expr operator, Expr child, int rationaleId, EssentialTypeCategory etc
where
not isExcluded(operator, EssentialTypesPackage::operandsOfAnInappropriateEssentialTypeQuery()) and
isInappropriateEssentialType(operator, child, etc, rationaleId)
-select operator, getRationaleMessage(rationaleId, etc)
+select child, getRationaleMessage(rationaleId, etc)
diff --git a/c/misra/src/rules/RULE-10-1/PointerTypeOnLogicalOperator.ql b/c/misra/src/rules/RULE-10-1/PointerTypeOnLogicalOperator.ql
index 21bfdcb2be..b17f3710d5 100644
--- a/c/misra/src/rules/RULE-10-1/PointerTypeOnLogicalOperator.ql
+++ b/c/misra/src/rules/RULE-10-1/PointerTypeOnLogicalOperator.ql
@@ -8,6 +8,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-10-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-10-2/AdditionSubtractionOnEssentiallyCharType.ql b/c/misra/src/rules/RULE-10-2/AdditionSubtractionOnEssentiallyCharType.ql
index ad0c630e23..750e589a1c 100644
--- a/c/misra/src/rules/RULE-10-2/AdditionSubtractionOnEssentiallyCharType.ql
+++ b/c/misra/src/rules/RULE-10-2/AdditionSubtractionOnEssentiallyCharType.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-10-2
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.ql b/c/misra/src/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.ql
index 353f6a9c8d..af120fb13d 100644
--- a/c/misra/src/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.ql
+++ b/c/misra/src/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-10-3
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-10-4/OperandsWithMismatchedEssentialTypeCategory.ql b/c/misra/src/rules/RULE-10-4/OperandsWithMismatchedEssentialTypeCategory.ql
index d5ef8b6d26..d1fed06319 100644
--- a/c/misra/src/rules/RULE-10-4/OperandsWithMismatchedEssentialTypeCategory.ql
+++ b/c/misra/src/rules/RULE-10-4/OperandsWithMismatchedEssentialTypeCategory.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-10-4
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
@@ -37,7 +38,7 @@ where
// be reported as non-compliant.
leftOpTypeCategory = EssentiallyEnumType() and
rightOpTypeCategory = EssentiallyEnumType() and
- not leftOpEssentialType = rightOpEssentialType and
+ not leftOpEssentialType.getUnspecifiedType() = rightOpEssentialType.getUnspecifiedType() and
message =
"The operands of this operator with usual arithmetic conversions have mismatched essentially Enum types (left operand: "
+ leftOpEssentialType + ", right operand: " + rightOpEssentialType + ")."
diff --git a/c/misra/src/rules/RULE-10-5/InappropriateEssentialTypeCast.ql b/c/misra/src/rules/RULE-10-5/InappropriateEssentialTypeCast.ql
index 1ff8374e97..f782a16597 100644
--- a/c/misra/src/rules/RULE-10-5/InappropriateEssentialTypeCast.ql
+++ b/c/misra/src/rules/RULE-10-5/InappropriateEssentialTypeCast.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-10-5
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-10-6/AssignmentToWiderEssentialType.ql b/c/misra/src/rules/RULE-10-6/AssignmentToWiderEssentialType.ql
index 09e731ba71..8927e8570a 100644
--- a/c/misra/src/rules/RULE-10-6/AssignmentToWiderEssentialType.ql
+++ b/c/misra/src/rules/RULE-10-6/AssignmentToWiderEssentialType.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-10-6
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-10-7/ImplicitConversionOfCompositeExpression.ql b/c/misra/src/rules/RULE-10-7/ImplicitConversionOfCompositeExpression.ql
index 1cf20378fa..911aa5e00e 100644
--- a/c/misra/src/rules/RULE-10-7/ImplicitConversionOfCompositeExpression.ql
+++ b/c/misra/src/rules/RULE-10-7/ImplicitConversionOfCompositeExpression.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-10-7
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
@@ -18,6 +19,12 @@ import codingstandards.c.misra
import codingstandards.c.misra.EssentialTypes
import codingstandards.c.misra.MisraExpressions
+bindingset[essentialTypeLeft, essentialTypeRight]
+pragma[inline_late]
+predicate isSameEssentialTypeCategory(Type essentialTypeLeft, Type essentialTypeRight) {
+ getEssentialTypeCategory(essentialTypeLeft) = getEssentialTypeCategory(essentialTypeRight)
+}
+
from
OperationWithUsualArithmeticConversions arith, CompositeExpression compositeOp, Expr otherOp,
Type compositeEssentialType, Type otherOpEssentialType
@@ -32,7 +39,7 @@ where
// Operands of a different type category in an operation with the usual arithmetic conversions is
// prohibited by Rule 10.4, so we only report cases here where the essential type categories are
// the same
- getEssentialTypeCategory(compositeEssentialType) = getEssentialTypeCategory(otherOpEssentialType)
+ isSameEssentialTypeCategory(compositeEssentialType, otherOpEssentialType)
select arith,
"Implicit conversion of $@ from " + compositeEssentialType + " to " + otherOpEssentialType,
compositeOp, "composite op"
diff --git a/c/misra/src/rules/RULE-10-8/InappropriateCastOfCompositeExpression.ql b/c/misra/src/rules/RULE-10-8/InappropriateCastOfCompositeExpression.ql
index 8e58ded416..162ba4439c 100644
--- a/c/misra/src/rules/RULE-10-8/InappropriateCastOfCompositeExpression.ql
+++ b/c/misra/src/rules/RULE-10-8/InappropriateCastOfCompositeExpression.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-10-8
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-11-1/ConversionBetweenFunctionPointerAndOtherType.ql b/c/misra/src/rules/RULE-11-1/ConversionBetweenFunctionPointerAndOtherType.ql
index bfac04da6f..36157e130e 100644
--- a/c/misra/src/rules/RULE-11-1/ConversionBetweenFunctionPointerAndOtherType.ql
+++ b/c/misra/src/rules/RULE-11-1/ConversionBetweenFunctionPointerAndOtherType.ql
@@ -8,12 +8,13 @@
* @problem.severity error
* @tags external/misra/id/rule-11-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
from CStyleCast cast, Type type, Type newType
where
diff --git a/c/misra/src/rules/RULE-11-2/ConversionBetweenIncompleteTypePointerAndOtherType.ql b/c/misra/src/rules/RULE-11-2/ConversionBetweenIncompleteTypePointerAndOtherType.ql
index 007b43963b..6c552b0f39 100644
--- a/c/misra/src/rules/RULE-11-2/ConversionBetweenIncompleteTypePointerAndOtherType.ql
+++ b/c/misra/src/rules/RULE-11-2/ConversionBetweenIncompleteTypePointerAndOtherType.ql
@@ -8,12 +8,13 @@
* @problem.severity error
* @tags external/misra/id/rule-11-2
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
import codingstandards.cpp.Type
from Cast cast, Type type, Type newType
diff --git a/c/misra/src/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.ql b/c/misra/src/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.ql
index ede0a2834e..8292bd3b6f 100644
--- a/c/misra/src/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.ql
+++ b/c/misra/src/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.ql
@@ -9,12 +9,13 @@
* @problem.severity error
* @tags external/misra/id/rule-11-3
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
from CStyleCast cast, Type baseTypeFrom, Type baseTypeTo
where
diff --git a/c/misra/src/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.ql b/c/misra/src/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.ql
index 263545dc1f..8877d04323 100644
--- a/c/misra/src/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.ql
+++ b/c/misra/src/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.ql
@@ -8,19 +8,79 @@
* @problem.severity error
* @tags external/misra/id/rule-11-4
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Macro
+import codingstandards.cpp.Pointers
-from CStyleCast cast, Type typeFrom, Type typeTo
+MacroInvocation getAMacroInvocation(CStyleCast cast) { result.getAnExpandedElement() = cast }
+
+Macro getPrimaryMacro(CStyleCast cast) {
+ exists(MacroInvocation mi |
+ mi = getAMacroInvocation(cast) and
+ not exists(MacroInvocation otherMi |
+ otherMi = getAMacroInvocation(cast) and otherMi.getParentInvocation() = mi
+ ) and
+ result = mi.getMacro()
+ )
+}
+
+Macro getNonFunctionPrimaryMacro(CStyleCast cast) {
+ result = getPrimaryMacro(cast) and
+ not result instanceof FunctionLikeMacro
+}
+
+from
+ Locatable primaryLocation, CStyleCast cast, Type typeFrom, Type typeTo, string message,
+ string extraMessage, Locatable optionalPlaceholderLocation, string optionalPlaceholderMessage
where
not isExcluded(cast, Pointers1Package::conversionBetweenPointerToObjectAndIntegerTypeQuery()) and
typeFrom = cast.getExpr().getUnderlyingType() and
typeTo = cast.getUnderlyingType() and
- [typeFrom, typeTo] instanceof IntegralType and
- [typeFrom, typeTo] instanceof PointerToObjectType and
- not isNullPointerConstant(cast.getExpr())
-select cast, "Cast performed between a pointer to object type and a pointer to an integer type."
+ (
+ typeFrom instanceof PointerToObjectType and
+ typeTo instanceof IntegralType and
+ message =
+ "Cast from pointer to object type '" + typeFrom + "' to integer type '" + typeTo + "'" +
+ extraMessage + "."
+ or
+ typeFrom instanceof IntegralType and
+ typeTo instanceof PointerToObjectType and
+ message =
+ "Cast from integer type '" + typeFrom + "' to pointer to object type '" + typeTo + "'" +
+ extraMessage + "."
+ ) and
+ not isNullPointerConstant(cast.getExpr()) and
+ // If this alert is arising through a non-function-like macro expansion, flag the macro instead, to
+ // help make the alerts more manageable. We only do this for non-function-like macros because they
+ // cannot be context specific.
+ if exists(getNonFunctionPrimaryMacro(cast))
+ then
+ primaryLocation = getNonFunctionPrimaryMacro(cast) and
+ extraMessage = "" and
+ optionalPlaceholderLocation = primaryLocation and
+ optionalPlaceholderMessage = ""
+ else (
+ primaryLocation = cast and
+ // If the cast is in a macro expansion which is context specific, we still report the original
+ // location, but also add a link to the most specific macro that contains the cast, to aid
+ // validation.
+ if exists(getPrimaryMacro(cast))
+ then
+ extraMessage = " from expansion of macro $@" and
+ exists(Macro m |
+ m = getPrimaryMacro(cast) and
+ optionalPlaceholderLocation = m and
+ optionalPlaceholderMessage = m.getName()
+ )
+ else (
+ extraMessage = "" and
+ optionalPlaceholderLocation = cast and
+ optionalPlaceholderMessage = ""
+ )
+ )
+select primaryLocation, message, optionalPlaceholderLocation, optionalPlaceholderMessage
diff --git a/c/misra/src/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.ql b/c/misra/src/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.ql
index 3450f1ae90..0363c28c19 100644
--- a/c/misra/src/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.ql
+++ b/c/misra/src/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.ql
@@ -8,17 +8,18 @@
* @problem.severity error
* @tags external/misra/id/rule-11-5
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
from Cast cast, VoidPointerType type, PointerToObjectType newType
where
not isExcluded(cast, Pointers1Package::conversionFromPointerToVoidIntoPointerToObjectQuery()) and
- type = cast.getExpr().getUnderlyingType() and
+ type = cast.getExpr().getUnspecifiedType() and
newType = cast.getUnderlyingType() and
not isNullPointerConstant(cast.getExpr())
select cast,
diff --git a/c/misra/src/rules/RULE-11-6/CastBetweenPointerToVoidAndArithmeticType.ql b/c/misra/src/rules/RULE-11-6/CastBetweenPointerToVoidAndArithmeticType.ql
index b36d8dafb1..cc0adf0517 100644
--- a/c/misra/src/rules/RULE-11-6/CastBetweenPointerToVoidAndArithmeticType.ql
+++ b/c/misra/src/rules/RULE-11-6/CastBetweenPointerToVoidAndArithmeticType.ql
@@ -8,12 +8,13 @@
* @problem.severity error
* @tags external/misra/id/rule-11-6
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
from CStyleCast cast, Type typeFrom, Type typeTo
where
@@ -22,5 +23,5 @@ where
typeTo = cast.getUnderlyingType() and
[typeFrom, typeTo] instanceof ArithmeticType and
[typeFrom, typeTo] instanceof VoidPointerType and
- not isNullPointerConstant(cast.getExpr())
+ not cast.getExpr() instanceof Zero
select cast, "Cast performed between a pointer to void type and an arithmetic type."
diff --git a/c/misra/src/rules/RULE-11-7/CastBetweenPointerToObjectAndNonIntArithmeticType.ql b/c/misra/src/rules/RULE-11-7/CastBetweenPointerToObjectAndNonIntArithmeticType.ql
index 30b643963c..e499ea6485 100644
--- a/c/misra/src/rules/RULE-11-7/CastBetweenPointerToObjectAndNonIntArithmeticType.ql
+++ b/c/misra/src/rules/RULE-11-7/CastBetweenPointerToObjectAndNonIntArithmeticType.ql
@@ -8,12 +8,13 @@
* @problem.severity error
* @tags external/misra/id/rule-11-7
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
class MisraNonIntegerArithmeticType extends Type {
MisraNonIntegerArithmeticType() {
diff --git a/c/misra/src/rules/RULE-11-8/CastRemovesConstOrVolatileQualification.ql b/c/misra/src/rules/RULE-11-8/CastRemovesConstOrVolatileQualification.ql
index 17b0df1a0e..17b12aaf99 100644
--- a/c/misra/src/rules/RULE-11-8/CastRemovesConstOrVolatileQualification.ql
+++ b/c/misra/src/rules/RULE-11-8/CastRemovesConstOrVolatileQualification.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-11-8
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-11-9/MacroNullNotUsedAsIntegerNullPointerConstant.ql b/c/misra/src/rules/RULE-11-9/MacroNullNotUsedAsIntegerNullPointerConstant.ql
index 81ea8b1dfd..cb18ed0d1d 100644
--- a/c/misra/src/rules/RULE-11-9/MacroNullNotUsedAsIntegerNullPointerConstant.ql
+++ b/c/misra/src/rules/RULE-11-9/MacroNullNotUsedAsIntegerNullPointerConstant.ql
@@ -7,26 +7,37 @@
* @problem.severity error
* @tags external/misra/id/rule-11-9
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
import codingstandards.cpp.Type
from Zero zero, Expr e, string type
where
not isExcluded(zero, Pointers1Package::macroNullNotUsedAsIntegerNullPointerConstantQuery()) and
- // exclude the base-case (NULL macros and void pointer casts)
- not isNullPointerConstant(zero) and
+ // Exclude the base-case (NULL macros and void pointer casts)
+ // Note: we cannot use the isNullPointerConstant predicate here because it permits
+ // the use of `0` without casting, which is prohibited here.
+ not (
+ zero.findRootCause() instanceof NullMacro
+ or
+ // integer constant `0` explicitly cast to void pointer
+ exists(Conversion c | c = zero.getConversion() |
+ not c.isImplicit() and
+ c.getUnderlyingType() instanceof VoidPointerType
+ )
+ ) and
(
// ?: operator
exists(ConditionalExpr parent |
(
- parent.getThen().getAChild*() = zero and parent.getElse().getType() instanceof PointerType
+ parent.getThen() = zero and parent.getElse().getType() instanceof PointerType
or
- parent.getElse().getAChild*() = zero and parent.getThen().getType() instanceof PointerType
+ parent.getElse() = zero and parent.getThen().getType() instanceof PointerType
) and
// exclude a common conditional pattern used in macros such as 'assert'
not parent.isInMacroExpansion() and
diff --git a/c/misra/src/rules/RULE-12-1/ImplicitPrecedenceOfOperatorsInExpression.ql b/c/misra/src/rules/RULE-12-1/ImplicitPrecedenceOfOperatorsInExpression.ql
index 005fffa32d..134068463c 100644
--- a/c/misra/src/rules/RULE-12-1/ImplicitPrecedenceOfOperatorsInExpression.ql
+++ b/c/misra/src/rules/RULE-12-1/ImplicitPrecedenceOfOperatorsInExpression.ql
@@ -9,6 +9,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-12-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-12-1/UnenclosedSizeofOperand.ql b/c/misra/src/rules/RULE-12-1/UnenclosedSizeofOperand.ql
index 8975e7dff7..0081de320c 100644
--- a/c/misra/src/rules/RULE-12-1/UnenclosedSizeofOperand.ql
+++ b/c/misra/src/rules/RULE-12-1/UnenclosedSizeofOperand.ql
@@ -9,6 +9,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-12-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftRange.ql b/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftRange.ql
index 891ca1e82a..da7a0f181e 100644
--- a/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftRange.ql
+++ b/c/misra/src/rules/RULE-12-2/RightHandOperandOfAShiftRange.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-12-2
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
@@ -20,14 +21,51 @@ class ShiftExpr extends BinaryBitwiseOperation {
ShiftExpr() { this instanceof LShiftExpr or this instanceof RShiftExpr }
}
-from ShiftExpr e, Expr right, int max_val
+MacroInvocation getAMacroInvocation(ShiftExpr se) { result.getAnExpandedElement() = se }
+
+Macro getPrimaryMacro(ShiftExpr se) {
+ exists(MacroInvocation mi |
+ mi = getAMacroInvocation(se) and
+ not exists(MacroInvocation otherMi |
+ otherMi = getAMacroInvocation(se) and otherMi.getParentInvocation() = mi
+ ) and
+ result = mi.getMacro()
+ )
+}
+
+from
+ ShiftExpr e, Expr right, int max_val, float lowerBound, float upperBound, Type essentialType,
+ string extraMessage, Locatable optionalPlaceholderLocation, string optionalPlaceholderMessage
where
not isExcluded(right, Contracts7Package::rightHandOperandOfAShiftRangeQuery()) and
right = e.getRightOperand().getFullyConverted() and
- max_val = (8 * getEssentialType(e.getLeftOperand()).getSize()) - 1 and
+ essentialType = getEssentialType(e.getLeftOperand()) and
+ max_val = (8 * essentialType.getSize()) - 1 and
+ upperBound = upperBound(right) and
+ lowerBound = lowerBound(right) and
+ (
+ lowerBound < 0 or
+ upperBound > max_val
+ ) and
+ // If this shift happens inside a macro, then report the macro as well
+ // for easier validation
(
- lowerBound(right) < 0 or
- upperBound(right) > max_val
+ if exists(getPrimaryMacro(e))
+ then
+ extraMessage = " from expansion of macro $@" and
+ exists(Macro m |
+ m = getPrimaryMacro(e) and
+ optionalPlaceholderLocation = m and
+ optionalPlaceholderMessage = m.getName()
+ )
+ else (
+ extraMessage = "" and
+ optionalPlaceholderLocation = e and
+ optionalPlaceholderMessage = ""
+ )
)
select right,
- "The right hand operand of the shift operator shall lie in the range 0 to " + max_val + "."
+ "The possible range of the right operand of the shift operator (" + lowerBound + ".." + upperBound
+ + ") is outside the the valid shift range (0.." + max_val +
+ ") for the essential type of the left operand (" + essentialType + ")" + extraMessage + ".",
+ optionalPlaceholderLocation, optionalPlaceholderMessage
diff --git a/c/misra/src/rules/RULE-12-3/CommaOperatorShouldNotBeUsed.ql b/c/misra/src/rules/RULE-12-3/CommaOperatorShouldNotBeUsed.ql
index ec782d84f5..bccb382804 100644
--- a/c/misra/src/rules/RULE-12-3/CommaOperatorShouldNotBeUsed.ql
+++ b/c/misra/src/rules/RULE-12-3/CommaOperatorShouldNotBeUsed.ql
@@ -7,6 +7,7 @@
* @problem.severity recommendation
* @tags external/misra/id/rule-12-3
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-12-4/ConstantUnsignedIntegerExpressionsWrapAround.ql b/c/misra/src/rules/RULE-12-4/ConstantUnsignedIntegerExpressionsWrapAround.ql
index 5009ef292d..1ebbf184bb 100644
--- a/c/misra/src/rules/RULE-12-4/ConstantUnsignedIntegerExpressionsWrapAround.ql
+++ b/c/misra/src/rules/RULE-12-4/ConstantUnsignedIntegerExpressionsWrapAround.ql
@@ -14,6 +14,7 @@
* @tags external/misra/id/rule-12-4
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-12-5/SizeofOperatorUsedOnArrayTypeParam.ql b/c/misra/src/rules/RULE-12-5/SizeofOperatorUsedOnArrayTypeParam.ql
index 3eed267198..2e080419e1 100644
--- a/c/misra/src/rules/RULE-12-5/SizeofOperatorUsedOnArrayTypeParam.ql
+++ b/c/misra/src/rules/RULE-12-5/SizeofOperatorUsedOnArrayTypeParam.ql
@@ -7,6 +7,7 @@
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-12-5
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-13-1/InitializerListsContainPersistentSideEffects.ql b/c/misra/src/rules/RULE-13-1/InitializerListsContainPersistentSideEffects.ql
index 3cce2bb825..69ecbede58 100644
--- a/c/misra/src/rules/RULE-13-1/InitializerListsContainPersistentSideEffects.ql
+++ b/c/misra/src/rules/RULE-13-1/InitializerListsContainPersistentSideEffects.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-13-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-13-2/UnsequencedSideEffects.ql b/c/misra/src/rules/RULE-13-2/UnsequencedSideEffects.ql
index 2497e5d4a3..90b0315e88 100644
--- a/c/misra/src/rules/RULE-13-2/UnsequencedSideEffects.ql
+++ b/c/misra/src/rules/RULE-13-2/UnsequencedSideEffects.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-13-2
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-13-3/SideEffectAndCrementInFullExpression.ql b/c/misra/src/rules/RULE-13-3/SideEffectAndCrementInFullExpression.ql
index 3dd03120c8..173827e04e 100644
--- a/c/misra/src/rules/RULE-13-3/SideEffectAndCrementInFullExpression.ql
+++ b/c/misra/src/rules/RULE-13-3/SideEffectAndCrementInFullExpression.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-13-3
* readability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql b/c/misra/src/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
index 69a5d57f25..c840947b1f 100644
--- a/c/misra/src/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
+++ b/c/misra/src/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-13-4
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-13-5/PossibleSuppressedSideEffectInLogicOperatorOperand.ql b/c/misra/src/rules/RULE-13-5/PossibleSuppressedSideEffectInLogicOperatorOperand.ql
index 90faf9ec23..9a5b7b2b7b 100644
--- a/c/misra/src/rules/RULE-13-5/PossibleSuppressedSideEffectInLogicOperatorOperand.ql
+++ b/c/misra/src/rules/RULE-13-5/PossibleSuppressedSideEffectInLogicOperatorOperand.ql
@@ -9,6 +9,7 @@
* @problem.severity error
* @tags external/misra/id/rule-13-5
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-13-6/SizeofOperandWithSideEffect.ql b/c/misra/src/rules/RULE-13-6/SizeofOperandWithSideEffect.ql
index 10317b1169..ec1551c2a6 100644
--- a/c/misra/src/rules/RULE-13-6/SizeofOperandWithSideEffect.ql
+++ b/c/misra/src/rules/RULE-13-6/SizeofOperandWithSideEffect.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-13-6
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-14-1/LoopOverEssentiallyFloatType.ql b/c/misra/src/rules/RULE-14-1/LoopOverEssentiallyFloatType.ql
index 6a0f772f61..83d91dac63 100644
--- a/c/misra/src/rules/RULE-14-1/LoopOverEssentiallyFloatType.ql
+++ b/c/misra/src/rules/RULE-14-1/LoopOverEssentiallyFloatType.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-14-1
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-14-2/ForLoopNotWellFormed.ql b/c/misra/src/rules/RULE-14-2/ForLoopNotWellFormed.ql
index 106bd9b5c6..7b3dc3c8dc 100644
--- a/c/misra/src/rules/RULE-14-2/ForLoopNotWellFormed.ql
+++ b/c/misra/src/rules/RULE-14-2/ForLoopNotWellFormed.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-14-2
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-14-3/ControllingExprInvariant.ql b/c/misra/src/rules/RULE-14-3/ControllingExprInvariant.ql
index eb8e9ede82..1bd2708750 100644
--- a/c/misra/src/rules/RULE-14-3/ControllingExprInvariant.ql
+++ b/c/misra/src/rules/RULE-14-3/ControllingExprInvariant.ql
@@ -10,6 +10,7 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-14-4/NonBooleanIfCondition.ql b/c/misra/src/rules/RULE-14-4/NonBooleanIfCondition.ql
index 87d9d31512..f9a24d9492 100644
--- a/c/misra/src/rules/RULE-14-4/NonBooleanIfCondition.ql
+++ b/c/misra/src/rules/RULE-14-4/NonBooleanIfCondition.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-14-4
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-14-4/NonBooleanIterationCondition.ql b/c/misra/src/rules/RULE-14-4/NonBooleanIterationCondition.ql
index b2644a7a92..8418993db2 100644
--- a/c/misra/src/rules/RULE-14-4/NonBooleanIterationCondition.ql
+++ b/c/misra/src/rules/RULE-14-4/NonBooleanIterationCondition.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-14-4
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-15-1/GotoStatementUsed.ql b/c/misra/src/rules/RULE-15-1/GotoStatementUsed.ql
index d1c9aadadd..84c7dbd408 100644
--- a/c/misra/src/rules/RULE-15-1/GotoStatementUsed.ql
+++ b/c/misra/src/rules/RULE-15-1/GotoStatementUsed.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-15-1
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-15-2/GotoLabelLocationCondition.ql b/c/misra/src/rules/RULE-15-2/GotoLabelLocationCondition.ql
index d12521dd7e..623fb9baed 100644
--- a/c/misra/src/rules/RULE-15-2/GotoLabelLocationCondition.ql
+++ b/c/misra/src/rules/RULE-15-2/GotoLabelLocationCondition.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-15-2
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-15-3/GotoLabelBlockCondition.ql b/c/misra/src/rules/RULE-15-3/GotoLabelBlockCondition.ql
index 1f9f066f53..a88f3170de 100644
--- a/c/misra/src/rules/RULE-15-3/GotoLabelBlockCondition.ql
+++ b/c/misra/src/rules/RULE-15-3/GotoLabelBlockCondition.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-15-3
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-15-4/LoopIterationCondition.ql b/c/misra/src/rules/RULE-15-4/LoopIterationCondition.ql
index ed541a68d0..b172a2c1ea 100644
--- a/c/misra/src/rules/RULE-15-4/LoopIterationCondition.ql
+++ b/c/misra/src/rules/RULE-15-4/LoopIterationCondition.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-15-4
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-15-5/FunctionReturnCondition.ql b/c/misra/src/rules/RULE-15-5/FunctionReturnCondition.ql
index 2fb5ad9d65..8e777d7332 100644
--- a/c/misra/src/rules/RULE-15-5/FunctionReturnCondition.ql
+++ b/c/misra/src/rules/RULE-15-5/FunctionReturnCondition.ql
@@ -9,6 +9,7 @@
* maintainability
* readability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-15-6/LoopCompoundCondition.ql b/c/misra/src/rules/RULE-15-6/LoopCompoundCondition.ql
index a3e30ec345..9cc5bf9dda 100644
--- a/c/misra/src/rules/RULE-15-6/LoopCompoundCondition.ql
+++ b/c/misra/src/rules/RULE-15-6/LoopCompoundCondition.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-15-6
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-15-6/SelectionCompoundCondition.ql b/c/misra/src/rules/RULE-15-6/SelectionCompoundCondition.ql
index d181ca2d1c..f84c142414 100644
--- a/c/misra/src/rules/RULE-15-6/SelectionCompoundCondition.ql
+++ b/c/misra/src/rules/RULE-15-6/SelectionCompoundCondition.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-15-6
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-15-6/SwitchCompoundCondition.ql b/c/misra/src/rules/RULE-15-6/SwitchCompoundCondition.ql
index 837bfb12c1..1d446f323f 100644
--- a/c/misra/src/rules/RULE-15-6/SwitchCompoundCondition.ql
+++ b/c/misra/src/rules/RULE-15-6/SwitchCompoundCondition.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-15-6
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-15-7/IfElseEndCondition.ql b/c/misra/src/rules/RULE-15-7/IfElseEndCondition.ql
index f3992d26f5..ee06f484fe 100644
--- a/c/misra/src/rules/RULE-15-7/IfElseEndCondition.ql
+++ b/c/misra/src/rules/RULE-15-7/IfElseEndCondition.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-15-7
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-16-1/SwitchCaseStartCondition.ql b/c/misra/src/rules/RULE-16-1/SwitchCaseStartCondition.ql
index e30ac1bd7b..4ceca23d8f 100644
--- a/c/misra/src/rules/RULE-16-1/SwitchCaseStartCondition.ql
+++ b/c/misra/src/rules/RULE-16-1/SwitchCaseStartCondition.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-16-1
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-16-1/SwitchStmtNotWellFormed.ql b/c/misra/src/rules/RULE-16-1/SwitchStmtNotWellFormed.ql
index 9da9242a78..644994562a 100644
--- a/c/misra/src/rules/RULE-16-1/SwitchStmtNotWellFormed.ql
+++ b/c/misra/src/rules/RULE-16-1/SwitchStmtNotWellFormed.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-16-1
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-16-2/NestSwitchLabelInSwitchStatement.ql b/c/misra/src/rules/RULE-16-2/NestSwitchLabelInSwitchStatement.ql
index df4b6fc93a..45ad0519bb 100644
--- a/c/misra/src/rules/RULE-16-2/NestSwitchLabelInSwitchStatement.ql
+++ b/c/misra/src/rules/RULE-16-2/NestSwitchLabelInSwitchStatement.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-16-2
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-16-3/BreakShallTerminateSwitchClause.ql b/c/misra/src/rules/RULE-16-3/BreakShallTerminateSwitchClause.ql
index e62fe8c8d4..5ff30b53e0 100644
--- a/c/misra/src/rules/RULE-16-3/BreakShallTerminateSwitchClause.ql
+++ b/c/misra/src/rules/RULE-16-3/BreakShallTerminateSwitchClause.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-16-3
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-16-4/EverySwitchShallHaveDefaultLabel.ql b/c/misra/src/rules/RULE-16-4/EverySwitchShallHaveDefaultLabel.ql
index a5d7c3cf2c..441e30b7e7 100644
--- a/c/misra/src/rules/RULE-16-4/EverySwitchShallHaveDefaultLabel.ql
+++ b/c/misra/src/rules/RULE-16-4/EverySwitchShallHaveDefaultLabel.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-16-4
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-16-5/DefaultNotFirstOrLastOfSwitch.ql b/c/misra/src/rules/RULE-16-5/DefaultNotFirstOrLastOfSwitch.ql
index f86e242ee3..5a93477b9a 100644
--- a/c/misra/src/rules/RULE-16-5/DefaultNotFirstOrLastOfSwitch.ql
+++ b/c/misra/src/rules/RULE-16-5/DefaultNotFirstOrLastOfSwitch.ql
@@ -6,6 +6,7 @@
* @precision very-high
* @problem.severity recommendation
* @tags external/misra/id/rule-16-5
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-16-6/SwitchClauseNumberCondition.ql b/c/misra/src/rules/RULE-16-6/SwitchClauseNumberCondition.ql
index 8ddb2e49b2..0259f8023d 100644
--- a/c/misra/src/rules/RULE-16-6/SwitchClauseNumberCondition.ql
+++ b/c/misra/src/rules/RULE-16-6/SwitchClauseNumberCondition.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-16-6
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-16-7/SwitchExpressionBoolCondition.ql b/c/misra/src/rules/RULE-16-7/SwitchExpressionBoolCondition.ql
index 9aeb50d26e..06be288e2c 100644
--- a/c/misra/src/rules/RULE-16-7/SwitchExpressionBoolCondition.ql
+++ b/c/misra/src/rules/RULE-16-7/SwitchExpressionBoolCondition.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-16-7
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-17-1/FeaturesOfStdarghUsed.ql b/c/misra/src/rules/RULE-17-1/FeaturesOfStdarghUsed.ql
index 1cde8b98f2..ddccb58ad1 100644
--- a/c/misra/src/rules/RULE-17-1/FeaturesOfStdarghUsed.ql
+++ b/c/misra/src/rules/RULE-17-1/FeaturesOfStdarghUsed.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-17-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.ql b/c/misra/src/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.ql
new file mode 100644
index 0000000000..1e32793c3f
--- /dev/null
+++ b/c/misra/src/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.ql
@@ -0,0 +1,27 @@
+/**
+ * @id c/misra/non-void-return-type-of-noreturn-function
+ * @name RULE-17-10: A function declared with _noreturn shall have a return type of void
+ * @description Function declared with _noreturn will by definition not return a value, and should
+ * be declared to return void.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity recommendation
+ * @tags external/misra/id/rule-17-10
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.Noreturn
+
+from NoreturnFunction f, Type returnType
+where
+ not isExcluded(f, NoReturnPackage::nonVoidReturnTypeOfNoreturnFunctionQuery()) and
+ returnType = f.getType() and
+ not returnType instanceof VoidType and
+ not f.isCompilerGenerated()
+select f,
+ "The function " + f.getName() + " is declared _noreturn but has a return type of " +
+ returnType.toString() + "."
diff --git a/c/misra/src/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.ql b/c/misra/src/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.ql
new file mode 100644
index 0000000000..4dd939effe
--- /dev/null
+++ b/c/misra/src/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.ql
@@ -0,0 +1,29 @@
+/**
+ * @id c/misra/function-with-no-returning-branch-should-be-noreturn
+ * @name RULE-17-11: A function without a branch that returns shall be declared with _Noreturn
+ * @description Functions which cannot return should be declared with _Noreturn.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity recommendation
+ * @tags external/misra/id/rule-17-11
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/advisory
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.Noreturn
+
+from Function f
+where
+ not isExcluded(f, NoReturnPackage::functionWithNoReturningBranchShouldBeNoreturnQuery()) and
+ not f instanceof NoreturnFunction and
+ not mayReturn(f) and
+ f.hasDefinition() and
+ not f.getName() = "main" and // Allowed exception; _Noreturn main() is undefined behavior.
+ // Harden against c++ cases.
+ not f.isFromUninstantiatedTemplate(_) and
+ not f.isDeleted() and
+ not f.isCompilerGenerated()
+select f, "The function " + f.getName() + " cannot return and should be declared as _Noreturn."
diff --git a/c/misra/src/rules/RULE-17-12/FunctionAddressesShouldAddressOperator.ql b/c/misra/src/rules/RULE-17-12/FunctionAddressesShouldAddressOperator.ql
new file mode 100644
index 0000000000..c95612b7ba
--- /dev/null
+++ b/c/misra/src/rules/RULE-17-12/FunctionAddressesShouldAddressOperator.ql
@@ -0,0 +1,33 @@
+/**
+ * @id c/misra/function-addresses-should-address-operator
+ * @name RULE-17-12: A function identifier should only be called with a parenthesized parameter list or used with a &
+ * @description A function identifier should only be called with a parenthesized parameter list or
+ * used with a & (address-of).
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-17-12
+ * readability
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/advisory
+ */
+
+import cpp
+import codingstandards.c.misra
+
+predicate isImplicitlyAddressed(FunctionAccess access) {
+ not access.getParent() instanceof AddressOfExpr and
+ // Note: the following *seems* to only exist in c++ codebases, for instance,
+ // when calling a member. In c, this syntax should always extract as a
+ // [FunctionCall] rather than a [ExprCall] of a [FunctionAccess]. Still, this
+ // is a good pattern to be defensive against.
+ not exists(ExprCall call | call.getExpr() = access)
+}
+
+from FunctionAccess funcAccess
+where
+ not isExcluded(funcAccess, FunctionTypesPackage::functionAddressesShouldAddressOperatorQuery()) and
+ isImplicitlyAddressed(funcAccess)
+select funcAccess,
+ "The address of function " + funcAccess.getTarget().getName() +
+ " is taken without the & operator."
diff --git a/c/misra/src/rules/RULE-17-2/RecursiveFunctionCondition.ql b/c/misra/src/rules/RULE-17-2/RecursiveFunctionCondition.ql
index b6f13c4d1f..c7cb818119 100644
--- a/c/misra/src/rules/RULE-17-2/RecursiveFunctionCondition.ql
+++ b/c/misra/src/rules/RULE-17-2/RecursiveFunctionCondition.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-17-2
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-17-3/FunctionDeclaredImplicitly.ql b/c/misra/src/rules/RULE-17-3/FunctionDeclaredImplicitly.ql
index 304d0a9bf6..af6c9bccad 100644
--- a/c/misra/src/rules/RULE-17-3/FunctionDeclaredImplicitly.ql
+++ b/c/misra/src/rules/RULE-17-3/FunctionDeclaredImplicitly.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-17-3
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-17-4/NonVoidFunctionReturnCondition.ql b/c/misra/src/rules/RULE-17-4/NonVoidFunctionReturnCondition.ql
index 24329e5ab5..1529a403c9 100644
--- a/c/misra/src/rules/RULE-17-4/NonVoidFunctionReturnCondition.ql
+++ b/c/misra/src/rules/RULE-17-4/NonVoidFunctionReturnCondition.ql
@@ -10,6 +10,7 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql
index 208e8153d6..bb29be50ac 100644
--- a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql
+++ b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-17-5
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-17-6/UseOfArrayStatic.ql b/c/misra/src/rules/RULE-17-6/UseOfArrayStatic.ql
index 876321c455..0a1232b6ad 100644
--- a/c/misra/src/rules/RULE-17-6/UseOfArrayStatic.ql
+++ b/c/misra/src/rules/RULE-17-6/UseOfArrayStatic.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-17-6
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql
index 02d0a54ec1..42b0d7a2e2 100644
--- a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql
+++ b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-17-7
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-17-8/ModificationOfFunctionParameter.ql b/c/misra/src/rules/RULE-17-8/ModificationOfFunctionParameter.ql
index 6867455a45..95cddb57d3 100644
--- a/c/misra/src/rules/RULE-17-8/ModificationOfFunctionParameter.ql
+++ b/c/misra/src/rules/RULE-17-8/ModificationOfFunctionParameter.ql
@@ -9,6 +9,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-17-8
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-17-9/ReturnStatementInNoreturnFunction.ql b/c/misra/src/rules/RULE-17-9/ReturnStatementInNoreturnFunction.ql
new file mode 100644
index 0000000000..dedac9da9e
--- /dev/null
+++ b/c/misra/src/rules/RULE-17-9/ReturnStatementInNoreturnFunction.ql
@@ -0,0 +1,22 @@
+/**
+ * @id c/misra/return-statement-in-noreturn-function
+ * @name RULE-17-9: Verify that a function declared with _Noreturn does not return
+ * @description Returning inside a function declared with _Noreturn is undefined behavior.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-17-9
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/mandatory
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.rules.functionnoreturnattributecondition.FunctionNoReturnAttributeCondition
+
+class ReturnStatementInNoreturnFunctionQuery extends FunctionNoReturnAttributeConditionSharedQuery {
+ ReturnStatementInNoreturnFunctionQuery() {
+ this = NoReturnPackage::returnStatementInNoreturnFunctionQuery()
+ }
+}
diff --git a/c/misra/src/rules/RULE-18-1/PointerAndDerivedPointerMustAddressSameArray.ql b/c/misra/src/rules/RULE-18-1/PointerAndDerivedPointerMustAddressSameArray.ql
index f17d596ead..c8944bd30d 100644
--- a/c/misra/src/rules/RULE-18-1/PointerAndDerivedPointerMustAddressSameArray.ql
+++ b/c/misra/src/rules/RULE-18-1/PointerAndDerivedPointerMustAddressSameArray.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-18-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-18-2/SubtractionBetweenPointersMustAddressSameArray.ql b/c/misra/src/rules/RULE-18-2/SubtractionBetweenPointersMustAddressSameArray.ql
index b6fbb31f1c..ec3a30d5ba 100644
--- a/c/misra/src/rules/RULE-18-2/SubtractionBetweenPointersMustAddressSameArray.ql
+++ b/c/misra/src/rules/RULE-18-2/SubtractionBetweenPointersMustAddressSameArray.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-18-2
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-18-3/RelationalOperatorComparesPointerToDifferentArray.ql b/c/misra/src/rules/RULE-18-3/RelationalOperatorComparesPointerToDifferentArray.ql
index d7785a2d0e..4624cea616 100644
--- a/c/misra/src/rules/RULE-18-3/RelationalOperatorComparesPointerToDifferentArray.ql
+++ b/c/misra/src/rules/RULE-18-3/RelationalOperatorComparesPointerToDifferentArray.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-18-3
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-18-4/DoNotUseAdditionOrSubtractionOperatorsOnPointers.ql b/c/misra/src/rules/RULE-18-4/DoNotUseAdditionOrSubtractionOperatorsOnPointers.ql
index a5f8a85ff1..a1a1ad367b 100644
--- a/c/misra/src/rules/RULE-18-4/DoNotUseAdditionOrSubtractionOperatorsOnPointers.ql
+++ b/c/misra/src/rules/RULE-18-4/DoNotUseAdditionOrSubtractionOperatorsOnPointers.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-18-4
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-18-5/NoMoreThanTwoLevelsOfPointerNestingInDeclarations.ql b/c/misra/src/rules/RULE-18-5/NoMoreThanTwoLevelsOfPointerNestingInDeclarations.ql
index 7a847acbfa..f467c41804 100644
--- a/c/misra/src/rules/RULE-18-5/NoMoreThanTwoLevelsOfPointerNestingInDeclarations.ql
+++ b/c/misra/src/rules/RULE-18-5/NoMoreThanTwoLevelsOfPointerNestingInDeclarations.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-18-5
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-18-6/AutomaticStorageObjectAddressCopiedToOtherObject.ql b/c/misra/src/rules/RULE-18-6/AutomaticStorageObjectAddressCopiedToOtherObject.ql
index 6d947efb16..efbc8d1334 100644
--- a/c/misra/src/rules/RULE-18-6/AutomaticStorageObjectAddressCopiedToOtherObject.ql
+++ b/c/misra/src/rules/RULE-18-6/AutomaticStorageObjectAddressCopiedToOtherObject.ql
@@ -9,6 +9,7 @@
* @problem.severity error
* @tags external/misra/id/rule-18-6
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-18-7/FlexibleArrayMembersDeclared.ql b/c/misra/src/rules/RULE-18-7/FlexibleArrayMembersDeclared.ql
index 5ae2c9b9c6..73f0732ba5 100644
--- a/c/misra/src/rules/RULE-18-7/FlexibleArrayMembersDeclared.ql
+++ b/c/misra/src/rules/RULE-18-7/FlexibleArrayMembersDeclared.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-18-7
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-18-8/VariableLengthArrayTypesUsed.ql b/c/misra/src/rules/RULE-18-8/VariableLengthArrayTypesUsed.ql
index 00d02cdc02..a7c25ed35e 100644
--- a/c/misra/src/rules/RULE-18-8/VariableLengthArrayTypesUsed.ql
+++ b/c/misra/src/rules/RULE-18-8/VariableLengthArrayTypesUsed.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-18-8
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-19-1/ObjectAssignedToAnOverlappingObject.ql b/c/misra/src/rules/RULE-19-1/ObjectAssignedToAnOverlappingObject.ql
index b39ce4fba4..31c24dcdd8 100644
--- a/c/misra/src/rules/RULE-19-1/ObjectAssignedToAnOverlappingObject.ql
+++ b/c/misra/src/rules/RULE-19-1/ObjectAssignedToAnOverlappingObject.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-19-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-19-1/ObjectCopiedToAnOverlappingObject.ql b/c/misra/src/rules/RULE-19-1/ObjectCopiedToAnOverlappingObject.ql
index bee9b41e2c..e3e85faf34 100644
--- a/c/misra/src/rules/RULE-19-1/ObjectCopiedToAnOverlappingObject.ql
+++ b/c/misra/src/rules/RULE-19-1/ObjectCopiedToAnOverlappingObject.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-19-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-19-2/UnionKeywordShouldNotBeUsed.ql b/c/misra/src/rules/RULE-19-2/UnionKeywordShouldNotBeUsed.ql
index b3028d9add..14d01c47e3 100644
--- a/c/misra/src/rules/RULE-19-2/UnionKeywordShouldNotBeUsed.ql
+++ b/c/misra/src/rules/RULE-19-2/UnionKeywordShouldNotBeUsed.ql
@@ -7,6 +7,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-19-2
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-2-1/UnreachableCode.ql b/c/misra/src/rules/RULE-2-1/UnreachableCode.ql
index 5de46fd9ea..020338913a 100644
--- a/c/misra/src/rules/RULE-2-1/UnreachableCode.ql
+++ b/c/misra/src/rules/RULE-2-1/UnreachableCode.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-2-1
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-2-2/DeadCode.ql b/c/misra/src/rules/RULE-2-2/DeadCode.ql
index c9ecb5e934..97c3808607 100644
--- a/c/misra/src/rules/RULE-2-2/DeadCode.ql
+++ b/c/misra/src/rules/RULE-2-2/DeadCode.ql
@@ -9,13 +9,89 @@
* @tags external/misra/id/rule-2-2
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.cpp.rules.deadcode.DeadCode
+import codingstandards.cpp.alertreporting.HoldsForAllCopies
+import codingstandards.cpp.deadcode.UselessAssignments
-class MisraCDeadCodeQuery extends DeadCodeSharedQuery {
- MisraCDeadCodeQuery() { this = DeadCodePackage::deadCodeQuery() }
+/**
+ * Gets an explicit cast from `e` if one exists.
+ */
+Cast getExplicitCast(Expr e) {
+ exists(Conversion c | c = e.getExplicitlyConverted() |
+ result = c
+ or
+ result = c.(ParenthesisExpr).getExpr()
+ )
+}
+
+class ExprStmtExpr extends Expr {
+ ExprStmtExpr() { exists(ExprStmt es | es.getExpr() = this) }
+}
+
+/**
+ * An "operation" as defined by MISRA C Rule 2.2 that is dead, i.e. it's removal has no effect on
+ * the behaviour of the program.
+ */
+class DeadOperationInstance extends Expr {
+ string description;
+
+ DeadOperationInstance() {
+ // Exclude cases nested within macro expansions, because the code may be "live" in other
+ // expansions
+ isNotWithinMacroExpansion(this) and
+ exists(ExprStmtExpr e |
+ if exists(getExplicitCast(e))
+ then
+ this = getExplicitCast(e) and
+ // void conversions are permitted
+ not getExplicitCast(e) instanceof VoidConversion and
+ description = "Cast operation is unused"
+ else (
+ this = e and
+ (
+ if e instanceof Assignment
+ then
+ exists(SsaDefinition sd, LocalScopeVariable v |
+ e = sd.getDefinition() and
+ sd.getDefiningValue(v).isPure() and
+ // The definition is useless
+ isUselessSsaDefinition(sd, v) and
+ description = "Assignment to " + v.getName() + " is unused and has no side effects"
+ )
+ else (
+ e.isPure() and
+ description = "Result of operation is unused and has no side effects"
+ )
+ )
+ )
+ )
+ }
+
+ string getDescription() { result = description }
}
+
+class DeadOperation = HoldsForAllCopies::LogicalResultElement;
+
+from
+ DeadOperation deadOperation, DeadOperationInstance instance, string message, Element explainer,
+ string explainerDescription
+where
+ not isExcluded(instance, DeadCodePackage::deadCodeQuery()) and
+ instance = deadOperation.getAnElementInstance() and
+ if instance instanceof FunctionCall
+ then
+ message = instance.getDescription() + " from call to function $@" and
+ explainer = instance.(FunctionCall).getTarget() and
+ explainerDescription = explainer.(Function).getName()
+ else (
+ message = instance.getDescription() and
+ // Ignore the explainer
+ explainer = instance and
+ explainerDescription = ""
+ )
+select deadOperation, message + ".", explainer, explainerDescription
diff --git a/c/misra/src/rules/RULE-2-3/UnusedTypeDeclarations.ql b/c/misra/src/rules/RULE-2-3/UnusedTypeDeclarations.ql
index 3192ee960f..b4c6bbf42c 100644
--- a/c/misra/src/rules/RULE-2-3/UnusedTypeDeclarations.ql
+++ b/c/misra/src/rules/RULE-2-3/UnusedTypeDeclarations.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-2-3
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-2-4/UnusedTagDeclaration.ql b/c/misra/src/rules/RULE-2-4/UnusedTagDeclaration.ql
index c10985f28c..08fe2568e9 100644
--- a/c/misra/src/rules/RULE-2-4/UnusedTagDeclaration.ql
+++ b/c/misra/src/rules/RULE-2-4/UnusedTagDeclaration.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-2-4
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-2-5/UnusedMacroDeclaration.ql b/c/misra/src/rules/RULE-2-5/UnusedMacroDeclaration.ql
index ed2b1f6065..2b5a8e8c1d 100644
--- a/c/misra/src/rules/RULE-2-5/UnusedMacroDeclaration.ql
+++ b/c/misra/src/rules/RULE-2-5/UnusedMacroDeclaration.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-2-5
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
@@ -18,7 +19,18 @@ import codingstandards.c.misra
from Macro m
where
not isExcluded(m, DeadCodePackage::unusedMacroDeclarationQuery()) and
+ // We consider a macro "used" if there is a macro access
not exists(MacroAccess ma | ma.getMacro() = m) and
+ // Or if there exists a check whether the macro is defined which the extractor
+ // hasn't been able to tie to a macro (usually because this use came before
+ // the macro was defined e.g. a header guard)
+ not exists(PreprocessorBranchDirective bd |
+ // Covers the #ifdef and #ifndef cases
+ bd.getHead() = m.getName()
+ or
+ // Covers the use of defined() to check if a macro is defined
+ m.getName() = bd.getHead().regexpCapture(".*defined *\\(? *([^\\s()]+) *\\)?\\.*", 1)
+ ) and
// We consider a macro "used" if the name is undef-ed at some point in the same file, or a file
// that includes the file defining the macro. This will over approximate use in the case of a
// macro which is defined, then undefined, then re-defined but not used.
diff --git a/c/misra/src/rules/RULE-2-6/UnusedLabelDeclaration.ql b/c/misra/src/rules/RULE-2-6/UnusedLabelDeclaration.ql
index 4ab96707e4..7838c5fc1f 100644
--- a/c/misra/src/rules/RULE-2-6/UnusedLabelDeclaration.ql
+++ b/c/misra/src/rules/RULE-2-6/UnusedLabelDeclaration.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-2-6
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-2-7/UnusedParameter.ql b/c/misra/src/rules/RULE-2-7/UnusedParameter.ql
index b9c2f32f60..e27caee50b 100644
--- a/c/misra/src/rules/RULE-2-7/UnusedParameter.ql
+++ b/c/misra/src/rules/RULE-2-7/UnusedParameter.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-2-7
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-20-1/IncludeDirectivesPrecededByDirectivesOrComments.ql b/c/misra/src/rules/RULE-20-1/IncludeDirectivesPrecededByDirectivesOrComments.ql
index aa0d733eb2..ba78abcb5e 100644
--- a/c/misra/src/rules/RULE-20-1/IncludeDirectivesPrecededByDirectivesOrComments.ql
+++ b/c/misra/src/rules/RULE-20-1/IncludeDirectivesPrecededByDirectivesOrComments.ql
@@ -8,6 +8,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-20-1
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-20-10/PreprocessorHashOperatorsShouldNotBeUsed.ql b/c/misra/src/rules/RULE-20-10/PreprocessorHashOperatorsShouldNotBeUsed.ql
index f0d82928fb..016589af94 100644
--- a/c/misra/src/rules/RULE-20-10/PreprocessorHashOperatorsShouldNotBeUsed.ql
+++ b/c/misra/src/rules/RULE-20-10/PreprocessorHashOperatorsShouldNotBeUsed.ql
@@ -8,6 +8,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-20-10
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.ql b/c/misra/src/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.ql
index 42ea398e14..fc87186d3e 100644
--- a/c/misra/src/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.ql
+++ b/c/misra/src/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.ql
@@ -8,6 +8,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-20-11
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-20-12/MacroParameterUsedAsHashOperand.ql b/c/misra/src/rules/RULE-20-12/MacroParameterUsedAsHashOperand.ql
index 8b9d6ca763..da66f66fb2 100644
--- a/c/misra/src/rules/RULE-20-12/MacroParameterUsedAsHashOperand.ql
+++ b/c/misra/src/rules/RULE-20-12/MacroParameterUsedAsHashOperand.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-20-12
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-20-2/ForbiddenCharactersInHeaderFileName.ql b/c/misra/src/rules/RULE-20-2/ForbiddenCharactersInHeaderFileName.ql
index a9b27e8669..d9942c3e56 100644
--- a/c/misra/src/rules/RULE-20-2/ForbiddenCharactersInHeaderFileName.ql
+++ b/c/misra/src/rules/RULE-20-2/ForbiddenCharactersInHeaderFileName.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-20-2
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql b/c/misra/src/rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql
index 6b9ae71120..210e081bb1 100644
--- a/c/misra/src/rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql
+++ b/c/misra/src/rules/RULE-20-4/MacroDefinedWithTheSameNameAsKeyword.ql
@@ -11,6 +11,7 @@
* correctness
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-20-5/UndefShouldNotBeUsed.ql b/c/misra/src/rules/RULE-20-5/UndefShouldNotBeUsed.ql
index c253c795e8..15bec51bf8 100644
--- a/c/misra/src/rules/RULE-20-5/UndefShouldNotBeUsed.ql
+++ b/c/misra/src/rules/RULE-20-5/UndefShouldNotBeUsed.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-20-5
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-20-6/FunctionLikeMacroArgsContainHashTokenCQuery.ql b/c/misra/src/rules/RULE-20-6/FunctionLikeMacroArgsContainHashTokenCQuery.ql
index 3e212dc972..e0fc8e4510 100644
--- a/c/misra/src/rules/RULE-20-6/FunctionLikeMacroArgsContainHashTokenCQuery.ql
+++ b/c/misra/src/rules/RULE-20-6/FunctionLikeMacroArgsContainHashTokenCQuery.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-20-6
* readability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-20-7/MacroParameterNotEnclosedInParenthesesCQuery.ql b/c/misra/src/rules/RULE-20-7/MacroParameterNotEnclosedInParenthesesCQuery.ql
index ad4882d07c..e557f99a18 100644
--- a/c/misra/src/rules/RULE-20-7/MacroParameterNotEnclosedInParenthesesCQuery.ql
+++ b/c/misra/src/rules/RULE-20-7/MacroParameterNotEnclosedInParenthesesCQuery.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-20-7
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-20-8/ControllingExpressionIfDirective.ql b/c/misra/src/rules/RULE-20-8/ControllingExpressionIfDirective.ql
index cd55e03ee0..5e2c1fbc27 100644
--- a/c/misra/src/rules/RULE-20-8/ControllingExpressionIfDirective.ql
+++ b/c/misra/src/rules/RULE-20-8/ControllingExpressionIfDirective.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-20-8
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-20-9/IdentifiersUsedInPreprocessorExpression.ql b/c/misra/src/rules/RULE-20-9/IdentifiersUsedInPreprocessorExpression.ql
index 15ca323038..be6f3c00f3 100644
--- a/c/misra/src/rules/RULE-20-9/IdentifiersUsedInPreprocessorExpression.ql
+++ b/c/misra/src/rules/RULE-20-9/IdentifiersUsedInPreprocessorExpression.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-20-9
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-1/DefineAndUndefUsedOnReservedIdentifierOrMacroName.ql b/c/misra/src/rules/RULE-21-1/DefineAndUndefUsedOnReservedIdentifierOrMacroName.ql
index b37b5cb92e..86d8426df8 100644
--- a/c/misra/src/rules/RULE-21-1/DefineAndUndefUsedOnReservedIdentifierOrMacroName.ql
+++ b/c/misra/src/rules/RULE-21-1/DefineAndUndefUsedOnReservedIdentifierOrMacroName.ql
@@ -10,6 +10,7 @@
* correctness
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-10/StandardLibraryTimeAndDateFunctionsUsed.ql b/c/misra/src/rules/RULE-21-10/StandardLibraryTimeAndDateFunctionsUsed.ql
index c519ebe701..0ad9c350f2 100644
--- a/c/misra/src/rules/RULE-21-10/StandardLibraryTimeAndDateFunctionsUsed.ql
+++ b/c/misra/src/rules/RULE-21-10/StandardLibraryTimeAndDateFunctionsUsed.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-21-10
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-11/StandardHeaderFileTgmathhUsed.ql b/c/misra/src/rules/RULE-21-11/StandardHeaderFileTgmathhUsed.ql
index 5a33f94fb6..1c6b1bcd3d 100644
--- a/c/misra/src/rules/RULE-21-11/StandardHeaderFileTgmathhUsed.ql
+++ b/c/misra/src/rules/RULE-21-11/StandardHeaderFileTgmathhUsed.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-21-11
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-12/ExceptionHandlingFeaturesOfFenvhUsed.ql b/c/misra/src/rules/RULE-21-12/ExceptionHandlingFeaturesOfFenvhUsed.ql
index 727cb190e9..33da2f5d03 100644
--- a/c/misra/src/rules/RULE-21-12/ExceptionHandlingFeaturesOfFenvhUsed.ql
+++ b/c/misra/src/rules/RULE-21-12/ExceptionHandlingFeaturesOfFenvhUsed.ql
@@ -8,6 +8,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-21-12
* correctness
+ * external/misra/c/2012/amendment2
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-21-13/CtypeFunctionArgNotUnsignedCharOrEof.ql b/c/misra/src/rules/RULE-21-13/CtypeFunctionArgNotUnsignedCharOrEof.ql
index 70ec91e3c1..b7ccf534fa 100644
--- a/c/misra/src/rules/RULE-21-13/CtypeFunctionArgNotUnsignedCharOrEof.ql
+++ b/c/misra/src/rules/RULE-21-13/CtypeFunctionArgNotUnsignedCharOrEof.ql
@@ -7,6 +7,7 @@
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-21-13
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.ql b/c/misra/src/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.ql
index 44e21d14db..c51ff10744 100644
--- a/c/misra/src/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.ql
+++ b/c/misra/src/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-21-14
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-15/MemcpyMemmoveMemcmpArgNotPointersToCompatibleTypes.ql b/c/misra/src/rules/RULE-21-15/MemcpyMemmoveMemcmpArgNotPointersToCompatibleTypes.ql
index 2c585d8f10..f5d8057b3a 100644
--- a/c/misra/src/rules/RULE-21-15/MemcpyMemmoveMemcmpArgNotPointersToCompatibleTypes.ql
+++ b/c/misra/src/rules/RULE-21-15/MemcpyMemmoveMemcmpArgNotPointersToCompatibleTypes.ql
@@ -7,12 +7,13 @@
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-21-15
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
class MemCmpMoveCpy extends Function {
// Couldn't extend BuiltInFunction because it misses `memcmp`
diff --git a/c/misra/src/rules/RULE-21-16/MemcmpOnInappropriateEssentialTypeArgs.ql b/c/misra/src/rules/RULE-21-16/MemcmpOnInappropriateEssentialTypeArgs.ql
index 1a939e920c..cb70567660 100644
--- a/c/misra/src/rules/RULE-21-16/MemcmpOnInappropriateEssentialTypeArgs.ql
+++ b/c/misra/src/rules/RULE-21-16/MemcmpOnInappropriateEssentialTypeArgs.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-21-16
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-17/StringFunctionPointerArgumentOutOfBounds.ql b/c/misra/src/rules/RULE-21-17/StringFunctionPointerArgumentOutOfBounds.ql
index a4850781f6..31d3434c58 100644
--- a/c/misra/src/rules/RULE-21-17/StringFunctionPointerArgumentOutOfBounds.ql
+++ b/c/misra/src/rules/RULE-21-17/StringFunctionPointerArgumentOutOfBounds.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-21-17
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-21-18/StringLibrarySizeArgumentOutOfBounds.ql b/c/misra/src/rules/RULE-21-18/StringLibrarySizeArgumentOutOfBounds.ql
index 3554b2791e..22ccc14b69 100644
--- a/c/misra/src/rules/RULE-21-18/StringLibrarySizeArgumentOutOfBounds.ql
+++ b/c/misra/src/rules/RULE-21-18/StringLibrarySizeArgumentOutOfBounds.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-21-18
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-21-19/ValuesReturnedByLocaleSettingUsedAsPtrToConst.ql b/c/misra/src/rules/RULE-21-19/ValuesReturnedByLocaleSettingUsedAsPtrToConst.ql
index 0e02cc1d84..6fa3ad92be 100644
--- a/c/misra/src/rules/RULE-21-19/ValuesReturnedByLocaleSettingUsedAsPtrToConst.ql
+++ b/c/misra/src/rules/RULE-21-19/ValuesReturnedByLocaleSettingUsedAsPtrToConst.ql
@@ -9,6 +9,7 @@
* @problem.severity error
* @tags external/misra/id/rule-21-19
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.ql b/c/misra/src/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.ql
index 89140222da..80ad8386bc 100644
--- a/c/misra/src/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.ql
+++ b/c/misra/src/rules/RULE-21-2/DoNotDeclareAReservedIdentifier.ql
@@ -9,6 +9,7 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-20/CallToSetlocaleInvalidatesOldPointers.ql b/c/misra/src/rules/RULE-21-20/CallToSetlocaleInvalidatesOldPointers.ql
index c193e899db..6441add7fc 100644
--- a/c/misra/src/rules/RULE-21-20/CallToSetlocaleInvalidatesOldPointers.ql
+++ b/c/misra/src/rules/RULE-21-20/CallToSetlocaleInvalidatesOldPointers.ql
@@ -9,6 +9,7 @@
* @problem.severity error
* @tags external/misra/id/rule-21-20
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-21-20/CallToSetlocaleInvalidatesOldPointersWarn.ql b/c/misra/src/rules/RULE-21-20/CallToSetlocaleInvalidatesOldPointersWarn.ql
index 0bbcb045d9..e7e97e2639 100644
--- a/c/misra/src/rules/RULE-21-20/CallToSetlocaleInvalidatesOldPointersWarn.ql
+++ b/c/misra/src/rules/RULE-21-20/CallToSetlocaleInvalidatesOldPointersWarn.ql
@@ -9,6 +9,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-21-20
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-21-21/SystemOfStdlibhUsed.ql b/c/misra/src/rules/RULE-21-21/SystemOfStdlibhUsed.ql
index b38f159c14..81dd6ba1a3 100644
--- a/c/misra/src/rules/RULE-21-21/SystemOfStdlibhUsed.ql
+++ b/c/misra/src/rules/RULE-21-21/SystemOfStdlibhUsed.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-21-21
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-24/CallToBannedRandomFunction.ql b/c/misra/src/rules/RULE-21-24/CallToBannedRandomFunction.ql
new file mode 100644
index 0000000000..8066cc80cb
--- /dev/null
+++ b/c/misra/src/rules/RULE-21-24/CallToBannedRandomFunction.ql
@@ -0,0 +1,23 @@
+/**
+ * @id c/misra/call-to-banned-random-function
+ * @name RULE-21-24: The random number generator functions of shall not be used
+ * @description The standard functions rand() and srand() will not give high quality random results
+ * in all implementations and are therefore banned.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-21-24
+ * security
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+
+from FunctionCall call, string name
+where
+ not isExcluded(call, Banned2Package::callToBannedRandomFunctionQuery()) and
+ name = ["rand", "srand"] and
+ call.getTarget().hasGlobalOrStdName(name)
+select call, "Call to banned random number generation function '" + name + "'."
diff --git a/c/misra/src/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.ql b/c/misra/src/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.ql
index ed3317b696..ab3ba3e328 100644
--- a/c/misra/src/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.ql
+++ b/c/misra/src/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-21-3
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql b/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql
index 6de73499c0..88ad0aa6db 100644
--- a/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql
+++ b/c/misra/src/rules/RULE-21-4/StandardHeaderFileUsedSetjmph.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-21-4
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-5/StandardHeaderFileUsedSignalh.ql b/c/misra/src/rules/RULE-21-5/StandardHeaderFileUsedSignalh.ql
index 004060b5a5..d22ee55742 100644
--- a/c/misra/src/rules/RULE-21-5/StandardHeaderFileUsedSignalh.ql
+++ b/c/misra/src/rules/RULE-21-5/StandardHeaderFileUsedSignalh.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-21-5
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.ql b/c/misra/src/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.ql
index 6ef8c84cfe..6395ddc5ac 100644
--- a/c/misra/src/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.ql
+++ b/c/misra/src/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-21-6
* security
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.ql b/c/misra/src/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.ql
index 7263e91d53..ce781403b1 100644
--- a/c/misra/src/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.ql
+++ b/c/misra/src/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-21-7
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-8/TerminationFunctionsOfStdlibhUsed.ql b/c/misra/src/rules/RULE-21-8/TerminationFunctionsOfStdlibhUsed.ql
index 3414e82ab2..cbc7dd5a92 100644
--- a/c/misra/src/rules/RULE-21-8/TerminationFunctionsOfStdlibhUsed.ql
+++ b/c/misra/src/rules/RULE-21-8/TerminationFunctionsOfStdlibhUsed.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-21-8
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-8/TerminationMacrosOfStdlibhUsed.ql b/c/misra/src/rules/RULE-21-8/TerminationMacrosOfStdlibhUsed.ql
index 2f83ec6b70..7a911c1525 100644
--- a/c/misra/src/rules/RULE-21-8/TerminationMacrosOfStdlibhUsed.ql
+++ b/c/misra/src/rules/RULE-21-8/TerminationMacrosOfStdlibhUsed.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-21-8
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-21-9/BsearchAndQsortOfStdlibhUsed.ql b/c/misra/src/rules/RULE-21-9/BsearchAndQsortOfStdlibhUsed.ql
index b446b7f3f6..6759fa93d1 100644
--- a/c/misra/src/rules/RULE-21-9/BsearchAndQsortOfStdlibhUsed.ql
+++ b/c/misra/src/rules/RULE-21-9/BsearchAndQsortOfStdlibhUsed.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-21-9
* security
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-22-1/CloseFileHandleWhenNoLongerNeededMisra.ql b/c/misra/src/rules/RULE-22-1/CloseFileHandleWhenNoLongerNeededMisra.ql
index c756bc2526..d888d87b6c 100644
--- a/c/misra/src/rules/RULE-22-1/CloseFileHandleWhenNoLongerNeededMisra.ql
+++ b/c/misra/src/rules/RULE-22-1/CloseFileHandleWhenNoLongerNeededMisra.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-22-1
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-22-1/FreeMemoryWhenNoLongerNeededMisra.ql b/c/misra/src/rules/RULE-22-1/FreeMemoryWhenNoLongerNeededMisra.ql
index 1650590559..ca5853dac9 100644
--- a/c/misra/src/rules/RULE-22-1/FreeMemoryWhenNoLongerNeededMisra.ql
+++ b/c/misra/src/rules/RULE-22-1/FreeMemoryWhenNoLongerNeededMisra.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-22-1
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-22-10/OnlyTestErrnoRightAfterErrnoSettingFunction.ql b/c/misra/src/rules/RULE-22-10/OnlyTestErrnoRightAfterErrnoSettingFunction.ql
index eab5a0c089..50e5350936 100644
--- a/c/misra/src/rules/RULE-22-10/OnlyTestErrnoRightAfterErrnoSettingFunction.ql
+++ b/c/misra/src/rules/RULE-22-10/OnlyTestErrnoRightAfterErrnoSettingFunction.ql
@@ -9,6 +9,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-22-10
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-22-2/OnlyFreeMemoryAllocatedDynamicallyMisra.ql b/c/misra/src/rules/RULE-22-2/OnlyFreeMemoryAllocatedDynamicallyMisra.ql
index a149103c9a..cdbe8e2c16 100644
--- a/c/misra/src/rules/RULE-22-2/OnlyFreeMemoryAllocatedDynamicallyMisra.ql
+++ b/c/misra/src/rules/RULE-22-2/OnlyFreeMemoryAllocatedDynamicallyMisra.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-22-2
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql b/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql
index c01afea39f..ee103ca6dc 100644
--- a/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql
+++ b/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-22-3
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql b/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql
index 6dc3b3ee71..19bad99baa 100644
--- a/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql
+++ b/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-22-4
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-22-5/PointerToAFileObjectDereferenced.ql b/c/misra/src/rules/RULE-22-5/PointerToAFileObjectDereferenced.ql
index 86e0b76e21..05cc4e3433 100644
--- a/c/misra/src/rules/RULE-22-5/PointerToAFileObjectDereferenced.ql
+++ b/c/misra/src/rules/RULE-22-5/PointerToAFileObjectDereferenced.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-22-5
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-22-6/FileUsedAfterClosed.ql b/c/misra/src/rules/RULE-22-6/FileUsedAfterClosed.ql
index 78c5063ddd..64318dbedd 100644
--- a/c/misra/src/rules/RULE-22-6/FileUsedAfterClosed.ql
+++ b/c/misra/src/rules/RULE-22-6/FileUsedAfterClosed.ql
@@ -7,6 +7,7 @@
* @problem.severity error
* @tags external/misra/id/rule-22-6
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-22-7/EofShallBeComparedWithUnmodifiedReturnValues.ql b/c/misra/src/rules/RULE-22-7/EofShallBeComparedWithUnmodifiedReturnValues.ql
index 307357a93a..a29ee7c898 100644
--- a/c/misra/src/rules/RULE-22-7/EofShallBeComparedWithUnmodifiedReturnValues.ql
+++ b/c/misra/src/rules/RULE-22-7/EofShallBeComparedWithUnmodifiedReturnValues.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-22-7
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-22-8/ErrnoSetToZeroPriorToCall.ql b/c/misra/src/rules/RULE-22-8/ErrnoSetToZeroPriorToCall.ql
index de9a083545..6a39070ef0 100644
--- a/c/misra/src/rules/RULE-22-8/ErrnoSetToZeroPriorToCall.ql
+++ b/c/misra/src/rules/RULE-22-8/ErrnoSetToZeroPriorToCall.ql
@@ -9,6 +9,7 @@
* @problem.severity error
* @tags external/misra/id/rule-22-8
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-22-9/ErrnoSetToZeroAfterCall.ql b/c/misra/src/rules/RULE-22-9/ErrnoSetToZeroAfterCall.ql
index da4504b75b..274bf5b2ae 100644
--- a/c/misra/src/rules/RULE-22-9/ErrnoSetToZeroAfterCall.ql
+++ b/c/misra/src/rules/RULE-22-9/ErrnoSetToZeroAfterCall.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-22-9
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-3-1/CharacterSequencesAndUsedWithinAComment.ql b/c/misra/src/rules/RULE-3-1/CharacterSequencesAndUsedWithinAComment.ql
index f59606a0ac..6eb605dbd9 100644
--- a/c/misra/src/rules/RULE-3-1/CharacterSequencesAndUsedWithinAComment.ql
+++ b/c/misra/src/rules/RULE-3-1/CharacterSequencesAndUsedWithinAComment.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-3-1
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-3-2/LineSplicingUsedInComments.ql b/c/misra/src/rules/RULE-3-2/LineSplicingUsedInComments.ql
index cf6a2bb547..f1fd85b129 100644
--- a/c/misra/src/rules/RULE-3-2/LineSplicingUsedInComments.ql
+++ b/c/misra/src/rules/RULE-3-2/LineSplicingUsedInComments.ql
@@ -10,6 +10,7 @@
* maintainability
* readability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.ql b/c/misra/src/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.ql
index fd77f1a688..0f04a7362b 100644
--- a/c/misra/src/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.ql
+++ b/c/misra/src/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.ql
@@ -10,6 +10,7 @@
* maintainability
* readability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql
index fa7190c39b..2c2c302bc0 100644
--- a/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql
+++ b/c/misra/src/rules/RULE-5-1/ExternalIdentifiersNotDistinct.ql
@@ -9,6 +9,7 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-5-2/IdentifiersDeclaredInTheSameScopeNotDistinct.ql b/c/misra/src/rules/RULE-5-2/IdentifiersDeclaredInTheSameScopeNotDistinct.ql
index 682d7538c5..eb24d1c094 100644
--- a/c/misra/src/rules/RULE-5-2/IdentifiersDeclaredInTheSameScopeNotDistinct.ql
+++ b/c/misra/src/rules/RULE-5-2/IdentifiersDeclaredInTheSameScopeNotDistinct.ql
@@ -9,6 +9,7 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-5-3/IdentifierHidingC.ql b/c/misra/src/rules/RULE-5-3/IdentifierHidingC.ql
index 3463d08e1c..1c54b70147 100644
--- a/c/misra/src/rules/RULE-5-3/IdentifierHidingC.ql
+++ b/c/misra/src/rules/RULE-5-3/IdentifierHidingC.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-5-3
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql b/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql
index 886e05f0ea..d8a78cb680 100644
--- a/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql
+++ b/c/misra/src/rules/RULE-5-4/MacroIdentifierNotDistinctFromParameter.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-5-4
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql
index 5b3683bdc4..36b946491b 100644
--- a/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql
+++ b/c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql
@@ -9,13 +9,62 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.Macro
+import codingstandards.cpp.Includes
+import codingstandards.cpp.PreprocessorDirective
-from Macro m, Macro m2
+/**
+ * Gets a top level element that this macro is expanded to, e.g. an element which does not also have
+ * an enclosing element in the macro.
+ */
+Element getATopLevelElement(MacroInvocation mi) {
+ result = mi.getAnExpandedElement() and
+ not result.getEnclosingElement() = mi.getAnExpandedElement() and
+ not result instanceof Conversion
+}
+
+/**
+ * Gets a link target that this macro is expanded in.
+ */
+LinkTarget getALinkTarget(Macro m) {
+ exists(MacroInvocation mi, Element e |
+ mi = m.getAnInvocation() and
+ e = getATopLevelElement(mi)
+ |
+ result = e.(Expr).getEnclosingFunction().getALinkTarget()
+ or
+ result = e.(Stmt).getEnclosingFunction().getALinkTarget()
+ or
+ exists(GlobalOrNamespaceVariable g |
+ result = g.getALinkTarget() and
+ g = e.(Expr).getEnclosingDeclaration()
+ )
+ )
+}
+
+/**
+ * Holds if the m1 and m2 are unconditionally included from a common file.
+ *
+ * Extracted out for performance reasons - otherwise the call to determine the file path for the
+ * message was specializing the calls to `getAnUnconditionallyIncludedFile*(..)` and causing
+ * slow performance.
+ */
+bindingset[m1, m2]
+pragma[inline_late]
+private predicate isIncludedUnconditionallyFromCommonFile(Macro m1, Macro m2) {
+ exists(File f |
+ getAnUnconditionallyIncludedFile*(f) = m1.getFile() and
+ getAnUnconditionallyIncludedFile*(f) = m2.getFile()
+ )
+}
+
+from Macro m, Macro m2, string message
where
not isExcluded(m, Declarations1Package::macroIdentifiersNotDistinctQuery()) and
not m = m2 and
@@ -24,12 +73,40 @@ where
//C90 states the first 31 characters of macro identifiers are significant and is not currently considered by this rule
//ie an identifier differing on the 32nd character would be indistinct for C90 but distinct for C99
//and is currently not reported by this rule
- if m.getName().length() >= 64
- then m.getName().prefix(63) = m2.getName().prefix(63)
- else m.getName() = m2.getName()
+ if m.getName().length() >= 64 and not m.getName() = m2.getName()
+ then (
+ m.getName().prefix(63) = m2.getName().prefix(63) and
+ message =
+ "Macro identifer " + m.getName() + " is nondistinct in first 63 characters, compared to $@."
+ ) else (
+ m.getName() = m2.getName() and
+ message =
+ "Definition of macro " + m.getName() +
+ " is not distinct from alternative definition of $@ in " +
+ m2.getLocation().getFile().getRelativePath() + "."
+ )
) and
//reduce double report since both macros are in alert, arbitrary ordering
- m.getLocation().getStartLine() >= m2.getLocation().getStartLine()
-select m,
- "Macro identifer " + m.getName() + " is nondistinct in first 63 characters, compared to $@.", m2,
- m2.getName()
+ m.getLocation().getStartLine() >= m2.getLocation().getStartLine() and
+ // Not within an #ifndef MACRO_NAME
+ not exists(PreprocessorIfndef ifBranch |
+ m.getAGuard() = ifBranch or
+ m2.getAGuard() = ifBranch
+ |
+ ifBranch.getHead() = m.getName()
+ ) and
+ // Must be included unconditionally from the same file, otherwise m1 may not be defined
+ // when m2 is defined
+ isIncludedUnconditionallyFromCommonFile(m, m2) and
+ // Macros can't be mutually exclusive
+ not mutuallyExclusiveBranchDirectiveMacros(m, m2) and
+ not mutuallyExclusiveBranchDirectiveMacros(m2, m) and
+ // If at least one invocation exists for at least one of the macros, then they must share a link
+ // target - i.e. must both be expanded in the same context
+ (
+ (exists(m.getAnInvocation()) and exists(m2.getAnInvocation()))
+ implies
+ // Must share a link target - e.g. must both be expanded in the same context
+ getALinkTarget(m) = getALinkTarget(m2)
+ )
+select m, message, m2, m2.getName()
diff --git a/c/misra/src/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.ql b/c/misra/src/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.ql
index a63d9656b8..da6b725ab5 100644
--- a/c/misra/src/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.ql
+++ b/c/misra/src/rules/RULE-5-5/IdentifiersNotDistinctFromMacroNames.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-5-5
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql b/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql
index 2e9126d3af..1398df6a4d 100644
--- a/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql
+++ b/c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-5-6
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-5-7/TagNameNotUnique.ql b/c/misra/src/rules/RULE-5-7/TagNameNotUnique.ql
index 1c8a7a6b34..fa6560ab49 100644
--- a/c/misra/src/rules/RULE-5-7/TagNameNotUnique.ql
+++ b/c/misra/src/rules/RULE-5-7/TagNameNotUnique.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-5-7
* readability
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-5-8/IdentifiersWithExternalLinkageNotUnique.ql b/c/misra/src/rules/RULE-5-8/IdentifiersWithExternalLinkageNotUnique.ql
index 7406f05f14..fa1b2b1fad 100644
--- a/c/misra/src/rules/RULE-5-8/IdentifiersWithExternalLinkageNotUnique.ql
+++ b/c/misra/src/rules/RULE-5-8/IdentifiersWithExternalLinkageNotUnique.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-5-8
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
@@ -41,7 +42,25 @@ class NotUniqueExternalIdentifier extends ExternalIdentifiers {
Declaration getAConflictingDeclaration() {
not result = this and
- isConflictingDeclaration(result, getName())
+ isConflictingDeclaration(result, getName()) and
+ // We only consider a declaration to be conflicting if it shares a link target with the external
+ // identifier. This avoids reporting false positives where multiple binaries or libraries are
+ // built in the same CodeQL database, but are not intended to be linked together.
+ exists(LinkTarget lt |
+ // External declaration can only be a function or global variable
+ lt = this.(Function).getALinkTarget() or
+ lt = this.(GlobalVariable).getALinkTarget()
+ |
+ lt = result.(Function).getALinkTarget()
+ or
+ lt = result.(GlobalVariable).getALinkTarget()
+ or
+ exists(Class c | c.getAMember() = result and c.getALinkTarget() = lt)
+ or
+ result.(LocalVariable).getFunction().getALinkTarget() = lt
+ or
+ result.(Class).getALinkTarget() = lt
+ )
}
}
diff --git a/c/misra/src/rules/RULE-5-9/IdentifiersWithInternalLinkageNotUnique.ql b/c/misra/src/rules/RULE-5-9/IdentifiersWithInternalLinkageNotUnique.ql
index 45f63a3207..fcba48f2fd 100644
--- a/c/misra/src/rules/RULE-5-9/IdentifiersWithInternalLinkageNotUnique.ql
+++ b/c/misra/src/rules/RULE-5-9/IdentifiersWithInternalLinkageNotUnique.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-5-9
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-6-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.ql b/c/misra/src/rules/RULE-6-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.ql
index f5bc589a4d..078c2c48b7 100644
--- a/c/misra/src/rules/RULE-6-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.ql
+++ b/c/misra/src/rules/RULE-6-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.ql
@@ -7,6 +7,7 @@
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-6-1
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql b/c/misra/src/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql
index d699c1c9b7..142a0b542d 100644
--- a/c/misra/src/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql
+++ b/c/misra/src/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql
@@ -7,6 +7,7 @@
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-6-2
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql b/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql
new file mode 100644
index 0000000000..4befbb9dd6
--- /dev/null
+++ b/c/misra/src/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql
@@ -0,0 +1,24 @@
+/**
+ * @id c/misra/bit-field-declared-as-member-of-a-union
+ * @name RULE-6-3: A bit field shall not be declared as a member of a union
+ * @description Type punning on a union with bit fields relies on implementation-specific alignment
+ * behavior.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-6-3
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+
+from BitField field, Union u
+where
+ not isExcluded(field, BitfieldTypes2Package::bitFieldDeclaredAsMemberOfAUnionQuery()) and
+ u.getAField() = field
+select field,
+ "Union member " + field.getName() +
+ " is declared as a bit field which relies on implementation-specific behavior."
diff --git a/c/misra/src/rules/RULE-7-1/OctalConstantsUsed.ql b/c/misra/src/rules/RULE-7-1/OctalConstantsUsed.ql
index d4a6c332a7..9934e80487 100644
--- a/c/misra/src/rules/RULE-7-1/OctalConstantsUsed.ql
+++ b/c/misra/src/rules/RULE-7-1/OctalConstantsUsed.ql
@@ -10,6 +10,7 @@
* readability
* correctness
* maintainability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-7-2/UOrUSuffixRepresentedInUnsignedType.ql b/c/misra/src/rules/RULE-7-2/UOrUSuffixRepresentedInUnsignedType.ql
index b1dca9ac4a..c02e0e2aca 100644
--- a/c/misra/src/rules/RULE-7-2/UOrUSuffixRepresentedInUnsignedType.ql
+++ b/c/misra/src/rules/RULE-7-2/UOrUSuffixRepresentedInUnsignedType.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-7-2
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
@@ -19,6 +20,13 @@ from Literal l
where
not isExcluded(l, SyntaxPackage::uOrUSuffixRepresentedInUnsignedTypeQuery()) and
not l instanceof StringLiteral and
- l.getImplicitlyConverted().getType().(IntegralType).isUnsigned() and
- not exists(l.getValueText().toUpperCase().indexOf("U"))
-select l, "Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix."
+ // Determine if the extractor deduced that the literal is unsigned, based on the C rules
+ l.getType().(IntegralType).isUnsigned() and
+ // And report if the literal does not contain a 'U' or 'u' suffix, e.g. explicitly unsigned
+ not exists(l.getValueText().toUpperCase().indexOf("U")) and
+ // Exclude constants generated by macro expansions, because the suffix information is lost in this
+ // case, so can cause false positives.
+ not l.isInMacroExpansion()
+select l,
+ "Unsigned literal " + l.getValueText() +
+ " does not explicitly express sign with a 'U' or 'u' suffix."
diff --git a/c/misra/src/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.ql b/c/misra/src/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.ql
index 85c14ff419..0b38b26eea 100644
--- a/c/misra/src/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.ql
+++ b/c/misra/src/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-7-3
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-7-4/StringLiteralAssignedToNonConstChar.ql b/c/misra/src/rules/RULE-7-4/StringLiteralAssignedToNonConstChar.ql
index c93740139b..bc2fa5f5bf 100644
--- a/c/misra/src/rules/RULE-7-4/StringLiteralAssignedToNonConstChar.ql
+++ b/c/misra/src/rules/RULE-7-4/StringLiteralAssignedToNonConstChar.ql
@@ -7,6 +7,7 @@
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-7-4
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.ql b/c/misra/src/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.ql
new file mode 100644
index 0000000000..87c945d6b6
--- /dev/null
+++ b/c/misra/src/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.ql
@@ -0,0 +1,45 @@
+/**
+ * @id c/misra/incorrectly-sized-integer-constant-macro-argument
+ * @name RULE-7-5: The argument of an integer constant macro shall have an appropriate size
+ * @description Integer constant macros argument values should be values of a compatible size.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-7-5
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.IntegerConstantMacro
+import codingstandards.cpp.Literals
+
+predicate matchesSign(IntegerConstantMacro macro, PossiblyNegativeLiteral literal) {
+ literal.isNegative() implies macro.isSigned()
+}
+
+predicate matchesSize(IntegerConstantMacro macro, PossiblyNegativeLiteral literal) {
+ literal.getRawValue() <= macro.maxValue() and
+ literal.getRawValue() >= macro.minValue()
+}
+
+from
+ PossiblyNegativeLiteral literal, MacroInvocation invoke, IntegerConstantMacro macro,
+ string explanation
+where
+ not isExcluded(invoke, Types2Package::incorrectlySizedIntegerConstantMacroArgumentQuery()) and
+ invoke.getMacro() = macro and
+ literal = invoke.getExpr() and
+ (
+ not matchesSign(macro, literal) and
+ explanation = " cannot be negative"
+ or
+ matchesSign(macro, literal) and
+ // Wait for BigInt support to check 64 bit macro types.
+ macro.getSize() < 64 and
+ not matchesSize(macro, literal) and
+ explanation = " is outside of the allowed range " + macro.getRangeString()
+ )
+select literal, "Value provided to integer constant macro " + macro.getName() + explanation
diff --git a/c/misra/src/rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.ql b/c/misra/src/rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.ql
new file mode 100644
index 0000000000..84fb1a9872
--- /dev/null
+++ b/c/misra/src/rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.ql
@@ -0,0 +1,35 @@
+/**
+ * @id c/misra/integer-constant-macro-argument-uses-suffix
+ * @name RULE-7-5: The argument of an integer constant macro shall not use literal suffixes u, l, or ul
+ * @description Integer constant macros should be used integer literal values with no u/l suffix.
+ * @kind problem
+ * @precision high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-7-5
+ * readability
+ * maintainability
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.IntegerConstantMacro
+import codingstandards.cpp.Literals
+
+string argumentSuffix(MacroInvocation invoke) {
+ // Extractor strips the suffix unless we look at the unexpanded argument text.
+ // Unexpanded argument text can be malformed in all sorts of ways, so make
+ // this match relatively strict, to be safe.
+ result = invoke.getUnexpandedArgument(0).regexpCapture("([0-9]+|0[xX][0-9A-F]+)([uUlL]+)$", 2)
+}
+
+from MacroInvocation invoke, PossiblyNegativeLiteral argument, string suffix
+where
+ not isExcluded(invoke, Types2Package::integerConstantMacroArgumentUsesSuffixQuery()) and
+ invoke.getMacro() instanceof IntegerConstantMacro and
+ invoke.getExpr() = argument and
+ suffix = argumentSuffix(invoke)
+select argument,
+ "Value suffix '" + suffix + "' is not allowed on provided argument to integer constant macro " +
+ invoke.getMacroName() + "."
diff --git a/c/misra/src/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.ql b/c/misra/src/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.ql
new file mode 100644
index 0000000000..4c750e32d8
--- /dev/null
+++ b/c/misra/src/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.ql
@@ -0,0 +1,30 @@
+/**
+ * @id c/misra/invalid-integer-constant-macro-argument
+ * @name RULE-7-5: The argument of an integer constant macro shall be a literal
+ * @description Integer constant macros should be given a literal value as an argument.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-7-5
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.IntegerConstantMacro
+import codingstandards.cpp.Literals
+import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
+
+from MacroInvocation invoke, IntegerConstantMacro macro
+where
+ not isExcluded(invoke, Types2Package::invalidIntegerConstantMacroArgumentQuery()) and
+ invoke.getMacro() = macro and
+ (
+ not invoke.getExpr() instanceof PossiblyNegativeLiteral
+ or
+ any(MacroInvocation inner).getParentInvocation() = invoke
+ )
+select invoke.getExpr(),
+ "Argument to integer constant macro " + macro.getName() + " must be an integer literal."
diff --git a/c/misra/src/rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.ql b/c/misra/src/rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.ql
new file mode 100644
index 0000000000..e4e660c628
--- /dev/null
+++ b/c/misra/src/rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.ql
@@ -0,0 +1,77 @@
+/**
+ * @id c/misra/invalid-literal-for-integer-constant-macro-argument
+ * @name RULE-7-5: The argument of an integer constant macro shall be a decimal, hex, or octal literal
+ * @description Integer constant macro arguments should be a decimal, hex, or octal literal.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-7-5
+ * correctness
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.IntegerConstantMacro
+import codingstandards.cpp.Literals
+
+/**
+ * Floating point literals are not allowed. Neither are char or string
+ * literals, although those are not `NumericLiteral`s and therefore detected in
+ * `InvalidIntegerConstantMacroArgument.ql`.
+ */
+predicate validLiteralType(PossiblyNegativeLiteral literal) {
+ literal.getBaseLiteral() instanceof Cpp14Literal::DecimalLiteral or
+ literal.getBaseLiteral() instanceof Cpp14Literal::OctalLiteral or
+ literal.getBaseLiteral() instanceof Cpp14Literal::HexLiteral or
+ // Ignore cases where the AST/extractor don't give us enough information:
+ literal.getBaseLiteral() instanceof Cpp14Literal::UnrecognizedNumericLiteral
+}
+
+/**
+ * Clang accepts `xINTsize_C(0b01)`, and expands the argument into a decimal
+ * literal. Binary literals are not standard c nor are they allowed by rule 7-5.
+ * Detect this pattern before macro expansion.
+ */
+predicate seemsBinaryLiteral(MacroInvocation invoke) {
+ invoke.getUnexpandedArgument(0).regexpMatch("-?0[bB][01]+")
+}
+
+/**
+ * Extractor converts `xINTsize_C('a')` to a decimal literal. Therefore, detect
+ * this pattern before macro expansion.
+ */
+predicate seemsCharLiteral(MacroInvocation invoke) {
+ invoke.getUnexpandedArgument(0).regexpMatch("-?'\\\\?.'")
+}
+
+string explainIncorrectArgument(MacroInvocation invoke) {
+ if seemsBinaryLiteral(invoke)
+ then result = "binary literal"
+ else
+ if seemsCharLiteral(invoke)
+ then result = "char literal"
+ else
+ exists(PossiblyNegativeLiteral literal |
+ literal = invoke.getExpr() and
+ if literal.getBaseLiteral() instanceof Cpp14Literal::FloatingLiteral
+ then result = "floating point literal"
+ else result = "invalid literal"
+ )
+}
+
+from MacroInvocation invoke, PossiblyNegativeLiteral literal
+where
+ not isExcluded(invoke, Types2Package::invalidLiteralForIntegerConstantMacroArgumentQuery()) and
+ invoke.getMacro() instanceof IntegerConstantMacro and
+ literal = invoke.getExpr() and
+ (
+ not validLiteralType(literal) or
+ seemsBinaryLiteral(invoke) or
+ seemsCharLiteral(invoke)
+ )
+select literal,
+ "Integer constant macro " + invoke.getMacroName() + " used with " +
+ explainIncorrectArgument(invoke) +
+ " argument, only decimal, octal, or hex integer literal allowed."
diff --git a/c/misra/src/rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.ql b/c/misra/src/rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.ql
new file mode 100644
index 0000000000..47e88196d5
--- /dev/null
+++ b/c/misra/src/rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.ql
@@ -0,0 +1,24 @@
+/**
+ * @id c/misra/use-of-banned-small-integer-constant-macro
+ * @name RULE-7-6: The small integer variants of the minimum-width integer constant macros shall not be used
+ * @description Small integer constant macros expression are promoted to type int, which can lead to
+ * unexpected results.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-7-6
+ * readability
+ * external/misra/c/2012/amendment3
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.IntegerConstantMacro
+
+from MacroInvocation macroInvoke, IntegerConstantMacro macro
+where
+ not isExcluded(macroInvoke, Types2Package::useOfBannedSmallIntegerConstantMacroQuery()) and
+ macroInvoke.getMacro() = macro and
+ macro.isSmall()
+select macroInvoke, "Usage of small integer constant macro " + macro.getName() + " is not allowed."
diff --git a/c/misra/src/rules/RULE-8-1/ExplicitlyDeclareTypes.ql b/c/misra/src/rules/RULE-8-1/ExplicitlyDeclareTypes.ql
index bfcbac4435..6484372f5b 100644
--- a/c/misra/src/rules/RULE-8-1/ExplicitlyDeclareTypes.ql
+++ b/c/misra/src/rules/RULE-8-1/ExplicitlyDeclareTypes.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-8-1
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-10/InlineFunctionNotDeclaredStaticStorage.ql b/c/misra/src/rules/RULE-8-10/InlineFunctionNotDeclaredStaticStorage.ql
index 47e80912af..250c00ca2e 100644
--- a/c/misra/src/rules/RULE-8-10/InlineFunctionNotDeclaredStaticStorage.ql
+++ b/c/misra/src/rules/RULE-8-10/InlineFunctionNotDeclaredStaticStorage.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-8-10
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-11/ArrayExternalLinkageSizeExplicitlySpecified.ql b/c/misra/src/rules/RULE-8-11/ArrayExternalLinkageSizeExplicitlySpecified.ql
index ada18c805d..d14e236755 100644
--- a/c/misra/src/rules/RULE-8-11/ArrayExternalLinkageSizeExplicitlySpecified.ql
+++ b/c/misra/src/rules/RULE-8-11/ArrayExternalLinkageSizeExplicitlySpecified.ql
@@ -10,6 +10,7 @@
* @tags external/misra/id/rule-8-11
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.ql b/c/misra/src/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.ql
index a4fcb0e4f3..6ebabc3810 100644
--- a/c/misra/src/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.ql
+++ b/c/misra/src/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-8-12
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.ql b/c/misra/src/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.ql
index 5e63e74e2c..ddb8cbcdcc 100644
--- a/c/misra/src/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.ql
+++ b/c/misra/src/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.ql
@@ -10,36 +10,62 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
import codingstandards.cpp.SideEffect
+import codingstandards.cpp.alertreporting.HoldsForAllCopies
-from Variable ptr, PointerOrArrayType type
+class NonConstPointerVariableCandidate extends Variable {
+ NonConstPointerVariableCandidate() {
+ // Ignore parameters in functions without bodies
+ (this instanceof Parameter implies exists(this.(Parameter).getFunction().getBlock())) and
+ // Ignore variables in functions that use ASM commands
+ not exists(AsmStmt a |
+ a.getEnclosingFunction() = this.(LocalScopeVariable).getFunction()
+ or
+ // In a type declared locally
+ this.(Field).getDeclaringType+().getEnclosingFunction() = a.getEnclosingFunction()
+ ) and
+ exists(PointerOrArrayType type |
+ // include only pointers which point to a const-qualified type
+ this.getType() = type and
+ not type.isDeeplyConstBelow()
+ ) and
+ // exclude pointers passed as arguments to functions which take a
+ // parameter that points to a non-const-qualified type
+ not exists(FunctionCall fc, int i |
+ fc.getArgument(i) = this.getAnAccess() and
+ not fc.getTarget().getParameter(i).getType().isDeeplyConstBelow()
+ ) and
+ // exclude any pointers which have their underlying data modified
+ not exists(VariableEffect effect |
+ effect.getTarget() = this and
+ // but not pointers that are only themselves modified
+ not effect.(AssignExpr).getLValue() = this.getAnAccess() and
+ not effect.(CrementOperation).getOperand() = this.getAnAccess()
+ ) and
+ // exclude pointers assigned to another pointer to a non-const-qualified type
+ not exists(Variable a |
+ a.getAnAssignedValue() = this.getAnAccess() and
+ not a.getType().(PointerOrArrayType).isDeeplyConstBelow()
+ )
+ }
+}
+
+/**
+ * Ensure that all copies of a variable are considered to be missing const qualification to avoid
+ * false positives where a variable is only used/modified in a single copy.
+ */
+class NonConstPointerVariable =
+ HoldsForAllCopies::LogicalResultElement;
+
+from NonConstPointerVariable ptr
where
- not isExcluded(ptr, Pointers1Package::pointerShouldPointToConstTypeWhenPossibleQuery()) and
- // include only pointers which point to a const-qualified type
- ptr.getType() = type and
- not type.isDeeplyConstBelow() and
- // exclude pointers passed as arguments to functions which take a
- // parameter that points to a non-const-qualified type
- not exists(FunctionCall fc, int i |
- fc.getArgument(i) = ptr.getAnAccess() and
- not fc.getTarget().getParameter(i).getType().isDeeplyConstBelow()
- ) and
- // exclude any pointers which have their underlying data modified
- not exists(VariableEffect effect |
- effect.getTarget() = ptr and
- // but not pointers that are only themselves modified
- not effect.(AssignExpr).getLValue() = effect.getAnAccess() and
- not effect.(CrementOperation).getOperand() = effect.getAnAccess()
- ) and
- // exclude pointers assigned to another pointer to a non-const-qualified type
- not exists(Variable a |
- a.getAnAssignedValue() = ptr.getAnAccess() and
- not a.getType().(PointerOrArrayType).isDeeplyConstBelow()
- )
-select ptr, "$@ points to a non-const-qualified type.", ptr, ptr.getName()
+ not isExcluded(ptr.getAnElementInstance(),
+ Pointers1Package::pointerShouldPointToConstTypeWhenPossibleQuery())
+select ptr, "$@ points to a non-const-qualified type.", ptr, ptr.getAnElementInstance().getName()
diff --git a/c/misra/src/rules/RULE-8-14/RestrictTypeQualifierUsed.ql b/c/misra/src/rules/RULE-8-14/RestrictTypeQualifierUsed.ql
index 1969947753..cff7d0df5c 100644
--- a/c/misra/src/rules/RULE-8-14/RestrictTypeQualifierUsed.ql
+++ b/c/misra/src/rules/RULE-8-14/RestrictTypeQualifierUsed.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-8-14
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql b/c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql
index e46085750d..1136dd714e 100644
--- a/c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql
+++ b/c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql
@@ -8,51 +8,16 @@
* @problem.severity error
* @tags external/misra/id/rule-8-2
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.cpp.Identifiers
+import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared
-/**
- * `Parameter`s without names
- */
-class UnnamedParameter extends Parameter {
- UnnamedParameter() { not this.isNamed() }
+class FunctionTypesNotInPrototypeFormQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery {
+ FunctionTypesNotInPrototypeFormQuery() {
+ this = Declarations4Package::functionTypesNotInPrototypeFormQuery()
+ }
}
-
-/*
- * This is a copy of the private `hasZeroParamDecl` predicate from the standard set of
- * queries as of the `codeql-cli/2.11.2` tag in `github/codeql`.
- */
-
-predicate hasZeroParamDecl(Function f) {
- exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- not fde.isImplicit() and
- not fde.hasVoidParamList() and
- fde.getNumberOfParameters() = 0 and
- not fde.isDefinition()
- )
-}
-
-from Function f, string msg
-where
- not isExcluded(f, Declarations4Package::functionTypesNotInPrototypeFormQuery()) and
- f instanceof InterestingIdentifiers and
- (
- f.getAParameter() instanceof UnnamedParameter and
- msg = "Function " + f + " declares parameter that is unnamed."
- or
- hasZeroParamDecl(f) and
- msg = "Function " + f + " does not specify void for no parameters present."
- or
- //parameters declared in declaration list (not in function signature)
- //have placeholder file location associated only
- exists(Parameter p |
- p.getFunction() = f and
- not p.getFile() = f.getFile() and
- msg = "Function " + f + " declares parameter in unsupported declaration list."
- )
- )
-select f, msg
diff --git a/c/misra/src/rules/RULE-8-3/DeclarationsOfAFunctionSameNameAndType.ql b/c/misra/src/rules/RULE-8-3/DeclarationsOfAFunctionSameNameAndType.ql
index 6803af9380..8c80c64a40 100644
--- a/c/misra/src/rules/RULE-8-3/DeclarationsOfAFunctionSameNameAndType.ql
+++ b/c/misra/src/rules/RULE-8-3/DeclarationsOfAFunctionSameNameAndType.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-8-3
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-3/DeclarationsOfAnObjectSameNameAndType.ql b/c/misra/src/rules/RULE-8-3/DeclarationsOfAnObjectSameNameAndType.ql
index dfd9d622e9..421998c582 100644
--- a/c/misra/src/rules/RULE-8-3/DeclarationsOfAnObjectSameNameAndType.ql
+++ b/c/misra/src/rules/RULE-8-3/DeclarationsOfAnObjectSameNameAndType.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-8-3
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
@@ -21,7 +22,19 @@ where
not isExcluded(decl2, Declarations4Package::declarationsOfAnObjectSameNameAndTypeQuery()) and
not decl1 = decl2 and
not decl1.getVariable().getDeclaringType().isAnonymous() and
+ // Declarations are for the same qualified name
+ // Note: decl1.getVariable() = decl2.getVariable() does not work for common cases where an aliased
+ // type is used.
decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and
+ // As we use qualified name, require that they share a common link target to ensure they are
+ // for the same object
+ (
+ decl1.getVariable().(GlobalVariable).getALinkTarget() =
+ decl2.getVariable().(GlobalVariable).getALinkTarget()
+ or
+ decl1.getVariable().(Field).getDeclaringType().(Class).getALinkTarget() =
+ decl2.getVariable().(Field).getDeclaringType().(Class).getALinkTarget()
+ ) and
not typesCompatible(decl1.getType(), decl2.getType())
select decl1,
"The object $@ of type " + decl1.getType().toString() +
diff --git a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql
index c87e5b556c..63f70d3541 100644
--- a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql
+++ b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql
@@ -10,6 +10,7 @@
* readability
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql
index 433597cf4a..7e5baacd9a 100644
--- a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql
+++ b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql
@@ -10,6 +10,7 @@
* readability
* maintainability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-5/ExternalObjectOrFunctionNotDeclaredInOneFile.ql b/c/misra/src/rules/RULE-8-5/ExternalObjectOrFunctionNotDeclaredInOneFile.ql
index 56e1d742a6..9a3f1c7900 100644
--- a/c/misra/src/rules/RULE-8-5/ExternalObjectOrFunctionNotDeclaredInOneFile.ql
+++ b/c/misra/src/rules/RULE-8-5/ExternalObjectOrFunctionNotDeclaredInOneFile.ql
@@ -7,6 +7,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-8-5
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-6/IdentifierWithExternalLinkageOneDefinition.ql b/c/misra/src/rules/RULE-8-6/IdentifierWithExternalLinkageOneDefinition.ql
index 1a85775236..0781eef539 100644
--- a/c/misra/src/rules/RULE-8-6/IdentifierWithExternalLinkageOneDefinition.ql
+++ b/c/misra/src/rules/RULE-8-6/IdentifierWithExternalLinkageOneDefinition.ql
@@ -8,6 +8,7 @@
* @problem.severity error
* @tags external/misra/id/rule-8-6
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-7/ShouldNotBeDefinedWithExternalLinkage.ql b/c/misra/src/rules/RULE-8-7/ShouldNotBeDefinedWithExternalLinkage.ql
index 824a4cf1cf..faa915fdd5 100644
--- a/c/misra/src/rules/RULE-8-7/ShouldNotBeDefinedWithExternalLinkage.ql
+++ b/c/misra/src/rules/RULE-8-7/ShouldNotBeDefinedWithExternalLinkage.ql
@@ -12,6 +12,7 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierFunctionRedeclarationC.ql b/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierFunctionRedeclarationC.ql
index c210273cd1..c3a5ce897f 100644
--- a/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierFunctionRedeclarationC.ql
+++ b/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierFunctionRedeclarationC.ql
@@ -8,6 +8,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-8-8
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql b/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql
index 2cb65c4fda..877ef19d2a 100644
--- a/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql
+++ b/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql
@@ -8,20 +8,17 @@
* @problem.severity warning
* @tags external/misra/id/rule-8-8
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared
-from VariableDeclarationEntry redeclaration, VariableDeclarationEntry de
-where
- not isExcluded(redeclaration,
- Declarations5Package::missingStaticSpecifierObjectRedeclarationCQuery()) and
- //following implies de != redeclaration
- de.hasSpecifier("static") and
- not redeclaration.hasSpecifier("static") and
- de.getDeclaration().isTopLevel() and
- redeclaration.getDeclaration() = de.getDeclaration()
-select redeclaration, "The redeclaration of $@ with internal linkage misses the static specifier.",
- de, de.getName()
+class MissingStaticSpecifierObjectRedeclarationCQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery
+{
+ MissingStaticSpecifierObjectRedeclarationCQuery() {
+ this = Declarations5Package::missingStaticSpecifierObjectRedeclarationCQuery()
+ }
+}
diff --git a/c/misra/src/rules/RULE-8-9/UnnecessaryExposedIdentifierDeclarationC.ql b/c/misra/src/rules/RULE-8-9/UnnecessaryExposedIdentifierDeclarationC.ql
index 88cf72fdcd..5dc697e425 100644
--- a/c/misra/src/rules/RULE-8-9/UnnecessaryExposedIdentifierDeclarationC.ql
+++ b/c/misra/src/rules/RULE-8-9/UnnecessaryExposedIdentifierDeclarationC.ql
@@ -8,6 +8,7 @@
* @problem.severity warning
* @tags external/misra/id/rule-8-9
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
diff --git a/c/misra/src/rules/RULE-9-1/ObjectWithAutoStorageDurationReadBeforeInit.ql b/c/misra/src/rules/RULE-9-1/ObjectWithAutoStorageDurationReadBeforeInit.ql
index b9960fc886..f3204ef2e3 100644
--- a/c/misra/src/rules/RULE-9-1/ObjectWithAutoStorageDurationReadBeforeInit.ql
+++ b/c/misra/src/rules/RULE-9-1/ObjectWithAutoStorageDurationReadBeforeInit.ql
@@ -8,6 +8,7 @@
* @tags external/misra/id/rule-9-1
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
diff --git a/c/misra/src/rules/RULE-9-2/InitializerForAggregateOrUnionNotEnclosedInBraces.ql b/c/misra/src/rules/RULE-9-2/InitializerForAggregateOrUnionNotEnclosedInBraces.ql
index 02ee294036..c5a9ae4814 100644
--- a/c/misra/src/rules/RULE-9-2/InitializerForAggregateOrUnionNotEnclosedInBraces.ql
+++ b/c/misra/src/rules/RULE-9-2/InitializerForAggregateOrUnionNotEnclosedInBraces.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-9-2
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-9-3/PartiallyInitializedArrayWithExplicitInitializers.ql b/c/misra/src/rules/RULE-9-3/PartiallyInitializedArrayWithExplicitInitializers.ql
index 231520ce50..d10c8315e1 100644
--- a/c/misra/src/rules/RULE-9-3/PartiallyInitializedArrayWithExplicitInitializers.ql
+++ b/c/misra/src/rules/RULE-9-3/PartiallyInitializedArrayWithExplicitInitializers.ql
@@ -9,6 +9,7 @@
* @tags external/misra/id/rule-9-3
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
diff --git a/c/misra/src/rules/RULE-9-4/RepeatedInitializationOfAggregateObjectElement.ql b/c/misra/src/rules/RULE-9-4/RepeatedInitializationOfAggregateObjectElement.ql
index 3566835ae3..dfe3fd8fff 100644
--- a/c/misra/src/rules/RULE-9-4/RepeatedInitializationOfAggregateObjectElement.ql
+++ b/c/misra/src/rules/RULE-9-4/RepeatedInitializationOfAggregateObjectElement.ql
@@ -10,6 +10,7 @@
* correctness
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
@@ -61,25 +62,15 @@ int getMaxDepth(ArrayAggregateLiteral al) {
// internal recursive predicate for `hasMultipleInitializerExprsForSameIndex`
predicate hasMultipleInitializerExprsForSameIndexInternal(
- ArrayAggregateLiteral al1, ArrayAggregateLiteral al2, Expr out_al1_expr, Expr out_al2_expr
+ ArrayAggregateLiteral root, Expr e1, Expr e2
) {
- exists(int shared_index, Expr al1_expr, Expr al2_expr |
- // an `Expr` initializing an element of the same index in both `al1` and `al2`
- shared_index = [0 .. al1.getArraySize() - 1] and
- al1_expr = al1.getAnElementExpr(shared_index) and
- al2_expr = al2.getAnElementExpr(shared_index) and
- // but not the same `Expr`
- not al1_expr = al2_expr and
- (
- // case A - the children are not aggregate literals
- // holds if `al1` and `al2` both hold for .getElement[sharedIndex]
- not al1_expr instanceof ArrayAggregateLiteral and
- out_al1_expr = al1_expr and
- out_al2_expr = al2_expr
- or
- // case B - `al1` and `al2` both have an aggregate literal child at the same index, so recurse
- hasMultipleInitializerExprsForSameIndexInternal(al1_expr, al2_expr, out_al1_expr, out_al2_expr)
- )
+ root = e1 and root = e2
+ or
+ exists(ArrayAggregateLiteral parent1, ArrayAggregateLiteral parent2, int shared_index |
+ hasMultipleInitializerExprsForSameIndexInternal(root, parent1, parent2) and
+ shared_index = [0 .. parent1.getArraySize() - 1] and
+ e1 = parent1.getAnElementExpr(shared_index) and
+ e2 = parent2.getAnElementExpr(shared_index)
)
}
@@ -87,7 +78,15 @@ predicate hasMultipleInitializerExprsForSameIndexInternal(
* Holds if `expr1` and `expr2` both initialize the same array element of `root`.
*/
predicate hasMultipleInitializerExprsForSameIndex(ArrayAggregateLiteral root, Expr expr1, Expr expr2) {
- hasMultipleInitializerExprsForSameIndexInternal(root, root, expr1, expr2)
+ hasMultipleInitializerExprsForSameIndexInternal(root, expr1, expr2) and
+ not root = expr1 and
+ not root = expr2 and
+ not expr1 = expr2 and
+ (
+ not expr1 instanceof ArrayAggregateLiteral
+ or
+ not expr2 instanceof ArrayAggregateLiteral
+ )
}
/**
diff --git a/c/misra/test/c/misra/EssentialTypes.expected b/c/misra/test/c/misra/EssentialTypes.expected
index 8bf299bd63..c0e010b8e4 100644
--- a/c/misra/test/c/misra/EssentialTypes.expected
+++ b/c/misra/test/c/misra/EssentialTypes.expected
@@ -1,3 +1,9 @@
+| file://:0:0:0:0 | 0 | signed char | signed char | essentially Signed type |
+| file://:0:0:0:0 | 0 | signed char | signed char | essentially Signed type |
+| file://:0:0:0:0 | 0 | signed char | signed char | essentially Signed type |
+| file://:0:0:0:0 | 0 | signed char | signed char | essentially Signed type |
+| file://:0:0:0:0 | 0 | signed char | signed char | essentially Signed type |
+| file://:0:0:0:0 | 0 | signed char | signed char | essentially Signed type |
| test.c:4:20:4:20 | 1 | signed char | signed char | essentially Signed type |
| test.c:4:20:4:20 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type |
| test.c:5:23:5:23 | 1 | signed char | signed char | essentially Signed type |
@@ -38,3 +44,49 @@
| test.c:26:3:26:3 | f | float | float | essentially Floating type |
| test.c:27:3:27:5 | f32 | float32_t | float32_t | essentially Floating type |
| test.c:28:3:28:6 | cf32 | float | float | essentially Floating type |
+| test.c:32:3:32:3 | 1 | signed char | signed char | essentially Signed type |
+| test.c:33:3:33:4 | 1 | unsigned char | unsigned char | essentially Unsigned type |
+| test.c:34:3:34:5 | 1 | unsigned long | unsigned long | essentially Unsigned type |
+| test.c:38:13:38:16 | 1 | bool | bool | essentially Boolean type |
+| test.c:38:13:38:16 | (bool)... | bool | bool | essentially Boolean type |
+| test.c:39:20:39:20 | 1 | signed char | signed char | essentially Signed type |
+| test.c:39:20:39:20 | (unsigned int)... | unsigned int | unsigned int | essentially Unsigned type |
+| test.c:40:23:40:23 | 1 | signed char | signed char | essentially Signed type |
+| test.c:40:23:40:23 | (unsigned short)... | unsigned short | unsigned short | essentially Unsigned type |
+| test.c:41:17:41:18 | 1 | signed char | signed char | essentially Signed type |
+| test.c:42:21:42:21 | 1 | signed char | signed char | essentially Signed type |
+| test.c:42:21:42:21 | (signed short)... | signed short | signed short | essentially Signed type |
+| test.c:44:3:44:4 | ! ... | bool | bool | essentially Boolean type |
+| test.c:44:4:44:4 | b | bool | bool | essentially Boolean type |
+| test.c:45:3:45:4 | ! ... | bool | bool | essentially Boolean type |
+| test.c:45:4:45:4 | u | unsigned int | unsigned int | essentially Unsigned type |
+| test.c:46:3:46:5 | ! ... | bool | bool | essentially Boolean type |
+| test.c:46:4:46:5 | us | unsigned short | unsigned short | essentially Unsigned type |
+| test.c:47:3:47:4 | ! ... | bool | bool | essentially Boolean type |
+| test.c:47:4:47:4 | s | signed int | signed int | essentially Signed type |
+| test.c:48:3:48:5 | ! ... | bool | bool | essentially Boolean type |
+| test.c:48:4:48:5 | ss | signed short | signed short | essentially Signed type |
+| test.c:50:3:50:4 | ~ ... | int | int | essentially Signed type |
+| test.c:50:4:50:4 | (int)... | int | int | essentially Signed type |
+| test.c:50:4:50:4 | b | bool | bool | essentially Boolean type |
+| test.c:51:3:51:4 | ~ ... | unsigned int | unsigned int | essentially Unsigned type |
+| test.c:51:4:51:4 | u | unsigned int | unsigned int | essentially Unsigned type |
+| test.c:52:3:52:5 | ~ ... | unsigned short | unsigned short | essentially Unsigned type |
+| test.c:52:4:52:5 | (int)... | int | int | essentially Signed type |
+| test.c:52:4:52:5 | us | unsigned short | unsigned short | essentially Unsigned type |
+| test.c:53:3:53:4 | ~ ... | signed int | signed int | essentially Signed type |
+| test.c:53:4:53:4 | s | signed int | signed int | essentially Signed type |
+| test.c:54:3:54:5 | ~ ... | int | int | essentially Signed type |
+| test.c:54:4:54:5 | (int)... | int | int | essentially Signed type |
+| test.c:54:4:54:5 | ss | signed short | signed short | essentially Signed type |
+| test.c:63:30:63:32 | ((unnamed enum))... | (unnamed enum) | (unnamed enum) | essentially Enum Type |
+| test.c:63:30:63:32 | EC5 | (unnamed enum) | (unnamed enum) | essentially Enum Type |
+| test.c:70:3:70:5 | EC1 | signed char | signed char | essentially Signed type |
+| test.c:71:3:71:5 | EC2 | E1 | E1 | essentially Enum Type |
+| test.c:72:3:72:5 | EC3 | (unnamed enum) | (unnamed enum) | essentially Enum Type |
+| test.c:73:3:73:5 | EC4 | (unnamed enum) | (unnamed enum) | essentially Enum Type |
+| test.c:74:3:74:5 | EC5 | (unnamed enum) | (unnamed enum) | essentially Enum Type |
+| test.c:75:3:75:5 | EC6 | (unnamed enum) | (unnamed enum) | essentially Enum Type |
+| test.c:79:3:79:5 | 97 | char | char | essentially Character type |
+| test.c:80:3:80:6 | 10 | char | char | essentially Character type |
+| test.c:81:3:81:6 | 0 | char | char | essentially Character type |
diff --git a/c/misra/test/c/misra/test.c b/c/misra/test/c/misra/test.c
index 8788f7e93a..b3fdddd591 100644
--- a/c/misra/test/c/misra/test.c
+++ b/c/misra/test/c/misra/test.c
@@ -26,4 +26,57 @@ void testCategoriesForComplexTypes() {
f; // Should be essentially Floating type
f32; // Should be essentially Floating type
cf32; // Should be essentially Floating type
+}
+
+void testConstants() {
+ 1; // Essentially signed char
+ 1U; // Essentially unsigned char
+ 1UL; // Essentially unsigned long
+}
+
+void testUnary() {
+ _Bool b = true;
+ unsigned int u = 1;
+ unsigned short us = 1;
+ signed int s = 1;
+ signed short ss = 1;
+
+ !b; // Should be boolean
+ !u; // Should be boolean
+ !us; // Should be boolean
+ !s; // Should be boolean
+ !ss; // Should be boolean
+
+ ~b; // Should be essentially signed
+ ~u; // Should be essentially unsigned
+ ~us; // Should be essentially unsigned
+ ~s; // Should be essentially signed
+ ~ss; // Should be essentially signed
+}
+
+enum { EC1 };
+enum E1 { EC2 };
+typedef enum { EC3 } E2;
+
+enum { EC4 } g;
+
+enum { EC5 } test() { return EC5; }
+
+struct S1 {
+ enum { EC6 } m;
+};
+
+void testEnums() {
+ EC1; // Should be essentially signed
+ EC2; // Should be essentially enum
+ EC3; // Should be essentially enum
+ EC4; // Should be essentially enum
+ EC5; // Should be essentially enum
+ EC6; // Should be essentially enum
+}
+
+void testControlChar() {
+ 'a'; // Essentially char
+ '\n'; // Essentially char
+ '\0'; // Essentially char
}
\ No newline at end of file
diff --git a/c/misra/test/codeql-pack.lock.yml b/c/misra/test/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/c/misra/test/codeql-pack.lock.yml
+++ b/c/misra/test/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/c/misra/test/qlpack.yml b/c/misra/test/qlpack.yml
index efe05e7d75..f27c03ca9e 100644
--- a/c/misra/test/qlpack.yml
+++ b/c/misra/test/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/misra-c-coding-standards-tests
-version: 2.33.0-dev
+version: 2.38.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.expected b/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.expected
index f9f034c980..0e2cbb26ee 100644
--- a/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.expected
+++ b/c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.expected
@@ -1,51 +1,51 @@
-| test.c:34:1:34:23 | #define A __BASE_FILE__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:35:1:35:23 | #define B __FILE_NAME__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:36:1:36:21 | #define C __COUNTER__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:37:1:37:27 | #define D __INCLUDE_LEVEL__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:39:1:39:19 | #define F __clang__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:40:1:40:25 | #define G __clang_major__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:41:1:41:25 | #define H __clang_minor__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:42:1:42:30 | #define I __clang_patchlevel__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:43:1:43:27 | #define J __clang_version__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:44:1:44:36 | #define K __clang_literal_encoding__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:45:1:45:41 | #define L __clang_wide_literal_encoding__ | Is a compiler extension and is not portable to other compilers. |
-| test.c:53:33:53:43 | vector_size | Is a compiler extension and is not portable to other compilers. |
-| test.c:54:33:54:47 | vector_size | Is a compiler extension and is not portable to other compilers. |
-| test.c:55:37:55:51 | ext_vector_type | Is a compiler extension and is not portable to other compilers. |
-| test.c:56:37:56:51 | ext_vector_type | Is a compiler extension and is not portable to other compilers. |
-| test.c:61:3:69:4 | (statement expression) | Is a compiler extension and is not portable to other compilers. |
-| test.c:96:3:96:18 | call to __builtin_setjmp | Is a compiler extension and is not portable to other compilers. |
-| test.c:97:3:97:19 | call to __builtin_longjmp | Is a compiler extension and is not portable to other compilers. |
-| test.c:113:11:113:16 | ... ? ... : ... | Is a compiler extension and is not portable to other compilers. |
-| test.c:124:12:124:12 | definition of a | Is a compiler extension and is not portable to other compilers. |
-| test.c:128:17:128:17 | definition of a | Is a compiler extension and is not portable to other compilers. |
-| test.c:165:8:165:15 | definition of contents | Is a compiler extension and is not portable to other compilers. |
-| test.c:182:8:182:11 | gf19 | Is a compiler extension and is not portable to other compilers. |
-| test.c:214:33:214:35 | declaration of out | Is a compiler extension and is not portable to other compilers. |
-| test.c:215:25:215:26 | declaration of in | Is a compiler extension and is not portable to other compilers. |
-| test.c:268:16:268:21 | access | Is a compiler extension and is not portable to other compilers. |
-| test.c:271:27:271:31 | alias | Is a compiler extension and is not portable to other compilers. |
-| test.c:274:23:274:29 | aligned | Is a compiler extension and is not portable to other compilers. |
-| test.c:285:25:285:34 | deprecated | Is a compiler extension and is not portable to other compilers. |
-| test.c:297:20:297:30 | fallthrough | Is a compiler extension and is not portable to other compilers. |
-| test.c:321:3:321:22 | alignof() | Is a compiler extension and is not portable to other compilers. |
-| test.c:340:3:340:31 | call to __builtin_extract_return_addr | Is a compiler extension and is not portable to other compilers. |
-| test.c:341:3:341:28 | call to __builtin_frob_return_addr | Is a compiler extension and is not portable to other compilers. |
-| test.c:342:3:342:25 | call to __builtin_frame_address | Is a compiler extension and is not portable to other compilers. |
-| test.c:363:3:363:22 | call to __sync_fetch_and_add_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:364:3:364:22 | call to __sync_fetch_and_sub_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:365:3:365:21 | call to __sync_fetch_and_or_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:366:3:366:22 | call to __sync_fetch_and_and_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:367:3:367:22 | call to __sync_fetch_and_xor_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:368:3:368:23 | call to __sync_fetch_and_nand_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:369:3:369:22 | call to __sync_add_and_fetch_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:370:3:370:22 | call to __sync_sub_and_fetch_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:371:3:371:21 | call to __sync_or_and_fetch_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:372:3:372:22 | call to __sync_and_and_fetch_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:373:3:373:22 | call to __sync_xor_and_fetch_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:374:3:374:23 | call to __sync_nand_and_fetch_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:376:3:376:30 | call to __sync_bool_compare_and_swap_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:377:3:377:29 | call to __sync_val_compare_and_swap_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:378:3:378:26 | call to __sync_lock_test_and_set_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:379:3:379:21 | call to __sync_lock_release_4 | Is a compiler extension and is not portable to other compilers. |
-| test.c:407:3:407:18 | call to __builtin_alloca | Is a compiler extension and is not portable to other compilers. |
+| test.c:34:1:34:23 | #define A __BASE_FILE__ | Use of builtin macro '__BASE_FILE__' is a compiler extension and is not portable to other compilers. |
+| test.c:35:1:35:23 | #define B __FILE_NAME__ | Use of builtin macro '__FILE_NAME__' is a compiler extension and is not portable to other compilers. |
+| test.c:36:1:36:21 | #define C __COUNTER__ | Use of builtin macro '__COUNTER__' is a compiler extension and is not portable to other compilers. |
+| test.c:37:1:37:27 | #define D __INCLUDE_LEVEL__ | Use of builtin macro '__INCLUDE_LEVEL__' is a compiler extension and is not portable to other compilers. |
+| test.c:39:1:39:19 | #define F __clang__ | Use of builtin macro '__clang__' is a compiler extension and is not portable to other compilers. |
+| test.c:40:1:40:25 | #define G __clang_major__ | Use of builtin macro '__clang_major__' is a compiler extension and is not portable to other compilers. |
+| test.c:41:1:41:25 | #define H __clang_minor__ | Use of builtin macro '__clang_minor__' is a compiler extension and is not portable to other compilers. |
+| test.c:42:1:42:30 | #define I __clang_patchlevel__ | Use of builtin macro '__clang_patchlevel__' is a compiler extension and is not portable to other compilers. |
+| test.c:43:1:43:27 | #define J __clang_version__ | Use of builtin macro '__clang_version__' is a compiler extension and is not portable to other compilers. |
+| test.c:44:1:44:36 | #define K __clang_literal_encoding__ | Use of builtin macro '__clang_literal_encoding__' is a compiler extension and is not portable to other compilers. |
+| test.c:45:1:45:41 | #define L __clang_wide_literal_encoding__ | Use of builtin macro '__clang_wide_literal_encoding__' is a compiler extension and is not portable to other compilers. |
+| test.c:53:33:53:43 | vector_size | Use of attribute 'vector_size' is a compiler extension and is not portable to other compilers. |
+| test.c:54:33:54:47 | vector_size | Use of attribute 'vector_size' is a compiler extension and is not portable to other compilers. |
+| test.c:55:37:55:51 | ext_vector_type | Use of attribute 'ext_vector_type' is a compiler extension and is not portable to other compilers. |
+| test.c:56:37:56:51 | ext_vector_type | Use of attribute 'ext_vector_type' is a compiler extension and is not portable to other compilers. |
+| test.c:61:3:69:4 | (statement expression) | Statement expressions are a compiler extension and are not portable to other compilers. |
+| test.c:96:3:96:18 | call to __builtin_setjmp | Call to builtin function '__builtin_setjmp' is a compiler extension and is not portable to other compilers. |
+| test.c:97:3:97:19 | call to __builtin_longjmp | Call to builtin function '__builtin_longjmp' is a compiler extension and is not portable to other compilers. |
+| test.c:113:11:113:16 | ... ? ... : ... | Ternaries with omitted middle operands are a compiler extension and is not portable to other compilers. |
+| test.c:124:12:124:12 | definition of a | 128-bit integers are a compiler extension and are not portable to other compilers. |
+| test.c:128:17:128:17 | definition of a | Double-Word integers are a compiler extension and are not portable to other compilers. |
+| test.c:165:8:165:15 | definition of contents | Zero length arrays are a compiler extension and are not portable to other compilers. |
+| test.c:182:8:182:11 | gf19 | Empty structures are a compiler extension and are not portable to other compilers. |
+| test.c:216:9:216:10 | definition of x1 | Zero length arrays are a compiler extension and are not portable to other compilers. |
+| test.c:266:16:266:21 | access | Use of attribute 'access' is a compiler extension and is not portable to other compilers. |
+| test.c:269:27:269:31 | alias | Use of attribute 'alias' is a compiler extension and is not portable to other compilers. |
+| test.c:272:23:272:29 | aligned | Use of attribute 'aligned' is a compiler extension and is not portable to other compilers. |
+| test.c:283:25:283:34 | deprecated | Use of attribute 'deprecated' is a compiler extension and is not portable to other compilers. |
+| test.c:295:20:295:30 | fallthrough | Use of attribute 'fallthrough' is a compiler extension and is not portable to other compilers. |
+| test.c:319:3:319:22 | alignof() | '__alignof__' is a compiler extension and is not portable to other compilers. |
+| test.c:338:3:338:31 | call to __builtin_extract_return_addr | Call to builtin function '__builtin_extract_return_addr' is a compiler extension and is not portable to other compilers. |
+| test.c:339:3:339:28 | call to __builtin_frob_return_addr | Call to builtin function '__builtin_frob_return_addr' is a compiler extension and is not portable to other compilers. |
+| test.c:340:3:340:25 | call to __builtin_frame_address | Call to builtin function '__builtin_frame_address' is a compiler extension and is not portable to other compilers. |
+| test.c:361:3:361:22 | call to __sync_fetch_and_add_4 | Call to builtin function '__sync_fetch_and_add_4' is a compiler extension and is not portable to other compilers. |
+| test.c:362:3:362:22 | call to __sync_fetch_and_sub_4 | Call to builtin function '__sync_fetch_and_sub_4' is a compiler extension and is not portable to other compilers. |
+| test.c:363:3:363:21 | call to __sync_fetch_and_or_4 | Call to builtin function '__sync_fetch_and_or_4' is a compiler extension and is not portable to other compilers. |
+| test.c:364:3:364:22 | call to __sync_fetch_and_and_4 | Call to builtin function '__sync_fetch_and_and_4' is a compiler extension and is not portable to other compilers. |
+| test.c:365:3:365:22 | call to __sync_fetch_and_xor_4 | Call to builtin function '__sync_fetch_and_xor_4' is a compiler extension and is not portable to other compilers. |
+| test.c:366:3:366:23 | call to __sync_fetch_and_nand_4 | Call to builtin function '__sync_fetch_and_nand_4' is a compiler extension and is not portable to other compilers. |
+| test.c:367:3:367:22 | call to __sync_add_and_fetch_4 | Call to builtin function '__sync_add_and_fetch_4' is a compiler extension and is not portable to other compilers. |
+| test.c:368:3:368:22 | call to __sync_sub_and_fetch_4 | Call to builtin function '__sync_sub_and_fetch_4' is a compiler extension and is not portable to other compilers. |
+| test.c:369:3:369:21 | call to __sync_or_and_fetch_4 | Call to builtin function '__sync_or_and_fetch_4' is a compiler extension and is not portable to other compilers. |
+| test.c:370:3:370:22 | call to __sync_and_and_fetch_4 | Call to builtin function '__sync_and_and_fetch_4' is a compiler extension and is not portable to other compilers. |
+| test.c:371:3:371:22 | call to __sync_xor_and_fetch_4 | Call to builtin function '__sync_xor_and_fetch_4' is a compiler extension and is not portable to other compilers. |
+| test.c:372:3:372:23 | call to __sync_nand_and_fetch_4 | Call to builtin function '__sync_nand_and_fetch_4' is a compiler extension and is not portable to other compilers. |
+| test.c:374:3:374:30 | call to __sync_bool_compare_and_swap_4 | Call to builtin function '__sync_bool_compare_and_swap_4' is a compiler extension and is not portable to other compilers. |
+| test.c:375:3:375:29 | call to __sync_val_compare_and_swap_4 | Call to builtin function '__sync_val_compare_and_swap_4' is a compiler extension and is not portable to other compilers. |
+| test.c:376:3:376:26 | call to __sync_lock_test_and_set_4 | Call to builtin function '__sync_lock_test_and_set_4' is a compiler extension and is not portable to other compilers. |
+| test.c:377:3:377:21 | call to __sync_lock_release_4 | Call to builtin function '__sync_lock_release_4' is a compiler extension and is not portable to other compilers. |
+| test.c:405:3:405:18 | call to __builtin_alloca | Call to builtin function '__builtin_alloca' is a compiler extension and is not portable to other compilers. |
+| test.c:409:1:411:8 | #define BUILTIN __builtin_alloca( 0) | Call to builtin function '__builtin_alloca' is a compiler extension and is not portable to other compilers. |
diff --git a/c/misra/test/rules/RULE-1-2/test.c b/c/misra/test/rules/RULE-1-2/test.c
index 86a3ae2f20..439df3733c 100644
--- a/c/misra/test/rules/RULE-1-2/test.c
+++ b/c/misra/test/rules/RULE-1-2/test.c
@@ -211,14 +211,12 @@ void gf24(int f, int g) {
// Reference:
// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length
-void gf25t(int N, int M, double out[M][N], // NON_COMPLIANT
- const double in[N][M]); // NON_COMPLIANT
-void gf25() {
- double x[3][2];
- double y[2][3];
- gf25t(3, 2, y,
- x); // in ISO C the const qualifier is formally attached
- // to the element type of the array and not the array itself
+void gf25(int n) {
+ struct S1 {
+ int x1[n]; // NON_COMPLIANT
+ int x2[5]; // COMPLIANT
+ int x3[]; // COMPLIANT
+ };
}
// Reference:
@@ -406,4 +404,10 @@ void gf47() { // NON_COMPLIANT in versions < C11.
void gf48() {
__builtin_alloca(
0); // NON_COMPLIANT (all __builtin functions are non-compliant.)
-}
\ No newline at end of file
+}
+
+#define BUILTIN \
+ __builtin_alloca( \
+ 0) // NON_COMPLIANT (all __builtin functions are non-compliant.)
+
+void gf49() { BUILTIN; }
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected b/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected
index 68216d500f..1e57f92e4a 100644
--- a/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected
+++ b/c/misra/test/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.expected
@@ -1,5 +1,8 @@
-| test.c:8:6:8:35 | ____codeql_coding_standards_m2 | May result in undefined behavior. |
-| test.c:11:5:11:34 | ____codeql_coding_standards_m3 | May result in undefined behavior. |
-| test.c:15:5:15:34 | ____codeql_coding_standards_m4 | May result in undefined behavior. |
-| test.c:19:5:19:34 | ____codeql_coding_standards_m5 | May result in undefined behavior. |
-| test.c:23:5:23:34 | ____codeql_coding_standards_m6 | May result in undefined behavior. |
+| test.c:4:6:4:38 | ____codeql_coding_standards_main1 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
+| test.c:8:5:8:37 | ____codeql_coding_standards_main2 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
+| test.c:27:5:27:37 | ____codeql_coding_standards_main6 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
+| test.c:32:6:32:38 | ____codeql_coding_standards_main7 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
+| test.c:36:5:36:37 | ____codeql_coding_standards_main8 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
+| test.c:40:5:40:37 | ____codeql_coding_standards_main9 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
+| test.c:44:5:44:38 | ____codeql_coding_standards_main10 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
+| test.c:48:5:48:38 | ____codeql_coding_standards_main11 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
diff --git a/c/misra/test/rules/RULE-1-3/test.c b/c/misra/test/rules/RULE-1-3/test.c
index 190cff4000..fd54959f56 100644
--- a/c/misra/test/rules/RULE-1-3/test.c
+++ b/c/misra/test/rules/RULE-1-3/test.c
@@ -1,25 +1,50 @@
-void main(void) { // COMPLIANT
+int main(void) { // COMPLIANT
}
-int ____codeql_coding_standards_m1(int argc, char **argv) { // NON_COMPLIANT
+void ____codeql_coding_standards_main1(void) { // NON_COMPLIANT
return 0;
}
-void ____codeql_coding_standards_m2(char *argc, char **argv) { // NON_COMPLIANT
+int ____codeql_coding_standards_main2() { // NON_COMPLIANT
+ return 0;
+}
+
+int ____codeql_coding_standards_main3(int argc, char **argv) { // COMPLIANT
+ return 0;
+}
+
+int ____codeql_coding_standards_main4(int argc, char argv[][]) { // COMPLIANT
+ return 0;
+}
+
+int ____codeql_coding_standards_main5(int argc, char *argv[]) { // COMPLIANT
+ return 0;
+}
+
+typedef int MY_INT;
+typedef char *MY_CHAR_PTR;
+
+int ____codeql_coding_standards_main6(MY_INT argc,
+ MY_CHAR_PTR argv[]) { // COMPLIANT
+ return 0;
+}
+
+void ____codeql_coding_standards_main7(char *argc,
+ char **argv) { // NON_COMPLIANT
}
-int ____codeql_coding_standards_m3(int argc, char *argv) { // NON_COMPLIANT
+int ____codeql_coding_standards_main8(int argc, char *argv) { // NON_COMPLIANT
return 0;
}
-int ____codeql_coding_standards_m4() { // NON_COMPLIANT
+int ____codeql_coding_standards_main9() { // NON_COMPLIANT
return 0;
}
-int ____codeql_coding_standards_m5(int argc, int *argv) { // NON_COMPLIANT
+int ____codeql_coding_standards_main10(int argc, int *argv) { // NON_COMPLIANT
return 0;
}
-int ____codeql_coding_standards_m6(int argc, int **argv) { // NON_COMPLIANT
+int ____codeql_coding_standards_main11(int argc, int **argv) { // NON_COMPLIANT
return 0;
}
diff --git a/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected
new file mode 100644
index 0000000000..4c8fdc27cf
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected
@@ -0,0 +1 @@
+| test.c:37:3:37:6 | call to gets | Call to obsolescent function 'gets'. |
diff --git a/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.qlref b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.qlref
new file mode 100644
index 0000000000..1a2ec096cf
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.qlref
@@ -0,0 +1 @@
+rules/RULE-1-5/CallToObsolescentFunctionGets.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.testref b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.testref
new file mode 100644
index 0000000000..1a6a69fc24
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.testref
@@ -0,0 +1 @@
+c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected
new file mode 100644
index 0000000000..854b200553
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected
@@ -0,0 +1,6 @@
+| test.c:22:1:22:14 | #define true 3 | Invalid define of boolean standard macro 'true'. |
+| test.c:23:1:23:15 | #define false 3 | Invalid define of boolean standard macro 'false'. |
+| test.c:24:1:24:18 | #define bool int * | Invalid define of boolean standard macro 'bool'. |
+| test.c:25:1:25:11 | #undef true | Invalid undefine of boolean standard macro 'true'. |
+| test.c:26:1:26:12 | #undef false | Invalid undefine of boolean standard macro 'false'. |
+| test.c:27:1:27:11 | #undef bool | Invalid undefine of boolean standard macro 'bool'. |
diff --git a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.qlref b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.qlref
new file mode 100644
index 0000000000..5b112609cc
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.qlref
@@ -0,0 +1 @@
+rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.testref b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.testref
new file mode 100644
index 0000000000..7d9f2ebc04
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.testref
@@ -0,0 +1 @@
+c/common/test/rules/missingstaticspecifierfunctionredeclarationshared/MissingStaticSpecifierFunctionRedeclarationShared.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.testref b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.testref
new file mode 100644
index 0000000000..23ed7c9fc5
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.testref
@@ -0,0 +1 @@
+c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.expected b/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.expected
new file mode 100644
index 0000000000..7b05a5fc0a
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.expected
@@ -0,0 +1 @@
+| test.c:14:3:14:9 | call to realloc | Size argument '$@' may equal zero in realloc call, resulting in obsolescent and/or implementation-defined behavior. | test.c:14:14:14:14 | 0 | 0 |
diff --git a/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.qlref b/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.qlref
new file mode 100644
index 0000000000..cef5e76d54
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.qlref
@@ -0,0 +1 @@
+rules/RULE-1-5/SizeInReallocCallIsZero.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.expected b/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.expected
new file mode 100644
index 0000000000..f86ad4c57c
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.expected
@@ -0,0 +1 @@
+| test.c:15:3:15:9 | call to realloc | Size argument '$@' equals zero in realloc call, resulting in obsolescent and/or implementation-defined behavior. | test.c:15:14:15:15 | p0 | p0 |
diff --git a/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.qlref b/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.qlref
new file mode 100644
index 0000000000..1287327c5d
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.qlref
@@ -0,0 +1 @@
+rules/RULE-1-5/SizeInReallocCallMayBeZero.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected
new file mode 100644
index 0000000000..ff25a58e3c
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected
@@ -0,0 +1,8 @@
+edges
+| test.c:39:16:39:20 | *call to fopen | test.c:41:15:41:18 | *file | provenance | |
+nodes
+| test.c:39:16:39:20 | *call to fopen | semmle.label | *call to fopen |
+| test.c:41:15:41:18 | *file | semmle.label | *file |
+subpaths
+#select
+| test.c:41:15:41:18 | *file | test.c:39:16:39:20 | *call to fopen | test.c:41:15:41:18 | *file | Obsolescent call to ungetc on file stream $@ at position zero. | test.c:39:16:39:20 | *call to fopen | *call to fopen |
diff --git a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.qlref b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.qlref
new file mode 100644
index 0000000000..8c28919dcb
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.qlref
@@ -0,0 +1 @@
+rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected
new file mode 100644
index 0000000000..edd607c52f
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected
@@ -0,0 +1 @@
+| test.c:29:18:29:36 | ATOMIC_VAR_INIT(value) | Usage of macro ATOMIC_VAR_INIT() is declared obscelescent in C18, and discouraged in earlier C versions. |
diff --git a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.qlref b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.qlref
new file mode 100644
index 0000000000..9a54fdc83a
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.qlref
@@ -0,0 +1 @@
+rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-1-5/test.c b/c/misra/test/rules/RULE-1-5/test.c
new file mode 100644
index 0000000000..52144bad13
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/test.c
@@ -0,0 +1,48 @@
+#include "stdatomic.h"
+#include "stdbool.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+void f1(int p0) {
+ // malloc() is not obsolete, though it is banned by Rule 21.3
+ int *t = malloc(10); // COMPLIANT
+
+ // Valid usage of realloc, but all use of realloc is banned by Rule 21.3
+ realloc(t, 20); // NON-COMPLIANT
+
+ // Obsolete usage of realloc.
+ realloc(t, 0); // NON-COMPLIANT
+ realloc(t, p0); // NON-COMPLIANT
+}
+
+extern const int g1; // COMPLIANT
+const extern int g2; // NON-COMPLIANT
+
+#define MY_TRUE 3 // COMPLIANT
+#define true 3 // NON-COMPLIANT
+#define false 3 // NON-COMPLIANT
+#define bool int * // NON-COMPLIANT
+#undef true // NON-COMPLIANT
+#undef false // NON-COMPLIANT
+#undef bool // NON-COMPLIANT
+
+_Atomic int g3 = ATOMIC_VAR_INIT(18); // NON-COMPLIANT
+_Atomic int g4 = 18; // COMPLIANT
+
+// `gets` was removed from C11.
+extern char *gets(FILE *stream);
+
+// Rule 21.6 covers the below cases:
+void f6(void) {
+ gets(stdin); // NON_COMPLIANT
+
+ FILE *file = fopen("", 0);
+ // Obsolete usage of ungetc.
+ ungetc('c', file); // NON-COMPLIANT
+
+ char buf[10];
+ fread(buf, sizeof(buf), 10, file);
+ // This is not an obsolete usage of ungetc, though ungetc isn't allowed by
+ // 21-3.
+ ungetc('c', file); // COMPLIANT
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.expected b/c/misra/test/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.expected
index b04a4ee4aa..8d1b1d8d1b 100644
--- a/c/misra/test/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.expected
+++ b/c/misra/test/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.expected
@@ -1,187 +1,191 @@
-| test.c:13:3:13:6 | access to array | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:14:3:14:6 | access to array | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:20:3:20:4 | + ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:21:3:21:4 | + ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:22:3:22:5 | + ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:27:3:27:4 | - ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:28:3:28:4 | - ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:29:3:29:5 | - ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:31:3:31:4 | - ... | Operand of essentially Unsigned type will be converted to a signed type with the signedness dependent on the implemented size of int. |
-| test.c:34:3:34:7 | ... + ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:36:3:36:8 | ... + ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:41:3:41:7 | ... - ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:43:3:43:8 | ... - ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:48:3:48:7 | ... + ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:50:3:50:8 | ... + ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:55:3:55:7 | ... - ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:57:3:57:8 | ... - ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:62:3:62:5 | ... ++ | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:64:3:64:6 | ... ++ | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:69:3:69:5 | ... -- | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:71:3:71:6 | ... -- | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:76:3:76:5 | ++ ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:78:3:78:6 | ++ ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:83:3:83:5 | -- ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:85:3:85:6 | -- ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:90:3:90:7 | ... * ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:91:3:91:7 | ... * ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:92:3:92:8 | ... * ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:97:3:97:7 | ... / ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:98:3:98:7 | ... / ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:99:3:99:8 | ... / ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:104:3:104:7 | ... * ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:105:3:105:7 | ... * ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:106:3:106:8 | ... * ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:111:3:111:7 | ... / ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:112:3:112:7 | ... / ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:113:3:113:8 | ... / ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:118:3:118:7 | ... % ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:119:3:119:7 | ... % ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:120:3:120:8 | ... % ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:125:3:125:7 | ... % ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:126:3:126:7 | ... % ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:127:3:127:8 | ... % ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:132:3:132:7 | ... < ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:139:3:139:7 | ... > ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:146:3:146:8 | ... <= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:153:3:153:8 | ... >= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:160:3:160:7 | ... < ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:167:3:167:7 | ... > ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:174:3:174:8 | ... <= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:181:3:181:8 | ... >= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:217:3:217:4 | ! ... | Operand of essentially Character type type interpreted as a Boolean value. |
-| test.c:218:3:218:5 | ! ... | Operand of essentially Enum Type type interpreted as a Boolean value. |
-| test.c:219:3:219:4 | ! ... | Operand of essentially Signed type type interpreted as a Boolean value. |
-| test.c:220:3:220:4 | ! ... | Operand of essentially Unsigned type type interpreted as a Boolean value. |
-| test.c:221:3:221:4 | ! ... | Operand of essentially Floating type type interpreted as a Boolean value. |
-| test.c:224:3:224:11 | ... && ... | Operand of essentially Character type type interpreted as a Boolean value. |
-| test.c:225:3:225:12 | ... && ... | Operand of essentially Enum Type type interpreted as a Boolean value. |
-| test.c:226:3:226:11 | ... && ... | Operand of essentially Signed type type interpreted as a Boolean value. |
-| test.c:227:3:227:11 | ... && ... | Operand of essentially Unsigned type type interpreted as a Boolean value. |
-| test.c:228:3:228:11 | ... && ... | Operand of essentially Floating type type interpreted as a Boolean value. |
-| test.c:231:3:231:12 | ... \|\| ... | Operand of essentially Character type type interpreted as a Boolean value. |
-| test.c:232:3:232:13 | ... \|\| ... | Operand of essentially Enum Type type interpreted as a Boolean value. |
-| test.c:233:3:233:12 | ... \|\| ... | Operand of essentially Signed type type interpreted as a Boolean value. |
-| test.c:234:3:234:12 | ... \|\| ... | Operand of essentially Unsigned type type interpreted as a Boolean value. |
-| test.c:235:3:235:12 | ... \|\| ... | Operand of essentially Floating type type interpreted as a Boolean value. |
-| test.c:238:3:238:11 | ... && ... | Operand of essentially Character type type interpreted as a Boolean value. |
-| test.c:239:3:239:12 | ... && ... | Operand of essentially Enum Type type interpreted as a Boolean value. |
-| test.c:240:3:240:11 | ... && ... | Operand of essentially Signed type type interpreted as a Boolean value. |
-| test.c:241:3:241:11 | ... && ... | Operand of essentially Unsigned type type interpreted as a Boolean value. |
-| test.c:242:3:242:11 | ... && ... | Operand of essentially Floating type type interpreted as a Boolean value. |
-| test.c:245:3:245:12 | ... \|\| ... | Operand of essentially Character type type interpreted as a Boolean value. |
-| test.c:246:3:246:13 | ... \|\| ... | Operand of essentially Enum Type type interpreted as a Boolean value. |
-| test.c:247:3:247:12 | ... \|\| ... | Operand of essentially Signed type type interpreted as a Boolean value. |
-| test.c:248:3:248:12 | ... \|\| ... | Operand of essentially Unsigned type type interpreted as a Boolean value. |
-| test.c:249:3:249:12 | ... \|\| ... | Operand of essentially Floating type type interpreted as a Boolean value. |
-| test.c:251:3:251:8 | ... << ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:252:3:252:8 | ... << ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:253:3:253:9 | ... << ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:254:3:254:8 | ... << ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:258:3:258:8 | ... >> ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:259:3:259:8 | ... >> ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:260:3:260:9 | ... >> ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:261:3:261:8 | ... >> ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:265:3:265:8 | ... << ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:266:3:266:8 | ... << ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:267:3:267:9 | ... << ... | Right hand operatand of shift operator is essentially Enum Type and not not essentially unsigned. |
-| test.c:268:3:268:8 | ... << ... | Right hand operatand of shift operator is essentially Signed type and not not essentially unsigned. |
-| test.c:272:3:272:8 | ... >> ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:273:3:273:8 | ... >> ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:274:3:274:9 | ... >> ... | Right hand operatand of shift operator is essentially Enum Type and not not essentially unsigned. |
-| test.c:275:3:275:8 | ... >> ... | Right hand operatand of shift operator is essentially Signed type and not not essentially unsigned. |
-| test.c:279:3:279:6 | ... & ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:280:3:280:6 | ... & ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:281:3:281:7 | ... & ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:282:3:282:6 | ... & ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:286:3:286:7 | ... \| ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:287:3:287:7 | ... \| ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:288:3:288:8 | ... \| ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:289:3:289:7 | ... \| ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:293:3:293:7 | ... ^ ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:294:3:294:7 | ... ^ ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:295:3:295:8 | ... ^ ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:296:3:296:7 | ... ^ ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:300:3:300:6 | ... & ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:301:3:301:6 | ... & ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:302:3:302:7 | ... & ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:303:3:303:6 | ... & ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:307:3:307:7 | ... \| ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:308:3:308:7 | ... \| ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:309:3:309:8 | ... \| ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:310:3:310:7 | ... \| ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:314:3:314:7 | ... ^ ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:315:3:315:7 | ... ^ ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:316:3:316:8 | ... ^ ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:317:3:317:7 | ... ^ ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:329:3:329:11 | ... ? ... : ... | Operand of essentially Character type type interpreted as a Boolean value. |
-| test.c:330:3:330:12 | ... ? ... : ... | Operand of essentially Enum Type type interpreted as a Boolean value. |
-| test.c:331:3:331:11 | ... ? ... : ... | Operand of essentially Signed type type interpreted as a Boolean value. |
-| test.c:332:3:332:11 | ... ? ... : ... | Operand of essentially Unsigned type type interpreted as a Boolean value. |
-| test.c:333:3:333:11 | ... ? ... : ... | Operand of essentially Floating type type interpreted as a Boolean value. |
-| test.c:342:3:342:8 | ... += ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:344:3:344:9 | ... += ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:349:3:349:8 | ... -= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:351:3:351:9 | ... -= ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:356:3:356:8 | ... += ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:358:3:358:9 | ... += ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:363:3:363:8 | ... -= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:365:3:365:9 | ... -= ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:370:3:370:8 | ... *= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:371:3:371:8 | ... *= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:372:3:372:9 | ... *= ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:377:3:377:8 | ... /= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:378:3:378:8 | ... /= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:379:3:379:9 | ... /= ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:384:3:384:8 | ... *= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:385:3:385:8 | ... *= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:386:3:386:9 | ... *= ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:391:3:391:8 | ... /= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:392:3:392:8 | ... /= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:393:3:393:9 | ... /= ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:398:3:398:8 | ... %= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:399:3:399:8 | ... %= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:400:3:400:9 | ... %= ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:405:3:405:8 | ... %= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:406:3:406:8 | ... %= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:407:3:407:9 | ... %= ... | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
-| test.c:412:3:412:9 | ... <<= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:413:3:413:9 | ... <<= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:414:3:414:10 | ... <<= ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:415:3:415:9 | ... <<= ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:419:3:419:9 | ... >>= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:420:3:420:9 | ... >>= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:421:3:421:10 | ... >>= ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:422:3:422:9 | ... >>= ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:426:3:426:9 | ... <<= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:427:3:427:9 | ... <<= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:428:3:428:10 | ... <<= ... | Right hand operatand of shift operator is essentially Enum Type and not not essentially unsigned. |
-| test.c:429:3:429:9 | ... <<= ... | Right hand operatand of shift operator is essentially Signed type and not not essentially unsigned. |
-| test.c:433:3:433:9 | ... >>= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:434:3:434:9 | ... >>= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:435:3:435:10 | ... >>= ... | Right hand operatand of shift operator is essentially Enum Type and not not essentially unsigned. |
-| test.c:436:3:436:9 | ... >>= ... | Right hand operatand of shift operator is essentially Signed type and not not essentially unsigned. |
-| test.c:440:3:440:8 | ... &= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:441:3:441:8 | ... &= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:442:3:442:9 | ... &= ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:443:3:443:8 | ... &= ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:447:3:447:8 | ... ^= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:448:3:448:8 | ... ^= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:449:3:449:9 | ... ^= ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:450:3:450:8 | ... ^= ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:454:3:454:8 | ... \|= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:455:3:455:8 | ... \|= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:456:3:456:9 | ... \|= ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:457:3:457:8 | ... \|= ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:461:3:461:8 | ... &= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:462:3:462:8 | ... &= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:463:3:463:9 | ... &= ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:464:3:464:8 | ... &= ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:468:3:468:8 | ... ^= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:469:3:469:8 | ... ^= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:470:3:470:9 | ... ^= ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:471:3:471:8 | ... ^= ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
-| test.c:475:3:475:8 | ... \|= ... | Operand of essentially Boolean type interpreted as a numeric value. |
-| test.c:476:3:476:8 | ... \|= ... | Operand of essentially Charater type interpreted as a numeric value. |
-| test.c:477:3:477:9 | ... \|= ... | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
-| test.c:478:3:478:8 | ... \|= ... | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:13:5:13:5 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:14:5:14:5 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:20:4:20:4 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:21:4:21:4 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:22:4:22:5 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:27:4:27:4 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:28:4:28:4 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:29:4:29:5 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:31:4:31:4 | u | Operand of essentially Unsigned type will be converted to a signed type with the signedness dependent on the implemented size of int. |
+| test.c:34:7:34:7 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:36:7:36:8 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:41:7:41:7 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:43:7:43:8 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:48:3:48:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:50:3:50:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:55:3:55:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:57:3:57:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:62:3:62:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:64:3:64:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:69:3:69:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:71:3:71:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:76:5:76:5 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:78:5:78:6 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:83:5:83:5 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:85:5:85:6 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:90:7:90:7 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:91:7:91:7 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:92:7:92:8 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:97:7:97:7 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:98:7:98:7 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:99:7:99:8 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:104:3:104:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:105:3:105:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:106:3:106:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:111:3:111:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:112:3:112:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:113:3:113:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:118:3:118:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:119:3:119:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:120:3:120:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:125:7:125:7 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:126:7:126:7 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:127:7:127:8 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:132:7:132:7 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:139:7:139:7 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:146:8:146:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:153:8:153:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:160:3:160:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:167:3:167:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:174:3:174:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:181:3:181:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:217:4:217:4 | c | Operand of essentially Character type type interpreted as a Boolean value. |
+| test.c:218:4:218:5 | e1 | Operand of essentially Enum Type type interpreted as a Boolean value. |
+| test.c:219:4:219:4 | s | Operand of essentially Signed type type interpreted as a Boolean value. |
+| test.c:220:4:220:4 | u | Operand of essentially Unsigned type type interpreted as a Boolean value. |
+| test.c:221:4:221:4 | f | Operand of essentially Floating type type interpreted as a Boolean value. |
+| test.c:224:3:224:3 | c | Operand of essentially Character type type interpreted as a Boolean value. |
+| test.c:225:3:225:4 | e1 | Operand of essentially Enum Type type interpreted as a Boolean value. |
+| test.c:226:3:226:3 | s | Operand of essentially Signed type type interpreted as a Boolean value. |
+| test.c:227:3:227:3 | u | Operand of essentially Unsigned type type interpreted as a Boolean value. |
+| test.c:228:3:228:3 | f | Operand of essentially Floating type type interpreted as a Boolean value. |
+| test.c:231:3:231:3 | c | Operand of essentially Character type type interpreted as a Boolean value. |
+| test.c:232:3:232:4 | e1 | Operand of essentially Enum Type type interpreted as a Boolean value. |
+| test.c:233:3:233:3 | s | Operand of essentially Signed type type interpreted as a Boolean value. |
+| test.c:234:3:234:3 | u | Operand of essentially Unsigned type type interpreted as a Boolean value. |
+| test.c:235:3:235:3 | f | Operand of essentially Floating type type interpreted as a Boolean value. |
+| test.c:238:11:238:11 | c | Operand of essentially Character type type interpreted as a Boolean value. |
+| test.c:239:11:239:12 | e1 | Operand of essentially Enum Type type interpreted as a Boolean value. |
+| test.c:240:11:240:11 | s | Operand of essentially Signed type type interpreted as a Boolean value. |
+| test.c:241:11:241:11 | u | Operand of essentially Unsigned type type interpreted as a Boolean value. |
+| test.c:242:11:242:11 | f | Operand of essentially Floating type type interpreted as a Boolean value. |
+| test.c:245:12:245:12 | c | Operand of essentially Character type type interpreted as a Boolean value. |
+| test.c:246:12:246:13 | e1 | Operand of essentially Enum Type type interpreted as a Boolean value. |
+| test.c:247:12:247:12 | s | Operand of essentially Signed type type interpreted as a Boolean value. |
+| test.c:248:12:248:12 | u | Operand of essentially Unsigned type type interpreted as a Boolean value. |
+| test.c:249:12:249:12 | f | Operand of essentially Floating type type interpreted as a Boolean value. |
+| test.c:251:3:251:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:252:3:252:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:253:3:253:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:254:3:254:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:258:3:258:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:259:3:259:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:260:3:260:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:261:3:261:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:265:8:265:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:266:8:266:8 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:267:8:267:9 | e1 | Right hand operand of shift operator is essentially Enum Type and not not essentially unsigned. |
+| test.c:268:8:268:8 | s | Right hand operand of shift operator is essentially Signed type and not not essentially unsigned. |
+| test.c:272:8:272:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:273:8:273:8 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:274:8:274:9 | e1 | Right hand operand of shift operator is essentially Enum Type and not not essentially unsigned. |
+| test.c:275:8:275:8 | s | Right hand operand of shift operator is essentially Signed type and not not essentially unsigned. |
+| test.c:279:3:279:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:280:3:280:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:281:3:281:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:282:3:282:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:286:3:286:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:287:3:287:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:288:3:288:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:289:3:289:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:293:3:293:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:294:3:294:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:295:3:295:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:296:3:296:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:300:6:300:6 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:301:6:301:6 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:302:6:302:7 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:303:6:303:6 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:307:7:307:7 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:308:7:308:7 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:309:7:309:8 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:310:7:310:7 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:314:7:314:7 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:315:7:315:7 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:316:7:316:8 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:317:7:317:7 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:321:4:321:4 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:322:4:322:4 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:323:4:323:5 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:324:4:324:4 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:329:3:329:3 | c | Operand of essentially Character type type interpreted as a Boolean value. |
+| test.c:330:3:330:4 | e1 | Operand of essentially Enum Type type interpreted as a Boolean value. |
+| test.c:331:3:331:3 | s | Operand of essentially Signed type type interpreted as a Boolean value. |
+| test.c:332:3:332:3 | u | Operand of essentially Unsigned type type interpreted as a Boolean value. |
+| test.c:333:3:333:3 | f | Operand of essentially Floating type type interpreted as a Boolean value. |
+| test.c:342:3:342:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:344:3:344:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:349:3:349:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:351:3:351:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:356:8:356:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:358:8:358:9 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:363:8:363:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:365:8:365:9 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:370:3:370:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:371:3:371:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:372:3:372:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:377:3:377:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:378:3:378:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:379:3:379:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:384:8:384:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:385:8:385:8 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:386:8:386:9 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:391:8:391:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:392:8:392:8 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:393:8:393:9 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:398:3:398:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:399:3:399:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:400:3:400:4 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:405:8:405:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:406:8:406:8 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:407:8:407:9 | e1 | Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type. |
+| test.c:412:3:412:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:413:3:413:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:414:3:414:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:415:3:415:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:419:3:419:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:420:3:420:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:421:3:421:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:422:3:422:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:426:9:426:9 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:427:9:427:9 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:428:9:428:10 | e1 | Right hand operand of shift operator is essentially Enum Type and not not essentially unsigned. |
+| test.c:429:9:429:9 | s | Right hand operand of shift operator is essentially Signed type and not not essentially unsigned. |
+| test.c:433:9:433:9 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:434:9:434:9 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:435:9:435:10 | e1 | Right hand operand of shift operator is essentially Enum Type and not not essentially unsigned. |
+| test.c:436:9:436:9 | s | Right hand operand of shift operator is essentially Signed type and not not essentially unsigned. |
+| test.c:440:3:440:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:441:3:441:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:442:3:442:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:443:3:443:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:447:3:447:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:448:3:448:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:449:3:449:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:450:3:450:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:454:3:454:3 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:455:3:455:3 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:456:3:456:4 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:457:3:457:3 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:461:8:461:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:462:8:462:8 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:463:8:463:9 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:464:8:464:8 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:468:8:468:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:469:8:469:8 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:470:8:470:9 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:471:8:471:8 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
+| test.c:475:8:475:8 | b | Operand of essentially Boolean type interpreted as a numeric value. |
+| test.c:476:8:476:8 | c | Operand of essentially Charater type interpreted as a numeric value. |
+| test.c:477:8:477:9 | e1 | Bitwise operator applied to operand of essentially Enum Type and not essentially unsigned. |
+| test.c:478:8:478:8 | s | Bitwise operator applied to operand of essentially Signed type and not essentially unsigned. |
diff --git a/c/misra/test/rules/RULE-10-4/test.c b/c/misra/test/rules/RULE-10-4/test.c
index 666590a2d5..cbcb7191f6 100644
--- a/c/misra/test/rules/RULE-10-4/test.c
+++ b/c/misra/test/rules/RULE-10-4/test.c
@@ -33,4 +33,13 @@ void testOps() {
A < A; // COMPLIANT
e1a < e2a; // NON_COMPLIANT
A < D; // NON_COMPLIANT
+
+ enum { G };
+ s32 + G; // COMPLIANT
+ c == '\n'; // COMPLIANT
+
+ typedef enum { H } E3;
+
+ E3 e3a = H;
+ e3a < H; // COMPLIANT
}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-11-1/ConversionBetweenFunctionPointerAndOtherType.expected b/c/misra/test/rules/RULE-11-1/ConversionBetweenFunctionPointerAndOtherType.expected
index ebe2c74742..0144180616 100644
--- a/c/misra/test/rules/RULE-11-1/ConversionBetweenFunctionPointerAndOtherType.expected
+++ b/c/misra/test/rules/RULE-11-1/ConversionBetweenFunctionPointerAndOtherType.expected
@@ -1,7 +1,6 @@
| test.c:11:8:11:16 | (fp1 *)... | Cast performed between a function pointer and another type. |
| test.c:11:8:11:16 | (fp1)... | Cast performed between a function pointer and another type. |
| test.c:12:14:12:23 | (void *)... | Cast performed between a function pointer and another type. |
-| test.c:14:8:14:15 | (fp2)... | Cast performed between a function pointer and another type. |
| test.c:15:8:15:15 | (fp2)... | Cast performed between a function pointer and another type. |
| test.c:22:12:22:13 | (fp1)... | Cast performed between a function pointer and another type. |
| test.c:25:8:25:9 | (fp1)... | Cast performed between a function pointer and another type. |
diff --git a/c/misra/test/rules/RULE-11-1/test.c b/c/misra/test/rules/RULE-11-1/test.c
index 858c6e68a9..4fcabb0599 100644
--- a/c/misra/test/rules/RULE-11-1/test.c
+++ b/c/misra/test/rules/RULE-11-1/test.c
@@ -11,7 +11,7 @@ void f1(void) {
v1 = (fp1 *)v2; // NON_COMPLIANT
void *v3 = (void *)v1; // NON_COMPLIANT
- v2 = (fp2 *)0; // NON_COMPLIANT
+ v2 = (fp2 *)0; // COMPLIANT - null pointer constant
v2 = (fp2 *)1; // NON_COMPLIANT
pfp2 v4;
diff --git a/c/misra/test/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.expected b/c/misra/test/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.expected
index 91fd9f274a..94cf6ee635 100644
--- a/c/misra/test/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.expected
+++ b/c/misra/test/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.expected
@@ -2,3 +2,7 @@
| test.c:14:8:14:9 | (int *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (int). |
| test.c:15:8:15:25 | (int *)... | Cast performed between a pointer to object type (short) and a pointer to a different object type (int). |
| test.c:15:15:15:25 | (short *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (short). |
+| test.c:20:3:20:17 | (const int *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (const int). |
+| test.c:21:3:21:16 | (int *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (int). |
+| test.c:22:20:22:21 | (int *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (int). |
+| test.c:23:3:23:18 | (long long *)... | Cast performed between a pointer to object type (int) and a pointer to a different object type (long long). |
diff --git a/c/misra/test/rules/RULE-11-3/test.c b/c/misra/test/rules/RULE-11-3/test.c
index 64ae688993..4730aeac03 100644
--- a/c/misra/test/rules/RULE-11-3/test.c
+++ b/c/misra/test/rules/RULE-11-3/test.c
@@ -13,4 +13,12 @@ void f1(void) {
int *v8 = (int *)0; // COMPLIANT
v8 = v2; // NON_COMPLIANT
v8 = (int *)(short *)v2; // NON_COMPLIANT
+ (const void *)v1; // COMPLIANT
+ const void *v9 = v1; // COMPLIANT
+ (int *)v9; // COMPLIANT - cast from void*
+ (const void *)v2; // COMPLIANT
+ (const int *)v2; // NON_COMPLIANT
+ (int *const)v2; // NON_COMPLIANT
+ int *const v10 = v2; // NON_COMPLIANT
+ (long long *)v10; // NON_COMPLIANT
}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.expected b/c/misra/test/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.expected
index 5fedfdcce4..17a2fa223f 100644
--- a/c/misra/test/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.expected
+++ b/c/misra/test/rules/RULE-11-4/ConversionBetweenPointerToObjectAndIntegerType.expected
@@ -1,6 +1,6 @@
-| test.c:5:21:5:42 | (unsigned int)... | Cast performed between a pointer to object type and a pointer to an integer type. |
-| test.c:5:35:5:42 | (int *)... | Cast performed between a pointer to object type and a pointer to an integer type. |
-| test.c:6:21:6:37 | (unsigned int)... | Cast performed between a pointer to object type and a pointer to an integer type. |
-| test.c:8:8:8:24 | (unsigned int)... | Cast performed between a pointer to object type and a pointer to an integer type. |
-| test.c:10:22:10:22 | (unsigned int *)... | Cast performed between a pointer to object type and a pointer to an integer type. |
-| test.c:12:22:12:39 | (unsigned int *)... | Cast performed between a pointer to object type and a pointer to an integer type. |
+| test.c:6:21:6:37 | (unsigned int)... | Cast from pointer to object type 'unsigned int *' to integer type 'unsigned int'. | test.c:6:21:6:37 | (unsigned int)... | |
+| test.c:8:8:8:24 | (unsigned int)... | Cast from pointer to object type 'unsigned int *' to integer type 'unsigned int'. | test.c:8:8:8:24 | (unsigned int)... | |
+| test.c:12:22:12:39 | (unsigned int *)... | Cast from integer type 'unsigned int' to pointer to object type 'unsigned int *'. | test.c:12:22:12:39 | (unsigned int *)... | |
+| test.c:18:1:18:24 | #define FOO (int *)0x200 | Cast from integer type 'int' to pointer to object type 'int *'. | test.c:18:1:18:24 | #define FOO (int *)0x200 | |
+| test.c:26:3:26:22 | (int *)... | Cast from integer type 'int' to pointer to object type 'int *' from expansion of macro $@. | test.c:20:1:20:34 | #define FOO_FUNCTIONAL(x) (int *)x | FOO_FUNCTIONAL |
+| test.c:27:14:27:25 | (int *)... | Cast from integer type 'int' to pointer to object type 'int *' from expansion of macro $@. | test.c:21:1:21:23 | #define FOO_INSERT(x) x | FOO_INSERT |
diff --git a/c/misra/test/rules/RULE-11-4/test.c b/c/misra/test/rules/RULE-11-4/test.c
index 25e3f3c4b2..283af5e560 100644
--- a/c/misra/test/rules/RULE-11-4/test.c
+++ b/c/misra/test/rules/RULE-11-4/test.c
@@ -2,12 +2,27 @@
void f1(void) {
unsigned int v1 = (unsigned int)(void *)0; // COMPLIANT
- unsigned int v2 = (unsigned int)(int *)0; // NON_COMPLIANT
+ unsigned int v2 = (unsigned int)(int *)0; // COMPLIANT
unsigned int v3 = (unsigned int)&v2; // NON_COMPLIANT
v3 = v2; // COMPLIANT
v3 = (unsigned int)&v2; // NON_COMPLIANT
v3 = NULL; // COMPLIANT
- unsigned int *v4 = 0; // NON_COMPLIANT
+ unsigned int *v4 = 0; // COMPLIANT
unsigned int *v5 = NULL; // COMPLIANT
unsigned int *v6 = (unsigned int *)v2; // NON_COMPLIANT
+ const void *v7 = 0;
+ (unsigned int)v7; // COMPLIANT - cast const void to int
+ (const void *)v1; // COMPLIANT - casting int to const void
+}
+
+#define FOO (int *)0x200 // NON_COMPLIANT
+#define FOO_WRAPPER FOO;
+#define FOO_FUNCTIONAL(x) (int *)x
+#define FOO_INSERT(x) x
+
+void test_macros() {
+ FOO; // Issue is reported at the macro
+ FOO_WRAPPER; // Issue is reported at the macro
+ FOO_FUNCTIONAL(0x200); // NON_COMPLIANT
+ FOO_INSERT((int *)0x200); // NON_COMPLIANT
}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.expected b/c/misra/test/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.expected
index 5b4eec8d15..42cf288b34 100644
--- a/c/misra/test/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.expected
+++ b/c/misra/test/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.expected
@@ -1 +1,2 @@
| test.c:6:13:6:21 | (int *)... | Cast performed from a void pointer into a pointer to an object (int *). |
+| test.c:11:3:11:11 | (int *)... | Cast performed from a void pointer into a pointer to an object (int *). |
diff --git a/c/misra/test/rules/RULE-11-5/test.c b/c/misra/test/rules/RULE-11-5/test.c
index a7ffa4822e..5b5a5b3a52 100644
--- a/c/misra/test/rules/RULE-11-5/test.c
+++ b/c/misra/test/rules/RULE-11-5/test.c
@@ -7,4 +7,8 @@ void f1(void) {
v2 = NULL; // COMPLIANT
void *v3 = (void *)v1; // COMPLIANT
v3 = (void *)v2; // COMPLIANT
+ const void *v4 = 0;
+ (int *)v4; // NON_COMPLIANT - const in type is irrelevant
+ (const void *)v1; // COMPLIANT - casting is from void to void, const addition
+ // should be irrelevant
}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-11-7/test.c b/c/misra/test/rules/RULE-11-7/test.c
index b7dd989b00..4891aaae85 100644
--- a/c/misra/test/rules/RULE-11-7/test.c
+++ b/c/misra/test/rules/RULE-11-7/test.c
@@ -7,4 +7,12 @@ void f1(void) {
float v4 = (float)(bool)v1; // NON_COMPLIANT
v1 = (int *)v2; // NON_COMPLIANT
v4 = (float)v3; // COMPLIANT
+ void *v5 = 0;
+ const void *v6 = 0;
+ // void pointers (regardless of specifier) are not pointers to object, so all
+ // these examples are compliant according to this rule
+ (bool)v5; // COMPLIANT
+ (bool)v6; // COMPLIANT
+ (void *)v2; // COMPLIANT
+ (const void *)v2; // COMPLIANT
}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-11-9/MacroNullNotUsedAsIntegerNullPointerConstant.expected b/c/misra/test/rules/RULE-11-9/MacroNullNotUsedAsIntegerNullPointerConstant.expected
index 8cdd34edd1..d854730296 100644
--- a/c/misra/test/rules/RULE-11-9/MacroNullNotUsedAsIntegerNullPointerConstant.expected
+++ b/c/misra/test/rules/RULE-11-9/MacroNullNotUsedAsIntegerNullPointerConstant.expected
@@ -1,4 +1,5 @@
| test.c:15:13:15:13 | 0 | $@ uses zero-value integer constant expression as null pointer constant. | test.c:15:7:15:13 | ... == ... | Equality operator |
| test.c:17:8:17:8 | 0 | $@ uses zero-value integer constant expression as null pointer constant. | test.c:17:3:17:8 | ... = ... | Assignment to pointer |
-| test.c:25:20:25:20 | 0 | $@ uses zero-value integer constant expression as null pointer constant. | test.c:25:3:25:35 | ... ? ... : ... | Ternary operator |
-| test.c:25:20:25:20 | 0 | $@ uses zero-value integer constant expression as null pointer constant. | test.c:25:15:25:20 | ... = ... | Assignment to pointer |
+| test.c:23:13:23:13 | 0 | $@ uses zero-value integer constant expression as null pointer constant. | test.c:23:3:23:13 | ... ? ... : ... | Ternary operator |
+| test.c:24:8:24:8 | 0 | $@ uses zero-value integer constant expression as null pointer constant. | test.c:24:3:24:13 | ... ? ... : ... | Ternary operator |
+| test.c:31:14:31:14 | 0 | $@ uses zero-value integer constant expression as null pointer constant. | test.c:31:9:31:14 | ... = ... | Assignment to pointer |
diff --git a/c/misra/test/rules/RULE-11-9/test.c b/c/misra/test/rules/RULE-11-9/test.c
index 216ea2b280..e87366d831 100644
--- a/c/misra/test/rules/RULE-11-9/test.c
+++ b/c/misra/test/rules/RULE-11-9/test.c
@@ -19,9 +19,16 @@ void *f1(void *p1, int p2) {
p1 = NULL; // COMPLIANT
if (p2 == 0) { // COMPLIANT
return NULL;
- } // COMPLIANT
- (p1) ? (p1 = NULL) : (p1 = NULL); // COMPLIANT
- (p2 > 0) ? (p1 = NULL) : (p1 = NULL); // COMPLIANT
- (p2 > 0) ? (p1 = 0) : (p1 = NULL); // NON_COMPLIANT
- return 0; // COMPLIANT
+ }
+ p2 ? p1 : 0; // NON_COMPLIANT
+ p2 ? 0 : p1; // NON_COMPLIANT
+ p2 ? (void *)0 : p1; // COMPLIANT
+ p2 ? p1 : (void *)0; // COMPLIANT
+ p2 ? p2 : 0; // COMPLIANT - p2 is not a pointer type
+ p2 ? 0 : p2; // COMPLIANT - p2 is not a pointer type
+ int x;
+ int *y;
+ p2 ? (p1 = 0) : p1; // NON_COMPLIANT - p1 is a pointer type
+ p2 ? (p2 = 0) : p1; // COMPLIANT - p2 is not a pointer type
+ return 0; // COMPLIANT
}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftRange.expected b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftRange.expected
index a4deb83a14..5ac6f8bfd4 100644
--- a/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftRange.expected
+++ b/c/misra/test/rules/RULE-12-2/RightHandOperandOfAShiftRange.expected
@@ -1,10 +1,12 @@
-| test.c:8:10:8:10 | 8 | The right hand operand of the shift operator shall lie in the range 0 to 7. |
-| test.c:9:10:9:11 | - ... | The right hand operand of the shift operator shall lie in the range 0 to 7. |
-| test.c:10:10:10:14 | ... + ... | The right hand operand of the shift operator shall lie in the range 0 to 7. |
-| test.c:11:10:11:14 | ... + ... | The right hand operand of the shift operator shall lie in the range 0 to 7. |
-| test.c:13:21:13:22 | 16 | The right hand operand of the shift operator shall lie in the range 0 to 15. |
-| test.c:16:9:16:9 | 8 | The right hand operand of the shift operator shall lie in the range 0 to 7. |
-| test.c:21:9:21:10 | 64 | The right hand operand of the shift operator shall lie in the range 0 to 63. |
-| test.c:25:10:25:10 | 8 | The right hand operand of the shift operator shall lie in the range 0 to 7. |
-| test.c:26:10:26:11 | 64 | The right hand operand of the shift operator shall lie in the range 0 to 7. |
-| test.c:30:16:30:17 | 64 | The right hand operand of the shift operator shall lie in the range 0 to 63. |
+| test.c:8:10:8:10 | 8 | The possible range of the right operand of the shift operator (8..8) is outside the the valid shift range (0..7) for the essential type of the left operand (uint8_t). | test.c:8:3:8:10 | ... >> ... | |
+| test.c:9:10:9:11 | - ... | The possible range of the right operand of the shift operator (-1..-1) is outside the the valid shift range (0..7) for the essential type of the left operand (uint8_t). | test.c:9:3:9:11 | ... >> ... | |
+| test.c:10:10:10:14 | ... + ... | The possible range of the right operand of the shift operator (8..8) is outside the the valid shift range (0..7) for the essential type of the left operand (uint8_t). | test.c:10:3:10:14 | ... >> ... | |
+| test.c:11:10:11:14 | ... + ... | The possible range of the right operand of the shift operator (8..8) is outside the the valid shift range (0..7) for the essential type of the left operand (uint8_t). | test.c:11:3:11:14 | ... << ... | |
+| test.c:13:21:13:22 | 16 | The possible range of the right operand of the shift operator (16..16) is outside the the valid shift range (0..15) for the essential type of the left operand (uint16_t). | test.c:13:3:13:22 | ... << ... | |
+| test.c:16:9:16:9 | 8 | The possible range of the right operand of the shift operator (8..8) is outside the the valid shift range (0..7) for the essential type of the left operand (unsigned char). | test.c:16:3:16:9 | ... << ... | |
+| test.c:21:9:21:10 | 64 | The possible range of the right operand of the shift operator (64..64) is outside the the valid shift range (0..63) for the essential type of the left operand (unsigned long). | test.c:21:3:21:10 | ... << ... | |
+| test.c:26:10:26:11 | 64 | The possible range of the right operand of the shift operator (64..64) is outside the the valid shift range (0..63) for the essential type of the left operand (unsigned long). | test.c:26:3:26:11 | ... << ... | |
+| test.c:30:16:30:17 | 64 | The possible range of the right operand of the shift operator (64..64) is outside the the valid shift range (0..63) for the essential type of the left operand (unsigned long). | test.c:30:3:30:17 | ... << ... | |
+| test.c:34:8:34:8 | y | The possible range of the right operand of the shift operator (0..4294967295) is outside the the valid shift range (0..31) for the essential type of the left operand (unsigned int). | test.c:34:3:34:8 | ... >> ... | |
+| test.c:40:8:40:8 | y | The possible range of the right operand of the shift operator (-2147483648..2147483647) is outside the the valid shift range (0..31) for the essential type of the left operand (signed int). | test.c:40:3:40:8 | ... >> ... | |
+| test.c:42:8:42:8 | y | The possible range of the right operand of the shift operator (-31..31) is outside the the valid shift range (0..31) for the essential type of the left operand (signed int). | test.c:42:3:42:8 | ... >> ... | |
diff --git a/c/misra/test/rules/RULE-12-2/test.c b/c/misra/test/rules/RULE-12-2/test.c
index 449a47b7ae..db7b7b062d 100644
--- a/c/misra/test/rules/RULE-12-2/test.c
+++ b/c/misra/test/rules/RULE-12-2/test.c
@@ -29,3 +29,15 @@ void f1() {
ULONG_MAX << 8; // COMPLIANT
ULONG_MAX << 64; // NON_COMPLIANT
}
+
+void unsignedRemAssign(unsigned int y, unsigned int x) {
+ x >> y; // NON_COMPLIANT
+ y %= 32;
+ x >> y; // COMPLIANT
+}
+
+void signedRemAssign(signed int y, signed int x) {
+ x >> y; // NON_COMPLIANT
+ y %= 32;
+ x >> y; // NON_COMPLIANT - may be negative
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.expected b/c/misra/test/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.expected
new file mode 100644
index 0000000000..a94e37baa4
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.expected
@@ -0,0 +1,4 @@
+| test.c:6:15:6:16 | f4 | The function f4 is declared _noreturn but has a return type of int. |
+| test.c:19:15:19:16 | f8 | The function f8 is declared _noreturn but has a return type of int. |
+| test.c:24:17:24:18 | f9 | The function f9 is declared _noreturn but has a return type of void *. |
+| test.c:26:31:26:33 | f10 | The function f10 is declared _noreturn but has a return type of int. |
diff --git a/c/misra/test/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.qlref b/c/misra/test/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.qlref
new file mode 100644
index 0000000000..6726b6957a
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.qlref
@@ -0,0 +1 @@
+rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-17-10/test.c b/c/misra/test/rules/RULE-17-10/test.c
new file mode 100644
index 0000000000..b5fc988af2
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-10/test.c
@@ -0,0 +1,26 @@
+#include "stdlib.h"
+
+void f1(); // COMPLIANT
+int f2(); // COMPLIANT
+_Noreturn void f3(); // COMPLIANT
+_Noreturn int f4(); // NON-COMPLIANT
+
+void f5() { // COMPLIANT
+}
+
+int f6() { // COMPLIANT
+ return 0;
+}
+
+_Noreturn void f7() { // COMPLIANT
+ abort();
+}
+
+_Noreturn int f8() { // NON-COMPLIANT
+ abort();
+ return 0;
+}
+
+_Noreturn void *f9(); // NON-COMPLIANT
+
+__attribute__((noreturn)) int f10(); // NON-COMPLIANT
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.expected b/c/misra/test/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.expected
new file mode 100644
index 0000000000..ecb77a477c
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.expected
@@ -0,0 +1,6 @@
+| test.c:7:6:7:21 | test_noreturn_f2 | The function test_noreturn_f2 cannot return and should be declared as _Noreturn. |
+| test.c:18:6:18:21 | test_noreturn_f4 | The function test_noreturn_f4 cannot return and should be declared as _Noreturn. |
+| test.c:47:6:47:21 | test_noreturn_f8 | The function test_noreturn_f8 cannot return and should be declared as _Noreturn. |
+| test.c:63:6:63:22 | test_noreturn_f10 | The function test_noreturn_f10 cannot return and should be declared as _Noreturn. |
+| test.c:97:6:97:22 | test_noreturn_f15 | The function test_noreturn_f15 cannot return and should be declared as _Noreturn. |
+| test.c:101:6:101:22 | test_noreturn_f16 | The function test_noreturn_f16 cannot return and should be declared as _Noreturn. |
diff --git a/c/misra/test/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.qlref b/c/misra/test/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.qlref
new file mode 100644
index 0000000000..feb6f40804
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.qlref
@@ -0,0 +1 @@
+rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-17-11/test.c b/c/misra/test/rules/RULE-17-11/test.c
new file mode 100644
index 0000000000..7baaea5821
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-11/test.c
@@ -0,0 +1,104 @@
+#include "stdlib.h"
+
+_Noreturn void test_noreturn_f1(int i) { // COMPLIANT
+ abort();
+}
+
+void test_noreturn_f2(int i) { // NON_COMPLIANT
+ abort();
+}
+
+_Noreturn void test_noreturn_f3(int i) { // COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+ exit(1);
+}
+
+void test_noreturn_f4(int i) { // NON_COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+ exit(1);
+}
+
+void test_noreturn_f5(int i) { // COMPLIANT
+ if (i > 0) {
+ return;
+ }
+ exit(1);
+}
+
+void test_noreturn_f6(int i) { // COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+ if (i < 0) {
+ abort();
+ }
+}
+
+void test_noreturn_f7(int i) { // COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+}
+
+void test_noreturn_f8(int i) { // NON_COMPLIANT
+ if (i > 0) {
+ abort();
+ } else {
+ abort();
+ }
+}
+
+_Noreturn void test_noreturn_f9(int i) { // COMPLIANT
+ if (i > 0) {
+ abort();
+ } else {
+ abort();
+ }
+}
+
+void test_noreturn_f10(int i) { // NON_COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+ while (1) {
+ i = 5;
+ }
+}
+
+_Noreturn void test_noreturn_f11(int i) { // COMPLIANT
+ if (i > 0) {
+ abort();
+ }
+ while (1) {
+ i = 5;
+ }
+}
+
+void test_noreturn_f12(); // COMPLIANT
+
+__attribute__((noreturn)) void test_noreturn_f13(int i) { // COMPLIANT
+ abort();
+}
+
+// Allowed by exception. It is undefined behavior for main() to be declared with
+// noreturn.
+int main(char **argv, int argc) { // COMPLIANT
+ abort();
+}
+
+_Noreturn void test_noreturn_f14(int i) { // COMPLIANT
+ test_noreturn_f1(i);
+}
+
+void test_noreturn_f15(int i) { // NON_COMPLIANT
+ test_noreturn_f1(i);
+}
+
+void test_noreturn_f16(int i) { // NON_COMPLIANT
+ // Infinite tail recursion
+ test_noreturn_f16(i);
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-17-12/FunctionAddressesShouldAddressOperator.expected b/c/misra/test/rules/RULE-17-12/FunctionAddressesShouldAddressOperator.expected
new file mode 100644
index 0000000000..5a37cbd97e
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-12/FunctionAddressesShouldAddressOperator.expected
@@ -0,0 +1,13 @@
+| test.c:14:25:14:29 | func2 | The address of function func2 is taken without the & operator. |
+| test.c:15:25:15:29 | func3 | The address of function func3 is taken without the & operator. |
+| test.c:21:12:21:16 | func1 | The address of function func1 is taken without the & operator. |
+| test.c:38:3:38:7 | func1 | The address of function func1 is taken without the & operator. |
+| test.c:39:3:39:7 | func2 | The address of function func2 is taken without the & operator. |
+| test.c:57:13:57:17 | func1 | The address of function func1 is taken without the & operator. |
+| test.c:58:21:58:25 | func2 | The address of function func2 is taken without the & operator. |
+| test.c:59:13:59:17 | func1 | The address of function func1 is taken without the & operator. |
+| test.c:59:20:59:24 | func2 | The address of function func2 is taken without the & operator. |
+| test.c:67:11:67:15 | func1 | The address of function func1 is taken without the & operator. |
+| test.c:68:12:68:16 | func1 | The address of function func1 is taken without the & operator. |
+| test.c:69:12:69:16 | func1 | The address of function func1 is taken without the & operator. |
+| test.c:71:18:71:22 | func1 | The address of function func1 is taken without the & operator. |
diff --git a/c/misra/test/rules/RULE-17-12/FunctionAddressesShouldAddressOperator.qlref b/c/misra/test/rules/RULE-17-12/FunctionAddressesShouldAddressOperator.qlref
new file mode 100644
index 0000000000..f0a4753620
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-12/FunctionAddressesShouldAddressOperator.qlref
@@ -0,0 +1 @@
+rules/RULE-17-12/FunctionAddressesShouldAddressOperator.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-17-12/test.c b/c/misra/test/rules/RULE-17-12/test.c
new file mode 100644
index 0000000000..5ab5a4984d
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-12/test.c
@@ -0,0 +1,107 @@
+void func1() {}
+void func2(int x, char *y) {}
+
+typedef struct {
+} s;
+
+int func3() { return 0; }
+
+typedef void (*func_ptr_t1)();
+typedef void (*func_ptr_t2)(int x, char *y);
+typedef s (*func_ptr_t3)();
+
+func_ptr_t1 func_ptr1 = &func1; // COMPLIANT
+func_ptr_t2 func_ptr2 = func2; // NON-COMPLIANT
+func_ptr_t3 func_ptr3 = func3 + 0; // NON-COMPLIANT
+
+void take_func(func_ptr_t1 f1, func_ptr_t2 f2);
+
+func_ptr_t1 returns_func(int x) {
+ if (x == 0) {
+ return func1; // NON-COMPLIANT
+ } else if (x == 1) {
+ return &func1; // COMPLIANT
+ }
+
+ return returns_func(0); // COMPLIANT
+}
+
+#define MACRO_IDENTITY(f) (f)
+#define MACRO_INVOKE_RISKY(f) (f())
+#define MACRO_INVOKE_IMPROVED(f) ((f)())
+#define MACRO_INVOKE_AND_USE_AS_TOKEN(f) f(0, #f)
+
+void test() {
+ func1(); // COMPLIANT
+ func2(1, "hello"); // COMPLIANT
+
+ func1; // NON-COMPLIANT
+ func2; // NON-COMPLIANT
+
+ &func1; // COMPLIANT
+ &func2; // COMPLIANT
+
+ (func1)(); // COMPLIANT
+ (func2)(1, "hello"); // COMPLIANT
+
+ &(func1); // COMPLIANT
+ &(func2); // COMPLIANT
+
+ (&func1)(); // COMPLIANT
+ (&func2)(1, "hello"); // COMPLIANT
+
+ (func1()); // COMPLIANT
+ (func2(1, "hello")); // COMPLIANT
+
+ take_func(&func1, &func2); // COMPLIANT
+ take_func(func1, &func2); // NON-COMPLIANT
+ take_func(&func1, func2); // NON-COMPLIANT
+ take_func(func1, func2); // NON-COMPLIANT
+
+ returns_func(0); // COMPLIANT
+ returns_func(0)(); // COMPLIANT
+ (returns_func(0))(); // COMPLIANT
+
+ (void *)&func1; // COMPLIANT
+ (void *)(&func1); // COMPLIANT
+ (void *)func1; // NON-COMPLIANT
+ (void *)(func1); // NON-COMPLIANT
+ ((void *)func1); // NON-COMPLIANT
+
+ MACRO_IDENTITY(func1); // NON-COMPLIANT
+ MACRO_IDENTITY(func1)(); // NON-COMPLIANT[FALSE NEGATIVE]
+ MACRO_IDENTITY(&func1); // COMPLIANT
+ MACRO_IDENTITY (&func1)(); // COMPLIANT
+
+ MACRO_INVOKE_RISKY(func3); // NON-COMPLIANT[FALSE NEGATIVE]
+ MACRO_INVOKE_IMPROVED(func3); // NON-COMPLIANT[FALSE NEGATIVE]
+ MACRO_INVOKE_IMPROVED(&func3); // COMPLIANT
+
+ MACRO_INVOKE_AND_USE_AS_TOKEN(func1); // COMPLIANT
+
+ // Function pointers are exempt from this rule.
+ func_ptr1(); // COMPLIANT
+ func_ptr2(1, "hello"); // COMPLIANT
+ func_ptr1; // COMPLIANT
+ func_ptr2; // COMPLIANT
+ &func_ptr1; // COMPLIANT
+ &func_ptr2; // COMPLIANT
+ (func_ptr1)(); // COMPLIANT
+ (func_ptr2)(1, "hello"); // COMPLIANT
+ (*func_ptr1)(); // COMPLIANT
+ (*func_ptr2)(1, "hello"); // COMPLIANT
+ take_func(func_ptr1, func_ptr2); // COMPLIANT
+ (void *)func_ptr1; // COMPLIANT
+ (void *)&func_ptr1; // COMPLIANT
+ (void *)(&func_ptr1); // COMPLIANT
+ (void *)func_ptr1; // COMPLIANT
+ (void *)(func_ptr1); // COMPLIANT
+ ((void *)func_ptr1); // COMPLIANT
+ MACRO_IDENTITY(func_ptr1); // COMPLIANT
+ MACRO_IDENTITY(func_ptr1)(); // COMPLIANT
+ MACRO_IDENTITY(&func_ptr1); // COMPLIANT
+ (*MACRO_IDENTITY(&func_ptr1))(); // COMPLIANT
+ MACRO_INVOKE_RISKY(func_ptr3); // COMPLIANT
+ MACRO_INVOKE_IMPROVED(func_ptr3); // COMPLIANT
+ MACRO_INVOKE_IMPROVED(*&func_ptr3); // COMPLIANT
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-17-9/ReturnStatementInNoreturnFunction.testref b/c/misra/test/rules/RULE-17-9/ReturnStatementInNoreturnFunction.testref
new file mode 100644
index 0000000000..09a6d90538
--- /dev/null
+++ b/c/misra/test/rules/RULE-17-9/ReturnStatementInNoreturnFunction.testref
@@ -0,0 +1 @@
+c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-2-2/DeadCode.expected b/c/misra/test/rules/RULE-2-2/DeadCode.expected
new file mode 100644
index 0000000000..e25a5a97ef
--- /dev/null
+++ b/c/misra/test/rules/RULE-2-2/DeadCode.expected
@@ -0,0 +1,9 @@
+| test.c:15:3:15:11 | ... = ... | Assignment to dead1 is unused and has no side effects. | test.c:15:3:15:11 | ... = ... | |
+| test.c:16:3:16:11 | ... = ... | Assignment to dead2 is unused and has no side effects. | test.c:16:3:16:11 | ... = ... | |
+| test.c:19:3:19:7 | ... + ... | Result of operation is unused and has no side effects. | test.c:19:3:19:7 | ... + ... | |
+| test.c:21:3:21:17 | call to no_side_effects | Result of operation is unused and has no side effects from call to function $@. | test.c:2:5:2:19 | no_side_effects | no_side_effects |
+| test.c:23:3:23:30 | (int)... | Cast operation is unused. | test.c:23:3:23:30 | (int)... | |
+| test.c:24:3:24:25 | (int)... | Cast operation is unused. | test.c:24:3:24:25 | (int)... | |
+| test.c:27:4:27:18 | call to no_side_effects | Result of operation is unused and has no side effects from call to function $@. | test.c:2:5:2:19 | no_side_effects | no_side_effects |
+| test.c:37:3:37:27 | call to no_side_effects | Result of operation is unused and has no side effects from call to function $@. | test.c:2:5:2:19 | no_side_effects | no_side_effects |
+| test.c:38:7:38:31 | call to no_side_effects | Result of operation is unused and has no side effects from call to function $@. | test.c:2:5:2:19 | no_side_effects | no_side_effects |
diff --git a/c/misra/test/rules/RULE-2-2/DeadCode.qlref b/c/misra/test/rules/RULE-2-2/DeadCode.qlref
new file mode 100644
index 0000000000..761e04d51b
--- /dev/null
+++ b/c/misra/test/rules/RULE-2-2/DeadCode.qlref
@@ -0,0 +1 @@
+rules/RULE-2-2/DeadCode.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-2-2/DeadCode.testref b/c/misra/test/rules/RULE-2-2/DeadCode.testref
deleted file mode 100644
index f084f30aaa..0000000000
--- a/c/misra/test/rules/RULE-2-2/DeadCode.testref
+++ /dev/null
@@ -1 +0,0 @@
-c/common/test/rules/deadcode/DeadCode.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-2-2/test.c b/c/misra/test/rules/RULE-2-2/test.c
new file mode 100644
index 0000000000..f8248c52d2
--- /dev/null
+++ b/c/misra/test/rules/RULE-2-2/test.c
@@ -0,0 +1,42 @@
+int may_have_side_effects();
+int no_side_effects(int x) { return 1 + 2; }
+int no_side_effects_nondeterministic();
+
+int test_dead_code(int x) {
+ int live1 = may_have_side_effects(),
+ live2 = may_have_side_effects(); // COMPLIANT
+ int live3 = 0,
+ live4 = may_have_side_effects(); // COMPLIANT
+ int live5 = 0, live6 = 0; // COMPLIANT
+ live5 = 1; // COMPLIANT
+ live6 = 2; // COMPLIANT
+
+ int dead1 = 0, dead2 = 0; // COMPLIANT - init not considered by this rule
+ dead1 = 1; // NON_COMPLIANT - useless assignment
+ dead2 = 1; // NON_COMPLIANT - useless assignment
+
+ may_have_side_effects(); // COMPLIANT
+ 1 + 2; // NON_COMPLIANT
+
+ no_side_effects(x); // NON_COMPLIANT
+
+ (int)may_have_side_effects(); // NON_COMPLIANT
+ (int)no_side_effects(x); // NON_COMPLIANT
+ (void)no_side_effects(x); // COMPLIANT
+ (may_have_side_effects()); // COMPLIANT
+ (no_side_effects(x)); // NON_COMPLIANT
+
+#define FULL_STMT_NO_SIDE_EFFECTS no_side_effects(1);
+#define PART_STMT_NO_SIDE_EFFECTS no_side_effects(1)
+#define BLOCK_SOME_SIDE_EFFECTS \
+ { \
+ may_have_side_effects(); \
+ no_side_effects(1); \
+ }
+
+ FULL_STMT_NO_SIDE_EFFECTS // NON_COMPLIANT
+ PART_STMT_NO_SIDE_EFFECTS; // NON_COMPLIANT
+ BLOCK_SOME_SIDE_EFFECTS; // COMPLIANT
+
+ return live5 + live6; // COMPLIANT
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-2-5/test.c b/c/misra/test/rules/RULE-2-5/test.c
index f37acb1509..15930f68d1 100644
--- a/c/misra/test/rules/RULE-2-5/test.c
+++ b/c/misra/test/rules/RULE-2-5/test.c
@@ -13,4 +13,55 @@
void test() {
MACRO2;
HEADER_MACRO2;
-}
\ No newline at end of file
+}
+
+#define CHECKED_MACRO_1 // COMPLIANT - used in branch
+#define CHECKED_MACRO_2 // COMPLIANT - used in branch
+#define CHECKED_MACRO_3 // COMPLIANT - used in branch
+
+#ifdef CHECKED_MACRO_1
+#endif
+
+#ifndef CHECKED_MACRO_2
+#endif
+
+#if defined(CHECKED_MACRO_3)
+#endif
+
+// In the case above, the extractor will identify macro accesses with each use
+// of the macro. In the case above, the extractor does not tie them together,
+// but the standard considers this acceptable usage. Notably, this type of
+// pattern occurs for header guards.
+
+#ifdef CHECKED_MACRO_BEFORE_1
+#endif
+
+#ifndef CHECKED_MACRO_BEFORE_2
+#endif
+
+#if defined(CHECKED_MACRO_BEFORE_3)
+#endif
+
+// clang-format off
+
+#if defined (CHECKED_MACRO_BEFORE_4)
+#endif
+
+#if defined( CHECKED_MACRO_BEFORE_5 )
+#endif
+
+#if defined ( CHECKED_MACRO_BEFORE_6 )
+#endif
+
+#if defined CHECKED_MACRO_BEFORE_7
+#endif
+
+// clang-format on
+
+#define CHECKED_MACRO_BEFORE_1 // COMPLIANT - used in branch
+#define CHECKED_MACRO_BEFORE_2 // COMPLIANT - used in branch
+#define CHECKED_MACRO_BEFORE_3 // COMPLIANT - used in branch
+#define CHECKED_MACRO_BEFORE_4 // COMPLIANT - used in branch
+#define CHECKED_MACRO_BEFORE_5 // COMPLIANT - used in branch
+#define CHECKED_MACRO_BEFORE_6 // COMPLIANT - used in branch
+#define CHECKED_MACRO_BEFORE_7 // COMPLIANT - used in branch
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.expected b/c/misra/test/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.expected
index bdfec99b4a..cded1a0a89 100644
--- a/c/misra/test/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.expected
+++ b/c/misra/test/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.expected
@@ -1,10 +1,10 @@
edges
-| test.c:12:13:12:15 | a | test.c:14:10:14:10 | a |
-| test.c:12:13:12:15 | a | test.c:23:13:23:13 | a |
-| test.c:12:13:12:15 | a | test.c:24:10:24:10 | a |
-| test.c:13:13:13:15 | b | test.c:14:13:14:13 | b |
-| test.c:18:15:18:28 | {...} | test.c:21:10:21:10 | e |
-| test.c:19:15:19:28 | {...} | test.c:21:13:21:13 | f |
+| test.c:12:13:12:15 | a | test.c:14:10:14:10 | a | provenance | |
+| test.c:12:13:12:15 | a | test.c:23:13:23:13 | a | provenance | |
+| test.c:12:13:12:15 | a | test.c:24:10:24:10 | a | provenance | |
+| test.c:13:13:13:15 | b | test.c:14:13:14:13 | b | provenance | |
+| test.c:18:15:18:28 | {...} | test.c:21:10:21:10 | e | provenance | |
+| test.c:19:15:19:28 | {...} | test.c:21:13:21:13 | f | provenance | |
nodes
| test.c:10:10:10:12 | a | semmle.label | a |
| test.c:10:15:10:17 | b | semmle.label | b |
diff --git a/c/misra/test/rules/RULE-21-24/CallToBannedRandomFunction.expected b/c/misra/test/rules/RULE-21-24/CallToBannedRandomFunction.expected
new file mode 100644
index 0000000000..b3953d166b
--- /dev/null
+++ b/c/misra/test/rules/RULE-21-24/CallToBannedRandomFunction.expected
@@ -0,0 +1,2 @@
+| test.c:5:3:5:7 | call to srand | Call to banned random number generation function 'srand'. |
+| test.c:6:11:6:14 | call to rand | Call to banned random number generation function 'rand'. |
diff --git a/c/misra/test/rules/RULE-21-24/CallToBannedRandomFunction.qlref b/c/misra/test/rules/RULE-21-24/CallToBannedRandomFunction.qlref
new file mode 100644
index 0000000000..b229c0e84f
--- /dev/null
+++ b/c/misra/test/rules/RULE-21-24/CallToBannedRandomFunction.qlref
@@ -0,0 +1 @@
+rules/RULE-21-24/CallToBannedRandomFunction.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-21-24/test.c b/c/misra/test/rules/RULE-21-24/test.c
new file mode 100644
index 0000000000..56cfae3cb1
--- /dev/null
+++ b/c/misra/test/rules/RULE-21-24/test.c
@@ -0,0 +1,11 @@
+#include "stdlib.h"
+
+void f() {
+ // rand() is banned -- and thus, so is srand().
+ srand(0); // NON-COMPLIANT
+ int x = rand(); // NON-COMPLIANT
+
+ // Other functions from stdlib are not banned by this rule.
+ x = abs(-4); // COMPLIANT
+ getenv("ENV_VAR"); // COMPLIANT
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected b/c/misra/test/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected
index 0215c2e5b8..e9ea6daecc 100644
--- a/c/misra/test/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected
+++ b/c/misra/test/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected
@@ -1,5 +1,5 @@
-| test.c:8:15:8:20 | call to malloc | Use of banned dynamic memory allocation. |
-| test.c:9:15:9:20 | call to calloc | Use of banned dynamic memory allocation. |
-| test.c:10:8:10:14 | call to realloc | Use of banned dynamic memory allocation. |
-| test.c:11:3:11:6 | call to free | Use of banned dynamic memory deallocation. |
-| test.c:12:3:12:6 | call to free | Use of banned dynamic memory deallocation. |
+| test.c:13:15:13:20 | call to malloc | Use of banned dynamic memory allocation. |
+| test.c:14:15:14:20 | call to calloc | Use of banned dynamic memory allocation. |
+| test.c:15:8:15:14 | call to realloc | Use of banned dynamic memory allocation. |
+| test.c:16:3:16:6 | call to free | Use of banned dynamic memory deallocation. |
+| test.c:17:3:17:6 | call to free | Use of banned dynamic memory deallocation. |
diff --git a/c/misra/test/rules/RULE-21-3/test.c b/c/misra/test/rules/RULE-21-3/test.c
index d9aee3a322..fd4543faaf 100644
--- a/c/misra/test/rules/RULE-21-3/test.c
+++ b/c/misra/test/rules/RULE-21-3/test.c
@@ -1,3 +1,8 @@
+// Note: A subset of these cases are also tested in c/misra/test/rules/RULE-1-5
+// via a MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref and .expected file in
+// that directory. Changes to these tests may require updating the test code or
+// expectations in that directory as well.
+
#include
#include
void f2();
diff --git a/c/misra/test/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.expected b/c/misra/test/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.expected
index 0dee7e9b3d..672480db33 100644
--- a/c/misra/test/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.expected
+++ b/c/misra/test/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.expected
@@ -1,7 +1,7 @@
-| test.c:8:10:8:14 | call to scanf | Call to banned function scanf. |
-| test.c:9:5:9:10 | call to printf | Call to banned function printf. |
-| test.c:16:16:16:21 | call to fgetwc | Call to banned function fgetwc. |
-| test.c:17:5:17:12 | call to putwchar | Call to banned function putwchar. |
-| test.c:22:7:22:10 | call to puts | Call to banned function puts. |
-| test.c:24:7:24:10 | call to puts | Call to banned function puts. |
-| test.c:26:5:26:8 | call to puts | Call to banned function puts. |
+| test.c:13:10:13:14 | call to scanf | Call to banned function scanf. |
+| test.c:14:5:14:10 | call to printf | Call to banned function printf. |
+| test.c:21:16:21:21 | call to fgetwc | Call to banned function fgetwc. |
+| test.c:22:5:22:12 | call to putwchar | Call to banned function putwchar. |
+| test.c:27:7:27:10 | call to puts | Call to banned function puts. |
+| test.c:29:7:29:10 | call to puts | Call to banned function puts. |
+| test.c:31:5:31:8 | call to puts | Call to banned function puts. |
diff --git a/c/misra/test/rules/RULE-21-6/test.c b/c/misra/test/rules/RULE-21-6/test.c
index 0ae580164e..b66bb9b6b7 100644
--- a/c/misra/test/rules/RULE-21-6/test.c
+++ b/c/misra/test/rules/RULE-21-6/test.c
@@ -1,3 +1,8 @@
+// Note: A subset of these cases are also tested in c/misra/test/rules/RULE-1-5
+// via a StandardLibraryInputoutputFunctionsUsed.qlref and .expected file in
+// that directory. Changes to these tests may require updating the test code or
+// expectations in that directory as well.
+
#include
#include
#include
diff --git a/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected
index 12507b2d3f..d44164d116 100644
--- a/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected
+++ b/c/misra/test/rules/RULE-5-4/MacroIdentifiersNotDistinct.expected
@@ -1,2 +1,4 @@
+| header3.h:7:1:7:24 | #define MULTIPLE_INCLUDE | Definition of macro MULTIPLE_INCLUDE is not distinct from alternative definition of $@ in rules/RULE-5-4/header4.h. | header4.h:1:1:1:24 | #define MULTIPLE_INCLUDE | MULTIPLE_INCLUDE |
+| header3.h:14:1:14:21 | #define NOT_PROTECTED | Definition of macro NOT_PROTECTED is not distinct from alternative definition of $@ in rules/RULE-5-4/header4.h. | header4.h:12:1:12:23 | #define NOT_PROTECTED 1 | NOT_PROTECTED |
| test.c:2:1:2:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB | Macro identifer iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB is nondistinct in first 63 characters, compared to $@. | test.c:1:1:1:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA |
-| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Macro identifer FUNCTION_MACRO is nondistinct in first 63 characters, compared to $@. | test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | FUNCTION_MACRO |
+| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Definition of macro FUNCTION_MACRO is not distinct from alternative definition of $@ in rules/RULE-5-4/test.c. | test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | FUNCTION_MACRO |
diff --git a/c/misra/test/rules/RULE-5-4/conditional.h b/c/misra/test/rules/RULE-5-4/conditional.h
new file mode 100644
index 0000000000..d30701c8e0
--- /dev/null
+++ b/c/misra/test/rules/RULE-5-4/conditional.h
@@ -0,0 +1,11 @@
+#ifdef FOO
+#include "header1.h"
+#else
+#include "header2.h"
+#endif
+
+#ifdef FOO
+#define A_MACRO 1 // COMPLIANT
+#else
+#define A_MACRO 2 // COMPLIANT
+#endif
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-5-4/header1.h b/c/misra/test/rules/RULE-5-4/header1.h
new file mode 100644
index 0000000000..526f4fa659
--- /dev/null
+++ b/c/misra/test/rules/RULE-5-4/header1.h
@@ -0,0 +1 @@
+#define REPEATED 11 // COMPLIANT
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-5-4/header2.h b/c/misra/test/rules/RULE-5-4/header2.h
new file mode 100644
index 0000000000..bd5dde123d
--- /dev/null
+++ b/c/misra/test/rules/RULE-5-4/header2.h
@@ -0,0 +1 @@
+#define REPEATED 1 // COMPLIANT
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-5-4/header3.h b/c/misra/test/rules/RULE-5-4/header3.h
new file mode 100644
index 0000000000..3aa82f5fd7
--- /dev/null
+++ b/c/misra/test/rules/RULE-5-4/header3.h
@@ -0,0 +1,16 @@
+#ifndef HEADER3_H
+#define HEADER3_H
+
+// We should ignore the header guards in this file
+
+// This is defined unconditionally by both header3.h and header4.h
+#define MULTIPLE_INCLUDE // NON_COMPLIANT
+
+// This is redefined in header3.h, but only if it isn't already defined
+#define PROTECTED // COMPLIANT
+
+// This is redefined in header3.h, but is conditional on some other condition,
+// so this is redefined
+#define NOT_PROTECTED // NON_COMPLIANT
+
+#endif
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-5-4/header4.h b/c/misra/test/rules/RULE-5-4/header4.h
new file mode 100644
index 0000000000..8fa6e8b5e8
--- /dev/null
+++ b/c/misra/test/rules/RULE-5-4/header4.h
@@ -0,0 +1,13 @@
+#define MULTIPLE_INCLUDE // NON_COMPLIANT
+
+// This case is triggered from root2.c
+// because PROTECTED isn't defined in
+// that case
+#ifndef PROTECTED
+#define PROTECTED // COMPLIANT - checked by guard
+#endif
+
+// Always enabled, so conflicts in root1.c case
+#ifdef MULTIPLE_INCLUDE
+#define NOT_PROTECTED 1 // NON_COMPLIANT
+#endif
diff --git a/c/misra/test/rules/RULE-5-4/root1.c b/c/misra/test/rules/RULE-5-4/root1.c
new file mode 100644
index 0000000000..98a94abed5
--- /dev/null
+++ b/c/misra/test/rules/RULE-5-4/root1.c
@@ -0,0 +1,6 @@
+#define FOO 1
+#include "conditional.h"
+
+// Both headers define MULTIPLE_INCLUDE
+#include "header3.h"
+#include "header4.h"
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-5-4/root2.c b/c/misra/test/rules/RULE-5-4/root2.c
new file mode 100644
index 0000000000..39926b9b1e
--- /dev/null
+++ b/c/misra/test/rules/RULE-5-4/root2.c
@@ -0,0 +1,3 @@
+#include "conditional.h"
+
+#include "header4.h"
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.expected b/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.expected
new file mode 100644
index 0000000000..7c39484796
--- /dev/null
+++ b/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.expected
@@ -0,0 +1,2 @@
+| test.c:7:7:7:7 | x | Union member x is declared as a bit field which relies on implementation-specific behavior. |
+| test.c:20:7:20:7 | (unnamed bitfield) | Union member (unnamed bitfield) is declared as a bit field which relies on implementation-specific behavior. |
diff --git a/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.qlref b/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.qlref
new file mode 100644
index 0000000000..21c43d4826
--- /dev/null
+++ b/c/misra/test/rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.qlref
@@ -0,0 +1 @@
+rules/RULE-6-3/BitFieldDeclaredAsMemberOfAUnion.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-6-3/test.c b/c/misra/test/rules/RULE-6-3/test.c
new file mode 100644
index 0000000000..1de648d294
--- /dev/null
+++ b/c/misra/test/rules/RULE-6-3/test.c
@@ -0,0 +1,21 @@
+union U1 {
+ int x; // COMPLIANT
+ char y; // COMPLIANT
+};
+
+union U2 {
+ int x : 2; // NON-COMPLIANT
+ char y; // COMPLIANT
+};
+
+union U3 {
+ struct str {
+ int x : 4; // COMPLIANT
+ int y : 2; // COMPLIANT
+ };
+};
+
+union U4 {
+ char x;
+ int : 0; // NON-COMPLIANT
+};
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-2/UOrUSuffixRepresentedInUnsignedType.expected b/c/misra/test/rules/RULE-7-2/UOrUSuffixRepresentedInUnsignedType.expected
index 4a131f4eaa..0d5504ba03 100644
--- a/c/misra/test/rules/RULE-7-2/UOrUSuffixRepresentedInUnsignedType.expected
+++ b/c/misra/test/rules/RULE-7-2/UOrUSuffixRepresentedInUnsignedType.expected
@@ -1,5 +1,12 @@
-| test.c:8:20:8:21 | 0 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
-| test.c:9:20:9:22 | 0 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
-| test.c:33:6:33:6 | 1 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
-| test.c:35:6:35:9 | 1 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
-| test.c:37:6:37:8 | 1 | Unsigned literal does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:111:3:111:12 | 2147483648 | Unsigned literal 0x80000000 does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:116:3:116:20 | 9223372036854775808 | Unsigned literal 0x8000000000000000 does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:139:3:139:21 | 9223372036854775808 | Unsigned literal 0x8000000000000000l does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:162:3:162:21 | 9223372036854775808 | Unsigned literal 0x8000000000000000L does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:185:3:185:22 | 9223372036854775808 | Unsigned literal 0x8000000000000000ll does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:208:3:208:22 | 9223372036854775808 | Unsigned literal 0x8000000000000000LL does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:227:3:227:14 | 2147483648 | Unsigned literal 020000000000 does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:232:3:232:25 | 9223372036854775808 | Unsigned literal 01000000000000000000000 does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:249:3:249:26 | 9223372036854775808 | Unsigned literal 01000000000000000000000l does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:266:3:266:26 | 9223372036854775808 | Unsigned literal 01000000000000000000000L does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:283:3:283:27 | 9223372036854775808 | Unsigned literal 01000000000000000000000ll does not explicitly express sign with a 'U' or 'u' suffix. |
+| test.c:300:3:300:27 | 9223372036854775808 | Unsigned literal 01000000000000000000000LL does not explicitly express sign with a 'U' or 'u' suffix. |
diff --git a/c/misra/test/rules/RULE-7-2/test.c b/c/misra/test/rules/RULE-7-2/test.c
index da62825755..170e822023 100644
--- a/c/misra/test/rules/RULE-7-2/test.c
+++ b/c/misra/test/rules/RULE-7-2/test.c
@@ -1,39 +1,319 @@
+// Assumed platform in qltest is linux_x86_64, so
+// int, long, long long sizes are assumed to be 32, 64, 64 bits respectively
-long a1 = 0L; // COMPLIANT
-long a2 = 0LL; // COMPLIANT
-long a3 = 0uL; // COMPLIANT
-long a4 = 0Lu; // COMPLIANT
-long a5 = 0LU; // COMPLIANT
-
-unsigned long b1 = 0L; // NON_COMPLIANT
-unsigned long b2 = 0LL; // NON_COMPLIANT
-unsigned long b3 = 0uL; // COMPLIANT
-unsigned long b4 = 0Lu; // COMPLIANT
-unsigned long b5 = 0LU; // COMPLIANT
-
-signed long c1 = 0L; // COMPLIANT
-signed long c2 = 0LL; // COMPLIANT
-signed long c3 = 0uL; // COMPLIANT
-signed long c4 = 0Lu; // COMPLIANT
-signed long c5 = 0LU; // COMPLIANT
-
-void f0(int a) {}
-
-void f1(unsigned int a) {}
-
-void f2() {
-
- f0(1); // COMPLIANT
- f0(1U); // COMPLIANT
- f0(0x01); // COMPLIANT
- f0(0x01U); // COMPLIANT
- f0(001); // COMPLIANT
- f0(001U); // COMPLIANT
-
- f1(1); // NON_COMPLIANT
- f1(1U); // COMPLIANT
- f1(0x01); // NON_COMPLIANT
- f1(0x01U); // COMPLIANT
- f1(001); // NON_COMPLIANT
- f1(001U); // COMPLIANT
+// The type of an integer constant is determined by "6.4.4.1 Integer constants"
+// in the C11 Standard. The principle is that any decimal integer constant will
+// be signed, unless it has the `U` or `u` suffix. Any hexadecimal integer will
+// depend on whether it is larger than the maximum value of the smallest signed
+// integer value that can hold the value. So the signedness depends on the
+// magnitude of the constant.
+
+void test_decimal_constants() {
+ 0; // COMPLIANT
+ 2147483648; // COMPLIANT - larger than int, but decimal constants never use
+ // unsigned without the suffix, so will be `long`
+ 4294967296; // COMPLIANT - larger than unsigned int, still `long`
+ 9223372036854775807; // COMPLIANT - max long int
+ // 9223372036854775808; Not a valid integer constant, out of signed range
+ 0U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807U; // COMPLIANT - max long int
+ 9223372036854775808U; // COMPLIANT - explicitly unsigned, so can go large than
+ // max long int
+ 0u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807u; // COMPLIANT - max long int
+ 9223372036854775808u; // COMPLIANT - explicitly unsigned, so can go large than
+ // max long int
+
+ // l suffix
+ 0l; // COMPLIANT
+ 2147483648l; // COMPLIANT - within the range of long int
+ 4294967296l; // COMPLIANT - within the range of long int
+ 9223372036854775807l; // COMPLIANT - max long int
+ // 9223372036854775808l; Not a valid integer constant, out of signed range
+ 0lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807lU; // COMPLIANT - max long int
+ 9223372036854775808lU; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long int
+ 0lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807lu; // COMPLIANT - max long int
+ 9223372036854775808lu; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long int
+
+ // L suffix
+ 0L; // COMPLIANT
+ 2147483648L; // COMPLIANT - within the range of long int
+ 4294967296L; // COMPLIANT - within the range of long int
+ 9223372036854775807L; // COMPLIANT - max long int
+ // 9223372036854775808L; Not a valid integer constant, out of signed range
+ 0LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807LU; // COMPLIANT - max long int
+ 9223372036854775808LU; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long int
+ 0Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807Lu; // COMPLIANT - max long int
+ 9223372036854775808Lu; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long int
+
+ // ll suffix
+ 0ll; // COMPLIANT
+ 2147483648ll; // COMPLIANT - within the range of long long int
+ 4294967296ll; // COMPLIANT - within the range of long long int
+ 9223372036854775807ll; // COMPLIANT - max long long int
+ // 9223372036854775808ll; Not a valid integer constant, out of signed range
+ 0llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807llU; // COMPLIANT - max long long int
+ 9223372036854775808llU; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long long int
+ 0llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807llu; // COMPLIANT - max long long int
+ 9223372036854775808llu; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long long int
+
+ // LL suffix
+ 0LL; // COMPLIANT
+ 2147483648LL; // COMPLIANT - within the range of long long int
+ 4294967296LL; // COMPLIANT - within the range of long long int
+ 9223372036854775807LL; // COMPLIANT - max long long int
+ // 9223372036854775808LL; Not a valid integer constant, out of signed range
+ 0LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807LLU; // COMPLIANT - max long long int
+ 9223372036854775808LLU; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long long int
+ 0LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807LLu; // COMPLIANT - max long long int
+ 9223372036854775808LLu; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long long int
}
+
+void test_hexadecimal_constants() {
+ 0x0; // COMPLIANT - uses signed int
+ 0x7FFFFFFF; // COMPLIANT - max value held by signed int
+ 0x80000000; // NON_COMPLIANT - larger than max signed int, so will be unsigned
+ // int
+ 0x100000000; // COMPLIANT - larger than unsigned int, but smaller than long
+ // int
+ 0x7FFFFFFFFFFFFFFF; // COMPLIANT - max long int
+ 0x8000000000000000; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 0x0U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000u; // COMPLIANT - unsigned, but uses the suffix correctly
+
+ // Use of the `l` suffix
+ 0x0l; // COMPLIANT - uses signed int
+ 0x7FFFFFFFl; // COMPLIANT - max value held by signed int
+ 0x80000000l; // COMPLIANT - larger than max signed int, but smaller than long
+ // int
+ 0x100000000l; // COMPLIANT - larger than unsigned int, but smaller than long
+ // int
+ 0x7FFFFFFFFFFFFFFFl; // COMPLIANT - max long int
+ 0x8000000000000000l; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 0x0lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFlU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFlU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFlu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFlu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000lu; // COMPLIANT - unsigned, but uses the suffix correctly
+
+ // Use of the `L` suffix
+ 0x0L; // COMPLIANT - uses signed int
+ 0x7FFFFFFFL; // COMPLIANT - max value held by signed int
+ 0x80000000L; // COMPLIANT - larger than max signed int, but smaller than long
+ // int
+ 0x100000000L; // COMPLIANT - larger than unsigned int, but smaller than long
+ // int
+ 0x7FFFFFFFFFFFFFFFL; // COMPLIANT - max long int
+ 0x8000000000000000L; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 0x0LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+
+ // Use of the `ll` suffix
+ 0x0ll; // COMPLIANT - uses signed int
+ 0x7FFFFFFFll; // COMPLIANT - max value held by signed int
+ 0x80000000ll; // COMPLIANT - larger than max signed int, but smaller than long
+ // long int
+ 0x100000000ll; // COMPLIANT - larger than unsigned int, but smaller than long
+ // long int
+ 0x7FFFFFFFFFFFFFFFll; // COMPLIANT - max long long int
+ 0x8000000000000000ll; // NON_COMPLIANT - larger than long long int, so will be
+ // unsigned long long int
+ 0x0llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFllU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFllU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFllu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFllu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000llu; // COMPLIANT - unsigned, but uses the suffix correctly
+
+ // Use of the `LL` suffix
+ 0x0LL; // COMPLIANT - uses signed int
+ 0x7FFFFFFFLL; // COMPLIANT - max value held by signed int
+ 0x80000000LL; // COMPLIANT - larger than max signed int, but smaller than long
+ // long int
+ 0x100000000LL; // COMPLIANT - larger than unsigned int, but smaller than long
+ // long int
+ 0x7FFFFFFFFFFFFFFFLL; // COMPLIANT - max long long int
+ 0x8000000000000000LL; // NON_COMPLIANT - larger than long long int, so will be
+ // unsigned long long int
+ 0x0LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFLLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFLLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFLLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFLLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+}
+
+void test_octal_constants() {
+ 00; // COMPLIANT - uses signed int
+ 017777777777; // COMPLIANT - max value held by signed int
+ 020000000000; // NON_COMPLIANT - larger than max signed int, so will be
+ // unsigned int
+ 040000000000; // COMPLIANT - larger than unsigned int, but smaller than long
+ // int
+ 0777777777777777777777; // COMPLIANT - max long int
+ 01000000000000000000000; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777U; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000U; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+
+ // Use of the `l` suffix
+ 00l; // COMPLIANT - uses signed long
+ 017777777777l; // COMPLIANT - uses signed long
+ 020000000000l; // COMPLIANT - uses signed long
+ 040000000000l; // COMPLIANT - uses signed long
+ 0777777777777777777777l; // COMPLIANT - max long int
+ 01000000000000000000000l; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00Ul; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777Ul; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000Ul; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000Ul; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777Ul; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000Ul; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+
+ // Use of the `L` suffix
+ 00L; // COMPLIANT - uses signed long
+ 017777777777L; // COMPLIANT - uses signed long
+ 020000000000L; // COMPLIANT - uses signed long
+ 040000000000L; // COMPLIANT - uses signed long
+ 0777777777777777777777L; // COMPLIANT - COMPLIANT - uses signed long
+ 01000000000000000000000L; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00UL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777UL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000UL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000UL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777UL; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000UL; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+
+ // Use of the `ll` suffix
+ 00ll; // COMPLIANT - uses signed long long
+ 017777777777ll; // COMPLIANT - uses signed long long
+ 020000000000ll; // COMPLIANT - uses signed long long
+ 040000000000ll; // COMPLIANT - uses signed long long
+ 0777777777777777777777ll; // COMPLIANT - max long int
+ 01000000000000000000000ll; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00Ull; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777Ull; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000Ull; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000Ull; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777Ull; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000Ull; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+
+ // Use of the `LL` suffix
+ 00LL; // COMPLIANT - uses signed long long
+ 017777777777LL; // COMPLIANT - uses signed long long
+ 020000000000LL; // COMPLIANT - uses signed long long
+ 040000000000LL; // COMPLIANT - uses signed long long
+ 0777777777777777777777LL; // COMPLIANT - max long int
+ 01000000000000000000000LL; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00ULL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777ULL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000ULL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000ULL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777ULL; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000ULL; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+}
+
+#define COMPLIANT_VAL 0x80000000U
+#define NON_COMPLIANT_VAL 0x80000000
+
+void test_macro() {
+ COMPLIANT_VAL; // COMPLIANT
+ NON_COMPLIANT_VAL; // NON_COMPLIANT[FALSE_NEGATIVE] - cannot determine suffix
+ // in macro expansions
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.expected b/c/misra/test/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.expected
new file mode 100644
index 0000000000..d3724e21a4
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.expected
@@ -0,0 +1,31 @@
+| test.c:17:13:17:16 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
+| test.c:19:13:19:18 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
+| test.c:21:13:21:16 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
+| test.c:37:13:37:15 | 256 | Value provided to integer constant macro UINT8_C is outside of the allowed range 0..255 |
+| test.c:38:13:38:16 | 256 | Value provided to integer constant macro UINT8_C is outside of the allowed range 0..255 |
+| test.c:39:13:39:17 | 256 | Value provided to integer constant macro UINT8_C is outside of the allowed range 0..255 |
+| test.c:42:13:42:14 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
+| test.c:43:13:43:15 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
+| test.c:44:13:44:15 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
+| test.c:45:13:45:17 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
+| test.c:70:12:70:14 | 128 | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
+| test.c:71:12:71:15 | 128 | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
+| test.c:72:12:72:15 | 128 | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
+| test.c:76:12:76:15 | - ... | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
+| test.c:77:12:77:16 | - ... | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
+| test.c:78:12:78:16 | - ... | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
+| test.c:91:14:91:18 | 65536 | Value provided to integer constant macro UINT16_C is outside of the allowed range 0..65535 |
+| test.c:92:14:92:20 | 65536 | Value provided to integer constant macro UINT16_C is outside of the allowed range 0..65535 |
+| test.c:93:14:93:20 | 65536 | Value provided to integer constant macro UINT16_C is outside of the allowed range 0..65535 |
+| test.c:106:13:106:17 | 32768 | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
+| test.c:107:13:107:19 | 32768 | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
+| test.c:108:13:108:18 | 32768 | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
+| test.c:112:13:112:18 | - ... | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
+| test.c:113:13:113:20 | - ... | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
+| test.c:114:13:114:19 | - ... | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
+| test.c:124:14:124:24 | 4294967296 | Value provided to integer constant macro UINT32_C is outside of the allowed range 0..4294967295 |
+| test.c:125:14:125:25 | 4294967296 | Value provided to integer constant macro UINT32_C is outside of the allowed range 0..4294967295 |
+| test.c:135:13:135:22 | 2147483648 | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
+| test.c:136:13:136:22 | 2147483648 | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
+| test.c:139:13:139:23 | - ... | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
+| test.c:140:13:140:23 | - ... | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
diff --git a/c/misra/test/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.qlref b/c/misra/test/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.qlref
new file mode 100644
index 0000000000..ca6959acec
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.qlref
@@ -0,0 +1 @@
+rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.expected b/c/misra/test/rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.expected
new file mode 100644
index 0000000000..97a35dd977
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.expected
@@ -0,0 +1,7 @@
+| test.c:25:13:25:14 | 1 | Value suffix 'u' is not allowed on provided argument to integer constant macro UINT8_C. |
+| test.c:26:13:26:14 | 2 | Value suffix 'U' is not allowed on provided argument to integer constant macro UINT8_C. |
+| test.c:27:13:27:14 | 3 | Value suffix 'l' is not allowed on provided argument to integer constant macro UINT8_C. |
+| test.c:28:13:28:14 | 4 | Value suffix 'L' is not allowed on provided argument to integer constant macro UINT8_C. |
+| test.c:29:13:29:15 | 5 | Value suffix 'ul' is not allowed on provided argument to integer constant macro UINT8_C. |
+| test.c:30:13:30:15 | 5 | Value suffix 'll' is not allowed on provided argument to integer constant macro UINT8_C. |
+| test.c:31:13:31:16 | 5 | Value suffix 'ull' is not allowed on provided argument to integer constant macro UINT8_C. |
diff --git a/c/misra/test/rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.qlref b/c/misra/test/rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.qlref
new file mode 100644
index 0000000000..afadb6e34b
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.qlref
@@ -0,0 +1 @@
+rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.expected b/c/misra/test/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.expected
new file mode 100644
index 0000000000..b29228b6df
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.expected
@@ -0,0 +1,8 @@
+| test.c:48:13:48:17 | ... + ... | Argument to integer constant macro UINT8_C must be an integer literal. |
+| test.c:49:13:49:18 | access to array | Argument to integer constant macro UINT8_C must be an integer literal. |
+| test.c:50:13:50:19 | access to array | Argument to integer constant macro UINT8_C must be an integer literal. |
+| test.c:51:5:51:22 | 255 | Argument to integer constant macro UINT8_C must be an integer literal. |
+| test.c:52:5:52:17 | 1 | Argument to integer constant macro UINT8_C must be an integer literal. |
+| test.c:53:5:53:18 | 0 | Argument to integer constant macro UINT8_C must be an integer literal. |
+| test.c:54:5:54:17 | 0 | Argument to integer constant macro UINT8_C must be an integer literal. |
+| test.c:55:5:55:20 | 0 | Argument to integer constant macro UINT8_C must be an integer literal. |
diff --git a/c/misra/test/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.qlref b/c/misra/test/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.qlref
new file mode 100644
index 0000000000..802f415bc9
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.qlref
@@ -0,0 +1 @@
+rules/RULE-7-5/InvalidIntegerConstantMacroArgument.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.expected b/c/misra/test/rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.expected
new file mode 100644
index 0000000000..ee5b75cb91
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.expected
@@ -0,0 +1,7 @@
+| test.c:16:13:16:15 | 1.0 | Integer constant macro UINT8_C used with floating point literal argument, only decimal, octal, or hex integer literal allowed. |
+| test.c:17:13:17:16 | - ... | Integer constant macro UINT8_C used with floating point literal argument, only decimal, octal, or hex integer literal allowed. |
+| test.c:18:13:18:17 | 7 | Integer constant macro UINT8_C used with binary literal argument, only decimal, octal, or hex integer literal allowed. |
+| test.c:19:13:19:18 | - ... | Integer constant macro UINT8_C used with binary literal argument, only decimal, octal, or hex integer literal allowed. |
+| test.c:20:13:20:15 | 97 | Integer constant macro UINT8_C used with char literal argument, only decimal, octal, or hex integer literal allowed. |
+| test.c:21:13:21:16 | - ... | Integer constant macro UINT8_C used with char literal argument, only decimal, octal, or hex integer literal allowed. |
+| test.c:22:13:22:16 | 10 | Integer constant macro UINT8_C used with char literal argument, only decimal, octal, or hex integer literal allowed. |
diff --git a/c/misra/test/rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.qlref b/c/misra/test/rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.qlref
new file mode 100644
index 0000000000..5584fe8d46
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.qlref
@@ -0,0 +1 @@
+rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-5/test.c b/c/misra/test/rules/RULE-7-5/test.c
new file mode 100644
index 0000000000..a3fb4b60e4
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-5/test.c
@@ -0,0 +1,179 @@
+#include "stdbool.h"
+#include "stdint.h"
+
+#define NULL 0
+#define NULLPTR ((void *)NULL)
+
+uint_least8_t g1[] = {
+ // Basic valid
+ UINT8_C(0), // COMPLIANT
+ UINT8_C(1), // COMPLIANT
+ UINT8_C(8), // COMPLIANT
+ UINT8_C(0x23), // COMPLIANT
+ UINT8_C(034), // COMPLIANT
+
+ // Incorrect literal types
+ UINT8_C(1.0), // NON-COMPLIANT
+ UINT8_C(-1.0), // NON-COMPLIANT
+ UINT8_C(0b111), // NON-COMPLIANT
+ UINT8_C(-0b111), // NON-COMPLIANT
+ UINT8_C('a'), // NON-COMPLIANT
+ UINT8_C(-'$'), // NON-COMPLIANT
+ UINT8_C('\n'), // NON-COMPLIANT
+
+ // Suffixes disallowed
+ UINT8_C(1u), // NON-COMPLIANT
+ UINT8_C(2U), // NON-COMPLIANT
+ UINT8_C(3l), // NON-COMPLIANT
+ UINT8_C(4L), // NON-COMPLIANT
+ UINT8_C(5ul), // NON-COMPLIANT
+ UINT8_C(5ll), // NON-COMPLIANT
+ UINT8_C(5ull), // NON-COMPLIANT
+
+ // Range tests
+ UINT8_C(255), // COMPLIANT
+ UINT8_C(0xFF), // COMPLIANT
+ UINT8_C(0377), // COMPLIANT
+ UINT8_C(256), // NON-COMPLIANT
+ UINT8_C(0400), // NON-COMPLIANT
+ UINT8_C(0x100), // NON-COMPLIANT
+
+ // Signage tests
+ UINT8_C(-1), // NON-COMPLIANT
+ UINT8_C(-20), // NON-COMPLIANT
+ UINT8_C(-33), // NON-COMPLIANT
+ UINT8_C(-0x44), // NON-COMPLIANT
+
+ // Invalid nonliteral expressions
+ UINT8_C(0 + 0), // NON-COMPLIANT
+ UINT8_C("a"[0]), // NON-COMPLIANT
+ UINT8_C(0 ["a"]), // NON-COMPLIANT
+ UINT8_C(UINT8_MAX), // NON-COMPLIANT
+ UINT8_C(true), // NON-COMPLIANT
+ UINT8_C(false), // NON-COMPLIANT
+ UINT8_C(NULL), // NON-COMPLIANT
+ UINT8_C(NULLPTR), // NON-COMPLIANT
+};
+
+int_least8_t g2[] = {
+ // Basic valid
+ INT8_C(0), // COMPLIANT
+ INT8_C(1), // COMPLIANT
+ INT8_C(8), // COMPLIANT
+ INT8_C(0x23), // COMPLIANT
+ INT8_C(034), // COMPLIANT
+
+ // Range tests
+ INT8_C(127), // COMPLIANT
+ INT8_C(0x79), // COMPLIANT
+ INT8_C(0177), // COMPLIANT
+ INT8_C(128), // NON-COMPLIANT
+ INT8_C(0200), // NON-COMPLIANT
+ INT8_C(0x80), // NON-COMPLIANT
+ INT8_C(-128), // COMPLIANT
+ INT8_C(-0x80), // COMPLIANT
+ INT8_C(-0200), // COMPLIANT
+ INT8_C(-129), // NON-COMPLIANT
+ INT8_C(-0201), // NON-COMPLIANT
+ INT8_C(-0x81), // NON-COMPLIANT
+};
+
+uint_least16_t g3[] = {
+ // Basic valid
+ UINT16_C(0), // COMPLIANT
+ UINT16_C(0x23), // COMPLIANT
+ UINT16_C(034), // COMPLIANT
+
+ // Range tests
+ UINT16_C(65535), // COMPLIANT
+ UINT16_C(0xFFFF), // COMPLIANT
+ UINT16_C(0177777), // COMPLIANT
+ UINT16_C(65536), // NON-COMPLIANT
+ UINT16_C(0200000), // NON-COMPLIANT
+ UINT16_C(0x10000), // NON-COMPLIANT
+};
+
+int_least16_t g4[] = {
+ // Basic valid
+ INT16_C(0), // COMPLIANT
+ INT16_C(0x23), // COMPLIANT
+ INT16_C(034), // COMPLIANT
+
+ // Range tests
+ INT16_C(32767), // COMPLIANT
+ INT16_C(0x7FFF), // COMPLIANT
+ INT16_C(077777), // COMPLIANT
+ INT16_C(32768), // NON-COMPLIANT
+ INT16_C(0100000), // NON-COMPLIANT
+ INT16_C(0x8000), // NON-COMPLIANT
+ INT16_C(-32768), // COMPLIANT
+ INT16_C(-0100000), // COMPLIANT
+ INT16_C(-0x8000), // COMPLIANT
+ INT16_C(-32769), // NON-COMPLIANT
+ INT16_C(-0100001), // NON-COMPLIANT
+ INT16_C(-0x8001), // NON-COMPLIANT
+};
+
+uint_least32_t g5[] = {
+ // Basic valid
+ UINT32_C(0), // COMPLIANT
+
+ // Range tests
+ UINT32_C(4294967295), // COMPLIANT
+ UINT32_C(0xFFFFFFFF), // COMPLIANT
+ UINT32_C(4294967296), // NON-COMPLIANT
+ UINT32_C(0x100000000), // NON-COMPLIANT
+};
+
+int_least32_t g6[] = {
+ // Basic valid
+ INT32_C(0), // COMPLIANT
+
+ // Range tests
+ INT32_C(2147483647), // COMPLIANT
+ INT32_C(0x7FFFFFFF), // COMPLIANT
+ INT32_C(2147483648), // NON-COMPLIANT
+ INT32_C(0x80000000), // NON-COMPLIANT
+ INT32_C(-2147483648), // COMPLIANT
+ INT32_C(-0x80000000), // COMPLIANT
+ INT32_C(-2147483649), // NON-COMPLIANT
+ INT32_C(-0x80000001), // NON-COMPLIANT
+};
+
+uint_least64_t g7[] = {
+ // Basic valid
+ UINT64_C(0), // COMPLIANT
+
+ // Range tests
+ UINT64_C(18446744073709551615), // COMPLIANT
+ UINT64_C(0xFFFFFFFFFFFFFFFF), // COMPLIANT
+ // Compile time error if we try to create integer literals beyond this.
+};
+
+int_least64_t g8[] = {
+ // Basic valid
+ INT64_C(0), // COMPLIANT
+
+ // Range tests
+ INT64_C(9223372036854775807), // COMPLIANT
+ // INT64_C(9223372036854775808) is a compile-time error
+
+ INT64_C(-9223372036854775807), // COMPLIANT
+ // -9223372036854775808 is correctly sized, but not a valid decimal literal
+ // value.
+ // -9223372036854775809 is not correctly sized, and not a valid decimal
+ // literal value.
+
+ INT64_C(0x7FFFFFFFFFFFFFFF), // COMPLIANT
+ INT64_C(0x8000000000000000), // NON-COMPLIANT[FALSE NEGATIVE]
+ INT64_C(-0x8000000000000000), // COMPLIANT
+ INT64_C(-0x8000000000000001), // NON-COMPLIANT[FALSE NEGATIVE]
+ INT64_C(-0x8001000000000000), // NON-COMPLIANT[FALSE NEGATIVE]
+};
+
+// Other edge cases:
+void f(void) {
+ uint32_t l1 = 1;
+ // `UnrecognizedNumericLiteral` case:
+ int64_t l2 = ((int32_t)UINT64_C(0x1b2) * (l1)); // COMPLIANT
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.expected b/c/misra/test/rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.expected
new file mode 100644
index 0000000000..ddf517ed9e
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.expected
@@ -0,0 +1,4 @@
+| test.c:3:13:3:24 | INT8_C(c) | Usage of small integer constant macro INT8_C is not allowed. |
+| test.c:4:14:4:26 | UINT8_C(c) | Usage of small integer constant macro UINT8_C is not allowed. |
+| test.c:5:14:5:28 | INT16_C(c) | Usage of small integer constant macro INT16_C is not allowed. |
+| test.c:6:15:6:30 | UINT16_C(c) | Usage of small integer constant macro UINT16_C is not allowed. |
diff --git a/c/misra/test/rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.qlref b/c/misra/test/rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.qlref
new file mode 100644
index 0000000000..e41e2912d8
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.qlref
@@ -0,0 +1 @@
+rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-6/test.c b/c/misra/test/rules/RULE-7-6/test.c
new file mode 100644
index 0000000000..9832cdf251
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-6/test.c
@@ -0,0 +1,10 @@
+#include "stdint.h"
+
+int8_t g1 = INT8_C(0x12); // NON-COMPLIANT
+uint8_t g2 = UINT8_C(0x12); // NON-COMPLIANT
+int16_t g3 = INT16_C(0x1234); // NON-COMPLIANT
+uint16_t g4 = UINT16_C(0x1234); // NON-COMPLIANT
+int32_t g5 = INT32_C(0x1234); // COMPLIANT
+uint32_t g6 = UINT32_C(0x1234); // COMPLIANT
+int64_t g7 = INT64_C(0x1234); // COMPLIANT
+uint64_t g8 = UINT64_C(0x1234); // COMPLIANT
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.expected b/c/misra/test/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.expected
index 39dbf04763..e3e0963087 100644
--- a/c/misra/test/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.expected
+++ b/c/misra/test/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.expected
@@ -12,3 +12,4 @@
| test.c:66:23:66:24 | p1 | $@ points to a non-const-qualified type. | test.c:66:23:66:24 | p1 | p1 |
| test.c:71:17:71:18 | p1 | $@ points to a non-const-qualified type. | test.c:71:17:71:18 | p1 | p1 |
| test.c:75:15:75:16 | p1 | $@ points to a non-const-qualified type. | test.c:75:15:75:16 | p1 | p1 |
+| test.c:103:30:103:30 | s | $@ points to a non-const-qualified type. | test.c:103:30:103:30 | s | s |
diff --git a/c/misra/test/rules/RULE-8-13/test.c b/c/misra/test/rules/RULE-8-13/test.c
index 1ac9e5028c..a2333d2a3d 100644
--- a/c/misra/test/rules/RULE-8-13/test.c
+++ b/c/misra/test/rules/RULE-8-13/test.c
@@ -75,4 +75,38 @@ char *f16(char *p1) { // NON_COMPLIANT
int f17(char *p1) { // NON_COMPLIANT
p1++;
return 0;
+}
+
+#include
+
+int16_t
+test_r(int16_t *value) { // COMPLIANT - ignored because of the use of ASM
+ int16_t result;
+ struct S {
+ int *x; // COMPLIANT - ignored because of the use of ASM
+ struct S2 {
+ int *y; // COMPLIANT - ignored because of the use of ASM
+ } s2;
+ };
+ __asm__("movb %bh (%eax)");
+ return result;
+}
+
+struct S {
+ int x;
+};
+
+void test_struct(struct S *s) { // COMPLIANT
+ s->x = 1;
+}
+
+void test_struct_2(struct S *s) { // NON_COMPLIANT - could be const
+ s = 0;
+}
+
+void test_no_body(int *p); // COMPLIANT - no body, so cannot evaluate whether it
+ // should be const
+
+void increment(int *p) { // COMPLIANT
+ *p++ = 1;
}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.qlref b/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.qlref
deleted file mode 100644
index 0a6121b324..0000000000
--- a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.testref b/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.testref
new file mode 100644
index 0000000000..1a6a69fc24
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.testref
@@ -0,0 +1 @@
+c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.qlref b/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.qlref
deleted file mode 100644
index 70b6073e14..0000000000
--- a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.testref b/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.testref
new file mode 100644
index 0000000000..23ed7c9fc5
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.testref
@@ -0,0 +1 @@
+c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql
\ No newline at end of file
diff --git a/change_notes/2023-07-28-rule-11-4-improvements.md b/change_notes/2023-07-28-rule-11-4-improvements.md
new file mode 100644
index 0000000000..3c385359a8
--- /dev/null
+++ b/change_notes/2023-07-28-rule-11-4-improvements.md
@@ -0,0 +1,12 @@
+ - `RULE-11-1` - `ConversionBetweenFunctionPointerAndOtherType.ql`:
+ - Fixed issue #331 - consider `0` a null pointer constant.
+ - `RULE-11-4` - `ConversionBetweenPointerToObjectAndIntegerType.ql`:
+ - Fixed issue #331 - consider `0` a null pointer constant.
+ - Improve reporting of the order of the cast and the actual types involved.
+ - Improve reporting where the result is expanded from a macro by either reporting the macro itself (if it is not dependent on the context) or by including a link to the macro in the alert message.
+ - `RULE-11-5` - `ConversionFromPointerToVoidIntoPointerToObject.ql`:
+ - Fixed issue #331 - consider `0` a null pointer constant.
+ - `RULE-11-6` - `CastBetweenPointerToVoidAndArithmeticType.ql`:
+ - Fixed issue #331 - accept integer constant expressions with value `0` instead of null pointer constants.
+ - `RULE-11-9` - `MacroNullNotUsedAsIntegerNullPointerConstant.ql`:
+ - Remove false positives in branches of ternary expressions, where `0` was used correctly.
\ No newline at end of file
diff --git a/change_notes/2023-12-05-a7-2-1-typo.md b/change_notes/2023-12-05-a7-2-1-typo.md
new file mode 100644
index 0000000000..f87fc7cf8b
--- /dev/null
+++ b/change_notes/2023-12-05-a7-2-1-typo.md
@@ -0,0 +1 @@
+ * `A7-2-1` - fix typo in some alert messages.
\ No newline at end of file
diff --git a/change_notes/2024-07-10-fix-fn-119-m0-2-1.md b/change_notes/2024-07-10-fix-fn-119-m0-2-1.md
new file mode 100644
index 0000000000..08d139ddbe
--- /dev/null
+++ b/change_notes/2024-07-10-fix-fn-119-m0-2-1.md
@@ -0,0 +1,2 @@
+- `M0-2-1` - `DoNotPassAliasedPointerToRestrictQualifiedParam.ql`:
+ - Fixes #119. Adds shared query to cover missing detection of overlapping arrays or pointers in specific list of functions that list undefined behaviour when their parameters overlap.
\ No newline at end of file
diff --git a/change_notes/2024-07-11-fix-fp-406.md b/change_notes/2024-07-11-fix-fp-406.md
new file mode 100644
index 0000000000..78e607ecb6
--- /dev/null
+++ b/change_notes/2024-07-11-fix-fp-406.md
@@ -0,0 +1,2 @@
+ - `A13-3-1` - `FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql`:
+ - Fixes #406. Exclude detection of overloaded implicit copy/move constructors.
\ No newline at end of file
diff --git a/change_notes/2024-07-16-fix-fp-606-A2-7-3.md b/change_notes/2024-07-16-fix-fp-606-A2-7-3.md
new file mode 100644
index 0000000000..a4fc343b76
--- /dev/null
+++ b/change_notes/2024-07-16-fix-fp-606-A2-7-3.md
@@ -0,0 +1,2 @@
+- `A2-7-3` - `UndocumentedUserDefinedType.ql`:
+ - Fixes #606. Fix false positive relating to friend functions in template classes.
\ No newline at end of file
diff --git a/change_notes/2024-07-30-fix-fp-650-PRE32-C.md b/change_notes/2024-07-30-fix-fp-650-PRE32-C.md
new file mode 100644
index 0000000000..e1ea391499
--- /dev/null
+++ b/change_notes/2024-07-30-fix-fp-650-PRE32-C.md
@@ -0,0 +1,2 @@
+- `PRE32-C` - `MacroOrFunctionArgsContainHashToken.ql`:
+ - Fixes #650. Correctly identifies presence of preprocessor directives in function calls.
diff --git a/change_notes/2024-08-06-fix-fp-658-M0-1-3.md b/change_notes/2024-08-06-fix-fp-658-M0-1-3.md
new file mode 100644
index 0000000000..47a26705ae
--- /dev/null
+++ b/change_notes/2024-08-06-fix-fp-658-M0-1-3.md
@@ -0,0 +1,2 @@
+- `M0-1-3` - `UnusedLocalVariable.ql`:
+ - Fixes #658. Considers usage of const/constexpr variables in array size and function parameters that are used in arguments of template functions.
diff --git a/change_notes/2024-09-11-rule-12-2-improvements.md b/change_notes/2024-09-11-rule-12-2-improvements.md
new file mode 100644
index 0000000000..0e713a5088
--- /dev/null
+++ b/change_notes/2024-09-11-rule-12-2-improvements.md
@@ -0,0 +1,6 @@
+- `RULE-12-2` - `RightHandOperandOfAShiftRange.ql`:
+ - Reduce false positives related to ranges determined by `%=`.
+ - Reduce false positives for integer constants with explicit size suffix were incorrectly identified as smaller types.
+ - Improve explanation of results, providing additional information on types and size ranges.
+ - Combine results stemming from the expansion of a macro, where the result is not dependent on the context.
+
\ No newline at end of file
diff --git a/change_notes/2024-09-16-rule-5-8-consider-linkage.md b/change_notes/2024-09-16-rule-5-8-consider-linkage.md
new file mode 100644
index 0000000000..2877d53f50
--- /dev/null
+++ b/change_notes/2024-09-16-rule-5-8-consider-linkage.md
@@ -0,0 +1,2 @@
+ - `RULE-5-8` - `IdentifiersWithExternalLinkageNotUnique.ql`
+ - Remove false positives where conflicting declarations do not appear in the same link target.
\ No newline at end of file
diff --git a/change_notes/2024-09-17-essential-types-unary.md b/change_notes/2024-09-17-essential-types-unary.md
new file mode 100644
index 0000000000..401f59a9a6
--- /dev/null
+++ b/change_notes/2024-09-17-essential-types-unary.md
@@ -0,0 +1,4 @@
+ - `RULE-10-1` - `OperandsOfAnInappropriateEssentialType.ql`
+ - Reduce false negatives by supporting operands to the `~` operator with the incorrect essential type.
+ - Reduce false positives by identifying the essential type of `!` as essentially boolean type.
+ - Improve clarity reporting by reporting the violating operand, instead of the operator, and addressing message typos.
\ No newline at end of file
diff --git a/change_notes/2024-09-17-fix-fp-678-m0-1-9.md b/change_notes/2024-09-17-fix-fp-678-m0-1-9.md
new file mode 100644
index 0000000000..e068825f4c
--- /dev/null
+++ b/change_notes/2024-09-17-fix-fp-678-m0-1-9.md
@@ -0,0 +1,2 @@
+- `M0-1-9` - `DeadCode.qll`:
+ - Fixes #678. Remove dead code false positive when integer constant expression is used to define the size of an array.
diff --git a/change_notes/2024-09-17-rule-8-3-linker-aware.md b/change_notes/2024-09-17-rule-8-3-linker-aware.md
new file mode 100644
index 0000000000..3e48bb1228
--- /dev/null
+++ b/change_notes/2024-09-17-rule-8-3-linker-aware.md
@@ -0,0 +1,2 @@
+ - `RULE-8-3` - `DeclarationsOfAnObjectSameNameAndType.ql`
+ - Remove false positives where two conflicting declarations are never linked together.
\ No newline at end of file
diff --git a/change_notes/2024-09-18-handle-warning-suppresion-flags b/change_notes/2024-09-18-handle-warning-suppresion-flags
new file mode 100644
index 0000000000..12bf30e937
--- /dev/null
+++ b/change_notes/2024-09-18-handle-warning-suppresion-flags
@@ -0,0 +1,2 @@
+- `A1-1-2` - `CompilerWarningLevelNotInCompliance.ql`:
+ - Fixes #689 false negatives where '-Wno-foo' was treated as enabling, rather than disabling warnings.
\ No newline at end of file
diff --git a/change_notes/2024-09-19-c-extensions.md b/change_notes/2024-09-19-c-extensions.md
new file mode 100644
index 0000000000..2f78574679
--- /dev/null
+++ b/change_notes/2024-09-19-c-extensions.md
@@ -0,0 +1,4 @@
+ - `RULE-1-2` - `LanguageExtensionsShouldNotBeUsed.ql`:
+ - Improve reporting by describing which language extensions are used.
+ - Improve reporting by aggregating results generated from a macro expansion at the generating macro location.
+ - Reduce false positives for the variable length array check by permitting those extensions which are included in the C99 standard.
\ No newline at end of file
diff --git a/change_notes/2024-09-19-fix-fp-665-M3-4-1.md b/change_notes/2024-09-19-fix-fp-665-M3-4-1.md
new file mode 100644
index 0000000000..63c5f91b56
--- /dev/null
+++ b/change_notes/2024-09-19-fix-fp-665-M3-4-1.md
@@ -0,0 +1,2 @@
+- `M3-4-1` - `UnnecessaryExposedIdentifierDeclarationShared.qll`:
+ - Fixes #665. Exclude variables that are constexpr and coming from template instantiations.
diff --git a/change_notes/2024-09-20-fix-7-2-fps.md b/change_notes/2024-09-20-fix-7-2-fps.md
new file mode 100644
index 0000000000..897aebadb7
--- /dev/null
+++ b/change_notes/2024-09-20-fix-7-2-fps.md
@@ -0,0 +1,3 @@
+ - `RULE-7-2` - `UOrUSuffixRepresentedInUnsignedType.ql`
+ - Remove false positives where integer constants are generated from macros.
+ - Remove false positives where a signed integer is implicitly converted to unsigned, which is permitted by the standard.
\ No newline at end of file
diff --git a/change_notes/2024-09-25-dead-code-improvements.md b/change_notes/2024-09-25-dead-code-improvements.md
new file mode 100644
index 0000000000..9cd8d95ff5
--- /dev/null
+++ b/change_notes/2024-09-25-dead-code-improvements.md
@@ -0,0 +1,5 @@
+ - `M0-1-9` - `DeadCode.ql`
+ - Remove false positives for statements where the enclosing function is compiled multiple times, either as part of different targets or a different template instantiations. Previously we would see false positives where a statement was dead in one instance of the code, but not other instances. We now only consider a statement dead if it is dead in all instances of that code.
+- `RULE-2-2` - `DeadCode.ql`:
+ - Query has been rewritten to report only _operations_ that are considered dead, not statements. This should reduce false positives.
+ - Remove false positives for operations where the enclosing function is compiled multiple times, either as part of different targets or a different template instantiations. Previously we would see false positives where a operation was dead in one instance of the code, but not other instances. We now only consider a operation dead if it is dead in all instances of that code.
\ No newline at end of file
diff --git a/change_notes/2024-09-28-improved-noreturn-rules.md b/change_notes/2024-09-28-improved-noreturn-rules.md
new file mode 100644
index 0000000000..99fb4a0f46
--- /dev/null
+++ b/change_notes/2024-09-28-improved-noreturn-rules.md
@@ -0,0 +1,3 @@
+ - `A7-6-1`, `MSC53-CPP`, `RULE-9-6-4` - `FunctionNoReturnAttbrituteCondition.qll`
+ - Analysis expanded from functions with "noreturn" attribute, now includes the "noreturn" specifier as well to handle new c rules. No difference in C++ results expected.
+ - Exclude compiler generated functions from being reported.
\ No newline at end of file
diff --git a/change_notes/2024-10-02-c-perf-issues.md b/change_notes/2024-10-02-c-perf-issues.md
new file mode 100644
index 0000000000..c9fcac1a05
--- /dev/null
+++ b/change_notes/2024-10-02-c-perf-issues.md
@@ -0,0 +1,4 @@
+ - `RULE-10-7` - `ImplicitConversionOfCompositeExpression.ql`:
+ - Improved performance on larger codebases.
+ - `SIG31-C` - `DoNotAccessSharedObjectsInSignalHandlers.ql`:
+ - Improved performance on larger codebases.
\ No newline at end of file
diff --git a/change_notes/2024-10-02-fix-fp-711-M0-1-10.md b/change_notes/2024-10-02-fix-fp-711-M0-1-10.md
new file mode 100644
index 0000000000..cff5d5ab43
--- /dev/null
+++ b/change_notes/2024-10-02-fix-fp-711-M0-1-10.md
@@ -0,0 +1,2 @@
+- `M0-1-10` - `UnusedFunction.ql`:
+ - Fixes #711. Excludes constexpr functions, considers functions from GoogleTest as an EntryPoint and does not consider special member functions. Another query called UnusedSplMemberFunction.ql is created that reports unused special member functions. This is done so as to enable deviations to be applied to this case.
diff --git a/change_notes/2024-10-03-misra-c-query-suites.md b/change_notes/2024-10-03-misra-c-query-suites.md
new file mode 100644
index 0000000000..c60aac8941
--- /dev/null
+++ b/change_notes/2024-10-03-misra-c-query-suites.md
@@ -0,0 +1,10 @@
+ - The following query suites have been added or modified for MISRA C:
+ - A new query suite has been created `misra-c-default.qls` to avoid confusion with the MISRA C++ query suites. The `misra-default.qls` suite has been deprecated, and will be removed in a future releases, and is replaced by the `misra-c-default.qls` suite.
+ - The `misra-c-default.qls` suite has been specified as the default for the pack, and will include our most up-to-date coverage for MISRA C.
+ - A new query suite `misra-c-2012-third-edition-with-amendment-2.qls` has been created to represent our previous MISRA C coverage. Note: this query suite will run the rules that were present in MISRA C 2012, Third Edition, First Revision and Amendment 2. The interpretation of those rules may be updated to reflect changes in more recent MISRA standards.
+ - Three new query suites, `misra-c-mandatory.qls`, `misra-c-required.qls` and `misra-c-advisory.qls`, have been added to enable running mandatory, required or advisory queries.
+ - The following query suites have been added or modified for MISRA C++:
+ - A new query suite has been created `misra-cpp-default.qls` to avoid confusion with the MISRA C query suites. The `misra-default.qls` suite has been deprecated, and will be removed in a future releases, and is replaced by the `misra-cpp-default.qls` suite.
+ - The `misra-cpp-default.qls` suite has been specified as the default for the pack, and will include our most up-to-date coverage for MISRA C.
+ - A new query suite has been created `misra-cpp-single-translation-unit.qls` to avoid confusion with the MISRA C query suites. The `misra-single-translation-unit.qls` suite has been deprecated, and will be removed in a future releases, and is replaced by the `misra-cpp-single-translation-unit.qls` suite.
+ - Three new query suites, `misra-cpp-mandatory.qls`, `misra-c-required.qls` and `misra-c-advisory.qls`, have been added to enable running mandatory, required or advisory queries.
\ No newline at end of file
diff --git a/change_notes/2024-10-04-fix-constexpr-arr-size-fp-a0-1-1.md b/change_notes/2024-10-04-fix-constexpr-arr-size-fp-a0-1-1.md
new file mode 100644
index 0000000000..184efa9462
--- /dev/null
+++ b/change_notes/2024-10-04-fix-constexpr-arr-size-fp-a0-1-1.md
@@ -0,0 +1,2 @@
+- `A0-1-1` - `UselessAssignments.qll`:
+ - Remove (dead code) useless assignment false positive when integer constant expression is used to define the size of an array.
diff --git a/change_notes/2024-10-08-upgrade-to-2.16.6.md b/change_notes/2024-10-08-upgrade-to-2.16.6.md
new file mode 100644
index 0000000000..9f1e11d3d3
--- /dev/null
+++ b/change_notes/2024-10-08-upgrade-to-2.16.6.md
@@ -0,0 +1,3 @@
+- Updated the CodeQL version to `2.16.6`.
+- `M0-1-2` - `InfeasiblePath.ql`:
+ - This query may now report additional results within templates where a relational operation is performed which has a constant value given the specified arguments.
\ No newline at end of file
diff --git a/change_notes/2024-10-11-specifiers-rule-11-misra-c.md b/change_notes/2024-10-11-specifiers-rule-11-misra-c.md
new file mode 100644
index 0000000000..5f74dc6b3f
--- /dev/null
+++ b/change_notes/2024-10-11-specifiers-rule-11-misra-c.md
@@ -0,0 +1,4 @@
+- `RULE-11-3`, `RULE-11-4`, `RULE-11-5`, `RULE-11-7` - `CastBetweenObjectPointerAndDifferentObjectType.ql`, `ConversionBetweenPointerToObjectAndIntegerType.ql`, `ConversionFromPointerToVoidIntoPointerToObject.ql`, `CastBetweenPointerToObjectAndNonIntArithmeticType.ql`:
+ - Removed false positives where casts involved a specified void type pointer, e.g. `const void*`, which should not be considered as a pointer to object.
+- `RULE-11-5` - `ConversionFromPointerToVoidIntoPointerToObject.ql`:
+ - Addressed false negatives where the pointer-to-void was specified.
\ No newline at end of file
diff --git a/change_notes/2024-10-15-a7-1-3-multi-refs.md b/change_notes/2024-10-15-a7-1-3-multi-refs.md
new file mode 100644
index 0000000000..39e00495cb
--- /dev/null
+++ b/change_notes/2024-10-15-a7-1-3-multi-refs.md
@@ -0,0 +1,2 @@
+- `A7-1-3` - `CvQualifiersNotPlacedOnTheRightHandSide.ql`:
+ - Removed false positives where a correctly CV-qualified typedef variable type was also referenced in the initializer.
\ No newline at end of file
diff --git a/change_notes/2024-10-15-fix-fp-739-a14-5-2.md b/change_notes/2024-10-15-fix-fp-739-a14-5-2.md
new file mode 100644
index 0000000000..6e3f422718
--- /dev/null
+++ b/change_notes/2024-10-15-fix-fp-739-a14-5-2.md
@@ -0,0 +1,2 @@
+- `A14-5-2` - `NonTemplateMemberDefinedInTemplate.ql`
+ - Fixes #739. Correctly detect template parameters specified in using alias base types, e.g. `using T1 = some_type::Type;`.
diff --git a/change_notes/2024-10-15-lits-and-constants-10-4.md b/change_notes/2024-10-15-lits-and-constants-10-4.md
new file mode 100644
index 0000000000..cfcb309204
--- /dev/null
+++ b/change_notes/2024-10-15-lits-and-constants-10-4.md
@@ -0,0 +1,5 @@
+ - `RULE-10-4` - `OperandswithMismatchedEssentialTypeCategory.ql`:
+ - Removed false positives where a specified or typedef'd enum type was compared to an enum constant type.
+ - `EssentialType` - for all queries related to essential types:
+ - `\n` and other control characters are now correctly deduced as essentially char type, instead of an essentially integer type.
+ - Enum constants for anonymous enums are now correctly deduced as an essentially signed integer type instead of essentially enum.
\ No newline at end of file
diff --git a/change_notes/2024-10-17-a5-2-6-no-ambiguity.md b/change_notes/2024-10-17-a5-2-6-no-ambiguity.md
new file mode 100644
index 0000000000..6e00b3bbaf
--- /dev/null
+++ b/change_notes/2024-10-17-a5-2-6-no-ambiguity.md
@@ -0,0 +1,3 @@
+ - `A5-2-6` - `OperandsOfAlogicalAndOrNotParenthesized.ql`:
+ - Remove false positives where the operator is identical.
+ - Improve alert message to clarify which expression needs to be parenthesized.
\ No newline at end of file
diff --git a/change_notes/2024-10-17-suffixes.md b/change_notes/2024-10-17-suffixes.md
new file mode 100644
index 0000000000..16d8ca4cda
--- /dev/null
+++ b/change_notes/2024-10-17-suffixes.md
@@ -0,0 +1,4 @@
+ - `5.13.4` - `UnsignedLiteralsNotAppropriatelySuffixed.ql`:
+ - Expand detection to binary literals.
+ - `M2-13-3` - `MissingUSuffix.ql`:
+ - Expand detection to binary literals.
\ No newline at end of file
diff --git a/change_notes/2024-10-18-init-base-class-deleted.md b/change_notes/2024-10-18-init-base-class-deleted.md
new file mode 100644
index 0000000000..992e1e88a2
--- /dev/null
+++ b/change_notes/2024-10-18-init-base-class-deleted.md
@@ -0,0 +1,2 @@
+- `A12-1-1`, `RULE-15-1-2` - `InitializeAllVirtualBaseClasses.ql`, `ExplicitConstructorBaseClassInitialization.ql`:
+ - Remove false positives for deleted member functions.
\ No newline at end of file
diff --git a/change_notes/2024-10-20-8-13-fixes.md b/change_notes/2024-10-20-8-13-fixes.md
new file mode 100644
index 0000000000..6ee8e3a32c
--- /dev/null
+++ b/change_notes/2024-10-20-8-13-fixes.md
@@ -0,0 +1,7 @@
+ - `RULE-8-13` - `PointerShouldPointToConstTypeWhenPossible.ql`
+ - Exclude false positives where a variable occurs in a file compiled multiple times, but where it may only be const in some of those scenarios.
+ - Exclude results for local scope variables in functions that use assembly code, as CodeQL cannot determine the impact of the assembly.
+ - Exclude false positives when an assignment is made to a struct field.
+ - Exclude false positives where the object pointed to by the variable is modified using `*p++ = ...`.
+ - Exclude false positives for functions without bodies.
+ - Rules that rely on the determination of side-effects of an expression may change as a result of considering `*p++ = ...` as having a side-effect on `p`.
\ No newline at end of file
diff --git a/change_notes/2024-10-21-rule-1-3-main.md b/change_notes/2024-10-21-rule-1-3-main.md
new file mode 100644
index 0000000000..7bd8d4bd54
--- /dev/null
+++ b/change_notes/2024-10-21-rule-1-3-main.md
@@ -0,0 +1,3 @@
+ - `RULE-1-3` - `OccurrenceOfUndefinedBehavior.ql`:
+ - Improve alert message to report the undefined behavior triggered.
+ - Address both false positives and false negatives in identifying standard compliant main methods. Previously, `void main()` was considered permitted and `int main(void)` banned. In addition, we now detect main methods as standard compliant if they use typedefs, and if arrays are used in the definition of `argv`.
\ No newline at end of file
diff --git a/change_notes/2024-10-21-rule-5-4-conditional.md b/change_notes/2024-10-21-rule-5-4-conditional.md
new file mode 100644
index 0000000000..cfc22f3642
--- /dev/null
+++ b/change_notes/2024-10-21-rule-5-4-conditional.md
@@ -0,0 +1,3 @@
+ - `RULE-5-4` - `MacroIdentifiersNotDistinct.ql`:
+ - Exclude false positives related to conditional compilation, where a macro may be defined twice, but not within the same compilation.
+ - Improve alert message in the case the 63 char limit is not relevant by using the form "Definition of macro `` is not distinct from alternative definition of `` in ``.
\ No newline at end of file
diff --git a/change_notes/2024-10-22-rule-2-5.md b/change_notes/2024-10-22-rule-2-5.md
new file mode 100644
index 0000000000..6de3f0be11
--- /dev/null
+++ b/change_notes/2024-10-22-rule-2-5.md
@@ -0,0 +1,2 @@
+ - `RULE-2-5` - `UnusedMacroDeclaration.ql`:
+ - Exclude false positives where a macro was used before definition, for example a header guard.
\ No newline at end of file
diff --git a/change_notes/2024-10-22-update-release-artifacts.md b/change_notes/2024-10-22-update-release-artifacts.md
new file mode 100644
index 0000000000..46d0ed0c30
--- /dev/null
+++ b/change_notes/2024-10-22-update-release-artifacts.md
@@ -0,0 +1,4 @@
+ - Modifications to the release artifacts:
+ - New CodeQL pack release artifacts have been created. These release artifacts can be downloaded from the release, and will be published to the GitHub registry under the `codeql` org for ease of deployment.
+ - The user manual has been updated to describe how to use the CodeQL packs.
+ - We no longer require a separate download of the CodeQL Standard Library for C++ - all queries have been pre-compiled and linked with the appropriate standard library.
\ No newline at end of file
diff --git a/change_notes/2024-10-24-compatible-types.md b/change_notes/2024-10-24-compatible-types.md
new file mode 100644
index 0000000000..05afbd64d9
--- /dev/null
+++ b/change_notes/2024-10-24-compatible-types.md
@@ -0,0 +1,2 @@
+ - `DCL40-C` - `IncompatibleFunctionDeclarations.ql`:
+ - Reduce false positives by identifying compatible integer arithmetic types (e.g. "signed int" and "int").
\ No newline at end of file
diff --git a/change_notes/2024-9-20-a1-1-2-improvements.md b/change_notes/2024-9-20-a1-1-2-improvements.md
new file mode 100644
index 0000000000..25e393954b
--- /dev/null
+++ b/change_notes/2024-9-20-a1-1-2-improvements.md
@@ -0,0 +1,2 @@
+- `A1-1-2` - `CompilerWarningLevelNotInCompliance.ql`:
+ - Report non-compliance for compilations that use the error-suppressing `-w` flag.
diff --git a/cpp/autosar/src/codeql-pack.lock.yml b/cpp/autosar/src/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/cpp/autosar/src/codeql-pack.lock.yml
+++ b/cpp/autosar/src/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/cpp/autosar/src/qlpack.yml b/cpp/autosar/src/qlpack.yml
index 9c0bccbc08..810af3bde4 100644
--- a/cpp/autosar/src/qlpack.yml
+++ b/cpp/autosar/src/qlpack.yml
@@ -1,8 +1,8 @@
name: codeql/autosar-cpp-coding-standards
-version: 2.33.0-dev
+version: 2.38.0-dev
description: AUTOSAR C++14 Guidelines R22-11, R21-11, R20-11, R19-11 and R19-03
suites: codeql-suites
license: MIT
dependencies:
codeql/common-cpp-coding-standards: '*'
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 0.12.9
diff --git a/cpp/autosar/src/rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql b/cpp/autosar/src/rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql
index bd98ad9162..1499191236 100644
--- a/cpp/autosar/src/rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql
+++ b/cpp/autosar/src/rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql
@@ -20,13 +20,57 @@ import codingstandards.cpp.autosar
predicate hasResponseFileArgument(Compilation c) { c.getAnArgument().matches("@%") }
-predicate hasWarningOption(Compilation c) { c.getAnArgument().regexpMatch("-W[\\w=-]+") }
+class CompilationWithNoWarnings extends Compilation {
+ CompilationWithNoWarnings() {
+ getAnArgument() = "-w"
+ or
+ not exists(EnableWarningFlag enableFlag |
+ this.getAnArgument() = enableFlag and
+ not exists(DisableWarningFlag disableFlag |
+ this.getAnArgument() = disableFlag and
+ enableFlag.getWarningType() = disableFlag.getWarningType()
+ )
+ )
+ }
+}
+
+class CompilationArgument extends string {
+ Compilation compilation;
+
+ CompilationArgument() { this = compilation.getAnArgument() }
+}
+
+/**
+ * Compiler flags of type -Wfoo or -Wfoo=bar, which enables the `foo` warning.
+ */
+class EnableWarningFlag extends CompilationArgument {
+ string warningType;
+
+ EnableWarningFlag() {
+ warningType = regexpCapture("^-W([\\w-]+)(=.*)?$", 1) and
+ not this instanceof DisableWarningFlag
+ }
+
+ string getWarningType() { result = warningType }
+}
+
+/**
+ * Compiler flags of type -Wno-foo or -Wfoo=0, which disables the `foo` warning
+ * and overrules -Wfoo.
+ */
+class DisableWarningFlag extends CompilationArgument {
+ string warningType;
+
+ DisableWarningFlag() {
+ warningType = regexpCapture("^-Wno-([\\w-]+)", 1) or
+ warningType = regexpCapture("^-W([\\w-]+)=0", 1)
+ }
+
+ string getWarningType() { result = warningType }
+}
from File f
where
not isExcluded(f, ToolchainPackage::compilerWarningLevelNotInComplianceQuery()) and
- exists(Compilation c | f = c.getAFileCompiled() |
- not hasResponseFileArgument(c) and
- not hasWarningOption(c)
- )
+ exists(CompilationWithNoWarnings c | f = c.getAFileCompiled() | not hasResponseFileArgument(c))
select f, "No warning-level options were used in the compilation of '" + f.getBaseName() + "'."
diff --git a/cpp/autosar/src/rules/A13-1-2/UserDefinedLiteralOperatorSuffixViolation.ql b/cpp/autosar/src/rules/A13-1-2/UserDefinedLiteralOperatorSuffixViolation.ql
index 7fe8bcdbe7..c739035596 100644
--- a/cpp/autosar/src/rules/A13-1-2/UserDefinedLiteralOperatorSuffixViolation.ql
+++ b/cpp/autosar/src/rules/A13-1-2/UserDefinedLiteralOperatorSuffixViolation.ql
@@ -15,9 +15,9 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.UserDefinedLiteral
+import codingstandards.cpp.UserDefinedLiteral as udl
-from UserDefinedLiteral udl
+from udl::UserDefinedLiteral udl
where
not isExcluded(udl, NamingPackage::userDefinedLiteralOperatorSuffixViolationQuery()) and
not udl.hasCompliantSuffix()
diff --git a/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallNotHaveSideEffects.ql b/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallNotHaveSideEffects.ql
index 0cbb9f101e..b41a57f900 100644
--- a/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallNotHaveSideEffects.ql
+++ b/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallNotHaveSideEffects.ql
@@ -14,11 +14,11 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.UserDefinedLiteral
+import codingstandards.cpp.UserDefinedLiteral as udl
import codingstandards.cpp.SideEffect
import codingstandards.cpp.sideeffect.DefaultEffects
-from UserDefinedLiteral udl, SideEffect e
+from udl::UserDefinedLiteral udl, SideEffect e
where
not isExcluded(udl,
SideEffects2Package::userDefinedLiteralsOperatorsShallNotHaveSideEffectsQuery()) and
diff --git a/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.ql b/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.ql
index b010e616cb..840d7423fb 100644
--- a/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.ql
+++ b/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.ql
@@ -16,10 +16,10 @@
import cpp
import codingstandards.cpp.dataflow.TaintTracking
import codingstandards.cpp.autosar
-import codingstandards.cpp.UserDefinedLiteral
+import codingstandards.cpp.UserDefinedLiteral as udl
import codingstandards.cpp.SideEffect
-from UserDefinedLiteral udl, Expr retExpr
+from udl::UserDefinedLiteral udl, Expr retExpr
where
not isExcluded(udl,
SideEffects2Package::userDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParametersQuery()) and
diff --git a/cpp/autosar/src/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql b/cpp/autosar/src/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql
index 393c1222fd..81ca7039c3 100644
--- a/cpp/autosar/src/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql
+++ b/cpp/autosar/src/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql
@@ -32,25 +32,13 @@ where
// allow for overloading with different number of parameters, because there is no
// confusion on what function will be called.
f.getNumberOfParameters() = c.getNumberOfParameters() and
- //build a dynamic select statement that guarantees to read that the overloading function is the explicit one
- if
- (f instanceof CopyConstructor or f instanceof MoveConstructor) and
- f.isCompilerGenerated()
- then (
- (
- f instanceof CopyConstructor and
- msg = "implicit copy constructor"
- or
- f instanceof MoveConstructor and
- msg = "implicit move constructor"
- ) and
- firstMsgSegment = " with a forwarding reference parameter " and
- overloaded = f and
- overload = c
- ) else (
- msg = "function with a forwarding reference parameter" and
- firstMsgSegment = " " and
- overloaded = c and
- overload = f
- )
+ //ignore implicit copy and move constructor overloads
+ not (
+ f.isCompilerGenerated() and
+ (f instanceof CopyConstructor or f instanceof MoveConstructor)
+ ) and
+ msg = "function with a forwarding reference parameter" and
+ firstMsgSegment = " " and
+ overloaded = c and
+ overload = f
select overload, "Function" + firstMsgSegment + "overloads a $@.", overloaded, msg
diff --git a/cpp/autosar/src/rules/A14-5-2/NonTemplateMemberDefinedInTemplate.ql b/cpp/autosar/src/rules/A14-5-2/NonTemplateMemberDefinedInTemplate.ql
index 4a81e32b0f..7f9ced9909 100644
--- a/cpp/autosar/src/rules/A14-5-2/NonTemplateMemberDefinedInTemplate.ql
+++ b/cpp/autosar/src/rules/A14-5-2/NonTemplateMemberDefinedInTemplate.ql
@@ -167,7 +167,10 @@ where
mf = c.getAMemberFunction() and not mf.isCompilerGenerated() and not exists(mf.getBlock())
)
)
- )
+ ) and
+ // Omit using alias (cf. https://github.com/github/codeql-coding-standards/issues/739)
+ // Exclude Using alias which refer directly to a TypeParameter
+ not d.(UsingAliasTypedefType).getBaseType() instanceof TemplateParameter
select d,
"Member " + d.getName() + " template class does not use any of template arguments of its $@.",
d.getDeclaringType(), "declaring type"
diff --git a/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql b/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql
index c3295275db..b38cf7d02c 100644
--- a/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql
+++ b/cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql
@@ -77,7 +77,11 @@ class DocumentableDeclaration extends Declaration {
// Exclude instantiated template functions, which cannot reasonably be documented.
not this.(Function).isFromTemplateInstantiation(_) and
// Exclude anonymous lambda functions.
- not exists(LambdaExpression lc | lc.getLambdaFunction() = this)
+ not exists(LambdaExpression lc | lc.getLambdaFunction() = this) and
+ //Exclude friend functions (because they have 2 entries in the database), and only one shows documented truly
+ not exists(FriendDecl d |
+ d.getFriend().(Function).getDefinition() = this.getADeclarationEntry()
+ )
or
this instanceof MemberVariable and
declarationType = "member variable" and
diff --git a/cpp/autosar/src/rules/A5-2-6/OperandsOfALogicalAndOrNotParenthesized.ql b/cpp/autosar/src/rules/A5-2-6/OperandsOfALogicalAndOrNotParenthesized.ql
index dd63288587..b2c3120556 100644
--- a/cpp/autosar/src/rules/A5-2-6/OperandsOfALogicalAndOrNotParenthesized.ql
+++ b/cpp/autosar/src/rules/A5-2-6/OperandsOfALogicalAndOrNotParenthesized.ql
@@ -17,11 +17,20 @@
import cpp
import codingstandards.cpp.autosar
-from BinaryLogicalOperation op, BinaryOperation binop
+from BinaryLogicalOperation op, BinaryOperation binop, string leftOrRight
where
not isExcluded(op, OrderOfEvaluationPackage::operandsOfALogicalAndOrNotParenthesizedQuery()) and
- op.getAnOperand() = binop and
+ (
+ op.getLeftOperand() = binop and
+ leftOrRight = "Left"
+ or
+ op.getRightOperand() = binop and
+ leftOrRight = "Right"
+ ) and
+ // Ignore cases with the same operator
+ not op.getOperator() = binop.getOperator() and
not exists(ParenthesisExpr p | p = binop.getFullyConverted()) and
// Exclude binary operations expanded by a macro.
not binop.isInMacroExpansion()
-select op, "Binary $@ operand of logical operation is not parenthesized.", binop, "operator"
+select op, "$@ of logical operation " + op.getOperator() + " is not parenthesized.", binop,
+ leftOrRight + " operand " + binop.getOperator()
diff --git a/cpp/autosar/src/rules/A7-1-3/CvQualifiersNotPlacedOnTheRightHandSide.ql b/cpp/autosar/src/rules/A7-1-3/CvQualifiersNotPlacedOnTheRightHandSide.ql
index 54968dc223..5d34f89c7d 100644
--- a/cpp/autosar/src/rules/A7-1-3/CvQualifiersNotPlacedOnTheRightHandSide.ql
+++ b/cpp/autosar/src/rules/A7-1-3/CvQualifiersNotPlacedOnTheRightHandSide.ql
@@ -20,37 +20,50 @@ import cpp
import codingstandards.cpp.autosar
/**
- * Holds if declaration `e` using a `TypedefType` is CV-qualified
- *
- * For example, given `using intconstptr = int * const`:
- * the predicate holds for `const/volatile intconstptr ptr1`, but not for `intconstptr ptr2`
+ * Unwrap layers of indirection that occur on the right side of the type.
*/
-predicate containsExtraSpecifiers(VariableDeclarationEntry e) {
- e.getType().toString().matches("const %") or
- e.getType().toString().matches("volatile %")
+Type unwrapIndirection(Type type) {
+ if type instanceof DerivedType and not type instanceof SpecifiedType
+ then result = unwrapIndirection(type.(DerivedType).getBaseType())
+ else result = type
}
// DeclStmts that have a TypedefType name use (ie TypeMention) in them
//AND TypeMention.getStartColumn() - DeclStmt.getStartColumn() > len(const)
//AND the declared thing contains one of these "extra" specifiers in the DeclarationEntry Location
-from VariableDeclarationEntry e, TypedefType t, TypeMention tm
+from
+ VariableDeclarationEntry e, TypedefType t, TypeMention tm, string message, Element explainer,
+ string explainerMessage
where
not isExcluded(e, ConstPackage::cvQualifiersNotPlacedOnTheRightHandSideQuery()) and
- containsExtraSpecifiers(e) and
+ // Variable type is specified, and has the typedef type as a base type
+ unwrapIndirection(e.getType()).(SpecifiedType).getBaseType() = t and
exists(string filepath, int startline |
e.getLocation().hasLocationInfo(filepath, startline, _, _, _) and
tm.getLocation().hasLocationInfo(filepath, startline, _, _, _) and
e = t.getATypeNameUse() and
tm.getMentionedType() = t and
+ // TypeMention occurs before the variable declaration
+ tm.getLocation().getStartColumn() < e.getLocation().getStartColumn() and
exists(DeclStmt s |
s.getDeclarationEntry(_) = e and
- //const could fit in there
+ // TypeMention occurs after the start of the StmtDecl, with enough space for const/volatile
tm.getLocation().getStartColumn() - s.getLocation().getStartColumn() > 5
- //volatile could fit in there
- //but the above condition subsumes this one
- //l.getStartColumn() - tm.getLocation().getStartColumn() > 8
)
+ ) and
+ if exists(t.getFile().getRelativePath())
+ then
+ message =
+ "There is possibly a const or volatile specifier on the left hand side of typedef name $@." and
+ explainer = t and
+ explainerMessage = t.getName()
+ else (
+ // Type occurs outside source root, so don't link
+ message =
+ "There is possibly a const or volatile specifier on the left hand side of typedef name " +
+ t.getName() + "." and
+ // explainer not used in this case
+ explainer = e and
+ explainerMessage = ""
)
-select e,
- "There is possibly a const or volatile specifier on the left hand side of typedef name $@.", t,
- t.getName()
+select e, message, explainer, explainerMessage
diff --git a/cpp/autosar/src/rules/A7-2-1/NonEnumeratorEnumValue.ql b/cpp/autosar/src/rules/A7-2-1/NonEnumeratorEnumValue.ql
index 9b41c97129..f4dcd7f32e 100644
--- a/cpp/autosar/src/rules/A7-2-1/NonEnumeratorEnumValue.ql
+++ b/cpp/autosar/src/rules/A7-2-1/NonEnumeratorEnumValue.ql
@@ -47,7 +47,7 @@ where
then
description =
"Cast to enum $@ with from expression with value " + c.getExpr().getValue().toFloat() +
- "_+ which is not one of the enumerator values in function " +
+ " which is not one of the enumerator values in function " +
c.getEnclosingFunction().getName() + "."
else
if exists(upperBound(c.getExpr()))
diff --git a/cpp/autosar/src/rules/M0-1-10/UnusedFunction.ql b/cpp/autosar/src/rules/M0-1-10/UnusedFunction.ql
index b8593e75c0..f175cb8992 100644
--- a/cpp/autosar/src/rules/M0-1-10/UnusedFunction.ql
+++ b/cpp/autosar/src/rules/M0-1-10/UnusedFunction.ql
@@ -26,5 +26,6 @@ where
then name = unusedFunction.getQualifiedName()
else name = unusedFunction.getName()
) and
- not unusedFunction.isDeleted()
+ not unusedFunction.isDeleted() and
+ not unusedFunction instanceof SpecialMemberFunction
select unusedFunction, "Function " + name + " is " + unusedFunction.getDeadCodeType()
diff --git a/cpp/autosar/src/rules/M0-1-10/UnusedSplMemberFunction.ql b/cpp/autosar/src/rules/M0-1-10/UnusedSplMemberFunction.ql
new file mode 100644
index 0000000000..bcbf6f4e1b
--- /dev/null
+++ b/cpp/autosar/src/rules/M0-1-10/UnusedSplMemberFunction.ql
@@ -0,0 +1,31 @@
+/**
+ * @id cpp/autosar/unused-spl-member-function
+ * @name M0-1-10: Every defined function should be called at least once
+ * @description Uncalled functions complicate the program and can indicate a possible mistake on the
+ * part of the programmer.
+ * @kind problem
+ * @precision medium
+ * @problem.severity warning
+ * @tags external/autosar/id/m0-1-10
+ * readability
+ * maintainability
+ * external/autosar/allocated-target/implementation
+ * external/autosar/enforcement/automated
+ * external/autosar/obligation/advisory
+ */
+
+import cpp
+import codingstandards.cpp.autosar
+import codingstandards.cpp.deadcode.UnusedFunctions
+
+from UnusedFunctions::UnusedSplMemberFunction unusedSplMemFunction, string name
+where
+ not isExcluded(unusedSplMemFunction, DeadCodePackage::unusedFunctionQuery()) and
+ (
+ if exists(unusedSplMemFunction.getQualifiedName())
+ then name = unusedSplMemFunction.getQualifiedName()
+ else name = unusedSplMemFunction.getName()
+ ) and
+ not unusedSplMemFunction.isDeleted()
+select unusedSplMemFunction,
+ "Special member function " + name + " is " + unusedSplMemFunction.getDeadCodeType()
diff --git a/cpp/autosar/src/rules/M0-1-2/InfeasiblePath.ql b/cpp/autosar/src/rules/M0-1-2/InfeasiblePath.ql
index 76ccdead69..83e056472b 100644
--- a/cpp/autosar/src/rules/M0-1-2/InfeasiblePath.ql
+++ b/cpp/autosar/src/rules/M0-1-2/InfeasiblePath.ql
@@ -151,186 +151,19 @@ predicate isConstantRelationalOperation(
* Holds if the `ConditionalNode` has an infeasible `path` for the reason given in `explanation`.
*/
predicate hasInfeasiblePath(ConditionalControlFlowNode node, string message) {
- //deal with the infeasible in all uninstantiated templates separately
- node.isFromUninstantiatedTemplate(_) and
- node instanceof ConditionControllingUnreachable and
- message = "The path is unreachable in a template."
- or
exists(boolean infeasiblePath, string explanation |
- (
- not node.isFromUninstantiatedTemplate(_) and
- not node.isFromTemplateInstantiation(_) and
- message = "The " + infeasiblePath + " path is infeasible because " + explanation + "."
- ) and
- (
- hasCFGDeducedInfeasiblePath(node, infeasiblePath, explanation) and
- not isConstantRelationalOperation(node, infeasiblePath, _)
- or
- isConstantRelationalOperation(node, infeasiblePath, explanation)
- )
+ not node.isFromTemplateInstantiation(_) and
+ if node.isFromUninstantiatedTemplate(_)
+ then message = "The path is unreachable in a template."
+ else message = "The " + infeasiblePath + " path is infeasible because " + explanation + "."
+ |
+ hasCFGDeducedInfeasiblePath(node, infeasiblePath, explanation) and
+ not isConstantRelationalOperation(node, infeasiblePath, _)
+ or
+ isConstantRelationalOperation(node, infeasiblePath, explanation)
)
}
-/**
- * A newtype representing "unreachable" blocks in the program. We use a newtype here to avoid
- * reporting the same block in multiple `Function` instances created from one function in a template.
- */
-private newtype TUnreachableBasicBlock =
- TUnreachableNonTemplateBlock(BasicBlock bb) {
- bb.isUnreachable() and
- // Exclude anything template related from this case
- not bb.getEnclosingFunction().isFromTemplateInstantiation(_) and
- not bb.getEnclosingFunction().isFromUninstantiatedTemplate(_) and
- // Exclude compiler generated basic blocks
- not isCompilerGenerated(bb)
- } or
- /**
- * A `BasicBlock` that occurs in at least one `Function` instance for a template. `BasicBlock`s
- * are matched up across templates by location.
- */
- TUnreachableTemplateBlock(
- string filepath, int startline, int startcolumn, int endline, int endcolumn,
- GuardCondition uninstantiatedGuardCondition
- ) {
- exists(BasicBlock bb |
- // BasicBlock occurs in this location
- bb.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
- // And is contained in the `uninstantiatedFunction` only
- // not from anything constructed from it
- // because we want infeasible paths independent of parameters
- exists(Function enclosing | enclosing = bb.getEnclosingFunction() |
- //guard is in the template function
- (
- enclosing.getBlock().getAChild*() = uninstantiatedGuardCondition and
- //function template
- enclosing.isFromUninstantiatedTemplate(_) and
- uninstantiatedGuardCondition.isFromUninstantiatedTemplate(_) and
- //true condition is unreachable: basic block starts on same line as guard
- (
- not exists(uninstantiatedGuardCondition.getATrueSuccessor()) and
- bb.hasLocationInfo(filepath, uninstantiatedGuardCondition.getLocation().getStartLine(),
- startcolumn, endline, endcolumn)
- or
- //false condition is unreachable: false basic block starts on one line after its true basic block
- not exists(uninstantiatedGuardCondition.getAFalseSuccessor()) and
- bb.hasLocationInfo(filepath,
- uninstantiatedGuardCondition.getATrueSuccessor().getLocation().getEndLine() + 1,
- startcolumn, endline, endcolumn)
- )
- )
- ) and
- // And is unreachable
- bb.isUnreachable() and
- // //Exclude compiler generated control flow nodes
- not isCompilerGenerated(bb) and
- //Exclude nodes affected by macros, because our find-the-same-basic-block-by-location doesn't
- //work in that case
- not bb.(ControlFlowNode).isAffectedByMacro()
- )
- }
-
-/**
- * An unreachable basic block.
- */
-class UnreachableBasicBlock extends TUnreachableBasicBlock {
- /** Gets a `BasicBlock` which is represented by this set of unreachable basic blocks. */
- BasicBlock getABasicBlock() { none() }
-
- /** Gets a `GuardCondition` instance which we treat as the original GuardCondition. */
- GuardCondition getGuardCondition() { none() }
-
- predicate hasLocationInfo(
- string filepath, int startline, int startcolumn, int endline, int endcolumn
- ) {
- none()
- }
-
- string toString() { result = "default" }
-}
-
-/**
- * A non-templated unreachable basic block.
- */
-class UnreachableNonTemplateBlock extends UnreachableBasicBlock, TUnreachableNonTemplateBlock {
- BasicBlock getBasicBlock() { this = TUnreachableNonTemplateBlock(result) }
-
- override BasicBlock getABasicBlock() { result = getBasicBlock() }
-
- override GuardCondition getGuardCondition() { result.controls(getBasicBlock(), true) }
-
- override predicate hasLocationInfo(
- string filepath, int startline, int startcolumn, int endline, int endcolumn
- ) {
- getBasicBlock().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
- }
-
- override string toString() { result = getBasicBlock().toString() }
-}
-
-/**
- * A templated unreachable basic block.
- */
-class UnreachableTemplateBlock extends UnreachableBasicBlock, TUnreachableTemplateBlock {
- override BasicBlock getABasicBlock() {
- exists(
- string filepath, int startline, int startcolumn, int endline, int endcolumn,
- GuardCondition uninstantiatedGuardCondition
- |
- this =
- TUnreachableTemplateBlock(filepath, startline, startcolumn, endline, endcolumn,
- uninstantiatedGuardCondition) and
- result.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
- exists(Function enclosing |
- //guard is in the template function
- (
- enclosing.getBlock().getAChild*() = uninstantiatedGuardCondition and
- //function template
- enclosing.isFromUninstantiatedTemplate(_) and
- uninstantiatedGuardCondition.isFromUninstantiatedTemplate(_) and
- //true condition is unreachable: basic block starts on same line as guard
- (
- not exists(uninstantiatedGuardCondition.getATrueSuccessor()) and
- this.hasLocationInfo(filepath,
- uninstantiatedGuardCondition.getLocation().getStartLine(), startcolumn, endline,
- endcolumn)
- or
- //false condition is unreachable: false basic block starts on one line after its true basic block
- not exists(uninstantiatedGuardCondition.getAFalseSuccessor()) and
- this.hasLocationInfo(filepath,
- uninstantiatedGuardCondition.getATrueSuccessor().getLocation().getEndLine() + 1,
- startcolumn, endline, endcolumn)
- )
- )
- )
- |
- result.isUnreachable() and
- // Exclude compiler generated control flow nodes
- not isCompilerGenerated(result) and
- // Exclude nodes affected by macros, because our find-the-same-basic-block-by-location doesn't
- // work in that case
- not result.(ControlFlowNode).isAffectedByMacro()
- )
- }
-
- override GuardCondition getGuardCondition() {
- this = TUnreachableTemplateBlock(_, _, _, _, _, result)
- }
-
- override predicate hasLocationInfo(
- string filepath, int startline, int startcolumn, int endline, int endcolumn
- ) {
- this = TUnreachableTemplateBlock(filepath, startline, startcolumn, endline, endcolumn, _)
- }
-
- override string toString() { result = getABasicBlock().toString() }
-}
-
-class ConditionControllingUnreachable extends GuardCondition {
- ConditionControllingUnreachable() {
- exists(UnreachableTemplateBlock b | this = b.getGuardCondition())
- }
-}
-
from ConditionalControlFlowNode cond, string explanation
where
not isExcluded(cond, DeadCodePackage::infeasiblePathQuery()) and
diff --git a/cpp/autosar/src/rules/M0-1-3/UnusedLocalVariable.ql b/cpp/autosar/src/rules/M0-1-3/UnusedLocalVariable.ql
index f088bb1b74..e89e9ec135 100644
--- a/cpp/autosar/src/rules/M0-1-3/UnusedLocalVariable.ql
+++ b/cpp/autosar/src/rules/M0-1-3/UnusedLocalVariable.ql
@@ -18,12 +18,6 @@ import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.deadcode.UnusedVariables
-/** Gets the constant value of a constexpr variable. */
-private string getConstExprValue(Variable v) {
- result = v.getInitializer().getExpr().getValue() and
- v.isConstexpr()
-}
-
// This predicate is similar to getUseCount for M0-1-4 except that it also
// considers static_asserts. This was created to cater for M0-1-3 specifically
// and hence, doesn't attempt to reuse the M0-1-4 specific predicate
@@ -41,7 +35,10 @@ int getUseCountConservatively(Variable v) {
) +
// For static asserts too, check if there is a child which has the same value
// as the constexpr variable.
- count(StaticAssert s | s.getCondition().getAChild*().getValue() = getConstExprValue(v))
+ count(StaticAssert s | s.getCondition().getAChild*().getValue() = getConstExprValue(v)) +
+ // In case an array type uses a constant in the same scope as the constexpr variable,
+ // consider it as used.
+ countUsesInLocalArraySize(v)
}
from PotentiallyUnusedLocalVariable v
@@ -49,5 +46,13 @@ where
not isExcluded(v, DeadCodePackage::unusedLocalVariableQuery()) and
// Local variable is never accessed
not exists(v.getAnAccess()) and
+ // Sometimes multiple objects representing the same entities are created in
+ // the AST. Check if those are not accessed as well. Refer issue #658
+ not exists(LocalScopeVariable another |
+ another.getDefinitionLocation() = v.getDefinitionLocation() and
+ another.hasName(v.getName()) and
+ exists(another.getAnAccess()) and
+ another != v
+ ) and
getUseCountConservatively(v) = 0
select v, "Local variable '" + v.getName() + "' in '" + v.getFunction().getName() + "' is not used."
diff --git a/cpp/autosar/src/rules/M0-1-4/SingleUsePODVariable.qll b/cpp/autosar/src/rules/M0-1-4/SingleUsePODVariable.qll
index 45ea8c35ab..c0a32baba9 100644
--- a/cpp/autosar/src/rules/M0-1-4/SingleUsePODVariable.qll
+++ b/cpp/autosar/src/rules/M0-1-4/SingleUsePODVariable.qll
@@ -4,12 +4,6 @@ import cpp
import codingstandards.cpp.TrivialType
import codingstandards.cpp.deadcode.UnusedVariables
-/** Gets the constant value of a constexpr variable. */
-private string getConstExprValue(Variable v) {
- result = v.getInitializer().getExpr().getValue() and
- v.isConstexpr()
-}
-
/**
* Gets the number of uses of variable `v` in an opaque assignment, where an opaque assignment is a cast from one type to the other, and `v` is assumed to be a member of the resulting type.
* e.g.,
diff --git a/cpp/autosar/src/rules/M0-2-1/DoNotPassAliasedPointerToParam.ql b/cpp/autosar/src/rules/M0-2-1/DoNotPassAliasedPointerToParam.ql
new file mode 100644
index 0000000000..d99ae486fc
--- /dev/null
+++ b/cpp/autosar/src/rules/M0-2-1/DoNotPassAliasedPointerToParam.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/autosar/do-not-pass-aliased-pointer-to-param
+ * @name M0-2-1: Do not pass aliased pointers as parameters of functions where it is undefined behaviour for those pointers to overlap
+ * @description Passing a aliased pointers as parameters of certain functions is undefined behavior.
+ * @kind problem
+ * @precision medium
+ * @problem.severity error
+ * @tags external/autosar/id/m0-2-1
+ * correctness
+ * external/autosar/allocated-target/implementation
+ * external/autosar/enforcement/automated
+ * external/autosar/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.donotpassaliasedpointertorestrictqualifiedparamshared.DoNotPassAliasedPointerToRestrictQualifiedParamShared
+
+class DoNotPassAliasedPointerToRestrictQualifiedParamQuery extends DoNotPassAliasedPointerToRestrictQualifiedParamSharedSharedQuery
+{
+ DoNotPassAliasedPointerToRestrictQualifiedParamQuery() {
+ this = RepresentationPackage::doNotPassAliasedPointerToParamQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M5-0-20/BitwiseOperatorOperandsHaveDifferentUnderlyingType.ql b/cpp/autosar/src/rules/M5-0-20/BitwiseOperatorOperandsHaveDifferentUnderlyingType.ql
index 9e85a15e50..6d0554bf11 100644
--- a/cpp/autosar/src/rules/M5-0-20/BitwiseOperatorOperandsHaveDifferentUnderlyingType.ql
+++ b/cpp/autosar/src/rules/M5-0-20/BitwiseOperatorOperandsHaveDifferentUnderlyingType.ql
@@ -16,7 +16,6 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.Bitwise
import codingstandards.cpp.Conversion
predicate isBinaryBitwiseOperation(Operation o, VariableAccess l, VariableAccess r) {
@@ -24,7 +23,7 @@ predicate isBinaryBitwiseOperation(Operation o, VariableAccess l, VariableAccess
l = bbo.getLeftOperand() and r = bbo.getRightOperand()
)
or
- exists(Bitwise::AssignBitwiseOperation abo | abo = o |
+ exists(AssignBitwiseOperation abo | abo = o |
l = abo.getLValue() and
r = abo.getRValue()
)
diff --git a/cpp/autosar/src/rules/M5-0-21/BitwiseOperatorAppliedToSignedTypes.ql b/cpp/autosar/src/rules/M5-0-21/BitwiseOperatorAppliedToSignedTypes.ql
index d000155189..02bb5314cd 100644
--- a/cpp/autosar/src/rules/M5-0-21/BitwiseOperatorAppliedToSignedTypes.ql
+++ b/cpp/autosar/src/rules/M5-0-21/BitwiseOperatorAppliedToSignedTypes.ql
@@ -17,7 +17,6 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.Bitwise
from Operation o, VariableAccess va
where
@@ -25,7 +24,7 @@ where
(
o instanceof UnaryBitwiseOperation or
o instanceof BinaryBitwiseOperation or
- o instanceof Bitwise::AssignBitwiseOperation
+ o instanceof AssignBitwiseOperation
) and
o.getAnOperand() = va and
va.getTarget().getUnderlyingType().(IntegralType).isSigned()
diff --git a/cpp/autosar/src/rules/M5-8-1/RightBitShiftOperandIsNegativeOrTooWide.ql b/cpp/autosar/src/rules/M5-8-1/RightBitShiftOperandIsNegativeOrTooWide.ql
index 38da7115f3..b94d76fd94 100644
--- a/cpp/autosar/src/rules/M5-8-1/RightBitShiftOperandIsNegativeOrTooWide.ql
+++ b/cpp/autosar/src/rules/M5-8-1/RightBitShiftOperandIsNegativeOrTooWide.ql
@@ -17,7 +17,6 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.Bitwise
class ShiftOperation extends Operation {
Expr leftOperand;
@@ -34,7 +33,7 @@ class ShiftOperation extends Operation {
rightOperand = o.getRightOperand()
)
or
- exists(Bitwise::AssignBitwiseOperation o | this = o |
+ exists(AssignBitwiseOperation o | this = o |
(
o instanceof AssignLShiftExpr
or
diff --git a/cpp/autosar/test/codeql-pack.lock.yml b/cpp/autosar/test/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/cpp/autosar/test/codeql-pack.lock.yml
+++ b/cpp/autosar/test/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/cpp/autosar/test/qlpack.yml b/cpp/autosar/test/qlpack.yml
index 6743c3b3ee..37dd488774 100644
--- a/cpp/autosar/test/qlpack.yml
+++ b/cpp/autosar/test/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/autosar-cpp-coding-standards-tests
-version: 2.33.0-dev
+version: 2.38.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/cpp/autosar/test/rules/A0-1-1/UselessAssignment.expected b/cpp/autosar/test/rules/A0-1-1/UselessAssignment.expected
index bdd73be2eb..a38f3afddf 100644
--- a/cpp/autosar/test/rules/A0-1-1/UselessAssignment.expected
+++ b/cpp/autosar/test/rules/A0-1-1/UselessAssignment.expected
@@ -12,3 +12,5 @@
| test.cpp:94:11:94:17 | new | Definition of $@ is unused. | test.cpp:94:6:94:7 | b4 | b4 |
| test.cpp:95:11:95:17 | 0 | Definition of $@ is unused. | test.cpp:95:6:95:7 | b5 | b5 |
| test.cpp:103:11:103:17 | 0 | Definition of $@ is unused. | test.cpp:103:6:103:7 | c5 | c5 |
+| test.cpp:132:43:132:45 | {...} | Definition of $@ is unused. | test.cpp:132:7:132:18 | unused_array | unused_array |
+| test.cpp:134:29:134:31 | 0 | Definition of $@ is unused. | test.cpp:134:17:134:26 | unused_int | unused_int |
diff --git a/cpp/autosar/test/rules/A0-1-1/test.cpp b/cpp/autosar/test/rules/A0-1-1/test.cpp
index 021b1bf792..694396406a 100644
--- a/cpp/autosar/test/rules/A0-1-1/test.cpp
+++ b/cpp/autosar/test/rules/A0-1-1/test.cpp
@@ -123,4 +123,16 @@ template void test_range_based_for_loop_template() {
// template
elem;
}
-}
\ No newline at end of file
+}
+
+#include
+
+std::int32_t test_constexpr_array_size() {
+ constexpr int constexpr_array_size = 7; // COMPLIANT
+ int unused_array[constexpr_array_size] = {}; // NON_COMPLIANT
+
+ constexpr int unused_int = {}; // NON_COMPLIANT
+
+ std::int32_t used_array[] = {-1, 0, 1}; // COMPLIANT
+ return used_array[1];
+}
diff --git a/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected b/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected
index e69de29bb2..81a5c4327e 100644
--- a/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected
+++ b/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected
@@ -0,0 +1 @@
+| Wcast-function-type.cpp:0:0:0:0 | Wcast-function-type.cpp | No warning-level options were used in the compilation of 'Wcast-function-type.cpp'. |
diff --git a/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.clang b/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.clang
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.gcc b/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.gcc
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.qcc b/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.qcc
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cpp/autosar/test/rules/A1-1-2.2/Wcast-function-type.cpp b/cpp/autosar/test/rules/A1-1-2.2/Wcast-function-type.cpp
index f405349bbb..bc48268931 100644
--- a/cpp/autosar/test/rules/A1-1-2.2/Wcast-function-type.cpp
+++ b/cpp/autosar/test/rules/A1-1-2.2/Wcast-function-type.cpp
@@ -1,2 +1,14 @@
// semmle-extractor-options: --clang -std=c++14 -Wcast-function-type
-// COMPLIANT
\ No newline at end of file
+// COMPLIANT
+
+// NOTE: When tested with `codeql test run`, the test extractor provides `-w`
+// which overrides `-Wcast-function-type` and causes this test case to be
+// non-compliant.
+//
+// However, when tested with our compiler matrix tests, this test db is built
+// via `codeql database create --command="..."`, and the `-w` flag will NOT be
+// used. This means the `-Wcast-function-type` flag is active and the test case
+// is compliant.
+//
+// Therefore, the .expected file for this test expects non-compliance, and the
+// .expected.gcc and .expected.clang files expect this test to be compliant.
diff --git a/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.expected b/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.expected
new file mode 100644
index 0000000000..dd7f320be2
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.expected
@@ -0,0 +1 @@
+| Wformat=0-Wno-format-security.cpp:0:0:0:0 | Wformat=0-Wno-format-security.cpp | No warning-level options were used in the compilation of 'Wformat=0-Wno-format-security.cpp'. |
diff --git a/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.qlref b/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.qlref
new file mode 100644
index 0000000000..30fb98b639
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.qlref
@@ -0,0 +1 @@
+rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2.4/Wformat=0-Wno-format-security.cpp b/cpp/autosar/test/rules/A1-1-2.4/Wformat=0-Wno-format-security.cpp
new file mode 100644
index 0000000000..29523ad24e
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.4/Wformat=0-Wno-format-security.cpp
@@ -0,0 +1,2 @@
+// semmle-extractor-options: --clang -std=c++14 -Wformat=0 -Wno-format-security
+// NON_COMPLIANT
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2.4/options.clang b/cpp/autosar/test/rules/A1-1-2.4/options.clang
new file mode 100644
index 0000000000..4544f91ecb
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.4/options.clang
@@ -0,0 +1 @@
+-Wformat=0 -Wno-format-security
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2.4/options.gcc b/cpp/autosar/test/rules/A1-1-2.4/options.gcc
new file mode 100644
index 0000000000..4544f91ecb
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.4/options.gcc
@@ -0,0 +1 @@
+-Wformat=0 -Wno-format-security
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2.4/options.qcc b/cpp/autosar/test/rules/A1-1-2.4/options.qcc
new file mode 100644
index 0000000000..e28a2c3ac5
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.4/options.qcc
@@ -0,0 +1 @@
+-Wno-format -Wno-format-security
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected
new file mode 100644
index 0000000000..df69d21d5a
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected
@@ -0,0 +1 @@
+| Wall-Wno-format.cpp:0:0:0:0 | Wall-Wno-format.cpp | No warning-level options were used in the compilation of 'Wall-Wno-format.cpp'. |
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.clang b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.clang
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.gcc b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.gcc
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.qcc b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.qcc
new file mode 100644
index 0000000000..c6354c2475
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.qcc
@@ -0,0 +1 @@
+| Wall-Wno-format.cpp:0:0:0:0 | Wall-Wno-format.cpp | No warning-level options were used in the compilation of 'Wall-Wno-format.cpp'. |
diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.qlref b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.qlref
new file mode 100644
index 0000000000..30fb98b639
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.qlref
@@ -0,0 +1 @@
+rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2.5/Wall-Wno-format.cpp b/cpp/autosar/test/rules/A1-1-2.5/Wall-Wno-format.cpp
new file mode 100644
index 0000000000..93c4b98248
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.5/Wall-Wno-format.cpp
@@ -0,0 +1,14 @@
+// semmle-extractor-options: --clang -std=c++14 -Wall -Wno-format
+// COMPLIANT
+
+// NOTE: When tested with `codeql test run`, the test extractor provides `-w`
+// which overrides `-Wcast-function-type` and causes this test case to be
+// non-compliant.
+//
+// However, when tested with our compiler matrix tests, this test db is built
+// via `codeql database create --command="..."`, and the `-w` flag will NOT be
+// used. This means the `-Wcast-function-type` flag is active and the test case
+// is compliant.
+//
+// Therefore, the .expected file for this test expects non-compliance, and the
+// .expected.gcc and .expected.clang files expect this test to be compliant.
diff --git a/cpp/autosar/test/rules/A1-1-2.5/options.clang b/cpp/autosar/test/rules/A1-1-2.5/options.clang
new file mode 100644
index 0000000000..735817b680
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.5/options.clang
@@ -0,0 +1 @@
+-Wall -Wno-format
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2.5/options.gcc b/cpp/autosar/test/rules/A1-1-2.5/options.gcc
new file mode 100644
index 0000000000..735817b680
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.5/options.gcc
@@ -0,0 +1 @@
+-Wall -Wno-format
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2.5/options.qcc b/cpp/autosar/test/rules/A1-1-2.5/options.qcc
new file mode 100644
index 0000000000..735817b680
--- /dev/null
+++ b/cpp/autosar/test/rules/A1-1-2.5/options.qcc
@@ -0,0 +1 @@
+-Wall -Wno-format
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected b/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected
index e69de29bb2..ddc4e03f62 100644
--- a/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected
+++ b/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected
@@ -0,0 +1 @@
+| Wall.cpp:0:0:0:0 | Wall.cpp | No warning-level options were used in the compilation of 'Wall.cpp'. |
diff --git a/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected.clang b/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected.clang
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected.gcc b/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected.gcc
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected.qcc b/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected.qcc
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cpp/autosar/test/rules/A1-1-2/Wall.cpp b/cpp/autosar/test/rules/A1-1-2/Wall.cpp
index cb21e0601e..b42189a8d1 100644
--- a/cpp/autosar/test/rules/A1-1-2/Wall.cpp
+++ b/cpp/autosar/test/rules/A1-1-2/Wall.cpp
@@ -1,2 +1,12 @@
// semmle-extractor-options: --clang -std=c++14 -Wall
-// COMPLIANT
\ No newline at end of file
+// COMPLIANT
+
+// NOTE: When tested with `codeql test run`, the test extractor provides `-w`
+// which overrides `-Wall` and causes this test case to be non-compliant.
+//
+// However, when tested with our compiler matrix tests, this test db is built
+// via `codeql database create --command="..."`, and the `-w` flag will NOT be
+// used. This means the `-Wall` flag is active and the test case is compliant.
+//
+// Therefore, the .expected file for this test expects non-compliance, and the
+// .expected.gcc and .expected.clang files expect this test to be compliant.
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.expected b/cpp/autosar/test/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.expected
index 6e79cb00a4..cb71b56b51 100644
--- a/cpp/autosar/test/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.expected
+++ b/cpp/autosar/test/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.expected
@@ -1,7 +1,3 @@
| test.cpp:24:6:24:7 | F1 | Function overloads a $@. | test.cpp:27:25:27:26 | F1 | function with a forwarding reference parameter |
| test.cpp:50:3:50:3 | A | Function overloads a $@. | test.cpp:48:3:48:3 | A | function with a forwarding reference parameter |
| test.cpp:51:3:51:3 | A | Function overloads a $@. | test.cpp:48:3:48:3 | A | function with a forwarding reference parameter |
-| test.cpp:69:3:69:3 | B | Function with a forwarding reference parameter overloads a $@. | test.cpp:64:8:64:8 | B | implicit copy constructor |
-| test.cpp:69:3:69:3 | B | Function with a forwarding reference parameter overloads a $@. | test.cpp:64:8:64:8 | B | implicit move constructor |
-| test.cpp:77:25:77:25 | C | Function with a forwarding reference parameter overloads a $@. | test.cpp:74:7:74:7 | C | implicit copy constructor |
-| test.cpp:77:25:77:25 | C | Function with a forwarding reference parameter overloads a $@. | test.cpp:74:7:74:7 | C | implicit move constructor |
diff --git a/cpp/autosar/test/rules/A13-3-1/test.cpp b/cpp/autosar/test/rules/A13-3-1/test.cpp
index 82fe866a0a..8ed4e4d609 100644
--- a/cpp/autosar/test/rules/A13-3-1/test.cpp
+++ b/cpp/autosar/test/rules/A13-3-1/test.cpp
@@ -40,7 +40,7 @@ template void F1(T &&x) {} //
class A {
public:
// COMPLIANT[FALSE_POSITIVE] - by exception, constrained to not match
- // copy/move ctors
+ // explicit copy/move ctors
template <
typename T,
std::enable_if_t>, A>::value> * = nullptr>
- B(T &&value) {} // COMPLIANT[FALSE_POSITIVE] - by exception
+ B(T &&value) {} // COMPLIANT - by exception
};
int main() {}
@@ -74,5 +74,6 @@ int main() {}
class C {
public:
C() {}
- template C(T &&) {} // NON_COMPLIANT
+ template
+ C(T &&) {} // COMPLIANT - ignore overloads of implicit copy/move ctors
};
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A13-5-3/UserDefinedConversionOperatorsShouldNotBeUsed.expected b/cpp/autosar/test/rules/A13-5-3/UserDefinedConversionOperatorsShouldNotBeUsed.expected
index e757cdf984..14e68ab4a9 100644
--- a/cpp/autosar/test/rules/A13-5-3/UserDefinedConversionOperatorsShouldNotBeUsed.expected
+++ b/cpp/autosar/test/rules/A13-5-3/UserDefinedConversionOperatorsShouldNotBeUsed.expected
@@ -1,4 +1,4 @@
| test.cpp:33:7:33:7 | call to operator A | User-defined conversion operators should not be used. |
| test.cpp:35:24:35:24 | call to operator A * | User-defined conversion operators should not be used. |
-| test.cpp:37:15:37:15 | call to operator B::array_A * | User-defined conversion operators should not be used. |
+| test.cpp:37:15:37:15 | call to operator A (*)[3] | User-defined conversion operators should not be used. |
| test.cpp:41:7:41:7 | call to operator A * | User-defined conversion operators should not be used. |
diff --git a/cpp/autosar/test/rules/A14-5-2/NonTemplateMemberDefinedInTemplate.expected b/cpp/autosar/test/rules/A14-5-2/NonTemplateMemberDefinedInTemplate.expected
index d45a3c6871..f0c78e2af1 100644
--- a/cpp/autosar/test/rules/A14-5-2/NonTemplateMemberDefinedInTemplate.expected
+++ b/cpp/autosar/test/rules/A14-5-2/NonTemplateMemberDefinedInTemplate.expected
@@ -1,4 +1,3 @@
-| test.cpp:10:9:10:10 | T1 | Member T1 template class does not use any of template arguments of its $@. | test.cpp:6:29:6:30 | C1 | declaring type |
| test.cpp:11:9:11:10 | T2 | Member T2 template class does not use any of template arguments of its $@. | test.cpp:6:29:6:30 | C1 | declaring type |
| test.cpp:28:31:28:33 | C12 | Member C12 template class does not use any of template arguments of its $@. | test.cpp:6:29:6:30 | C1 | declaring type |
| test.cpp:45:7:45:8 | a1 | Member a1 template class does not use any of template arguments of its $@. | test.cpp:37:31:37:33 | C22 | declaring type |
diff --git a/cpp/autosar/test/rules/A14-5-2/test.cpp b/cpp/autosar/test/rules/A14-5-2/test.cpp
index e60a955c68..260ff5b4b2 100644
--- a/cpp/autosar/test/rules/A14-5-2/test.cpp
+++ b/cpp/autosar/test/rules/A14-5-2/test.cpp
@@ -7,7 +7,7 @@ template class C1 {
public:
enum E1 : T { e1, e2 }; // COMPLIANT
- using T1 = typename template_base::type; // COMPLIANT[FALSE_POSITIVE]
+ using T1 = typename template_base::type; // COMPLIANT
using T2 = typename template_base::type; // NON_COMPLIANT
class C11 { // COMPLIANT
@@ -156,4 +156,4 @@ template class V {
void f4() {
V v;
v.type();
-}
\ No newline at end of file
+}
diff --git a/cpp/autosar/test/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.expected b/cpp/autosar/test/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.expected
index dcf263fc54..5f752403dc 100644
--- a/cpp/autosar/test/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.expected
+++ b/cpp/autosar/test/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.expected
@@ -1,10 +1,10 @@
edges
-| test.cpp:3:36:3:45 | new[] | test.cpp:19:27:19:44 | call to allocate_int_array |
-| test.cpp:3:36:3:45 | new[] | test.cpp:23:12:23:29 | call to allocate_int_array |
-| test.cpp:3:36:3:45 | new[] | test.cpp:27:20:27:37 | call to allocate_int_array |
-| test.cpp:11:29:11:41 | call to unique_ptr | test.cpp:12:27:12:28 | v2 |
-| test.cpp:12:27:12:28 | v2 | test.cpp:12:30:12:36 | call to release |
-| test.cpp:27:20:27:37 | call to allocate_int_array | test.cpp:32:12:32:20 | int_array |
+| test.cpp:3:36:3:45 | new[] | test.cpp:19:27:19:44 | call to allocate_int_array | provenance | |
+| test.cpp:3:36:3:45 | new[] | test.cpp:23:12:23:29 | call to allocate_int_array | provenance | |
+| test.cpp:3:36:3:45 | new[] | test.cpp:27:20:27:37 | call to allocate_int_array | provenance | |
+| test.cpp:11:29:11:41 | call to unique_ptr | test.cpp:12:27:12:28 | v2 | provenance | |
+| test.cpp:12:27:12:28 | v2 | test.cpp:12:30:12:36 | call to release | provenance | |
+| test.cpp:27:20:27:37 | call to allocate_int_array | test.cpp:32:12:32:20 | int_array | provenance | |
nodes
| test.cpp:3:36:3:45 | new[] | semmle.label | new[] |
| test.cpp:11:29:11:41 | call to unique_ptr | semmle.label | call to unique_ptr |
diff --git a/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected b/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected
index 66d2b38c57..d6f496a3c6 100644
--- a/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected
+++ b/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected
@@ -1,6 +1,6 @@
| test1a.cpp:2:12:2:13 | g1 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:2:12:2:13 | g1 | g1 | test1b.cpp:2:12:2:13 | g1 | g1 |
| test1a.cpp:6:12:6:13 | g3 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:6:12:6:13 | g3 | g3 | test1b.cpp:6:12:6:13 | g3 | g3 |
-| test1a.cpp:17:43:17:43 | number_two | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:17:43:17:43 | number_two | number_two | test1b.cpp:11:43:11:43 | number_two | number_two |
+| test1a.cpp:17:50:17:50 | number_two | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:17:50:17:50 | number_two | number_two | test1b.cpp:11:50:11:50 | number_two | number_two |
| test1b.cpp:2:12:2:13 | g1 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:2:12:2:13 | g1 | g1 | test1a.cpp:2:12:2:13 | g1 | g1 |
| test1b.cpp:6:12:6:13 | g3 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:6:12:6:13 | g3 | g3 | test1a.cpp:6:12:6:13 | g3 | g3 |
-| test1b.cpp:11:43:11:43 | number_two | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:11:43:11:43 | number_two | number_two | test1a.cpp:17:43:17:43 | number_two | number_two |
+| test1b.cpp:11:50:11:50 | number_two | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:11:50:11:50 | number_two | number_two | test1a.cpp:17:50:17:50 | number_two | number_two |
diff --git a/cpp/autosar/test/rules/A2-10-5/test1a.cpp b/cpp/autosar/test/rules/A2-10-5/test1a.cpp
index 80f63c3c69..749ad38b0f 100644
--- a/cpp/autosar/test/rules/A2-10-5/test1a.cpp
+++ b/cpp/autosar/test/rules/A2-10-5/test1a.cpp
@@ -14,7 +14,7 @@ int test() { return number_one; }
long test2() { return number_one; }
-template constexpr T number_two = T(1); // NON_COMPLIANT
+template static constexpr T number_two = T(1); // NON_COMPLIANT
int test3() { return number_two; }
diff --git a/cpp/autosar/test/rules/A2-10-5/test1b.cpp b/cpp/autosar/test/rules/A2-10-5/test1b.cpp
index 132588d5dd..342d739c4d 100644
--- a/cpp/autosar/test/rules/A2-10-5/test1b.cpp
+++ b/cpp/autosar/test/rules/A2-10-5/test1b.cpp
@@ -8,8 +8,8 @@ static int g3 = 0; // NON_COMPLIANT
static void f1() {} // NON_COMPLIANT
-template constexpr T number_two = T(1); // NON_COMPLIANT
+template static constexpr T number_two = T(1); // NON_COMPLIANT
-int test3() { return number_two; }
+int test5() { return number_two; }
-long test4() { return number_two; }
\ No newline at end of file
+long test6() { return number_two; }
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A2-7-3/UndocumentedUserDefinedType.expected b/cpp/autosar/test/rules/A2-7-3/UndocumentedUserDefinedType.expected
index 43a8773361..d14f6e21f7 100644
--- a/cpp/autosar/test/rules/A2-7-3/UndocumentedUserDefinedType.expected
+++ b/cpp/autosar/test/rules/A2-7-3/UndocumentedUserDefinedType.expected
@@ -9,3 +9,4 @@
| test.cpp:101:6:101:6 | definition of e | Declaration entry for function e is missing documentation. |
| test.cpp:108:1:108:30 | definition of message_to_string_undocumented | Declaration entry for function message_to_string_undocumented is missing documentation. |
| test.cpp:180:21:180:24 | definition of kBar | Declaration entry for member variable kBar is missing documentation. |
+| test.cpp:227:14:227:17 | definition of foo3 | Declaration entry for function foo3 is missing documentation. |
diff --git a/cpp/autosar/test/rules/A2-7-3/test.cpp b/cpp/autosar/test/rules/A2-7-3/test.cpp
index 43b75b604a..01f7bad611 100644
--- a/cpp/autosar/test/rules/A2-7-3/test.cpp
+++ b/cpp/autosar/test/rules/A2-7-3/test.cpp
@@ -195,4 +195,34 @@ void testFunctionScope() {
void fNestedTest(); // COMPLIANT - in function scope
};
};
-}
\ No newline at end of file
+}
+
+/// Test documentation
+template class ClassG { // COMPLIANT
+private:
+ /// Test documentation
+ int x; // COMPLIANT
+
+public:
+ /// Test documentation
+ friend int foo(ClassG g) { return g.x; } // COMPLIANT
+};
+
+/// Test documentation
+void test() { // COMPLIANT
+ ClassG g;
+ foo(g);
+}
+
+/// Test documentation
+class ClassG2 { // COMPLIANT
+public:
+ /// Test documentation
+ friend int foo2() { return 1; } // COMPLIANT
+};
+
+/// Test documentation
+class ClassG3 { // COMPLIANT
+public:
+ friend int foo3() { return 1; } // NON_COMPLIANT
+};
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.expected b/cpp/autosar/test/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.expected
index 4234d93b32..b47755725c 100644
--- a/cpp/autosar/test/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.expected
+++ b/cpp/autosar/test/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.expected
@@ -1,15 +1,15 @@
edges
-| test.cpp:10:18:10:20 | foo | test.cpp:11:23:11:25 | foo |
-| test.cpp:10:18:10:20 | foo | test.cpp:11:50:11:52 | foo |
-| test.cpp:22:18:22:20 | foo | test.cpp:24:18:24:20 | foo |
-| test.cpp:35:11:35:17 | new | test.cpp:38:6:38:7 | l1 |
-| test.cpp:35:11:35:17 | new | test.cpp:39:6:39:7 | l1 |
-| test.cpp:37:11:37:13 | & ... | test.cpp:40:6:40:7 | l3 |
-| test.cpp:37:11:37:13 | & ... | test.cpp:41:6:41:7 | l3 |
-| test.cpp:38:6:38:7 | l1 | test.cpp:10:18:10:20 | foo |
-| test.cpp:39:6:39:7 | l1 | test.cpp:22:18:22:20 | foo |
-| test.cpp:40:6:40:7 | l3 | test.cpp:10:18:10:20 | foo |
-| test.cpp:41:6:41:7 | l3 | test.cpp:22:18:22:20 | foo |
+| test.cpp:10:18:10:20 | foo | test.cpp:11:23:11:25 | foo | provenance | |
+| test.cpp:10:18:10:20 | foo | test.cpp:11:50:11:52 | foo | provenance | |
+| test.cpp:22:18:22:20 | foo | test.cpp:24:18:24:20 | foo | provenance | |
+| test.cpp:35:11:35:17 | new | test.cpp:38:6:38:7 | l1 | provenance | |
+| test.cpp:35:11:35:17 | new | test.cpp:39:6:39:7 | l1 | provenance | |
+| test.cpp:37:11:37:13 | & ... | test.cpp:40:6:40:7 | l3 | provenance | |
+| test.cpp:37:11:37:13 | & ... | test.cpp:41:6:41:7 | l3 | provenance | |
+| test.cpp:38:6:38:7 | l1 | test.cpp:10:18:10:20 | foo | provenance | |
+| test.cpp:39:6:39:7 | l1 | test.cpp:22:18:22:20 | foo | provenance | |
+| test.cpp:40:6:40:7 | l3 | test.cpp:10:18:10:20 | foo | provenance | |
+| test.cpp:41:6:41:7 | l3 | test.cpp:22:18:22:20 | foo | provenance | |
nodes
| test.cpp:10:18:10:20 | foo | semmle.label | foo |
| test.cpp:11:23:11:25 | foo | semmle.label | foo |
diff --git a/cpp/autosar/test/rules/A5-1-7/LambdaPassedToTypeid.expected b/cpp/autosar/test/rules/A5-1-7/LambdaPassedToTypeid.expected
index 4b19073ded..6d65a7b5d5 100644
--- a/cpp/autosar/test/rules/A5-1-7/LambdaPassedToTypeid.expected
+++ b/cpp/autosar/test/rules/A5-1-7/LambdaPassedToTypeid.expected
@@ -1,6 +1,6 @@
edges
-| test.cpp:5:13:5:30 | [...](...){...} | test.cpp:8:38:8:39 | l1 |
-| test.cpp:6:13:6:30 | [...](...){...} | test.cpp:9:38:9:39 | l2 |
+| test.cpp:5:13:5:30 | [...](...){...} | test.cpp:8:38:8:39 | l1 | provenance | |
+| test.cpp:6:13:6:30 | [...](...){...} | test.cpp:9:38:9:39 | l2 | provenance | |
nodes
| test.cpp:5:13:5:30 | [...](...){...} | semmle.label | [...](...){...} |
| test.cpp:6:13:6:30 | [...](...){...} | semmle.label | [...](...){...} |
diff --git a/cpp/autosar/test/rules/A5-2-6/OperandsOfALogicalAndOrNotParenthesized.expected b/cpp/autosar/test/rules/A5-2-6/OperandsOfALogicalAndOrNotParenthesized.expected
index 90516e6d96..34dbb0db4d 100644
--- a/cpp/autosar/test/rules/A5-2-6/OperandsOfALogicalAndOrNotParenthesized.expected
+++ b/cpp/autosar/test/rules/A5-2-6/OperandsOfALogicalAndOrNotParenthesized.expected
@@ -1,3 +1,3 @@
-| test.cpp:3:7:3:23 | ... && ... | Binary $@ operand of logical operation is not parenthesized. | test.cpp:3:7:3:12 | ... > ... | operator |
-| test.cpp:3:7:3:23 | ... && ... | Binary $@ operand of logical operation is not parenthesized. | test.cpp:3:17:3:23 | ... < ... | operator |
-| test.cpp:7:7:7:24 | ... \|\| ... | Binary $@ operand of logical operation is not parenthesized. | test.cpp:7:19:7:24 | ... > ... | operator |
+| test.cpp:3:7:3:23 | ... && ... | $@ of logical operation && is not parenthesized. | test.cpp:3:7:3:12 | ... > ... | Left operand > |
+| test.cpp:3:7:3:23 | ... && ... | $@ of logical operation && is not parenthesized. | test.cpp:3:17:3:23 | ... < ... | Right operand < |
+| test.cpp:7:7:7:24 | ... \|\| ... | $@ of logical operation \|\| is not parenthesized. | test.cpp:7:19:7:24 | ... > ... | Right operand > |
diff --git a/cpp/autosar/test/rules/A5-2-6/test.cpp b/cpp/autosar/test/rules/A5-2-6/test.cpp
index 0649f7dbc9..961eef3b36 100644
--- a/cpp/autosar/test/rules/A5-2-6/test.cpp
+++ b/cpp/autosar/test/rules/A5-2-6/test.cpp
@@ -25,6 +25,8 @@ void f2(int p1, int p2) {
f1();
}
+ (p1 > 0) && (p2 > 0) && (p1 > p2); // COMPLIANT - no ambiguity
+
Sample *sample_ptr = &sample;
if ((p1 > 0) || sample_ptr->x) { // COMPLIANT: struct member accessors with
diff --git a/cpp/autosar/test/rules/A7-1-3/CvQualifiersNotPlacedOnTheRightHandSide.expected b/cpp/autosar/test/rules/A7-1-3/CvQualifiersNotPlacedOnTheRightHandSide.expected
index 9d6a710449..d845df142d 100644
--- a/cpp/autosar/test/rules/A7-1-3/CvQualifiersNotPlacedOnTheRightHandSide.expected
+++ b/cpp/autosar/test/rules/A7-1-3/CvQualifiersNotPlacedOnTheRightHandSide.expected
@@ -1,3 +1,4 @@
| test.cpp:9:16:9:19 | definition of ptr1 | There is possibly a const or volatile specifier on the left hand side of typedef name $@. | test.cpp:1:7:1:12 | intptr | intptr |
| test.cpp:10:19:10:22 | definition of ptr2 | There is possibly a const or volatile specifier on the left hand side of typedef name $@. | test.cpp:1:7:1:12 | intptr | intptr |
| test.cpp:19:21:19:24 | definition of ptr8 | There is possibly a const or volatile specifier on the left hand side of typedef name $@. | test.cpp:3:7:3:17 | constintptr | constintptr |
+| test.cpp:32:23:32:26 | definition of u32d | There is possibly a const or volatile specifier on the left hand side of typedef name uint32_t. | test.cpp:32:23:32:26 | definition of u32d | |
diff --git a/cpp/autosar/test/rules/A7-1-3/test.cpp b/cpp/autosar/test/rules/A7-1-3/test.cpp
index 621a64115d..39f53b8623 100644
--- a/cpp/autosar/test/rules/A7-1-3/test.cpp
+++ b/cpp/autosar/test/rules/A7-1-3/test.cpp
@@ -18,4 +18,16 @@ void f() {
constintptr const ptr7 = &l; // COMPLIANT
const constintptr ptr8 = &l; // NON_COMPLIANT
inttypedef ptr9 = l; // COMPLIANT
+}
+
+#include
+
+void false_positive() {
+ std::uint8_t u8{0};
+
+ auto const u32 = static_cast(u8); // COMPLIANT - auto ignored
+ std::uint32_t const u32b = static_cast(u8); // COMPLIANT
+
+ const auto u32c = static_cast(u8); // COMPLIANT - auto ignored
+ const std::uint32_t u32d = static_cast(u8); // NON_COMPLIANT
}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-2-1/NonEnumeratorEnumValue.expected b/cpp/autosar/test/rules/A7-2-1/NonEnumeratorEnumValue.expected
index 9c99c44897..6ac5cfca86 100644
--- a/cpp/autosar/test/rules/A7-2-1/NonEnumeratorEnumValue.expected
+++ b/cpp/autosar/test/rules/A7-2-1/NonEnumeratorEnumValue.expected
@@ -7,4 +7,4 @@
| test.cpp:27:12:27:25 | (Foo)... | Cast to enum $@ with from expression with range 0...3 which may not be one of the enumerator values in function test_bitwise_or. | test.cpp:2:6:2:8 | Foo | Foo |
| test.cpp:28:12:28:25 | (Foo)... | Cast to enum $@ with from expression with range 0...7 which may not be one of the enumerator values in function test_bitwise_or. | test.cpp:2:6:2:8 | Foo | Foo |
| test.cpp:39:12:39:17 | (Bar)... | Cast to enum $@ with from expression with range 1...1 which may not be one of the enumerator values in function test_constant. | test.cpp:5:6:5:8 | Bar | Bar |
-| test.cpp:41:12:41:17 | (Bar)... | Cast to enum $@ with from expression with value 1_+ which is not one of the enumerator values in function test_constant. | test.cpp:5:6:5:8 | Bar | Bar |
+| test.cpp:41:12:41:17 | (Bar)... | Cast to enum $@ with from expression with value 1 which is not one of the enumerator values in function test_constant. | test.cpp:5:6:5:8 | Bar | Bar |
diff --git a/cpp/autosar/test/rules/M0-1-10/UnusedFunction.expected b/cpp/autosar/test/rules/M0-1-10/UnusedFunction.expected
index d9ab0d38ac..912e2104e8 100644
--- a/cpp/autosar/test/rules/M0-1-10/UnusedFunction.expected
+++ b/cpp/autosar/test/rules/M0-1-10/UnusedFunction.expected
@@ -10,4 +10,5 @@
| test.cpp:50:5:50:6 | i3 | Function C::i3 is never called. |
| test.cpp:51:8:51:9 | i4 | Function C::i4 is never called. |
| test.cpp:52:15:52:16 | i5 | Function C::i5 is never called. |
-| test.cpp:69:17:69:18 | g4 | Function g4 is never called. |
+| test.cpp:79:6:79:21 | anUnusedFunction | Function anUnusedFunction is never called. |
+| test.cpp:113:17:113:18 | g4 | Function g4 is never called. |
diff --git a/cpp/autosar/test/rules/M0-1-10/UnusedSplMemberFunction.expected b/cpp/autosar/test/rules/M0-1-10/UnusedSplMemberFunction.expected
new file mode 100644
index 0000000000..e2bf0acc79
--- /dev/null
+++ b/cpp/autosar/test/rules/M0-1-10/UnusedSplMemberFunction.expected
@@ -0,0 +1,2 @@
+| test.cpp:71:5:71:16 | ANestedClass | Special member function ANestedClass is never called. |
+| test.cpp:82:5:82:22 | AnotherNestedClass | Special member function AnotherNestedClass is never called from a main function or entry point. |
diff --git a/cpp/autosar/test/rules/M0-1-10/UnusedSplMemberFunction.qlref b/cpp/autosar/test/rules/M0-1-10/UnusedSplMemberFunction.qlref
new file mode 100644
index 0000000000..899f00fda1
--- /dev/null
+++ b/cpp/autosar/test/rules/M0-1-10/UnusedSplMemberFunction.qlref
@@ -0,0 +1 @@
+rules/M0-1-10/UnusedSplMemberFunction.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M0-1-10/test.cpp b/cpp/autosar/test/rules/M0-1-10/test.cpp
index 748d2196ef..e1a19abf24 100644
--- a/cpp/autosar/test/rules/M0-1-10/test.cpp
+++ b/cpp/autosar/test/rules/M0-1-10/test.cpp
@@ -52,6 +52,50 @@ template class C {
inline void i5() {} // NON_COMPLIANT - never used in any instantiation
};
+#include "test.hpp"
+#include
+
+template
+constexpr bool aConstExprFunc() noexcept { // COMPLIANT
+ static_assert(std::is_trivially_copy_constructible() &&
+ std::is_trivially_copy_constructible(),
+ "assert");
+ return true;
+}
+
+template class AClass { T anArr[val]; };
+
+void aCalledFunc1() // COMPLIANT
+{
+ struct ANestedClass {
+ ANestedClass() noexcept(false) { // COMPLIANT: False Positive!
+ static_cast(0);
+ }
+ };
+ static_assert(std::is_trivially_copy_constructible>(),
+ "Must be trivially copy constructible");
+}
+
+void anUnusedFunction() // NON_COMPLIANT
+{
+ struct AnotherNestedClass {
+ AnotherNestedClass() noexcept(false) { // NON_COMPLAINT
+ static_cast(0);
+ }
+ };
+ AnotherNestedClass d;
+}
+
+void aCalledFunc2() // COMPLIANT
+{
+ struct YetAnotherNestedClass {
+ YetAnotherNestedClass() noexcept(false) {
+ static_cast(0);
+ } // COMPLIANT
+ };
+ YetAnotherNestedClass d;
+};
+
int main() { // COMPLIANT - this is a main like function which acts as an entry
// point
f3();
@@ -88,8 +132,37 @@ int main() { // COMPLIANT - this is a main like function which acts as an entry
c1.getAT();
S s;
c2.i1(s);
+
+ int aVar;
+ aConstExprFunc();
+ aCalledFunc1();
+ aCalledFunc2();
}
class M {
public:
M(const M &) = delete; // COMPLIANT - ignore if deleted
-};
\ No newline at end of file
+};
+
+#include
+int called_from_google_test_function(
+ int a_param) // COMPLIANT - called from TEST
+{
+ int something = a_param;
+ something++;
+ return something;
+}
+
+TEST(sample_test,
+ called_from_google_test_function) // COMPLIANT - Google Test function
+{
+ bool pass = false;
+ if (called_from_google_test_function(0) >= 10)
+ pass = true;
+ struct a_nested_class_in_gtest {
+ a_nested_class_in_gtest() noexcept(false) {
+ static_cast(0);
+ } // COMPLIANT
+ };
+ static_assert(std::is_trivially_copy_constructible(),
+ "assert");
+}
diff --git a/cpp/autosar/test/rules/M0-1-10/test.hpp b/cpp/autosar/test/rules/M0-1-10/test.hpp
new file mode 100644
index 0000000000..a2da990951
--- /dev/null
+++ b/cpp/autosar/test/rules/M0-1-10/test.hpp
@@ -0,0 +1,4 @@
+template
+constexpr T aCalledFuncInHeader(T value) noexcept { // COMPLIANT
+ return static_cast(value);
+}
diff --git a/cpp/autosar/test/rules/M0-1-2/InfeasiblePath.expected b/cpp/autosar/test/rules/M0-1-2/InfeasiblePath.expected
index 9cb237e8b3..b5528014d1 100644
--- a/cpp/autosar/test/rules/M0-1-2/InfeasiblePath.expected
+++ b/cpp/autosar/test/rules/M0-1-2/InfeasiblePath.expected
@@ -8,3 +8,4 @@
| test.cpp:86:9:86:14 | ... < ... | The true path is infeasible because 0 (max value: 0) is always less than or equal to a (minimum value: 0). |
| test.cpp:117:7:117:7 | 0 | The path is unreachable in a template. |
| test.cpp:123:7:123:8 | ! ... | The path is unreachable in a template. |
+| test.cpp:137:7:137:12 | ... > ... | The path is unreachable in a template. |
diff --git a/cpp/autosar/test/rules/M0-1-2/test.cpp b/cpp/autosar/test/rules/M0-1-2/test.cpp
index 31c564d8a5..f36cbc790d 100644
--- a/cpp/autosar/test/rules/M0-1-2/test.cpp
+++ b/cpp/autosar/test/rules/M0-1-2/test.cpp
@@ -131,4 +131,15 @@ void test_infeasible_instantiates() {
template_infeasible_true_path();
template_infeasible_false_path();
template_infeasible_false_path();
+}
+
+template int template_infeasible_relation() {
+ if (i > -1) { // NON_COMPLIANT - true path is infeasible in all circumstances
+ return 3;
+ }
+}
+
+void test_infeasible_relation() {
+ template_infeasible_relation<0>();
+ template_infeasible_relation<1>();
}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M0-1-3/UnusedLocalVariable.expected b/cpp/autosar/test/rules/M0-1-3/UnusedLocalVariable.expected
index d6f398369f..19317d1d0d 100644
--- a/cpp/autosar/test/rules/M0-1-3/UnusedLocalVariable.expected
+++ b/cpp/autosar/test/rules/M0-1-3/UnusedLocalVariable.expected
@@ -1,7 +1,6 @@
| test.cpp:7:7:7:7 | y | Local variable 'y' in 'test_simple' is not used. |
-| test.cpp:14:13:14:13 | y | Local variable 'y' in 'test_const' is not used. |
-| test.cpp:17:7:17:7 | z | Local variable 'z' in 'test_const' is not used. |
-| test.cpp:23:5:23:5 | t | Local variable 't' in 'f1' is not used. |
-| test.cpp:23:5:23:5 | t | Local variable 't' in 'f1' is not used. |
-| test.cpp:44:6:44:6 | a | Local variable 'a' in 'test_side_effect_init' is not used. |
-| test.cpp:91:5:91:5 | t | Local variable 't' in 'template_function' is not used. |
+| test.cpp:15:7:15:7 | z | Local variable 'z' in 'test_const' is not used. |
+| test.cpp:21:5:21:5 | t | Local variable 't' in 'f1' is not used. |
+| test.cpp:21:5:21:5 | t | Local variable 't' in 'f1' is not used. |
+| test.cpp:42:6:42:6 | a | Local variable 'a' in 'test_side_effect_init' is not used. |
+| test.cpp:89:5:89:5 | t | Local variable 't' in 'template_function' is not used. |
diff --git a/cpp/autosar/test/rules/M0-1-3/test.cpp b/cpp/autosar/test/rules/M0-1-3/test.cpp
index a591c7e82b..5c9c4a3413 100644
--- a/cpp/autosar/test/rules/M0-1-3/test.cpp
+++ b/cpp/autosar/test/rules/M0-1-3/test.cpp
@@ -11,9 +11,7 @@ int test_simple() {
int test_const() {
const int x = 1; // COMPLIANT - used below
- const int y = 2; // COMPLIANT[FALSE_POSITIVE] - used in array initialization,
- // but the database does not contain sufficient information
- // for this case
+ const int y = 2; // COMPLIANT - used in array initialization,
int z[y]; // NON_COMPLIANT - never used
return x;
}
@@ -98,4 +96,20 @@ class ClassT {
void test() {}
};
-void test_template_function() { template_function(); }
\ No newline at end of file
+void test_template_function() { template_function(); }
+
+int foo() {
+ constexpr int arrayDim = 10; // COMPLIANT - used in array size below
+ static int array[arrayDim]{};
+ return array[4];
+}
+
+template static T another_templ_function() { return T(); }
+
+template
+static T another_templ_function(const First &first, const Rest &...rest) {
+ return first +
+ another_templ_function(rest...); // COMPLIANT - 'rest' is used here
+}
+
+static int templ_fnc2() { return another_templ_function(1, 2, 3, 4, 5); }
diff --git a/cpp/autosar/test/rules/M0-2-1/DoNotPassAliasedPointerToParam.testref b/cpp/autosar/test/rules/M0-2-1/DoNotPassAliasedPointerToParam.testref
new file mode 100644
index 0000000000..2c64dedd45
--- /dev/null
+++ b/cpp/autosar/test/rules/M0-2-1/DoNotPassAliasedPointerToParam.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M0-2-1/test.cpp b/cpp/autosar/test/rules/M0-2-1/test.cpp
index e5848e2752..3329f12824 100644
--- a/cpp/autosar/test/rules/M0-2-1/test.cpp
+++ b/cpp/autosar/test/rules/M0-2-1/test.cpp
@@ -51,4 +51,4 @@ void internal_shift() {
void separate_access() {
UnionSecret_t hash1, hash2;
hash2.diff.suffix = hash1.fnv.suffix; // COMPLIANT, different union.
-}
\ No newline at end of file
+}
diff --git a/cpp/cert/src/codeql-pack.lock.yml b/cpp/cert/src/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/cpp/cert/src/codeql-pack.lock.yml
+++ b/cpp/cert/src/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/cpp/cert/src/qlpack.yml b/cpp/cert/src/qlpack.yml
index 47c2c319c7..2fb82cfe3f 100644
--- a/cpp/cert/src/qlpack.yml
+++ b/cpp/cert/src/qlpack.yml
@@ -1,8 +1,8 @@
name: codeql/cert-cpp-coding-standards
-version: 2.33.0-dev
+version: 2.38.0-dev
description: CERT C++ 2016
suites: codeql-suites
license: MIT
dependencies:
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 0.12.9
codeql/common-cpp-coding-standards: '*'
diff --git a/cpp/cert/src/rules/DCL51-CPP/UseOfReservedLiteralSuffixIdentifier.ql b/cpp/cert/src/rules/DCL51-CPP/UseOfReservedLiteralSuffixIdentifier.ql
index f7dddb4d99..eb2163f667 100644
--- a/cpp/cert/src/rules/DCL51-CPP/UseOfReservedLiteralSuffixIdentifier.ql
+++ b/cpp/cert/src/rules/DCL51-CPP/UseOfReservedLiteralSuffixIdentifier.ql
@@ -15,9 +15,9 @@
import cpp
import codingstandards.cpp.cert
-import codingstandards.cpp.UserDefinedLiteral
+import codingstandards.cpp.UserDefinedLiteral as udl
-from UserDefinedLiteral udl
+from udl::UserDefinedLiteral udl
where
not isExcluded(udl, NamingPackage::useOfReservedLiteralSuffixIdentifierQuery()) and
not udl.hasCompliantSuffix()
diff --git a/cpp/cert/src/rules/MEM53-CPP/ManuallyManagedLifetime.qll b/cpp/cert/src/rules/MEM53-CPP/ManuallyManagedLifetime.qll
index 358a3583fc..54fafc60d7 100644
--- a/cpp/cert/src/rules/MEM53-CPP/ManuallyManagedLifetime.qll
+++ b/cpp/cert/src/rules/MEM53-CPP/ManuallyManagedLifetime.qll
@@ -14,12 +14,15 @@ module AllocToStaticCastConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(AllocationExpr ae |
ae.getType().getUnspecifiedType() instanceof VoidPointerType and
- source.asExpr() = ae and
- // Ignore realloc, as that memory may already be partially constructed
- not ae.(FunctionCall).getTarget().getName().toLowerCase().matches("%realloc%")
+ source.asExpr() = ae
)
}
+ predicate isBarrier(DataFlow::Node sanitizer) {
+ // Ignore realloc, as that memory may already be partially constructed
+ sanitizer.asExpr().(FunctionCall).getTarget().getName().toLowerCase().matches("%realloc%")
+ }
+
predicate isSink(DataFlow::Node sink) {
exists(StaticOrCStyleCast sc, Class nonTrivialClass |
sc.getExpr() = sink.asExpr() and
diff --git a/cpp/cert/test/codeql-pack.lock.yml b/cpp/cert/test/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/cpp/cert/test/codeql-pack.lock.yml
+++ b/cpp/cert/test/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/cpp/cert/test/qlpack.yml b/cpp/cert/test/qlpack.yml
index 7b8ed0858d..dfe027d387 100644
--- a/cpp/cert/test/qlpack.yml
+++ b/cpp/cert/test/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cert-cpp-coding-standards-tests
-version: 2.33.0-dev
+version: 2.38.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/cpp/cert/test/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.expected b/cpp/cert/test/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.expected
index 0ee15c65b5..eabb6d7515 100644
--- a/cpp/cert/test/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.expected
+++ b/cpp/cert/test/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.expected
@@ -1,15 +1,15 @@
edges
-| test.cpp:15:19:15:21 | foo | test.cpp:16:24:16:26 | foo |
-| test.cpp:15:19:15:21 | foo | test.cpp:16:51:16:53 | foo |
-| test.cpp:27:19:27:21 | foo | test.cpp:29:18:29:20 | foo |
-| test.cpp:40:12:40:19 | new | test.cpp:43:6:43:7 | l1 |
-| test.cpp:40:12:40:19 | new | test.cpp:44:6:44:7 | l1 |
-| test.cpp:42:12:42:14 | & ... | test.cpp:45:6:45:7 | l3 |
-| test.cpp:42:12:42:14 | & ... | test.cpp:46:6:46:7 | l3 |
-| test.cpp:43:6:43:7 | l1 | test.cpp:15:19:15:21 | foo |
-| test.cpp:44:6:44:7 | l1 | test.cpp:27:19:27:21 | foo |
-| test.cpp:45:6:45:7 | l3 | test.cpp:15:19:15:21 | foo |
-| test.cpp:46:6:46:7 | l3 | test.cpp:27:19:27:21 | foo |
+| test.cpp:15:19:15:21 | foo | test.cpp:16:24:16:26 | foo | provenance | |
+| test.cpp:15:19:15:21 | foo | test.cpp:16:51:16:53 | foo | provenance | |
+| test.cpp:27:19:27:21 | foo | test.cpp:29:18:29:20 | foo | provenance | |
+| test.cpp:40:12:40:19 | new | test.cpp:43:6:43:7 | l1 | provenance | |
+| test.cpp:40:12:40:19 | new | test.cpp:44:6:44:7 | l1 | provenance | |
+| test.cpp:42:12:42:14 | & ... | test.cpp:45:6:45:7 | l3 | provenance | |
+| test.cpp:42:12:42:14 | & ... | test.cpp:46:6:46:7 | l3 | provenance | |
+| test.cpp:43:6:43:7 | l1 | test.cpp:15:19:15:21 | foo | provenance | |
+| test.cpp:44:6:44:7 | l1 | test.cpp:27:19:27:21 | foo | provenance | |
+| test.cpp:45:6:45:7 | l3 | test.cpp:15:19:15:21 | foo | provenance | |
+| test.cpp:46:6:46:7 | l3 | test.cpp:27:19:27:21 | foo | provenance | |
nodes
| test.cpp:15:19:15:21 | foo | semmle.label | foo |
| test.cpp:16:24:16:26 | foo | semmle.label | foo |
diff --git a/cpp/cert/test/rules/DCL51-CPP/FunctionReusesReservedName.expected b/cpp/cert/test/rules/DCL51-CPP/FunctionReusesReservedName.expected
index e945f93c57..97bbccbbd0 100644
--- a/cpp/cert/test/rules/DCL51-CPP/FunctionReusesReservedName.expected
+++ b/cpp/cert/test/rules/DCL51-CPP/FunctionReusesReservedName.expected
@@ -1 +1 @@
-| test.cpp:20:6:20:8 | min | The function $@ reuses a reserved standard library name. | test.cpp:20:6:20:8 | min | min |
+| test.cpp:22:6:22:8 | min | The function $@ reuses a reserved standard library name. | test.cpp:22:6:22:8 | min | min |
diff --git a/cpp/cert/test/rules/DCL51-CPP/ObjectReusesReservedName.expected b/cpp/cert/test/rules/DCL51-CPP/ObjectReusesReservedName.expected
index 698b0c6067..d1c0b8d60e 100644
--- a/cpp/cert/test/rules/DCL51-CPP/ObjectReusesReservedName.expected
+++ b/cpp/cert/test/rules/DCL51-CPP/ObjectReusesReservedName.expected
@@ -1 +1 @@
-| test.cpp:18:5:18:10 | tzname | The variable $@ reuses a reserved standard library name. | test.cpp:18:5:18:10 | tzname | tzname |
+| test.cpp:19:5:19:10 | tzname | The variable $@ reuses a reserved standard library name. | test.cpp:19:5:19:10 | tzname | tzname |
diff --git a/cpp/cert/test/rules/DCL51-CPP/RedefiningOfStandardLibraryName.expected b/cpp/cert/test/rules/DCL51-CPP/RedefiningOfStandardLibraryName.expected
index f5b15966ba..fb01130c4d 100644
--- a/cpp/cert/test/rules/DCL51-CPP/RedefiningOfStandardLibraryName.expected
+++ b/cpp/cert/test/rules/DCL51-CPP/RedefiningOfStandardLibraryName.expected
@@ -1,3 +1,3 @@
| test.cpp:6:1:6:14 | #undef INT_MAX | Redefinition of INT_MAX declared in a standard library header. |
| test.cpp:7:1:7:20 | #define SIZE_MAX 256 | Redefinition of SIZE_MAX declared in a standard library header. |
-| test.cpp:37:1:38:9 | #define FD_SET(X) int _ ## X | Redefinition of FD_SET declared in a standard library header. |
+| test.cpp:39:1:40:9 | #define FD_SET(X) int _ ## X | Redefinition of FD_SET declared in a standard library header. |
diff --git a/cpp/cert/test/rules/DCL51-CPP/UseOfDoubleUnderscoreReservedPrefix.expected b/cpp/cert/test/rules/DCL51-CPP/UseOfDoubleUnderscoreReservedPrefix.expected
index 3b0a94429a..0d52226d5f 100644
--- a/cpp/cert/test/rules/DCL51-CPP/UseOfDoubleUnderscoreReservedPrefix.expected
+++ b/cpp/cert/test/rules/DCL51-CPP/UseOfDoubleUnderscoreReservedPrefix.expected
@@ -1,2 +1,2 @@
-| test.cpp:25:5:25:7 | __x | Name $@ uses the reserved prefix '__'. | test.cpp:25:5:25:7 | __x | __x |
-| test.cpp:30:5:30:7 | __x | Name $@ uses the reserved prefix '__'. | test.cpp:30:5:30:7 | __x | __x |
+| test.cpp:27:5:27:7 | __x | Name $@ uses the reserved prefix '__'. | test.cpp:27:5:27:7 | __x | __x |
+| test.cpp:32:5:32:7 | __x | Name $@ uses the reserved prefix '__'. | test.cpp:32:5:32:7 | __x | __x |
diff --git a/cpp/cert/test/rules/DCL51-CPP/UseOfReservedLiteralSuffixIdentifier.expected b/cpp/cert/test/rules/DCL51-CPP/UseOfReservedLiteralSuffixIdentifier.expected
index f8863eab59..96f3b1068e 100644
--- a/cpp/cert/test/rules/DCL51-CPP/UseOfReservedLiteralSuffixIdentifier.expected
+++ b/cpp/cert/test/rules/DCL51-CPP/UseOfReservedLiteralSuffixIdentifier.expected
@@ -1 +1 @@
-| test.cpp:22:6:22:17 | operator ""x | Literal suffix identifier $@ does not start with an underscore. | test.cpp:22:6:22:17 | operator ""x | operator ""x |
+| test.cpp:24:6:24:17 | operator ""x | Literal suffix identifier $@ does not start with an underscore. | test.cpp:24:6:24:17 | operator ""x | operator ""x |
diff --git a/cpp/cert/test/rules/DCL51-CPP/UseOfSingleUnderscoreReservedPrefix.expected b/cpp/cert/test/rules/DCL51-CPP/UseOfSingleUnderscoreReservedPrefix.expected
index 679ad58deb..544a26c996 100644
--- a/cpp/cert/test/rules/DCL51-CPP/UseOfSingleUnderscoreReservedPrefix.expected
+++ b/cpp/cert/test/rules/DCL51-CPP/UseOfSingleUnderscoreReservedPrefix.expected
@@ -1,5 +1,5 @@
-| test.cpp:26:5:26:6 | _X | Name $@ uses the reserved prefix '_'. | test.cpp:26:5:26:6 | _X | _X |
-| test.cpp:27:5:27:6 | _x | Name $@ uses the reserved prefix '_'. | test.cpp:27:5:27:6 | _x | _x |
-| test.cpp:31:5:31:6 | _X | Name $@ uses the reserved prefix '_'. | test.cpp:31:5:31:6 | _X | _X |
-| test.cpp:35:1:35:3 | _i | Name $@ uses the reserved prefix '_'. | test.cpp:35:1:35:3 | _i | _i |
+| test.cpp:28:5:28:6 | _X | Name $@ uses the reserved prefix '_'. | test.cpp:28:5:28:6 | _X | _X |
+| test.cpp:29:5:29:6 | _x | Name $@ uses the reserved prefix '_'. | test.cpp:29:5:29:6 | _x | _x |
+| test.cpp:33:5:33:6 | _X | Name $@ uses the reserved prefix '_'. | test.cpp:33:5:33:6 | _X | _X |
+| test.cpp:37:1:37:3 | _i | Name $@ uses the reserved prefix '_'. | test.cpp:37:1:37:3 | _i | _i |
| test.h:2:1:2:15 | #define _TEST_H | Name $@ uses the reserved prefix '_'. | test.h:2:1:2:15 | #define _TEST_H | _TEST_H |
diff --git a/cpp/cert/test/rules/DCL51-CPP/test.cpp b/cpp/cert/test/rules/DCL51-CPP/test.cpp
index 5e27dd2390..9248041b57 100644
--- a/cpp/cert/test/rules/DCL51-CPP/test.cpp
+++ b/cpp/cert/test/rules/DCL51-CPP/test.cpp
@@ -15,7 +15,9 @@ enum {
// int NULL = 0; // NON_COMPLIANT, but not supported by compilers in practice
+namespace ns {
int tzname = 0; // NON_COMPLIANT
+}
void min() {} // NON_COMPLIANT
@@ -48,4 +50,4 @@ void test_lambda(const int y) {
// Lambda generates a static function called `_FUN` when the lambda is
// converted to a function pointer
g([](int x) { return x; }); // COMPLIANT - compiler generated
-}
\ No newline at end of file
+}
diff --git a/cpp/cert/test/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.expected b/cpp/cert/test/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.expected
index a50daa096e..9c6e6dd071 100644
--- a/cpp/cert/test/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.expected
+++ b/cpp/cert/test/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.expected
@@ -1,6 +1,6 @@
edges
-| test.cpp:6:19:6:37 | new[] | test.cpp:9:12:9:13 | l1 |
-| test.cpp:7:22:7:40 | new[] | test.cpp:10:12:10:13 | l2 |
+| test.cpp:6:19:6:37 | new[] | test.cpp:9:12:9:13 | l1 | provenance | |
+| test.cpp:7:22:7:40 | new[] | test.cpp:10:12:10:13 | l2 | provenance | |
nodes
| test.cpp:6:19:6:37 | new[] | semmle.label | new[] |
| test.cpp:7:22:7:40 | new[] | semmle.label | new[] |
diff --git a/cpp/cert/test/rules/MEM53-CPP/MissingDestructorCallForManuallyManagedObject.expected b/cpp/cert/test/rules/MEM53-CPP/MissingDestructorCallForManuallyManagedObject.expected
index 00ed15c370..f7f4705ef3 100644
--- a/cpp/cert/test/rules/MEM53-CPP/MissingDestructorCallForManuallyManagedObject.expected
+++ b/cpp/cert/test/rules/MEM53-CPP/MissingDestructorCallForManuallyManagedObject.expected
@@ -1,8 +1,8 @@
edges
-| test.cpp:16:26:16:31 | call to malloc | test.cpp:22:8:22:9 | a1 |
-| test.cpp:17:38:17:43 | call to malloc | test.cpp:23:8:23:9 | a2 |
-| test.cpp:18:26:18:39 | call to operator new | test.cpp:26:21:26:22 | a3 |
-| test.cpp:20:29:20:42 | call to operator new | test.cpp:27:21:27:22 | a4 |
+| test.cpp:16:26:16:31 | call to malloc | test.cpp:22:8:22:9 | a1 | provenance | |
+| test.cpp:17:38:17:43 | call to malloc | test.cpp:23:8:23:9 | a2 | provenance | |
+| test.cpp:18:26:18:39 | call to operator new | test.cpp:26:21:26:22 | a3 | provenance | |
+| test.cpp:20:29:20:42 | call to operator new | test.cpp:27:21:27:22 | a4 | provenance | |
nodes
| test.cpp:16:26:16:31 | call to malloc | semmle.label | call to malloc |
| test.cpp:17:38:17:43 | call to malloc | semmle.label | call to malloc |
diff --git a/cpp/common/src/codeql-pack.lock.yml b/cpp/common/src/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/cpp/common/src/codeql-pack.lock.yml
+++ b/cpp/common/src/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/cpp/common/src/codingstandards/cpp/AlertReporting.qll b/cpp/common/src/codingstandards/cpp/AlertReporting.qll
new file mode 100644
index 0000000000..4259e1b67d
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/AlertReporting.qll
@@ -0,0 +1,41 @@
+/**
+ * Provides a library for managing how alerts are reported.
+ */
+
+import cpp
+
+signature class ResultType extends Element;
+
+/**
+ * A module for unwrapping results that occur in macro expansions.
+ */
+module MacroUnwrapper {
+ /**
+ * Gets a macro invocation that applies to the result element.
+ */
+ private MacroInvocation getAMacroInvocation(ResultElement re) {
+ result.getAnExpandedElement() = re
+ }
+
+ /**
+ * Gets the primary macro that generated the result element.
+ */
+ Macro getPrimaryMacro(ResultElement re) {
+ exists(MacroInvocation mi |
+ mi = getAMacroInvocation(re) and
+ // No other more specific macro that expands to element
+ not exists(MacroInvocation otherMi |
+ otherMi = getAMacroInvocation(re) and otherMi.getParentInvocation() = mi
+ ) and
+ result = mi.getMacro()
+ )
+ }
+
+ /**
+ * If a result element is expanded from a macro invocation, then return the "primary" macro that
+ * generated the element, otherwise return the element itself.
+ */
+ Element unwrapElement(ResultElement re) {
+ if exists(getPrimaryMacro(re)) then result = getPrimaryMacro(re) else result = re
+ }
+}
diff --git a/cpp/common/src/codingstandards/cpp/Bitwise.qll b/cpp/common/src/codingstandards/cpp/Bitwise.qll
deleted file mode 100644
index 0e19cae29d..0000000000
--- a/cpp/common/src/codingstandards/cpp/Bitwise.qll
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * A library for addressing issues in bitwise operator modelling in our database schema.
- */
-
-private import cpp as cpp
-
-module Bitwise {
- /**
- * A binary bitwise assign operation, excluding += and -= on pointers, which seem to be erroneously
- * included.
- */
- class AssignBitwiseOperation extends cpp::AssignBitwiseOperation {
- AssignBitwiseOperation() {
- // exclude += and -= on pointers, which seem to be erroneously included
- // in the database schema
- not this instanceof cpp::AssignPointerAddExpr and
- not this instanceof cpp::AssignPointerSubExpr
- }
- }
-}
diff --git a/cpp/common/src/codingstandards/cpp/Compatible.qll b/cpp/common/src/codingstandards/cpp/Compatible.qll
index 12a53965fe..0f6e2108ff 100644
--- a/cpp/common/src/codingstandards/cpp/Compatible.qll
+++ b/cpp/common/src/codingstandards/cpp/Compatible.qll
@@ -1,5 +1,7 @@
import cpp
+pragma[noinline]
+pragma[nomagic]
predicate typesCompatible(Type t1, Type t2) {
t1 = t2
or
@@ -8,6 +10,7 @@ predicate typesCompatible(Type t1, Type t2) {
}
predicate parameterTypesIncompatible(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) {
+ f1.getDeclaration() = f2.getDeclaration() and
exists(ParameterDeclarationEntry p1, ParameterDeclarationEntry p2, int i |
p1 = f1.getParameterDeclarationEntry(i) and
p2 = f2.getParameterDeclarationEntry(i)
@@ -17,6 +20,7 @@ predicate parameterTypesIncompatible(FunctionDeclarationEntry f1, FunctionDeclar
}
predicate parameterNamesIncompatible(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) {
+ f1.getDeclaration() = f2.getDeclaration() and
exists(ParameterDeclarationEntry p1, ParameterDeclarationEntry p2, int i |
p1 = f1.getParameterDeclarationEntry(i) and
p2 = f2.getParameterDeclarationEntry(i)
diff --git a/cpp/common/src/codingstandards/cpp/Cpp14Literal.qll b/cpp/common/src/codingstandards/cpp/Cpp14Literal.qll
index c974ec7eb8..ca3a7fb251 100644
--- a/cpp/common/src/codingstandards/cpp/Cpp14Literal.qll
+++ b/cpp/common/src/codingstandards/cpp/Cpp14Literal.qll
@@ -9,6 +9,9 @@ module Cpp14Literal {
/** An numeric literal. */
abstract class NumericLiteral extends StandardLibrary::Literal { }
+ /** Convenience for implementing class `UnrecognizedNumericLiteral` */
+ abstract private class RecognizedNumericLiteral extends StandardLibrary::Literal { }
+
/** An integer literal. */
abstract class IntegerLiteral extends NumericLiteral {
predicate isSigned() { not isUnsigned() }
@@ -23,7 +26,7 @@ module Cpp14Literal {
* ```
* Octal literals must always start with the digit `0`.
*/
- class OctalLiteral extends IntegerLiteral {
+ class OctalLiteral extends IntegerLiteral, RecognizedNumericLiteral {
OctalLiteral() { getValueText().regexpMatch("\\s*0[0-7']*[uUlL]*\\s*") }
override string getAPrimaryQlClass() { result = "OctalLiteral" }
@@ -35,7 +38,7 @@ module Cpp14Literal {
* unsigned int32_t minus2 = 0xfffffffe;
* ```
*/
- class HexLiteral extends IntegerLiteral {
+ class HexLiteral extends IntegerLiteral, RecognizedNumericLiteral {
HexLiteral() { getValueText().regexpMatch("\\s*0[xX][0-9a-fA-F']+[uUlL]*\\s*") }
override string getAPrimaryQlClass() { result = "HexLiteral" }
@@ -47,7 +50,7 @@ module Cpp14Literal {
* unsigned int32_t binary = 0b101010;
* ```
*/
- class BinaryLiteral extends IntegerLiteral {
+ class BinaryLiteral extends IntegerLiteral, RecognizedNumericLiteral {
BinaryLiteral() { getValueText().regexpMatch("\\s*0[bB][0-1']*[uUlL]*\\s*") }
override string getAPrimaryQlClass() { result = "BinaryLiteral" }
@@ -59,7 +62,7 @@ module Cpp14Literal {
* unsigned int32_t decimal = 10340923;
* ```
*/
- class DecimalLiteral extends IntegerLiteral {
+ class DecimalLiteral extends IntegerLiteral, RecognizedNumericLiteral {
DecimalLiteral() { getValueText().regexpMatch("\\s*[1-9][0-9']*[uUlL]*\\s*") }
override string getAPrimaryQlClass() { result = "DecimalLiteral" }
@@ -71,7 +74,7 @@ module Cpp14Literal {
* double floating = 1.340923e-19;
* ```
*/
- class FloatingLiteral extends NumericLiteral {
+ class FloatingLiteral extends NumericLiteral, RecognizedNumericLiteral {
FloatingLiteral() {
getValueText().regexpMatch("\\s*[0-9][0-9']*(\\.[0-9']+)?([eE][\\+\\-]?[0-9']+)?[flFL]?\\s*") and
// A decimal literal takes precedent
@@ -83,6 +86,21 @@ module Cpp14Literal {
override string getAPrimaryQlClass() { result = "FloatingLiteral" }
}
+ /**
+ * Literal values with conversions and macros cannot always be trivially
+ * parsed from `Literal.getValueText()`, and have loss of required
+ * information in `Literal.getValue()`. This class covers cases that appear
+ * to be `NumericLiteral`s but cannot be determined to be a hex, decimal,
+ * octal, binary, or float literal, but still are parsed as a Literal with a
+ * number value.
+ */
+ class UnrecognizedNumericLiteral extends NumericLiteral {
+ UnrecognizedNumericLiteral() {
+ this.getValue().regexpMatch("[0-9.e]+") and
+ not this instanceof RecognizedNumericLiteral
+ }
+ }
+
/**
* A character literal. For example:
* ```
diff --git a/cpp/common/src/codingstandards/cpp/EncapsulatingFunctions.qll b/cpp/common/src/codingstandards/cpp/EncapsulatingFunctions.qll
index f82705e2c7..559c04ce98 100644
--- a/cpp/common/src/codingstandards/cpp/EncapsulatingFunctions.qll
+++ b/cpp/common/src/codingstandards/cpp/EncapsulatingFunctions.qll
@@ -3,6 +3,7 @@
*/
import cpp
+import codingstandards.cpp.Class
/** A function which represents the entry point into a specific thread of execution in the program. */
abstract class MainLikeFunction extends Function { }
@@ -18,6 +19,37 @@ class MainFunction extends MainLikeFunction {
}
}
+/**
+ * A test function from the GoogleTest infrastructure.
+ *
+ * Such functions can be treated as valid EntryPoint functions during analysis
+ * of "called" or "unused" functions. It is not straightforward to identify
+ * such functions, however, they have certain features that can be used for
+ * identification. This can be refined based on experiments/real-world use.
+ */
+class GoogleTestFunction extends MainLikeFunction {
+ GoogleTestFunction() {
+ // A GoogleTest function is named "TestBody" and
+ (
+ this.hasName("TestBody") or
+ this instanceof SpecialMemberFunction
+ ) and
+ // it's parent class inherits a base class
+ exists(Class base |
+ base = this.getEnclosingAccessHolder+().(Class).getABaseClass+() and
+ (
+ // with a name "Test" inside a namespace called "testing"
+ base.hasName("Test") and
+ base.getNamespace().hasName("testing")
+ or
+ // or at a location in a file called gtest.h (or gtest-internal.h,
+ // gtest-typed-test.h etc).
+ base.getDefinitionLocation().getFile().getBaseName().regexpMatch("gtest*.h")
+ )
+ )
+ }
+}
+
/**
* A "task main" function.
*/
diff --git a/cpp/common/src/codingstandards/cpp/Includes.qll b/cpp/common/src/codingstandards/cpp/Includes.qll
new file mode 100644
index 0000000000..c0c66ae2f5
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/Includes.qll
@@ -0,0 +1,37 @@
+/** A library which supports analysis of includes. */
+
+import cpp
+import codingstandards.cpp.PreprocessorDirective
+import semmle.code.cpp.headers.MultipleInclusion
+
+pragma[noinline]
+private predicate hasIncludeLocation(Include include, string filepath, int startline) {
+ include.getLocation().hasLocationInfo(filepath, startline, _, _, _)
+}
+
+/**
+ * Holds if `include` is included conditionally based on the branch directive `b1`.
+ */
+pragma[noinline]
+predicate isConditionallyIncluded(PreprocessorBranchDirective bd, Include include) {
+ not bd = any(CorrectIncludeGuard c).getIfndef() and
+ not bd.getHead().regexpMatch(".*_H(_.*)?") and
+ exists(string filepath, int startline, int endline, int includeline |
+ isBranchDirectiveRange(bd, filepath, startline, endline) and
+ hasIncludeLocation(include, filepath, includeline) and
+ startline < includeline and
+ endline > includeline
+ )
+}
+
+/**
+ * Gets a file which is directly included from `fromFile` unconditionally.
+ */
+File getAnUnconditionallyIncludedFile(File fromFile) {
+ // Find an include which isn't conditional
+ exists(Include i |
+ i.getFile() = fromFile and
+ not isConditionallyIncluded(_, i) and
+ result = i.getIncludedFile()
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/IntegerConstantMacro.qll b/cpp/common/src/codingstandards/cpp/IntegerConstantMacro.qll
new file mode 100644
index 0000000000..ce72033ecc
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/IntegerConstantMacro.qll
@@ -0,0 +1,37 @@
+import cpp
+
+/**
+ * The family of macros `xINTsize_C(arg)` (e.g. `UINT16_C(123)`) which are used
+ * to create an integer constant of type `Xint_leastSIZE_t` (e.g.
+ * `uint_least16_t).
+ */
+class IntegerConstantMacro extends Macro {
+ boolean signed;
+ int size;
+
+ IntegerConstantMacro() {
+ signed = true and size = getName().regexpCapture("INT(8|16|32|64)_C", 1).toInt()
+ or
+ signed = false and size = getName().regexpCapture("UINT(8|16|32|64)_C", 1).toInt()
+ }
+
+ predicate isSmall() { size < any(IntType it | it.isSigned()).getSize() * 8 }
+
+ int getSize() { result = size }
+
+ predicate isSigned() { signed = true }
+
+ float maxValue() {
+ signed = true and result = 2.pow(size - 1 * 1.0) - 1
+ or
+ signed = false and result = 2.pow(size) - 1
+ }
+
+ float minValue() {
+ signed = true and result = -2.pow(size - 1)
+ or
+ signed = false and result = 0
+ }
+
+ string getRangeString() { result = minValue().toString() + ".." + maxValue().toString() }
+}
diff --git a/cpp/common/src/codingstandards/cpp/Literals.qll b/cpp/common/src/codingstandards/cpp/Literals.qll
index 66e15b28dc..edec04152e 100644
--- a/cpp/common/src/codingstandards/cpp/Literals.qll
+++ b/cpp/common/src/codingstandards/cpp/Literals.qll
@@ -70,3 +70,46 @@ class BoolLiteral extends Literal {
this.getValue() = "0" and this.getValueText() = "false"
}
}
+
+/**
+ * Abstract case to handle positive and negative "literal" expressions.
+ *
+ * All numeric literals in c/cpp are positive. To create a negative constant
+ * value in a program means applying the unary- operator to a positive literal.
+ * This class effectively describes positive or negative literals.
+ */
+abstract class PossiblyNegativeLiteral extends Expr {
+ /* The syntactic literal, stripped of potential negation */
+ abstract Cpp14Literal::NumericLiteral getBaseLiteral();
+
+ /* The value as a literal reads, without potential underflows from negation */
+ abstract float getRawValue();
+
+ predicate isNegative() { this instanceof NegativeLiteral }
+}
+
+/**
+ * A negation of a positive literal, creating what can be thought of as a
+ * "negative literal."
+ */
+class NegativeLiteral extends PossiblyNegativeLiteral, UnaryMinusExpr {
+ Cpp14Literal::NumericLiteral literal;
+
+ NegativeLiteral() { literal = getOperand() }
+
+ override Cpp14Literal::NumericLiteral getBaseLiteral() { result = literal }
+
+ override float getRawValue() { result = -literal.getValue().toFloat() }
+}
+
+/**
+ * A literal which is not immediately negated by a parent unary- expression,
+ * which can be thought of as a "positive literal."
+ */
+class PositiveLiteral extends PossiblyNegativeLiteral, Cpp14Literal::NumericLiteral {
+ PositiveLiteral() { not exists(UnaryMinusExpr l | l.getOperand() = this) }
+
+ override Cpp14Literal::NumericLiteral getBaseLiteral() { result = this }
+
+ override float getRawValue() { result = getValue().toFloat() }
+}
diff --git a/cpp/common/src/codingstandards/cpp/Noreturn.qll b/cpp/common/src/codingstandards/cpp/Noreturn.qll
new file mode 100644
index 0000000000..eabe86b56e
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/Noreturn.qll
@@ -0,0 +1,22 @@
+import cpp
+
+/**
+ * A function marked with _Noreturn or __attribute((noreturn))
+ */
+class NoreturnFunction extends Function {
+ NoreturnFunction() {
+ this.getASpecifier().getName() = "noreturn" or
+ this.getAnAttribute().getName() = "noreturn"
+ }
+}
+
+/**
+ * A function that may complete normally, and/or contains an explicit reachable
+ * return statement.
+ */
+predicate mayReturn(Function function) {
+ exists(ReturnStmt s |
+ function = s.getEnclosingFunction() and
+ s.getBasicBlock().isReachable()
+ )
+}
diff --git a/c/common/src/codingstandards/c/Pointers.qll b/cpp/common/src/codingstandards/cpp/Pointers.qll
similarity index 82%
rename from c/common/src/codingstandards/c/Pointers.qll
rename to cpp/common/src/codingstandards/cpp/Pointers.qll
index 034080363e..28b6abc340 100644
--- a/c/common/src/codingstandards/c/Pointers.qll
+++ b/cpp/common/src/codingstandards/cpp/Pointers.qll
@@ -6,7 +6,7 @@ import cpp
import codingstandards.cpp.Type
/**
- * A type that is a pointer or array type.
+ * A type that is a pointer or array type after stripping top-level specifiers.
*/
class PointerOrArrayType extends DerivedType {
PointerOrArrayType() {
@@ -15,6 +15,16 @@ class PointerOrArrayType extends DerivedType {
}
}
+/**
+ * A type that is a pointer or array type.
+ */
+class UnspecifiedPointerOrArrayType extends DerivedType {
+ UnspecifiedPointerOrArrayType() {
+ this instanceof PointerType or
+ this instanceof ArrayType
+ }
+}
+
/**
* An expression which performs pointer arithmetic
*/
@@ -62,12 +72,9 @@ class ArrayPointerArithmeticExpr extends PointerArithmeticExpr, ArrayExpr {
predicate isNullPointerConstant(Expr e) {
e.findRootCause() instanceof NullMacro
or
- exists(CStyleCast c |
- not c.isImplicit() and
- c.getExpr() = e and
- e instanceof Zero and
- c.getType() instanceof VoidPointerType
- )
+ // 8.11 Pointer type conversions states:
+ // A null pointer constant, i.e. the value 0, optionally cast to void *.
+ e instanceof Zero
or
isNullPointerConstant(e.(Conversion).getExpr())
}
@@ -83,9 +90,9 @@ predicate isCastNullPointerConstant(Cast c) {
class PointerToObjectType extends PointerType {
PointerToObjectType() {
not (
- this.getUnderlyingType() instanceof FunctionPointerType or
- this.getUnderlyingType() instanceof VoidPointerType or
- this.getBaseType().getUnderlyingType() instanceof IncompleteType
+ this.getUnspecifiedType() instanceof FunctionPointerType or
+ this.getUnspecifiedType() instanceof VoidPointerType or
+ this.getBaseType().getUnspecifiedType() instanceof IncompleteType
)
}
}
diff --git a/cpp/common/src/codingstandards/cpp/PreprocessorDirective.qll b/cpp/common/src/codingstandards/cpp/PreprocessorDirective.qll
index fe619e5317..ca943742d9 100644
--- a/cpp/common/src/codingstandards/cpp/PreprocessorDirective.qll
+++ b/cpp/common/src/codingstandards/cpp/PreprocessorDirective.qll
@@ -40,3 +40,68 @@ class PreprocessorIfOrElif extends PreprocessorBranch {
this instanceof PreprocessorElif
}
}
+
+/**
+ * Holds if the preprocessor directive `m` is located at `filepath` and `startline`.
+ */
+pragma[noinline]
+predicate hasPreprocessorLocation(PreprocessorDirective m, string filepath, int startline) {
+ m.getLocation().hasLocationInfo(filepath, startline, _, _, _)
+}
+
+/**
+ * Holds if `first` and `second` are a pair of branch directives in the same file, such that they
+ * share the same root if condition.
+ */
+pragma[noinline]
+private predicate isBranchDirectivePair(
+ PreprocessorBranchDirective first, PreprocessorBranchDirective second, string filepath,
+ int b1StartLocation, int b2StartLocation
+) {
+ first.getIf() = second.getIf() and
+ not first = second and
+ hasPreprocessorLocation(first, filepath, b1StartLocation) and
+ hasPreprocessorLocation(second, filepath, b2StartLocation) and
+ b1StartLocation < b2StartLocation
+}
+
+/**
+ * Holds if `bd` is a branch directive in the range `filepath`, `startline`, `endline`.
+ */
+pragma[noinline]
+predicate isBranchDirectiveRange(
+ PreprocessorBranchDirective bd, string filepath, int startline, int endline
+) {
+ hasPreprocessorLocation(bd, filepath, startline) and
+ exists(PreprocessorBranchDirective next |
+ next = bd.getNext() and
+ // Avoid referencing filepath here, otherwise the optimiser will try to join
+ // on it
+ hasPreprocessorLocation(next, _, endline)
+ )
+}
+
+/**
+ * Holds if the macro `m` is defined within the branch directive `bd`.
+ */
+pragma[noinline]
+predicate isMacroDefinedWithinBranch(PreprocessorBranchDirective bd, Macro m) {
+ exists(string filepath, int startline, int endline, int macroline |
+ isBranchDirectiveRange(bd, filepath, startline, endline) and
+ hasPreprocessorLocation(m, filepath, macroline) and
+ startline < macroline and
+ endline > macroline
+ )
+}
+
+/**
+ * Holds if the pair of macros are "conditional" i.e. only one of the macros is followed in any
+ * particular compilation of the containing file.
+ */
+predicate mutuallyExclusiveBranchDirectiveMacros(Macro firstMacro, Macro secondMacro) {
+ exists(PreprocessorBranchDirective b1, PreprocessorBranchDirective b2 |
+ isBranchDirectivePair(b1, b2, _, _, _) and
+ isMacroDefinedWithinBranch(b1, firstMacro) and
+ isMacroDefinedWithinBranch(b2, secondMacro)
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/Realloc.qll b/cpp/common/src/codingstandards/cpp/Realloc.qll
new file mode 100644
index 0000000000..71acb7d7b1
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/Realloc.qll
@@ -0,0 +1,18 @@
+import cpp
+import codingstandards.cpp.CodingStandards
+
+class ReallocCall extends FunctionCall {
+ ReallocCall() { getTarget().hasGlobalOrStdName("realloc") }
+
+ Expr getSizeArgument() { result = getArgument(1) }
+
+ predicate sizeIsExactlyZero() {
+ upperBound(getSizeArgument().getConversion()) = 0 and
+ lowerBound(getSizeArgument().getConversion()) = 0
+ }
+
+ predicate sizeMayBeZero() {
+ upperBound(getSizeArgument().getConversion()) >= 0 and
+ lowerBound(getSizeArgument().getConversion()) <= 0
+ }
+}
diff --git a/cpp/common/src/codingstandards/cpp/SideEffect.qll b/cpp/common/src/codingstandards/cpp/SideEffect.qll
index 08cd9394d3..68fe2cd0cd 100644
--- a/cpp/common/src/codingstandards/cpp/SideEffect.qll
+++ b/cpp/common/src/codingstandards/cpp/SideEffect.qll
@@ -190,6 +190,8 @@ Expr getAnEffect(Expr base) {
or
exists(PointerDereferenceExpr e | e.getOperand() = base | result = getAnEffect(e))
or
+ exists(CrementOperation c | c.getOperand() = base | result = getAnEffect(c))
+ or
// local alias analysis, assume alias when data flows to derived type (pointer/reference)
// auto ptr = &base;
exists(VariableAccess va, AddressOfExpr addressOf |
diff --git a/cpp/common/src/codingstandards/cpp/SimpleRangeAnalysisCustomizations.qll b/cpp/common/src/codingstandards/cpp/SimpleRangeAnalysisCustomizations.qll
index 469fe9a738..5144f63dc2 100644
--- a/cpp/common/src/codingstandards/cpp/SimpleRangeAnalysisCustomizations.qll
+++ b/cpp/common/src/codingstandards/cpp/SimpleRangeAnalysisCustomizations.qll
@@ -151,6 +151,40 @@ private class CastEnumToIntegerSimpleRange extends SimpleRangeAnalysisExpr, Cast
override predicate dependsOnChild(Expr child) { child = getExpr() }
}
+/**
+ * A range analysis extension that supports `%=`.
+ */
+private class RemAssignSimpleRange extends SimpleRangeAnalysisExpr, AssignRemExpr {
+ override float getLowerBounds() {
+ exists(float maxDivisorNegated, float dividendLowerBounds |
+ // Find the max divisor, negated e.g. `%= 32` would be `-31`
+ maxDivisorNegated = (getFullyConvertedUpperBounds(getRValue()).abs() - 1) * -1 and
+ // Find the lower bounds of the dividend
+ dividendLowerBounds = getFullyConvertedLowerBounds(getLValue()) and
+ // The lower bound is calculated in two steps:
+ // 1. Determine the maximum of the dividend lower bound and maxDivisorNegated.
+ // When the dividend is negative this will result in a negative result
+ // 2. Find the minimum with 0. If the divided is always >0 this will produce 0
+ // otherwise it will produce the lowest negative number that can be held
+ // after the modulo.
+ result = 0.minimum(dividendLowerBounds.maximum(maxDivisorNegated))
+ )
+ }
+
+ override float getUpperBounds() {
+ exists(float maxDivisor, float maxDividend |
+ // The maximum divisor value is the absolute value of the divisor minus 1
+ maxDivisor = getFullyConvertedUpperBounds(getRValue()).abs() - 1 and
+ // value if > 0 otherwise 0
+ maxDividend = getFullyConvertedUpperBounds(getLValue()).maximum(0) and
+ // In the case the numerator is definitely less than zero, the result could be negative
+ result = maxDividend.minimum(maxDivisor)
+ )
+ }
+
+ override predicate dependsOnChild(Expr expr) { expr = getAChild() }
+}
+
/**
* functions that read a character from the STDIN,
* or return EOF if it fails to do so.
diff --git a/cpp/common/src/codingstandards/cpp/Variable.qll b/cpp/common/src/codingstandards/cpp/Variable.qll
index dba7af480a..47c6ca7f6c 100644
--- a/cpp/common/src/codingstandards/cpp/Variable.qll
+++ b/cpp/common/src/codingstandards/cpp/Variable.qll
@@ -5,3 +5,17 @@ import semmle.code.cpp.PODType03
class ScalarVariable extends Variable {
ScalarVariable() { isScalarType03(this.getType()) }
}
+
+/**
+ * Returns the target variable of a `VariableAccess`.
+ * If the access is a field access, then the target is the `Variable` of the qualifier.
+ * If the access is an array access, then the target is the array base.
+ */
+Variable getAddressOfExprTargetBase(AddressOfExpr expr) {
+ result = expr.getOperand().(ValueFieldAccess).getQualifier().(VariableAccess).getTarget()
+ or
+ not expr.getOperand() instanceof ValueFieldAccess and
+ result = expr.getOperand().(VariableAccess).getTarget()
+ or
+ result = expr.getOperand().(ArrayExpr).getArrayBase().(VariableAccess).getTarget()
+}
diff --git a/cpp/common/src/codingstandards/cpp/alertreporting/HoldsForAllCopies.qll b/cpp/common/src/codingstandards/cpp/alertreporting/HoldsForAllCopies.qll
new file mode 100644
index 0000000000..1d47e833dc
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/alertreporting/HoldsForAllCopies.qll
@@ -0,0 +1,117 @@
+/**
+ * A module for considering whether a result occurs in all copies of the code at a given location.
+ *
+ * Multiple copies of an element at the same location can occur for two main reasons:
+ * 1. Instantiations of a template
+ * 2. Re-compilation of a file under a different context
+ * This module helps ensure that a particular condition holds for all copies of a particular logical
+ * element. For example, this can be used to determine whether a line of code is dead in all copies
+ * of a piece of code.
+ *
+ * This module is parameterized by a set of _candidate_ elements in the program. For each candidate
+ * element, we determine whether all other elements in the same element set that occur at the same
+ * location in the program are also part of the same set, ignoring any results generated by macros.
+ *
+ * We do so by reporting a new type of result, `LogicalResultElement`, which represents a logical result
+ * where all instances of a element at a given location are considered to be part of the same set.
+ */
+
+import cpp
+
+/**
+ * Holds if the `Element` `e` is not within a macro expansion, i.e. generated by a macro, but not
+ * the outermost `Element` or `Expr` generated by the macro.
+ */
+predicate isNotWithinMacroExpansion(Element e) {
+ not e.isInMacroExpansion()
+ or
+ exists(MacroInvocation mi |
+ mi.getStmt() = e
+ or
+ mi.getExpr() = e
+ or
+ mi.getStmt().(ExprStmt).getExpr() = e
+ |
+ not exists(mi.getParentInvocation())
+ )
+}
+
+/**
+ * A type representing a set of Element's in the program that satisfy some condition.
+ *
+ * `HoldsForAllCopies::LogicalResultElement` will represent an element in this set
+ * iff all copies of that element satisfy the condition.
+ */
+signature class CandidateElementSig extends Element;
+
+/** The super set of relevant elements. */
+signature class ElementSetSig extends Element;
+
+/**
+ * A module for considering whether a result occurs in all copies of the code at a given location.
+ */
+module HoldsForAllCopies {
+ private predicate hasLocation(
+ ElementSet s, string filepath, int startline, int startcolumn, int endline, int endcolumn
+ ) {
+ s.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
+ }
+
+ final private class MyElement = ElementSet;
+
+ /**
+ * A `Element` that appears at the same location as a candidate element.
+ */
+ private class RelevantElement extends MyElement {
+ CandidateElement e;
+
+ RelevantElement() {
+ exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
+ hasLocation(this, filepath, startline, startcolumn, endline, endcolumn) and
+ hasLocation(e, filepath, startline, startcolumn, endline, endcolumn)
+ ) and
+ // Not within a macro expansion, as we cannot match up instances by location in that
+ // case
+ isNotWithinMacroExpansion(this) and
+ // Ignore catch handlers, as they occur at the same location as the catch block
+ not this instanceof Handler
+ }
+
+ CandidateElement getCandidateElement() { result = e }
+ }
+
+ newtype TResultElements =
+ TLogicalResultElement(
+ string filepath, int startline, int startcolumn, int endline, int endcolumn
+ ) {
+ exists(CandidateElement s |
+ hasLocation(s, filepath, startline, startcolumn, endline, endcolumn) and
+ // All relevant elements that occur at the same location are candidates
+ forall(RelevantElement relevantElement | s = relevantElement.getCandidateElement() |
+ relevantElement instanceof CandidateElement
+ )
+ )
+ }
+
+ /**
+ * A logical result element representing all copies of an element that occur at the same
+ * location, iff they all belong to the `CandidateElement` set.
+ */
+ class LogicalResultElement extends TLogicalResultElement {
+ predicate hasLocationInfo(
+ string filepath, int startline, int startcolumn, int endline, int endcolumn
+ ) {
+ this = TLogicalResultElement(filepath, startline, startcolumn, endline, endcolumn)
+ }
+
+ /** Gets a copy instance of this logical result element. */
+ CandidateElement getAnElementInstance() {
+ exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
+ this = TLogicalResultElement(filepath, startline, startcolumn, endline, endcolumn) and
+ hasLocation(result, filepath, startline, startcolumn, endline, endcolumn)
+ )
+ }
+
+ string toString() { result = getAnElementInstance().toString() }
+ }
+}
diff --git a/cpp/common/src/codingstandards/cpp/deadcode/UnusedFunctions.qll b/cpp/common/src/codingstandards/cpp/deadcode/UnusedFunctions.qll
index b01b80208e..fdd713b436 100644
--- a/cpp/common/src/codingstandards/cpp/deadcode/UnusedFunctions.qll
+++ b/cpp/common/src/codingstandards/cpp/deadcode/UnusedFunctions.qll
@@ -13,6 +13,7 @@ import cpp
import codingstandards.cpp.DynamicCallGraph
import codingstandards.cpp.EncapsulatingFunctions
import codingstandards.cpp.FunctionEquivalence
+import codingstandards.cpp.Class
module UnusedFunctions {
/**
@@ -119,7 +120,12 @@ module UnusedFunctions {
class UnusedFunction extends UsableFunction {
UnusedFunction() {
// This function, or an equivalent function, is not reachable from any entry point
- not exists(EntryPoint ep | getAnEquivalentFunction(this) = ep.getAReachableFunction())
+ not exists(EntryPoint ep | getAnEquivalentFunction(this) = ep.getAReachableFunction()) and
+ // and it is not a constexpr. Refer issue #646.
+ // The usages of constexpr is not well tracked and hence
+ // to avoid false positives, this is added. In case there is an improvement in
+ // handling constexpr in CodeQL, we can consider removing it.
+ not this.isConstexpr()
}
string getDeadCodeType() {
@@ -128,4 +134,7 @@ module UnusedFunctions {
else result = "never called."
}
}
+
+ /** A `SpecialMemberFunction` which is an `UnusedFunction`. */
+ class UnusedSplMemberFunction extends UnusedFunction, SpecialMemberFunction { }
}
diff --git a/cpp/common/src/codingstandards/cpp/deadcode/UnusedVariables.qll b/cpp/common/src/codingstandards/cpp/deadcode/UnusedVariables.qll
index f4607d82cb..912d2babcd 100644
--- a/cpp/common/src/codingstandards/cpp/deadcode/UnusedVariables.qll
+++ b/cpp/common/src/codingstandards/cpp/deadcode/UnusedVariables.qll
@@ -150,3 +150,21 @@ predicate maybeACompileTimeTemplateArgument(Variable v) {
)
)
}
+
+/** Gets the constant value of a constexpr/const variable. */
+string getConstExprValue(Variable v) {
+ result = v.getInitializer().getExpr().getValue() and
+ (v.isConst() or v.isConstexpr())
+}
+
+/**
+ * Counts uses of `Variable` v in a local array of size `n`
+ */
+int countUsesInLocalArraySize(Variable v) {
+ result =
+ count(ArrayType at, LocalVariable arrayVariable |
+ arrayVariable.getType().resolveTypedefs() = at and
+ v.(PotentiallyUnusedLocalVariable).getFunction() = arrayVariable.getFunction() and
+ at.getArraySize().toString() = getConstExprValue(v)
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/deadcode/UselessAssignments.qll b/cpp/common/src/codingstandards/cpp/deadcode/UselessAssignments.qll
index 465b023f3f..031ad2aa7c 100644
--- a/cpp/common/src/codingstandards/cpp/deadcode/UselessAssignments.qll
+++ b/cpp/common/src/codingstandards/cpp/deadcode/UselessAssignments.qll
@@ -3,6 +3,7 @@
*/
import cpp
+import codingstandards.cpp.deadcode.UnusedVariables
import codingstandards.cpp.enhancements.ControlFlowGraphEnhancements
/** If a variable may escape from the local context */
@@ -47,7 +48,9 @@ class InterestingStackVariable extends StackVariable {
// Ignore variables in uninstantiated templates
not this.isFromUninstantiatedTemplate(_) and
// Ignore compiler generated variables, such as those generated for range based for loops
- not this.isCompilerGenerated()
+ not this.isCompilerGenerated() and
+ // Explicitly ignore (propagated) constants that may be used to define sizes of local arrays
+ not countUsesInLocalArraySize(this) > 0
}
}
diff --git a/cpp/common/src/codingstandards/cpp/enhancements/ControlFlowGraphEnhancements.qll b/cpp/common/src/codingstandards/cpp/enhancements/ControlFlowGraphEnhancements.qll
index 74d7e8e1c1..9dac58377c 100644
--- a/cpp/common/src/codingstandards/cpp/enhancements/ControlFlowGraphEnhancements.qll
+++ b/cpp/common/src/codingstandards/cpp/enhancements/ControlFlowGraphEnhancements.qll
@@ -10,8 +10,8 @@ import cpp
* should be in this relation.
*/
pragma[noinline]
-private predicate isFunction(Element el) {
- el instanceof Function
+private predicate isFunction(@element el) {
+ el instanceof @function
or
el.(Expr).getParent() = el
}
@@ -22,7 +22,7 @@ private predicate isFunction(Element el) {
*/
pragma[noopt]
private predicate callHasNoTarget(@funbindexpr fc) {
- exists(Function f |
+ exists(@function f |
funbind(fc, f) and
not isFunction(f)
)
diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Banned2.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Banned2.qll
new file mode 100644
index 0000000000..024aa9b76c
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Banned2.qll
@@ -0,0 +1,26 @@
+//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
+import cpp
+import RuleMetadata
+import codingstandards.cpp.exclusions.RuleMetadata
+
+newtype Banned2Query = TCallToBannedRandomFunctionQuery()
+
+predicate isBanned2QueryMetadata(Query query, string queryId, string ruleId, string category) {
+ query =
+ // `Query` instance for the `callToBannedRandomFunction` query
+ Banned2Package::callToBannedRandomFunctionQuery() and
+ queryId =
+ // `@id` for the `callToBannedRandomFunction` query
+ "c/misra/call-to-banned-random-function" and
+ ruleId = "RULE-21-24" and
+ category = "required"
+}
+
+module Banned2Package {
+ Query callToBannedRandomFunctionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `callToBannedRandomFunction` query
+ TQueryC(TBanned2PackageQuery(TCallToBannedRandomFunctionQuery()))
+ }
+}
diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/BitfieldTypes2.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/BitfieldTypes2.qll
new file mode 100644
index 0000000000..ca116bb51c
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/BitfieldTypes2.qll
@@ -0,0 +1,26 @@
+//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
+import cpp
+import RuleMetadata
+import codingstandards.cpp.exclusions.RuleMetadata
+
+newtype BitfieldTypes2Query = TBitFieldDeclaredAsMemberOfAUnionQuery()
+
+predicate isBitfieldTypes2QueryMetadata(Query query, string queryId, string ruleId, string category) {
+ query =
+ // `Query` instance for the `bitFieldDeclaredAsMemberOfAUnion` query
+ BitfieldTypes2Package::bitFieldDeclaredAsMemberOfAUnionQuery() and
+ queryId =
+ // `@id` for the `bitFieldDeclaredAsMemberOfAUnion` query
+ "c/misra/bit-field-declared-as-member-of-a-union" and
+ ruleId = "RULE-6-3" and
+ category = "required"
+}
+
+module BitfieldTypes2Package {
+ Query bitFieldDeclaredAsMemberOfAUnionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `bitFieldDeclaredAsMemberOfAUnion` query
+ TQueryC(TBitfieldTypes2PackageQuery(TBitFieldDeclaredAsMemberOfAUnionQuery()))
+ }
+}
diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/FunctionTypes.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/FunctionTypes.qll
new file mode 100644
index 0000000000..3d6faadb42
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/FunctionTypes.qll
@@ -0,0 +1,26 @@
+//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
+import cpp
+import RuleMetadata
+import codingstandards.cpp.exclusions.RuleMetadata
+
+newtype FunctionTypesQuery = TFunctionAddressesShouldAddressOperatorQuery()
+
+predicate isFunctionTypesQueryMetadata(Query query, string queryId, string ruleId, string category) {
+ query =
+ // `Query` instance for the `functionAddressesShouldAddressOperator` query
+ FunctionTypesPackage::functionAddressesShouldAddressOperatorQuery() and
+ queryId =
+ // `@id` for the `functionAddressesShouldAddressOperator` query
+ "c/misra/function-addresses-should-address-operator" and
+ ruleId = "RULE-17-12" and
+ category = "advisory"
+}
+
+module FunctionTypesPackage {
+ Query functionAddressesShouldAddressOperatorQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `functionAddressesShouldAddressOperator` query
+ TQueryC(TFunctionTypesPackageQuery(TFunctionAddressesShouldAddressOperatorQuery()))
+ }
+}
diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll
new file mode 100644
index 0000000000..b4391ff5c2
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll
@@ -0,0 +1,163 @@
+//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
+import cpp
+import RuleMetadata
+import codingstandards.cpp.exclusions.RuleMetadata
+
+newtype Language4Query =
+ TMissingStaticSpecifierFuncRedeclarationObsoleteQuery() or
+ TMissingStaticSpecifierObjectRedeclarationObsoleteQuery() or
+ TFunctionTypesNotInPrototypeFormObsoleteQuery() or
+ TUseOfObsoleteMacroAtomicVarInitQuery() or
+ TInvalidDefineOrUndefOfStdBoolMacroQuery() or
+ TCallToObsolescentFunctionGetsQuery() or
+ TUngetcCallOnStreamPositionZeroQuery() or
+ TSizeInReallocCallMayBeZeroQuery() or
+ TSizeInReallocCallIsZeroQuery()
+
+predicate isLanguage4QueryMetadata(Query query, string queryId, string ruleId, string category) {
+ query =
+ // `Query` instance for the `missingStaticSpecifierFuncRedeclarationObsolete` query
+ Language4Package::missingStaticSpecifierFuncRedeclarationObsoleteQuery() and
+ queryId =
+ // `@id` for the `missingStaticSpecifierFuncRedeclarationObsolete` query
+ "c/misra/missing-static-specifier-func-redeclaration-obsolete" and
+ ruleId = "RULE-1-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `missingStaticSpecifierObjectRedeclarationObsolete` query
+ Language4Package::missingStaticSpecifierObjectRedeclarationObsoleteQuery() and
+ queryId =
+ // `@id` for the `missingStaticSpecifierObjectRedeclarationObsolete` query
+ "c/misra/missing-static-specifier-object-redeclaration-obsolete" and
+ ruleId = "RULE-1-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `functionTypesNotInPrototypeFormObsolete` query
+ Language4Package::functionTypesNotInPrototypeFormObsoleteQuery() and
+ queryId =
+ // `@id` for the `functionTypesNotInPrototypeFormObsolete` query
+ "c/misra/function-types-not-in-prototype-form-obsolete" and
+ ruleId = "RULE-1-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `useOfObsoleteMacroAtomicVarInit` query
+ Language4Package::useOfObsoleteMacroAtomicVarInitQuery() and
+ queryId =
+ // `@id` for the `useOfObsoleteMacroAtomicVarInit` query
+ "c/misra/use-of-obsolete-macro-atomic-var-init" and
+ ruleId = "RULE-1-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `invalidDefineOrUndefOfStdBoolMacro` query
+ Language4Package::invalidDefineOrUndefOfStdBoolMacroQuery() and
+ queryId =
+ // `@id` for the `invalidDefineOrUndefOfStdBoolMacro` query
+ "c/misra/invalid-define-or-undef-of-std-bool-macro" and
+ ruleId = "RULE-1-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `callToObsolescentFunctionGets` query
+ Language4Package::callToObsolescentFunctionGetsQuery() and
+ queryId =
+ // `@id` for the `callToObsolescentFunctionGets` query
+ "c/misra/call-to-obsolescent-function-gets" and
+ ruleId = "RULE-1-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `ungetcCallOnStreamPositionZero` query
+ Language4Package::ungetcCallOnStreamPositionZeroQuery() and
+ queryId =
+ // `@id` for the `ungetcCallOnStreamPositionZero` query
+ "c/misra/ungetc-call-on-stream-position-zero" and
+ ruleId = "RULE-1-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `sizeInReallocCallMayBeZero` query
+ Language4Package::sizeInReallocCallMayBeZeroQuery() and
+ queryId =
+ // `@id` for the `sizeInReallocCallMayBeZero` query
+ "c/misra/size-in-realloc-call-may-be-zero" and
+ ruleId = "RULE-1-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `sizeInReallocCallIsZero` query
+ Language4Package::sizeInReallocCallIsZeroQuery() and
+ queryId =
+ // `@id` for the `sizeInReallocCallIsZero` query
+ "c/misra/size-in-realloc-call-is-zero" and
+ ruleId = "RULE-1-5" and
+ category = "required"
+}
+
+module Language4Package {
+ Query missingStaticSpecifierFuncRedeclarationObsoleteQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `missingStaticSpecifierFuncRedeclarationObsolete` query
+ TQueryC(TLanguage4PackageQuery(TMissingStaticSpecifierFuncRedeclarationObsoleteQuery()))
+ }
+
+ Query missingStaticSpecifierObjectRedeclarationObsoleteQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `missingStaticSpecifierObjectRedeclarationObsolete` query
+ TQueryC(TLanguage4PackageQuery(TMissingStaticSpecifierObjectRedeclarationObsoleteQuery()))
+ }
+
+ Query functionTypesNotInPrototypeFormObsoleteQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `functionTypesNotInPrototypeFormObsolete` query
+ TQueryC(TLanguage4PackageQuery(TFunctionTypesNotInPrototypeFormObsoleteQuery()))
+ }
+
+ Query useOfObsoleteMacroAtomicVarInitQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `useOfObsoleteMacroAtomicVarInit` query
+ TQueryC(TLanguage4PackageQuery(TUseOfObsoleteMacroAtomicVarInitQuery()))
+ }
+
+ Query invalidDefineOrUndefOfStdBoolMacroQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `invalidDefineOrUndefOfStdBoolMacro` query
+ TQueryC(TLanguage4PackageQuery(TInvalidDefineOrUndefOfStdBoolMacroQuery()))
+ }
+
+ Query callToObsolescentFunctionGetsQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `callToObsolescentFunctionGets` query
+ TQueryC(TLanguage4PackageQuery(TCallToObsolescentFunctionGetsQuery()))
+ }
+
+ Query ungetcCallOnStreamPositionZeroQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `ungetcCallOnStreamPositionZero` query
+ TQueryC(TLanguage4PackageQuery(TUngetcCallOnStreamPositionZeroQuery()))
+ }
+
+ Query sizeInReallocCallMayBeZeroQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `sizeInReallocCallMayBeZero` query
+ TQueryC(TLanguage4PackageQuery(TSizeInReallocCallMayBeZeroQuery()))
+ }
+
+ Query sizeInReallocCallIsZeroQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `sizeInReallocCallIsZero` query
+ TQueryC(TLanguage4PackageQuery(TSizeInReallocCallIsZeroQuery()))
+ }
+}
diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/NoReturn.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/NoReturn.qll
new file mode 100644
index 0000000000..07b9360213
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/NoReturn.qll
@@ -0,0 +1,61 @@
+//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
+import cpp
+import RuleMetadata
+import codingstandards.cpp.exclusions.RuleMetadata
+
+newtype NoReturnQuery =
+ TNonVoidReturnTypeOfNoreturnFunctionQuery() or
+ TFunctionWithNoReturningBranchShouldBeNoreturnQuery() or
+ TReturnStatementInNoreturnFunctionQuery()
+
+predicate isNoReturnQueryMetadata(Query query, string queryId, string ruleId, string category) {
+ query =
+ // `Query` instance for the `nonVoidReturnTypeOfNoreturnFunction` query
+ NoReturnPackage::nonVoidReturnTypeOfNoreturnFunctionQuery() and
+ queryId =
+ // `@id` for the `nonVoidReturnTypeOfNoreturnFunction` query
+ "c/misra/non-void-return-type-of-noreturn-function" and
+ ruleId = "RULE-17-10" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `functionWithNoReturningBranchShouldBeNoreturn` query
+ NoReturnPackage::functionWithNoReturningBranchShouldBeNoreturnQuery() and
+ queryId =
+ // `@id` for the `functionWithNoReturningBranchShouldBeNoreturn` query
+ "c/misra/function-with-no-returning-branch-should-be-noreturn" and
+ ruleId = "RULE-17-11" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `returnStatementInNoreturnFunction` query
+ NoReturnPackage::returnStatementInNoreturnFunctionQuery() and
+ queryId =
+ // `@id` for the `returnStatementInNoreturnFunction` query
+ "c/misra/return-statement-in-noreturn-function" and
+ ruleId = "RULE-17-9" and
+ category = "mandatory"
+}
+
+module NoReturnPackage {
+ Query nonVoidReturnTypeOfNoreturnFunctionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `nonVoidReturnTypeOfNoreturnFunction` query
+ TQueryC(TNoReturnPackageQuery(TNonVoidReturnTypeOfNoreturnFunctionQuery()))
+ }
+
+ Query functionWithNoReturningBranchShouldBeNoreturnQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `functionWithNoReturningBranchShouldBeNoreturn` query
+ TQueryC(TNoReturnPackageQuery(TFunctionWithNoReturningBranchShouldBeNoreturnQuery()))
+ }
+
+ Query returnStatementInNoreturnFunctionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `returnStatementInNoreturnFunction` query
+ TQueryC(TNoReturnPackageQuery(TReturnStatementInNoreturnFunctionQuery()))
+ }
+}
diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll
index c2771f4171..b9de3424fb 100644
--- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll
@@ -3,7 +3,9 @@ import cpp
import codingstandards.cpp.exclusions.RuleMetadata
//** Import packages for this language **/
import Banned
+import Banned2
import BitfieldTypes
+import BitfieldTypes2
import Concurrency1
import Concurrency2
import Concurrency3
@@ -28,6 +30,7 @@ import Declarations8
import EssentialTypes
import Expressions
import FloatingTypes
+import FunctionTypes
import IO1
import IO2
import IO3
@@ -38,10 +41,12 @@ import InvalidMemory2
import Language1
import Language2
import Language3
+import Language4
import Memory1
import Memory2
import Memory3
import Misc
+import NoReturn
import OutOfBounds
import Pointers1
import Pointers2
@@ -70,11 +75,14 @@ import Strings2
import Strings3
import Syntax
import Types1
+import Types2
/** The TQuery type representing this language * */
newtype TCQuery =
TBannedPackageQuery(BannedQuery q) or
+ TBanned2PackageQuery(Banned2Query q) or
TBitfieldTypesPackageQuery(BitfieldTypesQuery q) or
+ TBitfieldTypes2PackageQuery(BitfieldTypes2Query q) or
TConcurrency1PackageQuery(Concurrency1Query q) or
TConcurrency2PackageQuery(Concurrency2Query q) or
TConcurrency3PackageQuery(Concurrency3Query q) or
@@ -99,6 +107,7 @@ newtype TCQuery =
TEssentialTypesPackageQuery(EssentialTypesQuery q) or
TExpressionsPackageQuery(ExpressionsQuery q) or
TFloatingTypesPackageQuery(FloatingTypesQuery q) or
+ TFunctionTypesPackageQuery(FunctionTypesQuery q) or
TIO1PackageQuery(IO1Query q) or
TIO2PackageQuery(IO2Query q) or
TIO3PackageQuery(IO3Query q) or
@@ -109,10 +118,12 @@ newtype TCQuery =
TLanguage1PackageQuery(Language1Query q) or
TLanguage2PackageQuery(Language2Query q) or
TLanguage3PackageQuery(Language3Query q) or
+ TLanguage4PackageQuery(Language4Query q) or
TMemory1PackageQuery(Memory1Query q) or
TMemory2PackageQuery(Memory2Query q) or
TMemory3PackageQuery(Memory3Query q) or
TMiscPackageQuery(MiscQuery q) or
+ TNoReturnPackageQuery(NoReturnQuery q) or
TOutOfBoundsPackageQuery(OutOfBoundsQuery q) or
TPointers1PackageQuery(Pointers1Query q) or
TPointers2PackageQuery(Pointers2Query q) or
@@ -140,12 +151,15 @@ newtype TCQuery =
TStrings2PackageQuery(Strings2Query q) or
TStrings3PackageQuery(Strings3Query q) or
TSyntaxPackageQuery(SyntaxQuery q) or
- TTypes1PackageQuery(Types1Query q)
+ TTypes1PackageQuery(Types1Query q) or
+ TTypes2PackageQuery(Types2Query q)
/** The metadata predicate * */
predicate isQueryMetadata(Query query, string queryId, string ruleId, string category) {
isBannedQueryMetadata(query, queryId, ruleId, category) or
+ isBanned2QueryMetadata(query, queryId, ruleId, category) or
isBitfieldTypesQueryMetadata(query, queryId, ruleId, category) or
+ isBitfieldTypes2QueryMetadata(query, queryId, ruleId, category) or
isConcurrency1QueryMetadata(query, queryId, ruleId, category) or
isConcurrency2QueryMetadata(query, queryId, ruleId, category) or
isConcurrency3QueryMetadata(query, queryId, ruleId, category) or
@@ -170,6 +184,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
isEssentialTypesQueryMetadata(query, queryId, ruleId, category) or
isExpressionsQueryMetadata(query, queryId, ruleId, category) or
isFloatingTypesQueryMetadata(query, queryId, ruleId, category) or
+ isFunctionTypesQueryMetadata(query, queryId, ruleId, category) or
isIO1QueryMetadata(query, queryId, ruleId, category) or
isIO2QueryMetadata(query, queryId, ruleId, category) or
isIO3QueryMetadata(query, queryId, ruleId, category) or
@@ -180,10 +195,12 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
isLanguage1QueryMetadata(query, queryId, ruleId, category) or
isLanguage2QueryMetadata(query, queryId, ruleId, category) or
isLanguage3QueryMetadata(query, queryId, ruleId, category) or
+ isLanguage4QueryMetadata(query, queryId, ruleId, category) or
isMemory1QueryMetadata(query, queryId, ruleId, category) or
isMemory2QueryMetadata(query, queryId, ruleId, category) or
isMemory3QueryMetadata(query, queryId, ruleId, category) or
isMiscQueryMetadata(query, queryId, ruleId, category) or
+ isNoReturnQueryMetadata(query, queryId, ruleId, category) or
isOutOfBoundsQueryMetadata(query, queryId, ruleId, category) or
isPointers1QueryMetadata(query, queryId, ruleId, category) or
isPointers2QueryMetadata(query, queryId, ruleId, category) or
@@ -211,5 +228,6 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
isStrings2QueryMetadata(query, queryId, ruleId, category) or
isStrings3QueryMetadata(query, queryId, ruleId, category) or
isSyntaxQueryMetadata(query, queryId, ruleId, category) or
- isTypes1QueryMetadata(query, queryId, ruleId, category)
+ isTypes1QueryMetadata(query, queryId, ruleId, category) or
+ isTypes2QueryMetadata(query, queryId, ruleId, category)
}
diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Types2.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Types2.qll
new file mode 100644
index 0000000000..3b2d3a4342
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Types2.qll
@@ -0,0 +1,95 @@
+//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
+import cpp
+import RuleMetadata
+import codingstandards.cpp.exclusions.RuleMetadata
+
+newtype Types2Query =
+ TInvalidIntegerConstantMacroArgumentQuery() or
+ TInvalidLiteralForIntegerConstantMacroArgumentQuery() or
+ TIntegerConstantMacroArgumentUsesSuffixQuery() or
+ TIncorrectlySizedIntegerConstantMacroArgumentQuery() or
+ TUseOfBannedSmallIntegerConstantMacroQuery()
+
+predicate isTypes2QueryMetadata(Query query, string queryId, string ruleId, string category) {
+ query =
+ // `Query` instance for the `invalidIntegerConstantMacroArgument` query
+ Types2Package::invalidIntegerConstantMacroArgumentQuery() and
+ queryId =
+ // `@id` for the `invalidIntegerConstantMacroArgument` query
+ "c/misra/invalid-integer-constant-macro-argument" and
+ ruleId = "RULE-7-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `invalidLiteralForIntegerConstantMacroArgument` query
+ Types2Package::invalidLiteralForIntegerConstantMacroArgumentQuery() and
+ queryId =
+ // `@id` for the `invalidLiteralForIntegerConstantMacroArgument` query
+ "c/misra/invalid-literal-for-integer-constant-macro-argument" and
+ ruleId = "RULE-7-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `integerConstantMacroArgumentUsesSuffix` query
+ Types2Package::integerConstantMacroArgumentUsesSuffixQuery() and
+ queryId =
+ // `@id` for the `integerConstantMacroArgumentUsesSuffix` query
+ "c/misra/integer-constant-macro-argument-uses-suffix" and
+ ruleId = "RULE-7-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `incorrectlySizedIntegerConstantMacroArgument` query
+ Types2Package::incorrectlySizedIntegerConstantMacroArgumentQuery() and
+ queryId =
+ // `@id` for the `incorrectlySizedIntegerConstantMacroArgument` query
+ "c/misra/incorrectly-sized-integer-constant-macro-argument" and
+ ruleId = "RULE-7-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `useOfBannedSmallIntegerConstantMacro` query
+ Types2Package::useOfBannedSmallIntegerConstantMacroQuery() and
+ queryId =
+ // `@id` for the `useOfBannedSmallIntegerConstantMacro` query
+ "c/misra/use-of-banned-small-integer-constant-macro" and
+ ruleId = "RULE-7-6" and
+ category = "required"
+}
+
+module Types2Package {
+ Query invalidIntegerConstantMacroArgumentQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `invalidIntegerConstantMacroArgument` query
+ TQueryC(TTypes2PackageQuery(TInvalidIntegerConstantMacroArgumentQuery()))
+ }
+
+ Query invalidLiteralForIntegerConstantMacroArgumentQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `invalidLiteralForIntegerConstantMacroArgument` query
+ TQueryC(TTypes2PackageQuery(TInvalidLiteralForIntegerConstantMacroArgumentQuery()))
+ }
+
+ Query integerConstantMacroArgumentUsesSuffixQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `integerConstantMacroArgumentUsesSuffix` query
+ TQueryC(TTypes2PackageQuery(TIntegerConstantMacroArgumentUsesSuffixQuery()))
+ }
+
+ Query incorrectlySizedIntegerConstantMacroArgumentQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `incorrectlySizedIntegerConstantMacroArgument` query
+ TQueryC(TTypes2PackageQuery(TIncorrectlySizedIntegerConstantMacroArgumentQuery()))
+ }
+
+ Query useOfBannedSmallIntegerConstantMacroQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `useOfBannedSmallIntegerConstantMacro` query
+ TQueryC(TTypes2PackageQuery(TUseOfBannedSmallIntegerConstantMacroQuery()))
+ }
+}
diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/DeadCode.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/DeadCode.qll
index 40b8795e5e..f11741fde5 100644
--- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/DeadCode.qll
+++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/DeadCode.qll
@@ -12,6 +12,7 @@ newtype DeadCodeQuery =
TUnusedTypeDeclarationsQuery() or
TUnreachableCodeQuery() or
TUnusedFunctionQuery() or
+ TUnusedSplMemberFunctionQuery() or
TInfeasiblePathQuery() or
TUnusedLocalVariableQuery() or
TUnusedGlobalOrNamespaceVariableQuery() or
@@ -94,6 +95,15 @@ predicate isDeadCodeQueryMetadata(Query query, string queryId, string ruleId, st
ruleId = "M0-1-10" and
category = "advisory"
or
+ query =
+ // `Query` instance for the `unusedSplMemberFunction` query
+ DeadCodePackage::unusedSplMemberFunctionQuery() and
+ queryId =
+ // `@id` for the `unusedSplMemberFunction` query
+ "cpp/autosar/unused-spl-member-function" and
+ ruleId = "M0-1-10" and
+ category = "advisory"
+ or
query =
// `Query` instance for the `infeasiblePath` query
DeadCodePackage::infeasiblePathQuery() and
@@ -224,6 +234,13 @@ module DeadCodePackage {
TQueryCPP(TDeadCodePackageQuery(TUnusedFunctionQuery()))
}
+ Query unusedSplMemberFunctionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `unusedSplMemberFunction` query
+ TQueryCPP(TDeadCodePackageQuery(TUnusedSplMemberFunctionQuery()))
+ }
+
Query infeasiblePathQuery() {
//autogenerate `Query` type
result =
diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Representation.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Representation.qll
index a423cfd4ff..2f92ea89ec 100644
--- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Representation.qll
+++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Representation.qll
@@ -7,6 +7,7 @@ newtype RepresentationQuery =
TBitFieldsShallBeUsedOnlyWhenInterfacingToHardwareOrConformingToCommunicationProtocolsQuery() or
TAuditPossibleHardwareInterfaceDueToBitFieldUsageInDataTypeDefinitionQuery() or
TObjectAssignedToAnOverlappingObjectQuery() or
+ TDoNotPassAliasedPointerToParamQuery() or
TUnderlyingBitRepresentationsOfFloatingPointValuesUsedQuery() or
TNamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBitQuery() or
TMemsetUsedToAccessObjectRepresentationQuery() or
@@ -41,6 +42,15 @@ predicate isRepresentationQueryMetadata(Query query, string queryId, string rule
ruleId = "M0-2-1" and
category = "required"
or
+ query =
+ // `Query` instance for the `doNotPassAliasedPointerToParam` query
+ RepresentationPackage::doNotPassAliasedPointerToParamQuery() and
+ queryId =
+ // `@id` for the `doNotPassAliasedPointerToParam` query
+ "cpp/autosar/do-not-pass-aliased-pointer-to-param" and
+ ruleId = "M0-2-1" and
+ category = "required"
+ or
query =
// `Query` instance for the `underlyingBitRepresentationsOfFloatingPointValuesUsed` query
RepresentationPackage::underlyingBitRepresentationsOfFloatingPointValuesUsedQuery() and
@@ -109,6 +119,13 @@ module RepresentationPackage {
TQueryCPP(TRepresentationPackageQuery(TObjectAssignedToAnOverlappingObjectQuery()))
}
+ Query doNotPassAliasedPointerToParamQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `doNotPassAliasedPointerToParam` query
+ TQueryCPP(TRepresentationPackageQuery(TDoNotPassAliasedPointerToParamQuery()))
+ }
+
Query underlyingBitRepresentationsOfFloatingPointValuesUsedQuery() {
//autogenerate `Query` type
result =
diff --git a/cpp/common/src/codingstandards/cpp/rules/deadcode/DeadCode.qll b/cpp/common/src/codingstandards/cpp/rules/deadcode/DeadCode.qll
index 4a008dc15a..fb0bd772a2 100644
--- a/cpp/common/src/codingstandards/cpp/rules/deadcode/DeadCode.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/deadcode/DeadCode.qll
@@ -12,10 +12,12 @@
*/
import cpp
+import codingstandards.cpp.alertreporting.HoldsForAllCopies
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.deadcode.UselessAssignments
import codingstandards.cpp.deadcode.UnreachableCode
+import codingstandards.cpp.deadcode.UnusedVariables
abstract class DeadCodeSharedQuery extends Query { }
@@ -30,15 +32,12 @@ predicate isDeadOrUnreachableStmt(Stmt s) {
s.getBasicBlock() = any(UnreachableBasicBlock ubb).getABasicBlock()
}
-/**
- * Holds if the `Stmt` `s` is dead, i.e. could be executed, but its removal would not meaningfully
- * affect the program.
- */
predicate isDeadStmt(Stmt s) {
// A `DeclStmt` is dead code if:
// - All the declarations are variable declarations
// - None of those variables are ever accessed in non-dead code
// - The initializers for each of the variables are pure
+ // - It isn't constexpr and used to declare an array size
exists(DeclStmt ds |
ds = s and
// Use forex so that we don't flag "fake" generated `DeclStmt`s (e.g. those generated by the
@@ -50,7 +49,8 @@ predicate isDeadStmt(Stmt s) {
not exists(VariableAccess va |
va.getTarget() = v and
not isDeadOrUnreachableStmt(va.getEnclosingStmt())
- )
+ ) and
+ not countUsesInLocalArraySize(v) > 0
)
)
)
@@ -105,17 +105,33 @@ predicate isDeadStmt(Stmt s) {
exists(TryStmt ts | s = ts and isDeadStmt(ts.getStmt()))
}
-query predicate problems(Stmt s, string message) {
- not isExcluded(s, getQuery()) and
+/**
+ * Holds if the `Stmt` `s` is dead, i.e. could be executed, but its removal would not meaningfully
+ * affect the program.
+ */
+class DeadStmtInstance extends Stmt {
+ DeadStmtInstance() {
+ isDeadStmt(this) and
+ // Exclude compiler generated statements
+ not this.isCompilerGenerated() and
+ // Exclude code fully generated by macros, because the code may be "live" in other expansions
+ isNotWithinMacroExpansion(this) and
+ // MISRA defines dead code as an "_executed_ statement whose removal would not affect the program
+ // output". We therefore exclude unreachable statements as they are, by definition, not executed.
+ not this.getBasicBlock() = any(UnreachableBasicBlock ubb).getABasicBlock()
+ }
+}
+
+class DeadStmt = HoldsForAllCopies::LogicalResultElement;
+
+query predicate problems(DeadStmt s, string message) {
+ not isExcluded(s.getAnElementInstance(), getQuery()) and
message = "This statement is dead code." and
- isDeadStmt(s) and
// Report only the highest level dead statement, to avoid over reporting
- not isDeadStmt(s.getParentStmt()) and
- // MISRA defines dead code as an "_executed_ statement whose removal would not affect the program
- // output". We therefore exclude unreachable statements as they are, by definition, not executed.
- not s.getBasicBlock() = any(UnreachableBasicBlock ubb).getABasicBlock() and
- // Exclude code fully generated by macros, because the code may be "live" in other expansions
- not s.isInMacroExpansion() and
- // Exclude compiler generated statements
- not s.isCompilerGenerated()
+ not exists(DeadStmt parent |
+ // All instances must share a dead statement parent for us to report the parent instead
+ forall(Stmt instance | instance = s.getAnElementInstance() |
+ parent.getAnElementInstance() = instance.getParentStmt()
+ )
+ )
}
diff --git a/cpp/common/src/codingstandards/cpp/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.qll b/cpp/common/src/codingstandards/cpp/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.qll
new file mode 100644
index 0000000000..bea0235881
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.qll
@@ -0,0 +1,193 @@
+/**
+ * Provides a library which includes a `problems` predicate for reporting....
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Pointers
+import codingstandards.cpp.Variable
+import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.pointsto.PointsTo
+import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
+
+/**
+ * A function that has a parameter with a restrict-qualified pointer type.
+ */
+class FunctionWithRestrictParameters extends Function {
+ Parameter restrictPtrParam;
+
+ FunctionWithRestrictParameters() {
+ restrictPtrParam.getUnspecifiedType() instanceof PointerOrArrayType and
+ (
+ restrictPtrParam.getType().hasSpecifier(["restrict"]) and
+ restrictPtrParam = this.getAParameter()
+ or
+ this.hasGlobalName(["strcpy", "strncpy", "strcat", "strncat", "memcpy"]) and
+ restrictPtrParam = this.getParameter([0, 1])
+ or
+ this.hasGlobalName(["strcpy_s", "strncpy_s", "strcat_s", "strncat_s", "memcpy_s"]) and
+ restrictPtrParam = this.getParameter([0, 2])
+ or
+ this.hasGlobalName(["strtok_s"]) and
+ restrictPtrParam = this.getAParameter()
+ or
+ this.hasGlobalName(["printf", "printf_s", "scanf", "scanf_s"]) and
+ restrictPtrParam = this.getParameter(0)
+ or
+ this.hasGlobalName(["sprintf", "sprintf_s", "snprintf", "snprintf_s"]) and
+ restrictPtrParam = this.getParameter(3)
+ )
+ }
+
+ Parameter getARestrictPtrParam() { result = restrictPtrParam }
+}
+
+/**
+ * A call to a function that has a parameter with a restrict-qualified pointer type.
+ */
+class CallToFunctionWithRestrictParameters extends FunctionCall {
+ CallToFunctionWithRestrictParameters() {
+ this.getTarget() instanceof FunctionWithRestrictParameters
+ }
+
+ Expr getARestrictPtrArg() {
+ result =
+ this.getArgument(this.getTarget()
+ .(FunctionWithRestrictParameters)
+ .getARestrictPtrParam()
+ .getIndex())
+ }
+
+ Expr getAPtrArg(int index) {
+ result = this.getArgument(index) and
+ pointerValue(result)
+ }
+
+ Expr getAPossibleSizeArg() {
+ exists(Parameter param |
+ param = this.getTarget().(FunctionWithRestrictParameters).getAParameter() and
+ param.getUnderlyingType() instanceof IntegralType and
+ // exclude __builtin_object_size
+ not result.(FunctionCall).getTarget() instanceof BuiltInFunction and
+ result = this.getArgument(param.getIndex())
+ )
+ }
+}
+
+/**
+ * A `PointsToExpr` that is an argument of a pointer-type in a `CallToFunctionWithRestrictParameters`
+ */
+class CallToFunctionWithRestrictParametersArgExpr extends Expr {
+ int paramIndex;
+
+ CallToFunctionWithRestrictParametersArgExpr() {
+ this = any(CallToFunctionWithRestrictParameters call).getAPtrArg(paramIndex)
+ }
+
+ int getParamIndex() { result = paramIndex }
+}
+
+int getStatedValue(Expr e) {
+ // `upperBound(e)` defaults to `exprMaxVal(e)` when `e` isn't analyzable. So to get a meaningful
+ // result in this case we pick the minimum value obtainable from dataflow and range analysis.
+ result =
+ upperBound(e)
+ .minimum(min(Expr source | DataFlow::localExprFlow(source, e) | source.getValue().toInt()))
+}
+
+int getPointerArithmeticOperandStatedValue(CallToFunctionWithRestrictParametersArgExpr expr) {
+ result = getStatedValue(expr.(PointerArithmeticExpr).getOperand())
+ or
+ // edge-case: &(array[index]) expressions
+ result = getStatedValue(expr.(AddressOfExpr).getOperand().(PointerArithmeticExpr).getOperand())
+ or
+ // fall-back if `expr` is not a pointer arithmetic expression
+ not expr instanceof PointerArithmeticExpr and
+ not expr.(AddressOfExpr).getOperand() instanceof PointerArithmeticExpr and
+ result = 0
+}
+
+module PointerValueToRestrictArgConfig implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node source) { pointerValue(source.asExpr()) }
+
+ predicate isSink(DataFlow::Node sink) {
+ exists(CallToFunctionWithRestrictParameters call |
+ sink.asExpr() = call.getAPtrArg(_).getAChild*()
+ )
+ }
+
+ predicate isBarrierIn(DataFlow::Node node) {
+ exists(AddressOfExpr a | node.asExpr() = a.getOperand().getAChild*())
+ }
+}
+
+module PointerValueToRestrictArgFlow = DataFlow::Global;
+
+abstract class DoNotPassAliasedPointerToRestrictQualifiedParamSharedSharedQuery extends Query { }
+
+Query getQuery() {
+ result instanceof DoNotPassAliasedPointerToRestrictQualifiedParamSharedSharedQuery
+}
+
+query predicate problems(
+ CallToFunctionWithRestrictParameters call, string message,
+ CallToFunctionWithRestrictParametersArgExpr arg2, string arg2message,
+ CallToFunctionWithRestrictParametersArgExpr arg1, string arg1message, Expr source1,
+ string sourceMessage2, Expr source2, string lastMessage2
+) {
+ not isExcluded(call, getQuery()) and
+ exists(int argOffset1, int argOffset2, string sourceMessage1 |
+ arg1 = call.getARestrictPtrArg() and
+ arg2 = call.getAPtrArg(_) and
+ // enforce ordering to remove permutations if multiple restrict-qualified args exist
+ (not arg2 = call.getARestrictPtrArg() or arg2.getParamIndex() > arg1.getParamIndex()) and
+ (
+ // check if two pointers address the same object
+ PointerValueToRestrictArgFlow::flow(DataFlow::exprNode(source1),
+ DataFlow::exprNode(arg1.getAChild*())) and
+ (
+ // one pointer value flows to both args
+ PointerValueToRestrictArgFlow::flow(DataFlow::exprNode(source1),
+ DataFlow::exprNode(arg2.getAChild*())) and
+ sourceMessage1 = "$@" and
+ sourceMessage2 = "source" and
+ source1 = source2
+ or
+ // there are two separate values that flow from an AddressOfExpr of the same target
+ getAddressOfExprTargetBase(source1) = getAddressOfExprTargetBase(source2) and
+ PointerValueToRestrictArgFlow::flow(DataFlow::exprNode(source2),
+ DataFlow::exprNode(arg2.getAChild*())) and
+ sourceMessage1 = "a pair of address-of expressions ($@, $@)" and
+ sourceMessage2 = "addressof1" and
+ not source1 = source2
+ )
+ ) and
+ // get the offset of the pointer arithmetic operand (or '0' if there is none)
+ argOffset1 = getPointerArithmeticOperandStatedValue(arg1) and
+ argOffset2 = getPointerArithmeticOperandStatedValue(arg2) and
+ (
+ // case 1: the pointer args are the same.
+ // (definite aliasing)
+ argOffset1 = argOffset2
+ or
+ // case 2: the pointer args are different, a size arg exists,
+ // and the size arg is greater than the difference between the offsets.
+ // (potential aliasing)
+ exists(Expr sizeArg |
+ sizeArg = call.getAPossibleSizeArg() and
+ getStatedValue(sizeArg) > (argOffset1 - argOffset2).abs()
+ )
+ or
+ // case 3: the pointer args are different, and a size arg does not exist
+ // (potential aliasing)
+ not exists(call.getAPossibleSizeArg())
+ ) and
+ lastMessage2 = "addressof2" and
+ arg2message = "aliased pointer" and
+ arg1message = "restrict-qualified parameter" and
+ message =
+ "Call to '" + call.getTarget().getName() +
+ "' passes an $@ to a $@ (pointer value derived from " + sourceMessage1 + "."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.qll b/cpp/common/src/codingstandards/cpp/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.qll
index 2b910612cb..bb54a31df6 100644
--- a/cpp/common/src/codingstandards/cpp/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.qll
@@ -5,20 +5,30 @@
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Noreturn
abstract class FunctionNoReturnAttributeConditionSharedQuery extends Query { }
Query getQuery() { result instanceof FunctionNoReturnAttributeConditionSharedQuery }
+/**
+ * `noreturn` functions are declared differently in c/c++. Attempt to match
+ * the description to the file; low risk if it chooses incorrectly.
+ */
+string describeNoreturn(Function f) {
+ if f.getFile().getExtension() = ["c", "C", "h", "H"]
+ then result = "_Noreturn"
+ else result = "[[noreturn]]"
+}
+
/**
* This checks that the return statement is reachable from the function entry point
*/
-query predicate problems(Function f, string message) {
+query predicate problems(NoreturnFunction f, string message) {
not isExcluded(f, getQuery()) and
- f.getAnAttribute().getName() = "noreturn" and
- exists(ReturnStmt s |
- f = s.getEnclosingFunction() and
- s.getBasicBlock().isReachable()
- ) and
- message = "The function " + f.getName() + " declared with attribute [[noreturn]] returns a value."
+ mayReturn(f) and
+ not f.isCompilerGenerated() and
+ message =
+ "The function " + f.getName() + " declared with attribute " + describeNoreturn(f) +
+ " returns a value."
}
diff --git a/cpp/common/src/codingstandards/cpp/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.qll b/cpp/common/src/codingstandards/cpp/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.qll
new file mode 100644
index 0000000000..3f6ce2786a
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.qll
@@ -0,0 +1,53 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The use of non-prototype format parameter type declarators is an obsolescent
+ * language feature.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Identifiers
+
+abstract class FunctionTypesNotInPrototypeFormSharedSharedQuery extends Query { }
+
+/**
+ * `Parameter`s without names
+ */
+class UnnamedParameter extends Parameter {
+ UnnamedParameter() { not this.isNamed() }
+}
+
+/*
+ * This is a copy of the private `hasZeroParamDecl` predicate from the standard set of
+ * queries as of the `codeql-cli/2.11.2` tag in `github/codeql`.
+ */
+
+predicate hasZeroParamDecl(Function f) {
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ not fde.isImplicit() and
+ not fde.hasVoidParamList() and
+ fde.getNumberOfParameters() = 0 and
+ not fde.isDefinition()
+ )
+}
+
+Query getQuery() { result instanceof FunctionTypesNotInPrototypeFormSharedSharedQuery }
+
+query predicate problems(Function f, string msg) {
+ not isExcluded(f, getQuery()) and
+ f instanceof InterestingIdentifiers and
+ (
+ f.getAParameter() instanceof UnnamedParameter and
+ msg = "Function " + f + " declares parameter that is unnamed."
+ or
+ hasZeroParamDecl(f) and
+ msg = "Function " + f + " does not specify void for no parameters present."
+ or
+ //parameters declared in declaration list (not in function signature)
+ //have no prototype
+ not f.isPrototyped() and
+ not hasZeroParamDecl(f) and
+ msg = "Function " + f + " declares parameter in unsupported declaration list."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.qll b/cpp/common/src/codingstandards/cpp/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.qll
index b3cfe203ac..ffb08283cd 100644
--- a/cpp/common/src/codingstandards/cpp/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.qll
@@ -38,6 +38,8 @@ query predicate problems(
not c.isCompilerGenerated() and
// Not a defaulted constructor
not c.isDefaulted() and
+ // Not a deleted constructor
+ not c.isDeleted() and
declaringType_string = declaringType.getSimpleName() and
baseClass_string = baseClass.getSimpleName() and
message =
diff --git a/cpp/common/src/codingstandards/cpp/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.qll b/cpp/common/src/codingstandards/cpp/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.qll
new file mode 100644
index 0000000000..90f28e6cc8
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.qll
@@ -0,0 +1,27 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Declaring an identifier with internal linkage without the static storage class
+ * specifier is an obselescent feature.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class MissingStaticSpecifierObjectRedeclarationSharedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof MissingStaticSpecifierObjectRedeclarationSharedSharedQuery }
+
+query predicate problems(
+ VariableDeclarationEntry redeclaration, string message, VariableDeclarationEntry de,
+ string deString
+) {
+ not isExcluded(redeclaration, getQuery()) and
+ //following implies de != redeclaration
+ de.hasSpecifier("static") and
+ not redeclaration.hasSpecifier("static") and
+ de.getDeclaration().isTopLevel() and
+ redeclaration.getDeclaration() = de.getDeclaration() and
+ message = "The redeclaration of $@ with internal linkage misses the static specifier." and
+ deString = de.getName()
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/notdistinctidentifier/NotDistinctIdentifier.qll b/cpp/common/src/codingstandards/cpp/rules/notdistinctidentifier/NotDistinctIdentifier.qll
index 093b804e0f..102c53428b 100644
--- a/cpp/common/src/codingstandards/cpp/rules/notdistinctidentifier/NotDistinctIdentifier.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/notdistinctidentifier/NotDistinctIdentifier.qll
@@ -12,6 +12,16 @@ abstract class NotDistinctIdentifierSharedQuery extends Query { }
Query getQuery() { result instanceof NotDistinctIdentifierSharedQuery }
+bindingset[d, d2]
+pragma[inline_late]
+private predicate after(ExternalIdentifiers d, ExternalIdentifiers d2) {
+ exists(int dStartLine, int d2StartLine |
+ d.getLocation().hasLocationInfo(_, dStartLine, _, _, _) and
+ d2.getLocation().hasLocationInfo(_, d2StartLine, _, _, _) and
+ dStartLine >= d2StartLine
+ )
+}
+
query predicate problems(
ExternalIdentifiers d, string message, ExternalIdentifiers d2, string nameplaceholder
) {
@@ -20,10 +30,10 @@ query predicate problems(
d.getName().length() >= 31 and
d2.getName().length() >= 31 and
not d = d2 and
- d.getLocation().getStartLine() >= d2.getLocation().getStartLine() and
d.getSignificantName() = d2.getSignificantName() and
not d.getName() = d2.getName() and
nameplaceholder = d2.getName() and
+ after(d, d2) and
message =
"External identifer " + d.getName() +
" is nondistinct in characters at or over 31 limit, compared to $@"
diff --git a/cpp/common/src/codingstandards/cpp/rules/unnecessaryexposedidentifierdeclarationshared/UnnecessaryExposedIdentifierDeclarationShared.qll b/cpp/common/src/codingstandards/cpp/rules/unnecessaryexposedidentifierdeclarationshared/UnnecessaryExposedIdentifierDeclarationShared.qll
index a18ab593bb..695a8740b6 100644
--- a/cpp/common/src/codingstandards/cpp/rules/unnecessaryexposedidentifierdeclarationshared/UnnecessaryExposedIdentifierDeclarationShared.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/unnecessaryexposedidentifierdeclarationshared/UnnecessaryExposedIdentifierDeclarationShared.qll
@@ -120,7 +120,10 @@ private predicate isTypeUse(Type t1, Type t2) {
}
newtype TDeclarationAccess =
- ObjectAccess(Variable v, VariableAccess va) { va = v.getAnAccess() } or
+ ObjectAccess(Variable v, VariableAccess va) {
+ va = v.getAnAccess() or
+ v.(TemplateVariable).getAnInstantiation().getAnAccess() = va
+ } or
/* Type access can be done in a declaration or an expression (e.g., static member function call) */
TypeAccess(Type t, Element access) {
isTypeUse(access.(Variable).getUnspecifiedType(), t)
@@ -205,9 +208,13 @@ class DeclarationAccess extends TDeclarationAccess {
class CandidateDeclaration extends Declaration {
CandidateDeclaration() {
- this instanceof LocalVariable
+ this instanceof LocalVariable and
+ not this.(LocalVariable).isConstexpr() and
+ not this.isFromTemplateInstantiation(_)
or
- this instanceof GlobalOrNamespaceVariable
+ this instanceof GlobalOrNamespaceVariable and
+ not this.isFromTemplateInstantiation(_) and
+ not this.(GlobalOrNamespaceVariable).isConstexpr()
or
this instanceof Type and
not this instanceof ClassTemplateInstantiation and
@@ -229,7 +236,13 @@ Scope possibleScopesForDeclaration(CandidateDeclaration d) {
result = scope.getStrictParent*()
) and
// Limit the best scope to block statements and namespaces or control structures
- (result instanceof BlockStmt or result instanceof Namespace)
+ (
+ result instanceof BlockStmt and
+ // Template variables cannot be in block scope
+ not d instanceof TemplateVariable
+ or
+ result instanceof Namespace
+ )
}
/* Gets the smallest scope that includes all the declaration accesses of declaration `d`. */
diff --git a/cpp/common/src/codingstandards/cpp/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll b/cpp/common/src/codingstandards/cpp/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll
index 0b9ccb17f1..a9535d9bfc 100644
--- a/cpp/common/src/codingstandards/cpp/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll
@@ -19,6 +19,8 @@ query predicate problems(Cpp14Literal::NumericLiteral nl, string message) {
nl instanceof Cpp14Literal::OctalLiteral and literalKind = "Octal"
or
nl instanceof Cpp14Literal::HexLiteral and literalKind = "Hex"
+ or
+ nl instanceof Cpp14Literal::BinaryLiteral and literalKind = "Binary"
) and
// This either directly has an unsigned integer type, or it is converted to an unsigned integer type
nl.getType().getUnspecifiedType().(IntegralType).isUnsigned() and
diff --git a/cpp/common/src/qlpack.yml b/cpp/common/src/qlpack.yml
index 764c164fcd..eeee5f1fa9 100644
--- a/cpp/common/src/qlpack.yml
+++ b/cpp/common/src/qlpack.yml
@@ -1,7 +1,7 @@
name: codeql/common-cpp-coding-standards
-version: 2.33.0-dev
+version: 2.38.0-dev
license: MIT
dependencies:
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 0.12.9
dataExtensions:
- - ext/*.model.yml
\ No newline at end of file
+- ext/*.model.yml
diff --git a/cpp/common/test/codeql-pack.lock.yml b/cpp/common/test/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/cpp/common/test/codeql-pack.lock.yml
+++ b/cpp/common/test/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/cpp/common/test/includes/custom-library/gtest/gtest-internal.h b/cpp/common/test/includes/custom-library/gtest/gtest-internal.h
new file mode 100644
index 0000000000..31d47b714f
--- /dev/null
+++ b/cpp/common/test/includes/custom-library/gtest/gtest-internal.h
@@ -0,0 +1,29 @@
+#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+
+#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
+ test_suite_name##_##test_name##_Test
+
+#define GTEST_TEST_(test_suite_name, test_name, parent_class) \
+ class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
+ : public parent_class { \
+ public: \
+ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \
+ ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \
+ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
+ (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \
+ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
+ const GTEST_TEST_CLASS_NAME_(test_suite_name, \
+ test_name) &) = delete; /* NOLINT */ \
+ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
+ (GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &&) noexcept = delete; \
+ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
+ GTEST_TEST_CLASS_NAME_(test_suite_name, \
+ test_name) &&) noexcept = delete; /* NOLINT */ \
+ \
+ private: \
+ void TestBody() override; \
+ }; \
+ void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() \
+
+#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
diff --git a/cpp/common/test/includes/custom-library/gtest/gtest.h b/cpp/common/test/includes/custom-library/gtest/gtest.h
new file mode 100644
index 0000000000..65fce9fc5a
--- /dev/null
+++ b/cpp/common/test/includes/custom-library/gtest/gtest.h
@@ -0,0 +1,28 @@
+#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_H_
+#define GOOGLETEST_INCLUDE_GTEST_GTEST_H_
+
+#include "gtest/gtest-internal.h"
+
+namespace testing {
+
+class Test
+{
+ public:
+ virtual ~Test();
+ protected:
+ // Creates a Test object.
+ Test();
+ private:
+ virtual void TestBody() = 0;
+ Test(const Test&) = delete;
+ Test& operator=(const Test&) = delete;
+};
+
+#define GTEST_TEST(test_suite_name, test_name) \
+ GTEST_TEST_(test_suite_name, test_name, ::testing::Test)
+
+#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)
+
+} // namespace testing
+
+#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_H_
diff --git a/cpp/common/test/qlpack.yml b/cpp/common/test/qlpack.yml
index 3ce9a6da2a..8c37adba8d 100644
--- a/cpp/common/test/qlpack.yml
+++ b/cpp/common/test/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/common-cpp-coding-standards-tests
-version: 2.33.0-dev
+version: 2.38.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/cpp/common/test/rules/accessofundefinedmemberthroughnullpointer/AccessOfUndefinedMemberThroughNullPointer.expected b/cpp/common/test/rules/accessofundefinedmemberthroughnullpointer/AccessOfUndefinedMemberThroughNullPointer.expected
index a4e40cc6cb..7a43b3757e 100644
--- a/cpp/common/test/rules/accessofundefinedmemberthroughnullpointer/AccessOfUndefinedMemberThroughNullPointer.expected
+++ b/cpp/common/test/rules/accessofundefinedmemberthroughnullpointer/AccessOfUndefinedMemberThroughNullPointer.expected
@@ -2,8 +2,8 @@ problems
| test.cpp:10:3:10:13 | call to expression | test.cpp:8:22:8:28 | 0 | test.cpp:10:9:10:10 | l2 | A null pointer-to-member value from $@ is passed as the second operand to a pointer-to-member expression. | test.cpp:8:22:8:28 | test.cpp:8:22:8:28 | initialization |
| test.cpp:11:8:11:9 | l3 | test.cpp:9:17:9:23 | 0 | test.cpp:11:8:11:9 | l3 | A null pointer-to-member value from $@ is passed as the second operand to a pointer-to-member expression. | test.cpp:9:17:9:23 | test.cpp:9:17:9:23 | initialization |
edges
-| test.cpp:8:22:8:28 | 0 | test.cpp:10:9:10:10 | l2 |
-| test.cpp:9:17:9:23 | 0 | test.cpp:11:8:11:9 | l3 |
+| test.cpp:8:22:8:28 | 0 | test.cpp:10:9:10:10 | l2 | provenance | |
+| test.cpp:9:17:9:23 | 0 | test.cpp:11:8:11:9 | l3 | provenance | |
nodes
| test.cpp:8:22:8:28 | 0 | semmle.label | 0 |
| test.cpp:9:17:9:23 | 0 | semmle.label | 0 |
diff --git a/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected b/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
index b02aa464bb..2caa0d197c 100644
--- a/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
+++ b/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
@@ -3,11 +3,11 @@ problems
| test.cpp:67:5:67:9 | conv4 | test.cpp:64:11:64:20 | call to localeconv | test.cpp:67:5:67:9 | conv4 | The object returned by the function localeconv should not be modified. |
| test.cpp:76:5:76:8 | conv | test.cpp:72:25:72:34 | call to localeconv | test.cpp:76:5:76:8 | conv | The object returned by the function localeconv should not be modified. |
edges
-| test.cpp:8:18:8:22 | c_str | test.cpp:11:8:11:12 | c_str |
-| test.cpp:18:16:18:21 | call to getenv | test.cpp:24:9:24:12 | env1 |
-| test.cpp:24:9:24:12 | env1 | test.cpp:8:18:8:22 | c_str |
-| test.cpp:64:11:64:20 | call to localeconv | test.cpp:67:5:67:9 | conv4 |
-| test.cpp:72:25:72:34 | call to localeconv | test.cpp:76:5:76:8 | conv |
+| test.cpp:8:18:8:22 | c_str | test.cpp:11:8:11:12 | c_str | provenance | |
+| test.cpp:18:16:18:21 | call to getenv | test.cpp:24:9:24:12 | env1 | provenance | |
+| test.cpp:24:9:24:12 | env1 | test.cpp:8:18:8:22 | c_str | provenance | |
+| test.cpp:64:11:64:20 | call to localeconv | test.cpp:67:5:67:9 | conv4 | provenance | |
+| test.cpp:72:25:72:34 | call to localeconv | test.cpp:76:5:76:8 | conv | provenance | |
nodes
| test.cpp:8:18:8:22 | c_str | semmle.label | c_str |
| test.cpp:11:8:11:12 | c_str | semmle.label | c_str |
diff --git a/cpp/common/test/rules/deadcode/DeadCode.expected b/cpp/common/test/rules/deadcode/DeadCode.expected
index 6c111d8a93..1756231343 100644
--- a/cpp/common/test/rules/deadcode/DeadCode.expected
+++ b/cpp/common/test/rules/deadcode/DeadCode.expected
@@ -12,3 +12,10 @@
| test.cpp:72:3:73:3 | try { ... } | This statement is dead code. |
| test.cpp:73:17:74:3 | { ... } | This statement is dead code. |
| test.cpp:79:17:80:3 | { ... } | This statement is dead code. |
+| test.cpp:85:3:85:43 | declaration | This statement is dead code. |
+| test.cpp:87:3:87:30 | declaration | This statement is dead code. |
+| test.cpp:90:3:90:50 | declaration | This statement is dead code. |
+| test.cpp:116:3:116:21 | ExprStmt | This statement is dead code. |
+| test.cpp:117:3:117:27 | ExprStmt | This statement is dead code. |
+| test.cpp:118:7:118:32 | ExprStmt | This statement is dead code. |
+| test.cpp:139:3:139:35 | ExprStmt | This statement is dead code. |
diff --git a/cpp/common/test/rules/deadcode/test.cpp b/cpp/common/test/rules/deadcode/test.cpp
index ba5c59b07c..d40667539d 100644
--- a/cpp/common/test/rules/deadcode/test.cpp
+++ b/cpp/common/test/rules/deadcode/test.cpp
@@ -81,5 +81,61 @@ int test_dead_code(int x) {
static_assert(1); // COMPLIANT
- return live5 + live6; // COMPLIANT
+ constexpr int constexpr_array_size{6}; // COMPLIANT
+ int unused_array[constexpr_array_size]{}; // NON_COMPLIANT
+
+ constexpr int unused_int{2}; // NON_COMPLIANT
+
+ constexpr int constexpr_used_array[]{3, 4, 5}; // COMPLIANT
+ constexpr int constexpr_unused_array[]{0, 1, 2}; // NON_COMPLIANT
+
+ return live5 + live6 + constexpr_used_array[1]; // COMPLIANT
+}
+
+class Foo {
+public:
+ void bar() { may_have_side_effects(); }
+};
+
+class Baz {
+public:
+ void bar() {} // No side effects
+};
+
+#define FULL_STMT_NO_SIDE_EFFECTS no_side_effects(1);
+#define PART_STMT_NO_SIDE_EFFECTS no_side_effects(1)
+#define BLOCK_SOME_SIDE_EFFECTS \
+ { \
+ may_have_side_effects(); \
+ no_side_effects(1); \
+ }
+
+template void test_template() {
+ T t;
+ t.bar(); // COMPLIANT
+ no_side_effects(1); // NON_COMPLIANT
+ FULL_STMT_NO_SIDE_EFFECTS // NON_COMPLIANT
+ PART_STMT_NO_SIDE_EFFECTS; // NON_COMPLIANT
+ BLOCK_SOME_SIDE_EFFECTS; // COMPLIANT - cannot determine loc for
+ // no_side_effects(1)
+}
+
+template void test_variant_side_effects() {
+ T t;
+ t.bar(); // COMPLIANT - not dead in at least one instance
+}
+
+template void test_unused_template() {
+ T t;
+ t.bar(); // COMPLIANT
+ no_side_effects(
+ 1); // NON_COMPLIANT[FALSE_NEGATIVE] - unused templates are not extracted
+}
+
+void test() {
+ test_template();
+ test_template();
+ test_variant_side_effects(); // COMPLIANT
+ test_variant_side_effects(); // NON_COMPLIANT - no effect in this
+ // instantiation
}
\ No newline at end of file
diff --git a/cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.expected b/cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.expected
new file mode 100644
index 0000000000..f94246bc63
--- /dev/null
+++ b/cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.expected
@@ -0,0 +1,2 @@
+| test.cpp:6:3:6:13 | call to memcpy | Call to 'memcpy' passes an $@ to a $@ (pointer value derived from a pair of address-of expressions ($@, $@). | test.cpp:6:22:6:26 | & ... | aliased pointer | test.cpp:6:15:6:19 | & ... | restrict-qualified parameter | test.cpp:6:15:6:19 | & ... | addressof1 | test.cpp:6:22:6:26 | & ... | addressof2 |
+| test.cpp:8:3:8:13 | call to memcpy | Call to 'memcpy' passes an $@ to a $@ (pointer value derived from a pair of address-of expressions ($@, $@). | test.cpp:8:22:8:26 | & ... | aliased pointer | test.cpp:8:15:8:19 | & ... | restrict-qualified parameter | test.cpp:8:15:8:19 | & ... | addressof1 | test.cpp:8:22:8:26 | & ... | addressof2 |
diff --git a/cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.ql b/cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.ql
new file mode 100644
index 0000000000..dc3a521edf
--- /dev/null
+++ b/cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/DoNotPassAliasedPointerToRestrictQualifiedParamShared.ql
@@ -0,0 +1,6 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.donotpassaliasedpointertorestrictqualifiedparamshared.DoNotPassAliasedPointerToRestrictQualifiedParamShared
+
+class TestFileQuery extends DoNotPassAliasedPointerToRestrictQualifiedParamSharedSharedQuery,
+ TestQuery
+{ }
diff --git a/cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/test.cpp b/cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/test.cpp
new file mode 100644
index 0000000000..42a35d0e92
--- /dev/null
+++ b/cpp/common/test/rules/donotpassaliasedpointertorestrictqualifiedparamshared/test.cpp
@@ -0,0 +1,10 @@
+#include
+
+int a[20];
+
+void undefined_behaviour_fn_119(void) {
+ std::memcpy(&a[0], &a[1], 10u * sizeof(a[0])); // NON_COMPLIANT
+ std::memmove(&a[0], &a[1], 10u * sizeof(a[0])); // COMPLIANT
+ std::memcpy(&a[1], &a[0], 10u * sizeof(a[0])); // NON_COMPLIANT
+ std::memmove(&a[1], &a[0], 10u * sizeof(a[0])); // COMPLIANT
+}
\ No newline at end of file
diff --git a/cpp/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected b/cpp/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected
index 537228a000..dcbc6d05bc 100644
--- a/cpp/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected
+++ b/cpp/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected
@@ -4,14 +4,14 @@ problems
| test.cpp:13:10:13:11 | p4 | test.cpp:5:14:5:15 | l2 | test.cpp:13:10:13:11 | p4 | Subtraction between left operand pointing to array $@ and other operand pointing to array $@. | test.cpp:3:7:3:8 | l2 | l2 | test.cpp:2:7:2:8 | l1 | l1 |
| test.cpp:13:15:13:16 | l1 | test.cpp:13:15:13:16 | l1 | test.cpp:13:15:13:16 | l1 | Subtraction between right operand pointing to array $@ and other operand pointing to array $@. | test.cpp:2:7:2:8 | l1 | l1 | test.cpp:3:7:3:8 | l2 | l2 |
edges
-| test.cpp:4:14:4:15 | l1 | test.cpp:4:14:4:18 | access to array |
-| test.cpp:4:14:4:18 | access to array | test.cpp:10:10:10:11 | p1 |
-| test.cpp:4:14:4:18 | access to array | test.cpp:12:10:12:11 | p1 |
-| test.cpp:5:14:5:15 | l2 | test.cpp:5:14:5:19 | access to array |
-| test.cpp:5:14:5:19 | access to array | test.cpp:11:10:11:11 | p2 |
-| test.cpp:5:14:5:19 | access to array | test.cpp:12:15:12:16 | p2 |
-| test.cpp:5:14:5:19 | access to array | test.cpp:13:10:13:11 | p4 |
-| test.cpp:5:14:5:19 | access to array | test.cpp:14:10:14:11 | p4 |
+| test.cpp:4:14:4:15 | l1 | test.cpp:4:14:4:18 | access to array | provenance | |
+| test.cpp:4:14:4:18 | access to array | test.cpp:10:10:10:11 | p1 | provenance | |
+| test.cpp:4:14:4:18 | access to array | test.cpp:12:10:12:11 | p1 | provenance | |
+| test.cpp:5:14:5:15 | l2 | test.cpp:5:14:5:19 | access to array | provenance | |
+| test.cpp:5:14:5:19 | access to array | test.cpp:11:10:11:11 | p2 | provenance | |
+| test.cpp:5:14:5:19 | access to array | test.cpp:12:15:12:16 | p2 | provenance | |
+| test.cpp:5:14:5:19 | access to array | test.cpp:13:10:13:11 | p4 | provenance | |
+| test.cpp:5:14:5:19 | access to array | test.cpp:14:10:14:11 | p4 | provenance | |
nodes
| test.cpp:4:14:4:15 | l1 | semmle.label | l1 |
| test.cpp:4:14:4:18 | access to array | semmle.label | access to array |
diff --git a/cpp/common/test/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.expected b/cpp/common/test/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.expected
index 22ddfd123a..f02c9a5712 100644
--- a/cpp/common/test/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.expected
+++ b/cpp/common/test/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.expected
@@ -10,19 +10,19 @@ problems
| test.cpp:25:7:25:14 | ... >= ... | test.cpp:7:14:7:15 | l1 | test.cpp:25:7:25:8 | p1 | Compare operation >= comparing left operand pointing to array $@ and other operand pointing to array $@. | test.cpp:2:7:2:8 | l1 | l1 | test.cpp:4:7:4:8 | l3 | l3 |
| test.cpp:25:7:25:14 | ... >= ... | test.cpp:25:13:25:14 | l3 | test.cpp:25:13:25:14 | l3 | Compare operation >= comparing right operand pointing to array $@ and other operand pointing to array $@. | test.cpp:4:7:4:8 | l3 | l3 | test.cpp:2:7:2:8 | l1 | l1 |
edges
-| test.cpp:6:13:6:14 | l1 | test.cpp:13:12:13:13 | p0 |
-| test.cpp:7:14:7:15 | l1 | test.cpp:7:14:7:18 | access to array |
-| test.cpp:7:14:7:18 | access to array | test.cpp:11:7:11:8 | p1 |
-| test.cpp:7:14:7:18 | access to array | test.cpp:13:7:13:8 | p1 |
-| test.cpp:7:14:7:18 | access to array | test.cpp:15:13:15:14 | p1 |
-| test.cpp:7:14:7:18 | access to array | test.cpp:17:7:17:8 | p1 |
-| test.cpp:7:14:7:18 | access to array | test.cpp:23:13:23:14 | p1 |
-| test.cpp:7:14:7:18 | access to array | test.cpp:25:7:25:8 | p1 |
-| test.cpp:8:14:8:15 | l1 | test.cpp:8:14:8:18 | access to array |
-| test.cpp:8:14:8:18 | access to array | test.cpp:11:12:11:13 | p2 |
-| test.cpp:8:14:8:18 | access to array | test.cpp:21:7:21:8 | p2 |
-| test.cpp:9:14:9:15 | l2 | test.cpp:9:14:9:18 | access to array |
-| test.cpp:9:14:9:18 | access to array | test.cpp:21:12:21:13 | p3 |
+| test.cpp:6:13:6:14 | l1 | test.cpp:13:12:13:13 | p0 | provenance | |
+| test.cpp:7:14:7:15 | l1 | test.cpp:7:14:7:18 | access to array | provenance | |
+| test.cpp:7:14:7:18 | access to array | test.cpp:11:7:11:8 | p1 | provenance | |
+| test.cpp:7:14:7:18 | access to array | test.cpp:13:7:13:8 | p1 | provenance | |
+| test.cpp:7:14:7:18 | access to array | test.cpp:15:13:15:14 | p1 | provenance | |
+| test.cpp:7:14:7:18 | access to array | test.cpp:17:7:17:8 | p1 | provenance | |
+| test.cpp:7:14:7:18 | access to array | test.cpp:23:13:23:14 | p1 | provenance | |
+| test.cpp:7:14:7:18 | access to array | test.cpp:25:7:25:8 | p1 | provenance | |
+| test.cpp:8:14:8:15 | l1 | test.cpp:8:14:8:18 | access to array | provenance | |
+| test.cpp:8:14:8:18 | access to array | test.cpp:11:12:11:13 | p2 | provenance | |
+| test.cpp:8:14:8:18 | access to array | test.cpp:21:7:21:8 | p2 | provenance | |
+| test.cpp:9:14:9:15 | l2 | test.cpp:9:14:9:18 | access to array | provenance | |
+| test.cpp:9:14:9:18 | access to array | test.cpp:21:12:21:13 | p3 | provenance | |
nodes
| test.cpp:6:13:6:14 | l1 | semmle.label | l1 |
| test.cpp:7:14:7:15 | l1 | semmle.label | l1 |
diff --git a/cpp/common/test/rules/initializeallvirtualbaseclasses/test.cpp b/cpp/common/test/rules/initializeallvirtualbaseclasses/test.cpp
index 7721da8b01..8e6b318b19 100644
--- a/cpp/common/test/rules/initializeallvirtualbaseclasses/test.cpp
+++ b/cpp/common/test/rules/initializeallvirtualbaseclasses/test.cpp
@@ -61,4 +61,13 @@ class Derived6 : public Base2 {
private:
Base2 b;
+};
+
+class Base3 {};
+
+class Derived7 final : public Base3 {
+public:
+ Derived7() = delete; // COMPLIANT
+ Derived7(const Derived7 &) = delete; // COMPLIANT
+ Derived7(Derived7 &&) = delete; // COMPLIANT
};
\ No newline at end of file
diff --git a/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected.gcc b/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected.gcc
index f09fafd410..87bf6e1b01 100644
--- a/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected.gcc
+++ b/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected.gcc
@@ -1 +1 @@
-| test.cpp:9:32:9:51 | offsetof(__typ,__id) | Use of banned macro offsetof. |
+| test.cpp:9:32:9:51 | offsetof(TYPE,MEMBER) | Use of banned macro offsetof. |
diff --git a/cpp/common/test/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.expected b/cpp/common/test/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.expected
index 3d00ff0d6a..0b23493cfa 100644
--- a/cpp/common/test/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.expected
+++ b/cpp/common/test/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.expected
@@ -6,21 +6,21 @@ problems
| test.cpp:12:28:12:29 | v2 | test.cpp:10:8:10:17 | new | test.cpp:12:28:12:29 | v2 | Raw pointer flows to initialize multiple unrelated smart pointers. |
| test.cpp:17:27:17:28 | v1 | test.cpp:16:13:16:22 | new | test.cpp:17:27:17:28 | v1 | Raw pointer flows to initialize multiple unrelated smart pointers. |
edges
-| test.cpp:3:14:3:15 | v1 | test.cpp:5:27:5:28 | v1 |
-| test.cpp:3:14:3:15 | v1 | test.cpp:5:27:5:28 | v1 |
-| test.cpp:3:14:3:15 | v1 | test.cpp:7:28:7:29 | v2 |
-| test.cpp:4:13:4:14 | v1 | test.cpp:7:28:7:29 | v2 |
-| test.cpp:5:27:5:28 | v1 | test.cpp:5:27:5:29 | call to shared_ptr |
-| test.cpp:5:27:5:29 | call to shared_ptr | test.cpp:6:28:6:29 | p1 |
-| test.cpp:5:27:5:29 | call to shared_ptr | test.cpp:6:28:6:29 | p1 |
-| test.cpp:6:28:6:29 | p1 | test.cpp:6:31:6:33 | call to get |
-| test.cpp:6:28:6:29 | p1 | test.cpp:6:31:6:33 | call to get |
-| test.cpp:8:8:8:14 | 0 | test.cpp:9:28:9:29 | v2 |
-| test.cpp:10:8:10:17 | new | test.cpp:11:28:11:29 | v2 |
-| test.cpp:10:8:10:17 | new | test.cpp:12:28:12:29 | v2 |
-| test.cpp:16:13:16:22 | new | test.cpp:17:27:17:28 | v1 |
-| test.cpp:16:13:16:22 | new | test.cpp:19:6:19:7 | v1 |
-| test.cpp:19:6:19:7 | v1 | test.cpp:3:14:3:15 | v1 |
+| test.cpp:3:14:3:15 | v1 | test.cpp:5:27:5:28 | v1 | provenance | |
+| test.cpp:3:14:3:15 | v1 | test.cpp:5:27:5:28 | v1 | provenance | |
+| test.cpp:3:14:3:15 | v1 | test.cpp:7:28:7:29 | v2 | provenance | |
+| test.cpp:4:13:4:14 | v1 | test.cpp:7:28:7:29 | v2 | provenance | |
+| test.cpp:5:27:5:28 | v1 | test.cpp:5:27:5:29 | call to shared_ptr | provenance | |
+| test.cpp:5:27:5:29 | call to shared_ptr | test.cpp:6:28:6:29 | p1 | provenance | |
+| test.cpp:5:27:5:29 | call to shared_ptr | test.cpp:6:28:6:29 | p1 | provenance | |
+| test.cpp:6:28:6:29 | p1 | test.cpp:6:31:6:33 | call to get | provenance | |
+| test.cpp:6:28:6:29 | p1 | test.cpp:6:31:6:33 | call to get | provenance | |
+| test.cpp:8:8:8:14 | 0 | test.cpp:9:28:9:29 | v2 | provenance | |
+| test.cpp:10:8:10:17 | new | test.cpp:11:28:11:29 | v2 | provenance | |
+| test.cpp:10:8:10:17 | new | test.cpp:12:28:12:29 | v2 | provenance | |
+| test.cpp:16:13:16:22 | new | test.cpp:17:27:17:28 | v1 | provenance | |
+| test.cpp:16:13:16:22 | new | test.cpp:19:6:19:7 | v1 | provenance | |
+| test.cpp:19:6:19:7 | v1 | test.cpp:3:14:3:15 | v1 | provenance | |
nodes
| test.cpp:3:14:3:15 | v1 | semmle.label | v1 |
| test.cpp:4:13:4:14 | v1 | semmle.label | v1 |
diff --git a/cpp/common/test/rules/placementnewinsufficientstorage/PlacementNewInsufficientStorage.expected b/cpp/common/test/rules/placementnewinsufficientstorage/PlacementNewInsufficientStorage.expected
index 3c38e192bc..a4c3bb1df6 100644
--- a/cpp/common/test/rules/placementnewinsufficientstorage/PlacementNewInsufficientStorage.expected
+++ b/cpp/common/test/rules/placementnewinsufficientstorage/PlacementNewInsufficientStorage.expected
@@ -7,18 +7,18 @@ problems
| test.cpp:100:16:100:39 | new | test.cpp:65:36:65:38 | call to pop | test.cpp:100:21:100:28 | badAlloc | Placement new expression is used with an insufficiently large memory allocation from $@. | test.cpp:65:36:65:38 | call to pop | call to pop |
| test.cpp:113:7:113:32 | new[] | test.cpp:113:14:113:21 | badAlloc | test.cpp:113:14:113:21 | badAlloc | Placement new expression is used with an insufficiently large memory allocation from $@. | test.cpp:113:14:113:21 | badAlloc | badAlloc |
edges
-| test.cpp:18:36:18:49 | call to operator new | test.cpp:19:21:19:44 | correctlyAllocatedMemory |
-| test.cpp:24:37:24:50 | call to operator new | test.cpp:25:21:25:45 | correctlyAllocatedMemory2 |
-| test.cpp:29:32:29:45 | call to operator new | test.cpp:31:21:31:40 | badlyAllocatedMemory |
-| test.cpp:35:33:35:46 | call to operator new | test.cpp:37:21:37:41 | badlyAllocatedMemory2 |
-| test.cpp:62:16:62:29 | call to operator new | test.cpp:67:12:67:17 | memory |
-| test.cpp:62:16:62:29 | call to operator new | test.cpp:67:12:67:17 | memory |
-| test.cpp:65:36:65:38 | call to pop | test.cpp:67:12:67:17 | memory |
-| test.cpp:65:36:65:38 | call to pop | test.cpp:67:12:67:17 | memory |
-| test.cpp:67:12:67:17 | memory | test.cpp:94:32:94:39 | call to allocate |
-| test.cpp:67:12:67:17 | memory | test.cpp:98:31:98:38 | call to allocate |
-| test.cpp:94:32:94:39 | call to allocate | test.cpp:95:21:95:29 | goodAlloc |
-| test.cpp:98:31:98:38 | call to allocate | test.cpp:100:21:100:28 | badAlloc |
+| test.cpp:18:36:18:49 | call to operator new | test.cpp:19:21:19:44 | correctlyAllocatedMemory | provenance | |
+| test.cpp:24:37:24:50 | call to operator new | test.cpp:25:21:25:45 | correctlyAllocatedMemory2 | provenance | |
+| test.cpp:29:32:29:45 | call to operator new | test.cpp:31:21:31:40 | badlyAllocatedMemory | provenance | |
+| test.cpp:35:33:35:46 | call to operator new | test.cpp:37:21:37:41 | badlyAllocatedMemory2 | provenance | |
+| test.cpp:62:16:62:29 | call to operator new | test.cpp:67:12:67:17 | memory | provenance | |
+| test.cpp:62:16:62:29 | call to operator new | test.cpp:67:12:67:17 | memory | provenance | |
+| test.cpp:65:36:65:38 | call to pop | test.cpp:67:12:67:17 | memory | provenance | |
+| test.cpp:65:36:65:38 | call to pop | test.cpp:67:12:67:17 | memory | provenance | |
+| test.cpp:67:12:67:17 | memory | test.cpp:94:32:94:39 | call to allocate | provenance | |
+| test.cpp:67:12:67:17 | memory | test.cpp:98:31:98:38 | call to allocate | provenance | |
+| test.cpp:94:32:94:39 | call to allocate | test.cpp:95:21:95:29 | goodAlloc | provenance | |
+| test.cpp:98:31:98:38 | call to allocate | test.cpp:100:21:100:28 | badAlloc | provenance | |
nodes
| test.cpp:18:36:18:49 | call to operator new | semmle.label | call to operator new |
| test.cpp:19:21:19:44 | correctlyAllocatedMemory | semmle.label | correctlyAllocatedMemory |
diff --git a/cpp/common/test/rules/throwingoperatornewreturnsnull/ThrowingOperatorNewReturnsNull.expected b/cpp/common/test/rules/throwingoperatornewreturnsnull/ThrowingOperatorNewReturnsNull.expected
index ae8a0d626b..5e047a77da 100644
--- a/cpp/common/test/rules/throwingoperatornewreturnsnull/ThrowingOperatorNewReturnsNull.expected
+++ b/cpp/common/test/rules/throwingoperatornewreturnsnull/ThrowingOperatorNewReturnsNull.expected
@@ -3,8 +3,8 @@ problems
| test.cpp:12:5:12:19 | return ... | test.cpp:12:12:12:18 | 0 | test.cpp:12:12:12:18 | 0 | operator new(size_t) may return null instead of throwing a std::bad_alloc exception. |
| test.cpp:14:5:14:33 | return ... | test.cpp:4:10:4:23 | call to operator new | test.cpp:14:12:14:26 | call to can_return_null | operator new(size_t) may return null instead of throwing a std::bad_alloc exception. |
edges
-| test.cpp:4:10:4:23 | call to operator new | test.cpp:14:12:14:26 | call to can_return_null |
-| test.cpp:8:23:8:23 | 0 | test.cpp:10:12:10:24 | localVariable |
+| test.cpp:4:10:4:23 | call to operator new | test.cpp:14:12:14:26 | call to can_return_null | provenance | |
+| test.cpp:8:23:8:23 | 0 | test.cpp:10:12:10:24 | localVariable | provenance | |
nodes
| test.cpp:4:10:4:23 | call to operator new | semmle.label | call to operator new |
| test.cpp:8:23:8:23 | 0 | semmle.label | 0 |
diff --git a/cpp/common/test/rules/unnecessaryexposedidentifierdeclarationshared/test.cpp b/cpp/common/test/rules/unnecessaryexposedidentifierdeclarationshared/test.cpp
index ae3bb7b887..c4e01b8224 100644
--- a/cpp/common/test/rules/unnecessaryexposedidentifierdeclarationshared/test.cpp
+++ b/cpp/common/test/rules/unnecessaryexposedidentifierdeclarationshared/test.cpp
@@ -136,4 +136,96 @@ void f17() {
ptr = &i;
}
*ptr = 1;
-}
\ No newline at end of file
+}
+
+namespace a_namespace {
+
+constexpr static unsigned int a_constexpr_var{
+ 10U}; // COMPLIANT; used in
+ // a_namespace and
+ // another_namespace_function
+static unsigned int
+ a_namespace_var[a_constexpr_var]{}; // COMPLIANT; used in
+ // a_namespace_function and
+ // another_namespace_function
+
+constexpr static unsigned int a_namespace_function(void) noexcept {
+ unsigned int a_return_value{0U};
+
+ for (auto loop_var : a_namespace_var) { // usage of a_namespace_var
+ a_return_value += loop_var;
+ }
+ return a_return_value;
+}
+
+constexpr static unsigned int another_namespace_function(void) noexcept {
+ unsigned int a_return_value{0U};
+
+ for (unsigned int i{0U}; i < a_constexpr_var;
+ i++) { // usage of a_constexpr_var
+ a_return_value += a_namespace_var[i]; // usage of a_namespace_var
+ }
+ return a_return_value;
+}
+} // namespace a_namespace
+
+namespace parent_namespace {
+namespace child_namespace {
+template class a_class_in_child_namespace {
+public:
+ template constexpr auto &&operator()(To &&val) const noexcept {
+ return static_cast(val);
+ }
+}; // a_class_in_child_namespace end
+
+template
+extern constexpr a_class_in_child_namespace
+ a_class_in_child_namespace_impl{};
+
+} // namespace child_namespace
+
+template
+static constexpr auto const &a_parent_namespace_variable =
+ child_namespace::a_class_in_child_namespace_impl<
+ From>; // COMPLIANT; used in child_namespace2::a_class::bar() and
+ // parent_namespace::another_class::foo()
+
+namespace child_namespace2 {
+class a_class {
+public:
+ int func(...) { return 0; }
+ void foo(int x) { x++; }
+ template constexpr auto bar(F(*func), int b) {
+ foo(func(a_parent_namespace_variable(
+ b))); // usage of a_parent_namespace_variable
+ }
+}; // a_class
+} // namespace child_namespace2
+
+class another_class {
+ int a;
+ int b;
+ void bar(int param) { param++; }
+
+ bool has_value() { return a == b; }
+
+public:
+ template int foo(F(*func), int b) {
+ if (has_value()) {
+ bar(func(a_parent_namespace_variable(
+ b))); // usage of a_parent_namespace_variable
+ }
+ return 0;
+ }
+}; // another_class
+} // namespace parent_namespace
+
+template T a_func(T v) { return v++; }
+
+int main() {
+ parent_namespace::child_namespace2::a_class a_class_obj;
+ a_class_obj.bar(a_func, 10);
+ parent_namespace::another_class another_class_obj;
+ another_class_obj.foo(a_func, 10);
+ return 0;
+}
diff --git a/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.expected b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.expected
index 56dce901dd..3326ede548 100644
--- a/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.expected
+++ b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.expected
@@ -1 +1,18 @@
-| test.cpp:3:3:3:12 | 4294967295 | Hex literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:111:3:111:12 | 2147483648 | Hex literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:116:3:116:20 | 9223372036854775808 | Hex literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:139:3:139:21 | 9223372036854775808 | Hex literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:162:3:162:21 | 9223372036854775808 | Hex literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:185:3:185:22 | 9223372036854775808 | Hex literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:208:3:208:22 | 9223372036854775808 | Hex literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:227:3:227:14 | 2147483648 | Octal literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:232:3:232:25 | 9223372036854775808 | Octal literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:249:3:249:26 | 9223372036854775808 | Octal literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:266:3:266:26 | 9223372036854775808 | Octal literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:283:3:283:27 | 9223372036854775808 | Octal literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:300:3:300:27 | 9223372036854775808 | Octal literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:315:3:315:36 | 2147483648 | Binary literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:322:3:322:68 | 9223372036854775808 | Binary literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:365:3:365:69 | 9223372036854775808 | Binary literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:412:3:412:69 | 9223372036854775808 | Binary literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:457:3:457:70 | 9223372036854775808 | Binary literal is an unsigned integer but does not include a 'U' suffix. |
+| test.cpp:502:3:502:70 | 9223372036854775808 | Binary literal is an unsigned integer but does not include a 'U' suffix. |
diff --git a/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp
index e5b3abfa47..fcbd51b3de 100644
--- a/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp
+++ b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp
@@ -1,5 +1,546 @@
-void test_unsigned_literals_without_suffix() {
- 0xFFFFFFFFU; // COMPLIANT - literal explicitly marked as unsigned
- 0xFFFFFFFF; // NON_COMPLIANT - literal is too large for a signed int, so has
- // type unsigned int
+// Assumed platform in qltest is linux_x86_64, so
+// int, long, long long sizes are assumed to be 32, 64, 64 bits respectively
+
+// The type of an integer constant is determined by "6.4.4.1 Integer constants"
+// in the C11 Standard. The principle is that any decimal integer constant will
+// be signed, unless it has the `U` or `u` suffix. Any hexadecimal integer will
+// depend on whether it is larger than the maximum value of the smallest signed
+// integer value that can hold the value. So the signedness depends on the
+// magnitude of the constant.
+
+void test_decimal_constants() {
+ 0; // COMPLIANT
+ 2147483648; // COMPLIANT - larger than int, but decimal constants never use
+ // unsigned without the suffix, so will be `long`
+ 4294967296; // COMPLIANT - larger than unsigned int, still `long`
+ 9223372036854775807; // COMPLIANT - max long int
+ // 9223372036854775808; Not a valid integer constant, out of signed range
+ 0U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807U; // COMPLIANT - max long int
+ 9223372036854775808U; // COMPLIANT - explicitly unsigned, so can go large than
+ // max long int
+ 0u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807u; // COMPLIANT - max long int
+ 9223372036854775808u; // COMPLIANT - explicitly unsigned, so can go large than
+ // max long int
+
+ // l suffix
+ 0l; // COMPLIANT
+ 2147483648l; // COMPLIANT - within the range of long int
+ 4294967296l; // COMPLIANT - within the range of long int
+ 9223372036854775807l; // COMPLIANT - max long int
+ // 9223372036854775808l; Not a valid integer constant, out of signed range
+ 0lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807lU; // COMPLIANT - max long int
+ 9223372036854775808lU; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long int
+ 0lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807lu; // COMPLIANT - max long int
+ 9223372036854775808lu; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long int
+
+ // L suffix
+ 0L; // COMPLIANT
+ 2147483648L; // COMPLIANT - within the range of long int
+ 4294967296L; // COMPLIANT - within the range of long int
+ 9223372036854775807L; // COMPLIANT - max long int
+ // 9223372036854775808L; Not a valid integer constant, out of signed range
+ 0LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807LU; // COMPLIANT - max long int
+ 9223372036854775808LU; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long int
+ 0Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807Lu; // COMPLIANT - max long int
+ 9223372036854775808Lu; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long int
+
+ // ll suffix
+ 0ll; // COMPLIANT
+ 2147483648ll; // COMPLIANT - within the range of long long int
+ 4294967296ll; // COMPLIANT - within the range of long long int
+ 9223372036854775807ll; // COMPLIANT - max long long int
+ // 9223372036854775808ll; Not a valid integer constant, out of signed range
+ 0llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807llU; // COMPLIANT - max long long int
+ 9223372036854775808llU; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long long int
+ 0llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807llu; // COMPLIANT - max long long int
+ 9223372036854775808llu; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long long int
+
+ // LL suffix
+ 0LL; // COMPLIANT
+ 2147483648LL; // COMPLIANT - within the range of long long int
+ 4294967296LL; // COMPLIANT - within the range of long long int
+ 9223372036854775807LL; // COMPLIANT - max long long int
+ // 9223372036854775808LL; Not a valid integer constant, out of signed range
+ 0LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807LLU; // COMPLIANT - max long long int
+ 9223372036854775808LLU; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long long int
+ 0LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 2147483648LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 4294967296LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 9223372036854775807LLu; // COMPLIANT - max long long int
+ 9223372036854775808LLu; // COMPLIANT - explicitly unsigned, so can go large
+ // than max long long int
+}
+
+void test_hexadecimal_constants() {
+ 0x0; // COMPLIANT - uses signed int
+ 0x7FFFFFFF; // COMPLIANT - max value held by signed int
+ 0x80000000; // NON_COMPLIANT - larger than max signed int, so will be unsigned
+ // int
+ 0x100000000; // COMPLIANT - larger than unsigned int, but smaller than long
+ // int
+ 0x7FFFFFFFFFFFFFFF; // COMPLIANT - max long int
+ 0x8000000000000000; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 0x0U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000u; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000u; // COMPLIANT - unsigned, but uses the suffix correctly
+
+ // Use of the `l` suffix
+ 0x0l; // COMPLIANT - uses signed int
+ 0x7FFFFFFFl; // COMPLIANT - max value held by signed int
+ 0x80000000l; // COMPLIANT - larger than max signed int, but smaller than long
+ // int
+ 0x100000000l; // COMPLIANT - larger than unsigned int, but smaller than long
+ // int
+ 0x7FFFFFFFFFFFFFFFl; // COMPLIANT - max long int
+ 0x8000000000000000l; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 0x0lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFlU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFlU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000lU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFlu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFlu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000lu; // COMPLIANT - unsigned, but uses the suffix correctly
+
+ // Use of the `L` suffix
+ 0x0L; // COMPLIANT - uses signed int
+ 0x7FFFFFFFL; // COMPLIANT - max value held by signed int
+ 0x80000000L; // COMPLIANT - larger than max signed int, but smaller than long
+ // int
+ 0x100000000L; // COMPLIANT - larger than unsigned int, but smaller than long
+ // int
+ 0x7FFFFFFFFFFFFFFFL; // COMPLIANT - max long int
+ 0x8000000000000000L; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 0x0LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000LU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000Lu; // COMPLIANT - unsigned, but uses the suffix correctly
+
+ // Use of the `ll` suffix
+ 0x0ll; // COMPLIANT - uses signed int
+ 0x7FFFFFFFll; // COMPLIANT - max value held by signed int
+ 0x80000000ll; // COMPLIANT - larger than max signed int, but smaller than long
+ // long int
+ 0x100000000ll; // COMPLIANT - larger than unsigned int, but smaller than long
+ // long int
+ 0x7FFFFFFFFFFFFFFFll; // COMPLIANT - max long long int
+ 0x8000000000000000ll; // NON_COMPLIANT - larger than long long int, so will be
+ // unsigned long long int
+ 0x0llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFllU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFllU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000llU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFllu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000llu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFllu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000llu; // COMPLIANT - unsigned, but uses the suffix correctly
+
+ // Use of the `LL` suffix
+ 0x0LL; // COMPLIANT - uses signed int
+ 0x7FFFFFFFLL; // COMPLIANT - max value held by signed int
+ 0x80000000LL; // COMPLIANT - larger than max signed int, but smaller than long
+ // long int
+ 0x100000000LL; // COMPLIANT - larger than unsigned int, but smaller than long
+ // long int
+ 0x7FFFFFFFFFFFFFFFLL; // COMPLIANT - max long long int
+ 0x8000000000000000LL; // NON_COMPLIANT - larger than long long int, so will be
+ // unsigned long long int
+ 0x0LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFLLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFLLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000LLU; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x0LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFLLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x80000000LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x100000000LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x7FFFFFFFFFFFFFFFLLu; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0x8000000000000000LLu; // COMPLIANT - unsigned, but uses the suffix correctly
+}
+
+void test_octal_constants() {
+ 00; // COMPLIANT - uses signed int
+ 017777777777; // COMPLIANT - max value held by signed int
+ 020000000000; // NON_COMPLIANT - larger than max signed int, so will be
+ // unsigned int
+ 040000000000; // COMPLIANT - larger than unsigned int, but smaller than long
+ // int
+ 0777777777777777777777; // COMPLIANT - max long int
+ 01000000000000000000000; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777U; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000U; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+
+ // Use of the `l` suffix
+ 00l; // COMPLIANT - uses signed long
+ 017777777777l; // COMPLIANT - uses signed long
+ 020000000000l; // COMPLIANT - uses signed long
+ 040000000000l; // COMPLIANT - uses signed long
+ 0777777777777777777777l; // COMPLIANT - max long int
+ 01000000000000000000000l; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00Ul; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777Ul; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000Ul; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000Ul; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777Ul; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000Ul; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+
+ // Use of the `L` suffix
+ 00L; // COMPLIANT - uses signed long
+ 017777777777L; // COMPLIANT - uses signed long
+ 020000000000L; // COMPLIANT - uses signed long
+ 040000000000L; // COMPLIANT - uses signed long
+ 0777777777777777777777L; // COMPLIANT - COMPLIANT - uses signed long
+ 01000000000000000000000L; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00UL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777UL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000UL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000UL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777UL; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000UL; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+
+ // Use of the `ll` suffix
+ 00ll; // COMPLIANT - uses signed long long
+ 017777777777ll; // COMPLIANT - uses signed long long
+ 020000000000ll; // COMPLIANT - uses signed long long
+ 040000000000ll; // COMPLIANT - uses signed long long
+ 0777777777777777777777ll; // COMPLIANT - max long int
+ 01000000000000000000000ll; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00Ull; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777Ull; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000Ull; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000Ull; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777Ull; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000Ull; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+
+ // Use of the `LL` suffix
+ 00LL; // COMPLIANT - uses signed long long
+ 017777777777LL; // COMPLIANT - uses signed long long
+ 020000000000LL; // COMPLIANT - uses signed long long
+ 040000000000LL; // COMPLIANT - uses signed long long
+ 0777777777777777777777LL; // COMPLIANT - max long int
+ 01000000000000000000000LL; // NON_COMPLIANT - larger than long int, so will be
+ // unsigned long int
+ 00ULL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 017777777777ULL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 020000000000ULL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 040000000000ULL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0777777777777777777777ULL; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+ 01000000000000000000000ULL; // COMPLIANT - unsigned, but uses the suffix
+ // correctly
+}
+
+void test_binary_constants() {
+ 0b0; // COMPLIANT - uses signed int
+ 0b1111111111111111111111111111111; // COMPLIANT - max value held by signed int
+ 0b10000000000000000000000000000000; // NON_COMPLIANT - larger than max signed
+ // int, so will be unsigned int
+ 0b100000000000000000000000000000000; // COMPLIANT - larger than unsigned int,
+ // but smaller than long int
+ 0b111111111111111111111111111111111111111111111111111111111111111; // COMPLIANT
+ // - max
+ // long int
+ 0b1000000000000000000000000000000000000000000000000000000000000000; // NON_COMPLIANT
+ // -
+ // larger
+ // than
+ // long
+ // int, so
+ // will be
+ // unsigned
+ // long
+ // int
+ 0b0U; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0b1111111111111111111111111111111U; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b10000000000000000000000000000000U; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b100000000000000000000000000000000U; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b111111111111111111111111111111111111111111111111111111111111111U; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+ 0b1000000000000000000000000000000000000000000000000000000000000000U; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+
+ // Use of the `l` suffix
+ 0b0l; // COMPLIANT - uses signed long
+ 0b1111111111111111111111111111111l; // COMPLIANT - uses signed long
+ 0b10000000000000000000000000000000l; // COMPLIANT - uses signed long
+ 0b100000000000000000000000000000000l; // COMPLIANT - uses signed long
+ 0b111111111111111111111111111111111111111111111111111111111111111l; // COMPLIANT
+ // - max
+ // long
+ // int
+ 0b1000000000000000000000000000000000000000000000000000000000000000l; // NON_COMPLIANT
+ // -
+ // larger
+ // than
+ // long
+ // int,
+ // so
+ // will
+ // be
+ // unsigned
+ // long
+ // int
+ 0b0Ul; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0b1111111111111111111111111111111Ul; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b10000000000000000000000000000000Ul; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b100000000000000000000000000000000Ul; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b111111111111111111111111111111111111111111111111111111111111111Ul; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+ 0b1000000000000000000000000000000000000000000000000000000000000000Ul; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+
+ // Use of the `L` suffix
+ 0b0L; // COMPLIANT - uses signed long
+ 0b1111111111111111111111111111111L; // COMPLIANT - uses signed long
+ 0b10000000000000000000000000000000L; // COMPLIANT - uses signed long
+ 0b100000000000000000000000000000000L; // COMPLIANT - uses signed long
+ 0b111111111111111111111111111111111111111111111111111111111111111L; // COMPLIANT
+ // -
+ // COMPLIANT
+ // - uses
+ // signed
+ // long
+ 0b1000000000000000000000000000000000000000000000000000000000000000L; // NON_COMPLIANT
+ // -
+ // larger
+ // than
+ // long
+ // int,
+ // so
+ // will
+ // be
+ // unsigned
+ // long
+ // int
+ 0b0UL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0b1111111111111111111111111111111UL; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b10000000000000000000000000000000UL; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b100000000000000000000000000000000UL; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b111111111111111111111111111111111111111111111111111111111111111UL; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+ 0b1000000000000000000000000000000000000000000000000000000000000000UL; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+
+ // Use of the `ll` suffix
+ 0b0ll; // COMPLIANT - uses signed long long
+ 0b1111111111111111111111111111111ll; // COMPLIANT - uses signed long long
+ 0b10000000000000000000000000000000ll; // COMPLIANT - uses signed long long
+ 0b100000000000000000000000000000000ll; // COMPLIANT - uses signed long long
+ 0b111111111111111111111111111111111111111111111111111111111111111ll; // COMPLIANT
+ // - max
+ // long
+ // int
+ 0b1000000000000000000000000000000000000000000000000000000000000000ll; // NON_COMPLIANT
+ // -
+ // larger
+ // than
+ // long
+ // int,
+ // so
+ // will
+ // be
+ // unsigned
+ // long
+ // int
+ 0b0Ull; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0b1111111111111111111111111111111Ull; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b10000000000000000000000000000000Ull; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b100000000000000000000000000000000Ull; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b111111111111111111111111111111111111111111111111111111111111111Ull; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+ 0b1000000000000000000000000000000000000000000000000000000000000000Ull; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+
+ // Use of the `LL` suffix
+ 00LL; // COMPLIANT - uses signed long long
+ 0b1111111111111111111111111111111LL; // COMPLIANT - uses signed long long
+ 0b10000000000000000000000000000000LL; // COMPLIANT - uses signed long long
+ 0b100000000000000000000000000000000LL; // COMPLIANT - uses signed long long
+ 0b111111111111111111111111111111111111111111111111111111111111111LL; // COMPLIANT
+ // - max
+ // long
+ // int
+ 0b1000000000000000000000000000000000000000000000000000000000000000LL; // NON_COMPLIANT
+ // -
+ // larger
+ // than
+ // long
+ // int,
+ // so
+ // will
+ // be
+ // unsigned
+ // long
+ // int
+ 00ULL; // COMPLIANT - unsigned, but uses the suffix correctly
+ 0b1111111111111111111111111111111ULL; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b10000000000000000000000000000000ULL; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b100000000000000000000000000000000ULL; // COMPLIANT - unsigned, but uses the
+ // suffix correctly
+ 0b111111111111111111111111111111111111111111111111111111111111111ULL; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+ 0b1000000000000000000000000000000000000000000000000000000000000000ULL; // COMPLIANT
+ // -
+ // unsigned,
+ // but
+ // uses
+ // the
+ // suffix
+ // correctly
+}
+
+#define COMPLIANT_VAL 0x80000000U
+#define NON_COMPLIANT_VAL 0x80000000
+
+void test_macro() {
+ COMPLIANT_VAL; // COMPLIANT
+ NON_COMPLIANT_VAL; // NON_COMPLIANT[FALSE_NEGATIVE] - cannot determine suffix
+ // in macro expansions
}
\ No newline at end of file
diff --git a/cpp/misra/src/codeql-pack.lock.yml b/cpp/misra/src/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/cpp/misra/src/codeql-pack.lock.yml
+++ b/cpp/misra/src/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/cpp/misra/src/codeql-suites/misra-cpp-advisory.qls b/cpp/misra/src/codeql-suites/misra-cpp-advisory.qls
new file mode 100644
index 0000000000..5da16cc2af
--- /dev/null
+++ b/cpp/misra/src/codeql-suites/misra-cpp-advisory.qls
@@ -0,0 +1,12 @@
+- description: MISRA C++ 2023 (Default)
+- qlpack: codeql/misra-cpp-coding-standards
+- include:
+ kind:
+ - problem
+ - path-problem
+ tags contain:
+ - external/misra/obligation/advisory
+- exclude:
+ tags contain:
+ - external/misra/audit
+ - external/misra/default-disabled
diff --git a/cpp/misra/src/codeql-suites/misra-cpp-default.qls b/cpp/misra/src/codeql-suites/misra-cpp-default.qls
new file mode 100644
index 0000000000..670b043caa
--- /dev/null
+++ b/cpp/misra/src/codeql-suites/misra-cpp-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-cpp-mandatory.qls b/cpp/misra/src/codeql-suites/misra-cpp-mandatory.qls
new file mode 100644
index 0000000000..0c5ec7155f
--- /dev/null
+++ b/cpp/misra/src/codeql-suites/misra-cpp-mandatory.qls
@@ -0,0 +1,12 @@
+- description: MISRA C++ 2023 (Default)
+- qlpack: codeql/misra-cpp-coding-standards
+- include:
+ kind:
+ - problem
+ - path-problem
+ tags contain:
+ - external/misra/obligation/mandatory
+- exclude:
+ tags contain:
+ - external/misra/audit
+ - external/misra/default-disabled
diff --git a/cpp/misra/src/codeql-suites/misra-cpp-required.qls b/cpp/misra/src/codeql-suites/misra-cpp-required.qls
new file mode 100644
index 0000000000..2fe61301e7
--- /dev/null
+++ b/cpp/misra/src/codeql-suites/misra-cpp-required.qls
@@ -0,0 +1,12 @@
+- description: MISRA C++ 2023 (Default)
+- qlpack: codeql/misra-cpp-coding-standards
+- include:
+ kind:
+ - problem
+ - path-problem
+ tags contain:
+ - external/misra/obligation/required
+- exclude:
+ tags contain:
+ - external/misra/audit
+ - external/misra/default-disabled
diff --git a/cpp/misra/src/codeql-suites/misra-cpp-single-translation-unit.qls b/cpp/misra/src/codeql-suites/misra-cpp-single-translation-unit.qls
new file mode 100644
index 0000000000..0782dd876d
--- /dev/null
+++ b/cpp/misra/src/codeql-suites/misra-cpp-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/codeql-suites/misra-default.qls b/cpp/misra/src/codeql-suites/misra-default.qls
index 670b043caa..3c205157cd 100644
--- a/cpp/misra/src/codeql-suites/misra-default.qls
+++ b/cpp/misra/src/codeql-suites/misra-default.qls
@@ -1,10 +1,2 @@
-- 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
+- description: "DEPRECATED - MISRA C++ 2023 - use misra-cpp-default.qls instead"
+- import: codeql-suites/misra-cpp-default.qls
diff --git a/cpp/misra/src/codeql-suites/misra-single-translation-unit.qls b/cpp/misra/src/codeql-suites/misra-single-translation-unit.qls
index 0782dd876d..9dcd3f0c97 100644
--- a/cpp/misra/src/codeql-suites/misra-single-translation-unit.qls
+++ b/cpp/misra/src/codeql-suites/misra-single-translation-unit.qls
@@ -1,12 +1,2 @@
-- 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
+- description: "DEPRECATED - MISRA C++ 2023 (Single Translation Unit) - use misra-cpp-single-translation-unit.qls instead"
+- import: codeql-suites/misra-cpp-single-translation-unit.qls
diff --git a/cpp/misra/src/qlpack.yml b/cpp/misra/src/qlpack.yml
index d177c9f651..2ca5752f9c 100644
--- a/cpp/misra/src/qlpack.yml
+++ b/cpp/misra/src/qlpack.yml
@@ -1,8 +1,8 @@
name: codeql/misra-cpp-coding-standards
-version: 2.33.0-dev
+version: 2.38.0-dev
description: MISRA C++ 2023
-suites: codeql-suites
+default-suite: codeql-suites/misra-cpp-default.qls
license: MIT
dependencies:
codeql/common-cpp-coding-standards: '*'
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 0.12.9
diff --git a/cpp/misra/test/codeql-pack.lock.yml b/cpp/misra/test/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/cpp/misra/test/codeql-pack.lock.yml
+++ b/cpp/misra/test/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/cpp/misra/test/qlpack.yml b/cpp/misra/test/qlpack.yml
index 2627cf1b66..b1601bcb74 100644
--- a/cpp/misra/test/qlpack.yml
+++ b/cpp/misra/test/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/misra-cpp-coding-standards-tests
-version: 2.33.0-dev
+version: 2.38.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/cpp/options b/cpp/options
index 1f8961ecda..44267e9323 100644
--- a/cpp/options
+++ b/cpp/options
@@ -1 +1 @@
-semmle-extractor-options:--clang -std=c++14 -nostdinc++ -I../../../../common/test/includes/standard-library -I../../../../common/test/includes/custom-library
\ No newline at end of file
+semmle-extractor-options:--clang -std=c++14 -nostdinc++ -I../../../../common/test/includes/standard-library -I../../../../common/test/includes/custom-library
diff --git a/cpp/report/src/codeql-pack.lock.yml b/cpp/report/src/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/cpp/report/src/codeql-pack.lock.yml
+++ b/cpp/report/src/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/cpp/report/src/qlpack.yml b/cpp/report/src/qlpack.yml
index 085b1e8a9e..797c50b92b 100644
--- a/cpp/report/src/qlpack.yml
+++ b/cpp/report/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/report-cpp-coding-standards
-version: 2.33.0-dev
+version: 2.38.0-dev
license: MIT
dependencies:
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 0.12.9
diff --git a/docs/development_handbook.md b/docs/development_handbook.md
index 10ad1637a5..dc50bf59ff 100644
--- a/docs/development_handbook.md
+++ b/docs/development_handbook.md
@@ -40,6 +40,8 @@
| 0.30.0 | 2023-11-14 | Remco Vermeulen | Clarify release steps in case of a hotfix release. |
| 0.31.0 | 2024-02-23 | Remco Vermeulen | Clarify the required use of Python version 3.9 |
| 0.32.0 | 2024-05-01 | Luke Cartey | Refer to the user manual for the list of supported standards. |
+| 0.33.0 | 2024-07-30 | Kristen Newbury | Remove out dated references to codeql modules directory usage. |
+| 0.34.0 | 2024-08-22 | Kristen Newbury | Remove out dated references to git submodules usage. |
## Scope of work
@@ -494,12 +496,11 @@ There are two external dependencies required for running the coding standards qu
For the purpose of this repository, and any tool qualification, we consider these external dependencies to be "black boxes" which require verification when upgrading.
-To (a) clearly specify the supported versions of these external dependencies and to (b) enable automation around them, the repository contains a `supported_codeql_configs.json` which lists the sets of supported configurations. There are four fields:
+To (a) clearly specify the supported versions of these external dependencies and to (b) enable automation around them, the repository contains a `supported_codeql_configs.json` which lists the sets of supported configurations under the `supported_environments` property. There are three fields:
- `codeql_cli` - this is the plain version number of the supported CodeQL CLI, e.g. `2.6.3`.
- `codeql_standard_library` - this is the name of a tag on the `github.com/github/codeql` repository. The tag should be compatible with the CodeQL CLI given above. This would typically use the `codeql-cli/v` tag for the release, although any tag which is compatible is allowed.
- `codeql_cli_bundle` - (optional) - if present, describes the CodeQL CLI bundle version that is compatible. The bundle should include precisely the CodeQL CLI version and CodeQL Standard Library versions specified in the two mandatory fields.
-- `ghes` - (optional) - if present describes the GitHub Enterprise Server release whose integrated copy of the CodeQL Action points to the CodeQL CLI bundle specified in the `codeql_cli_bundle` field.
#### Upgrading external dependencies
@@ -507,34 +508,41 @@ To upgrade the CodeQL external dependencies:
1. Determine appropriate versions of the CodeQL CLI and `github/codeql` repository, according to the release schedule and customer demands.
2. Determine if there is a compatible CodeQL CLI bundle version by looking at the releases specified at [CodeQL Action releases](https://github.com/github/codeql-action/releases). The bundle always includes the standard library at the version specified by the `codeql-cli/v` tag in the `github/codeql` repository.
-3. If you find a compatible CodeQL CLI bundle, determine whether that bundle was released in a GitHub Enterprise server release, by inspecting the `defaults.json` file at https://github.com/github/codeql-action/blob/main/lib/defaults.json#L2 for the CodeQL Action submitted with
-4. Populated the `supported_codeql_configs.json` file with the given values, ensuring to delete the optional fields if they are not populated.
-5. Update the `codeql_modules/codeql` submodule pointer to the `codeql_standard_library` tag identified.
-6. Submit a Pull Request to the `github/codeql-coding-standards` repository with the title `Upgrade `github/codeql` dependency to `. Use this template for the description, filling :
- ```md
- This PR updates the `supported_codeql_configs.json` file to target:
+If all components are being upgraded to a consistent veresion (e.g. CodeQL CLI v2.15.5, with `github/codeql` tag `codeql-cli/v2.15.5` and bundle `codeql-cli-bundle-v2.15.5`) then the following process can be used:
+
+1. Run the [upgrade_codeql_dependencies.yml](./github/workflows/upgrade_codeql_dependencies.yml) workflow, with the plain version number, e.g. `2.15.5`. This will:
+ - Download the specified version of the CodeQL CLI
+ - Run the [upgrade-codeql-dependencies.py](scripts/release/upgrade-codeql-dependencies.py) script, which
+ - Validates the version selected exists in all relevant places
+ - Updates the `supported_codeql_configs.json` file.
+ - Updates each `qlpack.yml` in the repository with an appropriate value for the `codeql/cpp-all` pack, consistent with the selected CodeQL CLI version.
+ - Updates each `codeql-lock.yml` file to upgrade to the new version.
+2. Follow the dependency upgrade checklist, confirming each step. The `.github/workflows/standard_library_upgrade_tests.yml` will trigger automation for running the `github/codeql` unit tests with the appropriate CLI version.
+3. Once all the automate tests have passed, and the checklist is complete, the PR can be merged.
+4. An internal notification should be shared with the development team.
+
+If the upgrade is of mismatched versions you will need to manually create the upgrade following this process:
- - CodeQL CLI
- - CodeQL Standard Library
- - GHES
- - CodeQL CLI Bundle
+1. Populate the `supported_codeql_configs.json` file with the given values, ensuring to delete the optional fields if they are not populated.
+2. Submit a Pull Request to the `github/codeql-coding-standards` repository with the title `Upgrade `github/codeql` dependency to `. Use this template for the description, filling:
- >
-
+ ```md
+ This PR updates the `supported_codeql_configs.json` file to target CodeQL CLI .
## CodeQL dependency upgrade checklist:
- - [ ] Reformat our CodeQL using the latest version (if required)
+ - [ ] Confirm the code has been correctly reformatted according to the new CodeQL CLI.
- [ ] Identify any CodeQL compiler warnings and errors, and update queries as required.
- [ ] Validate that the `github/codeql` test cases succeed.
- [ ] Address any CodeQL test failures in the `github/codeql-coding-standards` repository.
- - [ ] Validate performance vs pre-upgrade
+ - [ ] Validate performance vs pre-upgrade, using /test-performance
```
-7. Follow the dependency upgrade checklist, confirming each step. The `.github/workflows/standard_library_upgrade_tests.yml` will trigger automation for running the `github/codeql` unit tests with the appropriate CLI version.
-8. Once all the automate tests have passed, and the checklist is complete, the PR can be merged.
-9. An internal notification should be shared with the development team.
+3. Follow the dependency upgrade checklist, confirming each step. The `.github/workflows/standard_library_upgrade_tests.yml` will trigger automation for running the `github/codeql` unit tests with the appropriate CLI version.
+4. Once all the automate tests have passed, and the checklist is complete, the PR can be merged.
+5. An internal notification should be shared with the development team.
+
### Release process
@@ -735,14 +743,3 @@ codeql test run --show-extractor-output \
# The actual output can be accepted via codeql test accept (which moves some files):
codeql test accept \
cpp/cert/test/rules/EXP52-CPP/DoNotRelyOnSideEffectsInDeclTypeOperand.qlref
-
-
-```
-
-### Troubleshooting: Unrecoverable mismatch between extractor and library dbschemes
-
-The following error could be indicative of the Git submodule *codeql-coding-standards/github_modules* being out-of-date:
-
->Could not upgrade the dataset in /path/to/codeql-coding-standards/cpp/autosar/test/rules/...: Unrecoverable mismatch between extractor and library dbschemes.
-
-To resolve the problem, update the submodule by executing `git submodule update`.
diff --git a/docs/user_manual.md b/docs/user_manual.md
index a32abda8c4..7f505673df 100644
--- a/docs/user_manual.md
+++ b/docs/user_manual.md
@@ -26,17 +26,21 @@
| 0.18.0 | 2024-01-30 | Luke Cartey | Update product description and coverage table. |
| 0.19.0 | 2024-02-23 | Remco Vermeulen | Clarify the required use of Python version 3.9. |
| 0.20.0 | 2024-02-23 | Remco Vermeulen | Add table describing the permitted guideline re-categorizations. |
-| 0.21.0 | 2024-05-01 | Luke Cartey | Add MISRA C++ 2023 as under development, and clarify MISRA C 2012 coverage. |
+| 0.21.0 | 2024-05-01 | Luke Cartey | Add MISRA C++ 2023 as under development, and clarify MISRA C 2012 coverage. |
+| 0.22.0 | 2024-10-02 | Luke Cartey | Add MISRA C 2023 as under development, and clarify MISRA C 2012 coverage. |
+| 0.23.0 | 2024-10-21 | Luke Cartey | Add assembly as a hazard. |
+| 0.24.0 | 2024-10-22 | Luke Cartey | Add CodeQL packs as a usable output, update release artifacts list. |
## Release information
-This user manual documents release `2.33.0-dev` of the coding standards located at [https://github.com/github/codeql-coding-standards](https://github.com/github/codeql-coding-standards).
+This user manual documents release `2.38.0-dev` of the coding standards located at [https://github.com/github/codeql-coding-standards](https://github.com/github/codeql-coding-standards).
The release page documents the release notes and contains the following artifacts part of the release:
-- `code-scanning-cpp-query-pack-2.33.0-dev.zip`: coding standard queries and scripts to be used with GitHub Code Scanning or the CodeQL CLI as documented in the section _Operating manual_.
-- `supported_rules_list_2.33.0-dev.csv`: A Comma Separated File (CSV) containing the supported rules per standard and the queries that implement the rule.
-- `supported_rules_list_2.33.0-dev.md`: A Markdown formatted file with a table containing the supported rules per standard and the queries that implement the rule.
-- `user_manual_2.33.0-dev.md`: This user manual.
+- `coding-standards-codeql-packs-2.37.0-dev.zip`: CodeQL packs that can be used with GitHub Code Scanning or the CodeQL CLI as documented in the section _Operating manual_.
+- `code-scanning-cpp-query-pack-2.38.0-dev.zip`: Legacy packaging for the queries and scripts to be used with GitHub Code Scanning or the CodeQL CLI as documented in the section _Operating manual_.
+- `supported_rules_list_2.38.0-dev.csv`: A Comma Separated File (CSV) containing the supported rules per standard and the queries that implement the rule.
+- `supported_rules_list_2.38.0-dev.md`: A Markdown formatted file with a table containing the supported rules per standard and the queries that implement the rule.
+- `user_manual_2.38.0-dev.md`: This user manual.
- `Source Code (zip)`: A zip archive containing the contents of https://github.com/github/codeql-coding-standards
- `Source Code (tar.gz)`: A GZip compressed tar archive containing the contents of https://github.com/github/codeql-coding-standards
- `checksums.txt`: A text file containing sha256 checksums for the aforementioned artifacts.
@@ -58,8 +62,11 @@ The _CodeQL Coding Standards_ product is a set of CodeQL queries for identifying
| AUTOSAR C++ | [^1] [R22-11](https://www.autosar.org/fileadmin/standards/R22-11/AP/AUTOSAR_RS_CPP14Guidelines.pdf), R21-11, R20-11, R19-11, R19-03 | 397 | 372 | 370[^2] | Implemented |
| CERT-C++ | [2016](https://resources.sei.cmu.edu/downloads/secure-coding/assets/sei-cert-cpp-coding-standard-2016-v01.pdf) | 83 | 82 | 82 | Implemented |
| CERT C | [2016](https://resources.sei.cmu.edu/downloads/secure-coding/assets/sei-cert-c-coding-standard-2016-v01.pdf) | 99 | 97 | 97 | Implemented |
-| MISRA C | [2012 Third Edition, First Revision](](https://www.misra.org.uk/product/misra-c2012-third-edition-first-revision/)), and [Amendment 2](https://misra.org.uk/app/uploads/2021/06/MISRA-C-2012-AMD2.pdf) and TC2 | 175 | 164 | 162[^3] | Implemented |
-| MISRA C++ | [2023](https://misra.org.uk/product/misra-cpp2023/) | 179 | 176[^4] | 0 | Under development |
+| MISRA C | [2012 Third Edition, First Revision](https://www.misra.org.uk/product/misra-c2012-third-edition-first-revision/), [Amendment 2](https://misra.org.uk/app/uploads/2021/06/MISRA-C-2012-AMD2.pdf) and TC2 | 175 | 164 | 162[^3] | Implemented |
+| | [MISRA C 2012 Amendment 3](https://misra.org.uk/app/uploads/2021/06/MISRA-C-2012-AMD3.pdf) | 24 | 24 | - | Under development |
+| | [MISRA C 2012 Amendment 4](https://misra.org.uk/app/uploads/2021/06/MISRA-C-2012-AMD4.pdf) | 22 | 22 | - | Under development |
+| | [2023 Third Edition, Second Revision](https://misra.org.uk/product/misra-c2023/) | 221 | 210 | - | Under development |
+| MISRA C++ | [2023](https://misra.org.uk/product/misra-cpp2023/) | 179 | 176[^4] | - | Under development |
Not all rules in these standards are amenable to static analysis by CodeQL - some rules require external or domain specific knowledge to validate, or refer to properties which are not present in our representation of the codebase under analysis. In addition, some rules are natively enforced by the supported compilers. As CodeQL requires that the program under analysis compiles, we are unable to implement queries for these rules, and doing so would be redundant.
@@ -74,7 +81,7 @@ The datasheet _"CodeQL Coding Standards: supported rules"_, provided with each r
[^1]: AUTOSAR C++ versions R22-11, R21-11, R20-11, R19-11 and R19-03 are all identical as indicated in the document change history.
[^2]: The unimplemented supportable AUTOSAR rules are `A7-1-8` and `A8-2-1`. These rules require additional support in the CodeQL CLI to ensure the required information is available in the CodeQL database to identify violations of these rules.
-[^3]: The unimplemented supportable MISRA C 2012 rules are `Rule 9.5` and `Dir 4.14`. `Rule 9.5` requires additional support in the CodeQL CLI to ensure the required information is available in the CodeQL database to identify violations of these rules. `Dir 4.14` is covered by the default CodeQL queries, which identify potential security vulnerabilities caused by not validating external input.
+[^3]: The unimplemented supportable MISRA C 2012 rules are `Rule 9.5`, `Rule 17.13`, and `Dir 4.14`. `Rule 9.5` and `Rule 17.13` require additional support in the CodeQL CLI to ensure the required information is available in the CodeQL database to identify violations of these rules. `Dir 4.14` is covered by the default CodeQL queries, which identify potential security vulnerabilities caused by not validating external input.
[^4]: The rules 5.13.7, 19.0.1 and 19.1.2 are not planned to be implemented by CodeQL as they are compiler checked in all supported compilers.
## Supported environment
@@ -153,22 +160,52 @@ This section describes how to operate the "CodeQL Coding Standards".
#### Pre-requisite: downloading the CodeQL CLI
-You must download a compatible version of the CodeQL CLI and CodeQL Standard Library for C++.
+You must download a compatible version of the CodeQL CLI, as specified in the release notes for the release you are using.
-**Option 1:** Use the CodeQL CLI bundle, which includes both required components:
+**Option 1:** Use the CodeQL CLI bundle, which includes both the CodeQL CLI and GitHub's default security queries:
1. Download the CodeQL CLI bundle from the [`github/codeql-action` releases page](https://github.com/github/codeql-action/releases).
2. Expand the compressed archive to a specified location on your machine.
3. [Optional] Add the CodeQL CLI to your user or system path.
-**Option 2:** Fetch the components separately:
+This approach is recommended if you wish to use the default queries provided by GitHub in addition to the Coding Standards queries.
+
+**Option 2:** Use the CodeQL CLI binary:
1. Download the CodeQL CLI from the [`github/codeql-cli-binaries` releases page](https://github.com/github/codeql-cli-binaries/releases)
2. Expand the compressed archive to a specified location on your machine.
- 3. Using `git`, clone the [`github/codeql`](https://github.com/github/codeql) repository to a sibling directory of the CodeQL CLI. The `github/codeql` repository contains the CodeQL Standard Library for C++.
- 4. [Optional] Add the CodeQL CLI to your user or system path.
+3. [Optional] Add the CodeQL CLI to your user or system path.
+
+#### Pre-requisite: downloading the Coding Standards queries
+
+The Coding Standards packs can be downloaded into the local CodeQL package cache using the following command:
+
+```bash
+codeql pack download codeql/--coding-standards@
+```
+
+The supported standards and languages are:
+ * `codeql/misra-c-coding-standards` - a CodeQL query pack for reporting violations of MISRA C.
+ * `codeql/cert-c-coding-standards` - a CodeQL query pack for reporting violations of CERT C.
+ * `codeql/misra-cpp-coding-standards` - a CodeQL query pack for reporting violations of MISRA C++.
+ * `codeql/cert-cpp-coding-standards` - a CodeQL query pack for reporting violations of CERT C++.
+ * `codeql/autosar-cpp-coding-standards` - - a CodeQL query pack for reporting violations of AUTOSAR for C++.
+
+Ensure that the `@` string matches the desired Coding Standards version.
+
+Alternatively, the packs can be downloaded directly from a release on the `github/codeql-coding-standards` repository by choosing the `coding-standards-codeql-packs.zip`, which contains the following files:
+
+ * `misra-c-coding-standards.tgz` - a CodeQL query pack for reporting violations of MISRA C.
+ * `cert-c-coding-standards.tgz` - a CodeQL query pack for reporting violations of CERT C.
+ * `cert-cpp-coding-standards.tgz` - a CodeQL query pack for reporting violations of CERT C++.
+ * `autosar-cpp-coding-standards.tgz` - a CodeQL query pack for reporting violations of AUTOSAR for C++.
+ * `common-cpp-coding-standards.tgz` - a CodeQL library pack, used if you are writing your own C++ queries against Coding Standards.
+ * `common-c-coding-standards.tgz` - a CodeQL library pack, used if you are writing your own C queries against Coding Standards.
+ * `report-coding-standards.tgz` - a CodeQL query pack for running diagnostics on databases.
-The release notes for the "CodeQL Coding Standards" pack you are using will specify the appropriate versions to use.
+Each pack will need to be decompressed using the `tar` program, and placed in a known location.
+
+Finally, we provide a legacy single zip containing all the artifacts from a release, named `code-scanning-cpp-query-pack.zip`. This also contains the CodeQL packs listed above.
#### Creating a CodeQL database
@@ -189,26 +226,65 @@ Reference: [CodeQL CLI: Creating a CodeQL database](https://codeql.github.com/do
#### Running the default analysis for one or more Coding Standards
-Once you have a CodeQL database for your project, you can run the "default" query suite. This will run all the "automated" queries for each implemented rule in the specified Coding Standards.
+Once you have a CodeQL database for your project you can run the default analysis for a specified Coding Standard using the `codeql database analyze` command by specifying the names of the QL packs which you want to run as arguments, along with a version specifier:
+
+```bash
+codeql database analyze --format=sarifv2.1.0 --output=.sarif path/to/ codeql/--coding-standard@version
+```
+
+For example, this command would run MISRA C and CERT C with the default query sets:
+
+```bash
+codeql database analyze --format=sarifv2.1.0 --output=results.sarif path/to/ codeql/misra-c-coding-standard@version codeql/cert-c-coding-standard@version
+```
+The output of this command will be a [SARIF file](https://sarifweb.azurewebsites.net/) called `.sarif`.
+
+##### Locating the Coding Standards CodeQL packs
+
+If you have downloaded a release artifact containing the packs, you will need to provide the `--search-path` parameter, pointing to each of the uncompressed query packs.
+```
+--search-path path/to/pack1:path/to/pack2
+```
+
+Alternatively, the packs can be made available to CodeQL without specification on the comamnd line by placing them inside the distribution under the `qlpacks/codeql/` directory, or placed inside a directory adjacent to the folder containing the distribution.
+
+##### Alternative query sets
+
+Each supported standard includes a variety of query suites, which enable the running of different sets of queries based on specified properties. In addition, a custom query suite can be defined as specified by the CodeQL CLI documentation, in order to select any arbitrary sets of queries in this repository. To run
+
+```bash
+codeql database analyze --format=sarifv2.1.0 --output=.sarif path/to/ codeql/--coding-standard@version:codeql-suites/.qls
+```
-The query suites can be run by using the `codeql database analyze` command:
+If modifying the query suite, ensure that all Rules you expect to be covered by CodeQL in your Guideline Enforcement Plan (or similar) are included in the query suite, by running:
```bash
-codeql database analyze --format=sarifv2.1.0 --output=.sarif path/to/ path/to/codeql-coding-standards/cpp//src/codeql-suites/-default.qls...
+codeql resolve queries codeql/--coding-standard@version:codeql-suites/.qls
```
-For each Coding Standard you want to run, add a trailing entry in the following format: `path/to/codeql-coding-standards/cpp//src/codeql-suites/-default.qls`.
+##### Supported SARIF versions
The only supported SARIF version for use in a functional safety environment is version 2.1.0.
To select this SARIF version you **must** specify the flag `--format=sarifv2.1.0` when invoking the database analyze command `codeql database analyze ...` as shown in the above example.
-Running the default analysis for one or more Coding Standards may require further performance customizations for larger codebases.
-The following flags may be passed to the `database analyze` command to adjust the performance:
+##### Performance optimizations
-- `--ram` - to specify the maximum amount of RAM to use during the analysis as [documented](https://codeql.github.com/docs/codeql-cli/manual/database-analyze/#options-to-control-ram-usage) in the CodeQL CLI manual.
-- `--thread` - to specify number of threads to use while evaluating as [documented](https://codeql.github.com/docs/codeql-cli/manual/database-analyze/#cmdoption-codeql-database-analyze-j) in the CodeQL CLI manual.
+Running the default analysis for one or more Coding Standards may require further performance customizations for larger codebases. The following flags may be passed to the `database analyze` command to adjust the performance:
-The output of this command will be a [SARIF file](https://sarifweb.azurewebsites.net/) called `.sarif`.
+- `--ram` - to specify the maximum amount of RAM to use during the analysis as [documented](https://docs.github.com/en/code-security/codeql-cli/codeql-cli-manual/database-analyze#options-to-control-ram-usage) in the CodeQL CLI manual.
+- `--thread` - to specify number of threads to use while evaluating as [documented](https://docs.github.com/en/code-security/codeql-cli/codeql-cli-manual/database-analyze#-j---threadsnum) in the CodeQL CLI manual.
+
+##### Legacy approach
+
+If you have downloaded the legacy release artifact `code-scanning-query-pack.zip`, you can run the default query suite using the `codeql database analyze` command as follows:
+
+```bash
+codeql database analyze --format=sarifv2.1.0 --output=.sarif path/to/ path/to/codeql-coding-standards///src/codeql-suites/-default.qls...
+```
+
+For each Coding Standard you want to run, add a trailing entry in the following format: `path/to/codeql-coding-standards///src/codeql-suites/-default.qls`. Custom query suites can be run by specifying the appropriate paths.
+
+All other options discussed above are valid.
#### Running the analysis for audit level queries
@@ -218,8 +294,6 @@ Optionally, you may want to run the "audit" level queries. These queries produce
codeql database analyze --format=sarifv2.1.0 --output=.sarif path/to/ path/to/codeql-coding-standards/cpp//src/codeql-suites/-audit.qls...
```
-For each Coding Standard you want to run, add a trailing entry in the following format: `path/to/codeql-coding-standards/cpp//src/codeql-suites/-default.qls`.
-
#### Producing an analysis report
In addition to producing a results file, an analysis report can be produced that summarizes:
@@ -496,14 +570,15 @@ This section describes known failure modes for "CodeQL Coding Standards" and des
| | Use of incorrect build command | Less output. Some files may be only be partially analyzed, or not analyzed at all. | Analysis integrity report lists all analyzed files, and must be crossed referenced with the list of files that are expected to be analyzed. | Ensure the build command corresponds to the build command that is used to build the release artifacts. |
| | Incorrect build environment (e.g., concurrent builds writing to same file, overwriting translation unit/object file with different content) | Less or more output. Results are reported that are not violations of the guidelines or guideline violations are not reported | All reported results must be reviewed. | Ensure the build environment is configured to not use shared resources such as caches or artifact providers that can introduce race conditions. Report inconsistent results via the CodeQL Coding Standards [bug tracker](https://github.com/github/codeql-coding-standards/issues). |
| | Source root misspecification | Less output. The results cannot be correctly correlated to source files when viewing the resulting Sarif file in a Sarif viewer. | Verify that the reported results are display on the correct files in the Sarif viewer | Ensure the CodeQL CLI configured to use the correct source root that correspond to the root of the repository under consideration. |
-| | Ouf of space | Less output. Some files may be only be partially analyzed, or not analyzed at all. | Error reported on the command line. | Increase space. If it remains an issue report space consumption issues via the CodeQL Coding Standards [bug tracker](https://github.com/github/codeql-coding-standards/issues). |
+| | Out of space | Less output. Some files may be only be partially analyzed, or not analyzed at all. | Error reported on the command line. | Increase space. If it remains an issue report space consumption issues via the CodeQL Coding Standards [bug tracker](https://github.com/github/codeql-coding-standards/issues). |
| | False positives | More output. Results are reported which are not violations of the guidelines. | All reported results must be reviewed. | Report false positive issues via the CodeQL Coding Standards [bug tracker](https://github.com/github/codeql-coding-standards/issues). |
| | False negatives | Less output. Violations of the guidelines are not reported. | Other validation and verification processes during software development should be used to complement the analysis performed by CodeQL Coding Standards. | Report false negative issues via the CodeQL Coding Standards [bug tracker](https://github.com/github/codeql-coding-standards/issues). |
-| | Modifying coding standard suite | More or less output. If queries are added to the query set more result can be reported. If queries are removed less results might be reported. | All queries supported by the CodeQL Coding Standards are listed in the release artifacts `supported_rules_list_2.33.0-dev.csv` where VERSION is replaced with the used release. The rules in the resulting Sarif file must be cross-referenced with the expected rules in this list to determine the validity of the used CodeQL suite. | Ensure that the CodeQL Coding Standards are not modified in ways that are not documented as supported modifications. |
+| | Modifying coding standard suite | More or less output. If queries are added to the query set more result can be reported. If queries are removed less results might be reported. | All queries supported by the CodeQL Coding Standards are listed in the release artifacts `supported_rules_list_2.38.0-dev.csv` where VERSION is replaced with the used release. The rules in the resulting Sarif file must be cross-referenced with the expected rules in this list to determine the validity of the used CodeQL suite. | Ensure that the CodeQL Coding Standards are not modified in ways that are not documented as supported modifications. |
| | Incorrect deviation record specification | More output. Results are reported for guidelines for which a deviation is assigned. | Analysis integrity report lists all deviations and incorrectly specified deviation records with a reason. Ensure that all deviation records are correctly specified. | Ensure that the deviation record is specified according to the specification in the user manual. |
| | Incorrect deviation permit specification | More output. Results are reported for guidelines for which a deviation is assigned. | Analysis integrity report lists all deviations and incorrectly specified deviation permits with a reason. Ensure that all deviation permits are correctly specified. | Ensure that the deviation record is specified according to the specification in the user manual. |
| | Unapproved use of a deviation record | Less output. Results for guideline violations are not reported. | Validate that the deviation record use is approved by verifying the approved-by attribute of the deviation record specification. | Ensure that each raised deviation record is approved by an independent approver through an auditable process. |
| | Incorrect database. The information extracted by the CodeQL extractor deviates from what the compiler extracts resulting in an incorrect model of the source-code. | More or less output. Incorrect extraction can result in false positives or false negatives. | Combinations of supported compilers and CodeQL CLIs are tested against a [provided](https://github.com/github/codeql/tree/main/cpp/ql/test/library-tests) suite of test cases and a coding standards specific test suite to determine if the extracted information deviates from the expected information. | Report incorrect database issues via the CodeQL Coding Standards [bug tracker](https://github.com/github/codeql-coding-standards/issues). |
+| | Use of assembly language instructions, which are not inspected by CodeQL. | More or less output. Can result in false positives or false negatives. | Avoid the use of assembly language instructions where possible. Where unavoidable, encapasulate and isolate the use of assembly language in separate functions to limit impact. Careful manual review of all functions that use assembly language. | Ensure that all functions which use assembly language instructions are manually reviewed for compliance. |
## Reporting bugs
diff --git a/rule_packages/c/Banned.json b/rule_packages/c/Banned.json
index cab9ffc8c7..d3825f8f30 100644
--- a/rule_packages/c/Banned.json
+++ b/rule_packages/c/Banned.json
@@ -35,7 +35,8 @@
"short_name": "CommaOperatorShouldNotBeUsed",
"shared_implementation_short_name": "CommaOperatorUsed",
"tags": [
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -54,7 +55,8 @@
"severity": "error",
"short_name": "FeaturesOfStdarghUsed",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -73,7 +75,8 @@
"severity": "warning",
"short_name": "UnionKeywordShouldNotBeUsed",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -92,7 +95,8 @@
"severity": "error",
"short_name": "StandardLibraryTimeAndDateFunctionsUsed",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -111,7 +115,8 @@
"severity": "error",
"short_name": "StandardHeaderFileTgmathhUsed",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -130,7 +135,8 @@
"severity": "warning",
"short_name": "ExceptionHandlingFeaturesOfFenvhUsed",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/amendment2"
]
}
],
@@ -149,7 +155,8 @@
"severity": "error",
"short_name": "SystemOfStdlibhUsed",
"tags": [
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -169,7 +176,8 @@
"short_name": "MemoryAllocDeallocFunctionsOfStdlibhUsed",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -188,7 +196,8 @@
"severity": "error",
"short_name": "StandardHeaderFileUsedSetjmph",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -207,7 +216,8 @@
"severity": "error",
"short_name": "StandardHeaderFileUsedSignalh",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -227,7 +237,8 @@
"short_name": "StandardLibraryInputoutputFunctionsUsed",
"tags": [
"security",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -247,7 +258,8 @@
"short_name": "AtofAtoiAtolAndAtollOfStdlibhUsed",
"shared_implementation_short_name": "AtofAtoiAtolAndAtollUsed",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -267,7 +279,8 @@
"short_name": "TerminationFunctionsOfStdlibhUsed",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -279,7 +292,8 @@
"short_name": "TerminationMacrosOfStdlibhUsed",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -299,7 +313,8 @@
"short_name": "BsearchAndQsortOfStdlibhUsed",
"tags": [
"security",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -320,7 +335,8 @@
"tags": [
"security",
"correctness",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -342,7 +358,8 @@
"tags": [
"readability",
"correctness",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -362,7 +379,8 @@
"short_name": "RestrictTypeQualifierUsed",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Banned2.json b/rule_packages/c/Banned2.json
new file mode 100644
index 0000000000..3898125d73
--- /dev/null
+++ b/rule_packages/c/Banned2.json
@@ -0,0 +1,24 @@
+{
+ "MISRA-C-2012": {
+ "RULE-21-24": {
+ "properties": {
+ "obligation": "required"
+ },
+ "queries": [
+ {
+ "description": "The standard functions rand() and srand() will not give high quality random results in all implementations and are therefore banned.",
+ "kind": "problem",
+ "name": "The random number generator functions of shall not be used",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "CallToBannedRandomFunction",
+ "tags": [
+ "security",
+ "external/misra/c/2012/amendment3"
+ ]
+ }
+ ],
+ "title": "The random number generator functions of shall not be used"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rule_packages/c/BitfieldTypes.json b/rule_packages/c/BitfieldTypes.json
index 76490d73d1..43ed42f174 100644
--- a/rule_packages/c/BitfieldTypes.json
+++ b/rule_packages/c/BitfieldTypes.json
@@ -13,7 +13,9 @@
"severity": "error",
"short_name": "BitFieldsShallOnlyBeDeclaredWithAnAppropriateType",
"shared_implementation_short_name": "BitFieldShallHaveAnAppropriateType",
- "tags": []
+ "tags": [
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "Bit-fields shall only be declared with an appropriate type"
@@ -31,7 +33,9 @@
"severity": "error",
"short_name": "SingleBitNamedBitFieldsOfASignedType",
"shared_implementation_short_name": "NamedBitFieldsWithSignedIntegerType",
- "tags": []
+ "tags": [
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "Single-bit named bit fields shall not be of a signed type"
diff --git a/rule_packages/c/BitfieldTypes2.json b/rule_packages/c/BitfieldTypes2.json
new file mode 100644
index 0000000000..957e9bb729
--- /dev/null
+++ b/rule_packages/c/BitfieldTypes2.json
@@ -0,0 +1,24 @@
+{
+ "MISRA-C-2012": {
+ "RULE-6-3": {
+ "properties": {
+ "obligation": "required"
+ },
+ "queries": [
+ {
+ "description": "Type punning on a union with bit fields relies on implementation-specific alignment behavior.",
+ "kind": "problem",
+ "name": "A bit field shall not be declared as a member of a union",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "BitFieldDeclaredAsMemberOfAUnion",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ]
+ }
+ ],
+ "title": "A bit field shall not be declared as a member of a union"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rule_packages/c/Concurrency4.json b/rule_packages/c/Concurrency4.json
index 65a17ed2d7..d537ee713e 100644
--- a/rule_packages/c/Concurrency4.json
+++ b/rule_packages/c/Concurrency4.json
@@ -19,14 +19,13 @@
"implementation_scope": {
"description": "This query does not attempt to ensure that the deallocation function in fact deallocates memory and instead assumes the contract is valid. Additionally, this query requires that all `tss_create` calls are bookended by calls to `tss_delete`, even if a thread is not created."
}
-
}
],
"title": "Clean up thread-specific storage"
},
"CON34-C": {
"properties": {
- "obligation": "rule"
+ "obligation": "rule"
},
"queries": [
{
@@ -54,7 +53,7 @@
"tags": [
"external/cert/audit",
"correctness",
- "concurrency"
+ "concurrency"
]
}
],
diff --git a/rule_packages/c/Contracts1.json b/rule_packages/c/Contracts1.json
index 2882bb617f..21641922af 100644
--- a/rule_packages/c/Contracts1.json
+++ b/rule_packages/c/Contracts1.json
@@ -4,38 +4,42 @@
"properties": {
"obligation": "rule"
},
- "queries": [{
- "description": "Modification of return values of getenv and similar functions results in undefined behaviour.",
- "kind": "path-problem",
- "name": "Do not modify the return value of certain functions",
- "precision": "very-high",
- "severity": "warning",
- "short_name": "DoNotModifyTheReturnValueOfCertainFunctions",
- "shared_implementation_short_name": "ConstLikeReturnValue",
- "tags": [
- "correctness"
- ]
- }],
+ "queries": [
+ {
+ "description": "Modification of return values of getenv and similar functions results in undefined behaviour.",
+ "kind": "path-problem",
+ "name": "Do not modify the return value of certain functions",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "DoNotModifyTheReturnValueOfCertainFunctions",
+ "shared_implementation_short_name": "ConstLikeReturnValue",
+ "tags": [
+ "correctness"
+ ]
+ }
+ ],
"title": "Do not modify the object referenced by the return value of certain functions"
},
"ENV31-C": {
"properties": {
"obligation": "rule"
},
- "queries": [{
- "description": "Using the envp pointer after environment modifications can result in undefined behavior.",
- "kind": "problem",
- "name": "Do not rely on an env pointer following an operation that may invalidate it",
- "precision": "high",
- "severity": "error",
- "short_name": "EnvPointerIsInvalidAfterCertainOperations",
- "tags": [
- "correctness"
- ],
- "implementation_scope": {
- "description": "The rule is enforced in the context of a single function."
+ "queries": [
+ {
+ "description": "Using the envp pointer after environment modifications can result in undefined behavior.",
+ "kind": "problem",
+ "name": "Do not rely on an env pointer following an operation that may invalidate it",
+ "precision": "high",
+ "severity": "error",
+ "short_name": "EnvPointerIsInvalidAfterCertainOperations",
+ "tags": [
+ "correctness"
+ ],
+ "implementation_scope": {
+ "description": "The rule is enforced in the context of a single function."
+ }
}
- }],
+ ],
"title": "Do not rely on an environment pointer following an operation that may invalidate it"
}
}
diff --git a/rule_packages/c/Contracts2.json b/rule_packages/c/Contracts2.json
index b4845fc2be..b07f8f0503 100644
--- a/rule_packages/c/Contracts2.json
+++ b/rule_packages/c/Contracts2.json
@@ -67,7 +67,8 @@
"short_name": "ValuesReturnedByLocaleSettingUsedAsPtrToConst",
"shared_implementation_short_name": "ConstLikeReturnValue",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -87,7 +88,8 @@
"short_name": "CallToSetlocaleInvalidatesOldPointers",
"shared_implementation_short_name": "InvalidatedEnvStringPointers",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -99,7 +101,8 @@
"short_name": "CallToSetlocaleInvalidatesOldPointersWarn",
"shared_implementation_short_name": "InvalidatedEnvStringPointersWarn",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Contracts3.json b/rule_packages/c/Contracts3.json
index 8cb997c3b2..0122b858b5 100644
--- a/rule_packages/c/Contracts3.json
+++ b/rule_packages/c/Contracts3.json
@@ -4,46 +4,61 @@
"properties": {
"obligation": "required"
},
- "queries": [{
- "description": "The value of errno shall only be tested when the last function to be called was an errno-setting-function. Testing the value in these conditions does not guarantee the absence of an errors.",
- "kind": "problem",
- "name": "The value of errno shall only be tested when the last called function is errno-setting",
- "precision": "high",
- "severity": "warning",
- "short_name": "OnlyTestErrnoRightAfterErrnoSettingFunction",
- "tags": ["correctness"]
- }],
+ "queries": [
+ {
+ "description": "The value of errno shall only be tested when the last function to be called was an errno-setting-function. Testing the value in these conditions does not guarantee the absence of an errors.",
+ "kind": "problem",
+ "name": "The value of errno shall only be tested when the last called function is errno-setting",
+ "precision": "high",
+ "severity": "warning",
+ "short_name": "OnlyTestErrnoRightAfterErrnoSettingFunction",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
+ }
+ ],
"title": "The value of errno shall only be tested when the last function to be called was an errno-setting-function"
},
"RULE-22-8": {
"properties": {
"obligation": "required"
},
- "queries": [{
- "description": "The value of errno shall be set to zero prior to a call to an errno-setting-function. Not setting the value leads to incorrectly identifying errors.",
- "kind": "problem",
- "name": "The value of errno shall be set to zero prior to a call to an errno-setting-function",
- "precision": "very-high",
- "severity": "error",
- "short_name": "ErrnoSetToZeroPriorToCall",
- "tags": ["correctness"]
- }],
+ "queries": [
+ {
+ "description": "The value of errno shall be set to zero prior to a call to an errno-setting-function. Not setting the value leads to incorrectly identifying errors.",
+ "kind": "problem",
+ "name": "The value of errno shall be set to zero prior to a call to an errno-setting-function",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "ErrnoSetToZeroPriorToCall",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
+ }
+ ],
"title": "The value of errno shall be set to zero prior to a call to an errno-setting-function"
},
"RULE-22-9": {
"properties": {
"obligation": "required"
},
- "queries": [{
- "description": "The value of errno shall be tested against zero after calling an errno-setting-function. Not testing the value leads to unidentified errors.",
- "kind": "problem",
- "name": "The value of errno shall be tested against zero after calling an errno-setting-function",
- "precision": "very-high",
- "severity": "error",
- "short_name": "ErrnoSetToZeroAfterCall",
- "tags": ["correctness"]
- }],
+ "queries": [
+ {
+ "description": "The value of errno shall be tested against zero after calling an errno-setting-function. Not testing the value leads to unidentified errors.",
+ "kind": "problem",
+ "name": "The value of errno shall be tested against zero after calling an errno-setting-function",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "ErrnoSetToZeroAfterCall",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
+ }
+ ],
"title": "The value of errno shall be tested against zero after calling an errno-setting-function"
}
}
-}
+}
\ No newline at end of file
diff --git a/rule_packages/c/Contracts4.json b/rule_packages/c/Contracts4.json
index 90568bec98..8ba25ab32b 100644
--- a/rule_packages/c/Contracts4.json
+++ b/rule_packages/c/Contracts4.json
@@ -4,22 +4,28 @@
"properties": {
"obligation": "rule"
},
- "queries": [{
+ "queries": [
+ {
"description": "Do not rely solely on errno to determine if en error occurred in setlocale.",
"kind": "problem",
"name": "Do not rely solely on errno to determine if en error occurred in setlocale",
"precision": "high",
"severity": "error",
"short_name": "SetlocaleMightSetErrno",
- "tags": ["correctness"]
- }, {
+ "tags": [
+ "correctness"
+ ]
+ },
+ {
"description": "Do not check errno before the function return value. Failing to do so might invalidate the error detection.",
"kind": "problem",
"name": "Do not check errno before the function return value",
"precision": "high",
"severity": "error",
"short_name": "ErrnoReadBeforeReturn",
- "tags": ["correctness"]
+ "tags": [
+ "correctness"
+ ]
},
{
"description": "After calling an errno-setting function, check errno before calling any other function. Failing to do so might end in errno being overwritten.",
@@ -28,7 +34,9 @@
"precision": "high",
"severity": "error",
"short_name": "FunctionCallBeforeErrnoCheck",
- "tags": ["correctness"]
+ "tags": [
+ "correctness"
+ ]
},
{
"description": "Set errno to zero prior to each call to an errno-setting function. Failing to do so might end in spurious errno values.",
@@ -37,7 +45,9 @@
"precision": "high",
"severity": "error",
"short_name": "ErrnoNotSetToZero",
- "tags": ["correctness"]
+ "tags": [
+ "correctness"
+ ]
}
],
"title": "Take care when reading errno"
diff --git a/rule_packages/c/Contracts5.json b/rule_packages/c/Contracts5.json
index 1032e0546e..9f62ce9255 100644
--- a/rule_packages/c/Contracts5.json
+++ b/rule_packages/c/Contracts5.json
@@ -4,36 +4,44 @@
"properties": {
"obligation": "rule"
},
- "queries": [{
- "description": "Do not rely on indeterminate values of errno. This may result in undefined behavior.",
- "kind": "problem",
- "name": "Do not rely on indeterminate values of errno",
- "precision": "high",
- "severity": "error",
- "short_name": "DoNotRelyOnIndeterminateValuesOfErrno",
- "tags": ["correctness"],
- "implementation_scope": {
- "description": "The rule is enforced in the context of a single function."
+ "queries": [
+ {
+ "description": "Do not rely on indeterminate values of errno. This may result in undefined behavior.",
+ "kind": "problem",
+ "name": "Do not rely on indeterminate values of errno",
+ "precision": "high",
+ "severity": "error",
+ "short_name": "DoNotRelyOnIndeterminateValuesOfErrno",
+ "tags": [
+ "correctness"
+ ],
+ "implementation_scope": {
+ "description": "The rule is enforced in the context of a single function."
+ }
}
- }],
+ ],
"title": "Do not rely on indeterminate values of errno"
},
"ERR33-C": {
"properties": {
"obligation": "rule"
},
- "queries": [{
- "description": "Detect and handle standard library errors. Undetected failures can lead to unexpected or undefined behavior.",
- "kind": "problem",
- "name": "Detect and handle standard library errors",
- "precision": "high",
- "severity": "error",
- "short_name": "DetectAndHandleStandardLibraryErrors",
- "tags": ["correctness"],
- "implementation_scope": {
- "description": "The rule is enforced in the context of a single function."
+ "queries": [
+ {
+ "description": "Detect and handle standard library errors. Undetected failures can lead to unexpected or undefined behavior.",
+ "kind": "problem",
+ "name": "Detect and handle standard library errors",
+ "precision": "high",
+ "severity": "error",
+ "short_name": "DetectAndHandleStandardLibraryErrors",
+ "tags": [
+ "correctness"
+ ],
+ "implementation_scope": {
+ "description": "The rule is enforced in the context of a single function."
+ }
}
- }],
+ ],
"title": "Detect and handle standard library errors"
}
}
diff --git a/rule_packages/c/Contracts6.json b/rule_packages/c/Contracts6.json
index bc707f19f4..4dbae7e121 100644
--- a/rule_packages/c/Contracts6.json
+++ b/rule_packages/c/Contracts6.json
@@ -12,7 +12,9 @@
"precision": "high",
"severity": "error",
"short_name": "DoNotModifyConstantObjects",
- "tags": ["correctness"],
+ "tags": [
+ "correctness"
+ ],
"implementation_scope": {
"description": "The implementation does not consider pointer aliasing via multiple indirection."
}
@@ -34,7 +36,10 @@
"precision": "high",
"severity": "error",
"short_name": "ArrayFunctionArgumentNumberOfElements",
- "tags": ["correctness"]
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "The function argument corresponding to an array parameter shall have an appropriate number of elements"
@@ -51,7 +56,10 @@
"precision": "very-high",
"severity": "error",
"short_name": "ValueReturnedByAFunctionNotUsed",
- "tags": ["correctness"]
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "The value returned by a function having non-void return type shall be used or cast to void"
diff --git a/rule_packages/c/Contracts7.json b/rule_packages/c/Contracts7.json
index 38a038621e..f76b737db1 100644
--- a/rule_packages/c/Contracts7.json
+++ b/rule_packages/c/Contracts7.json
@@ -54,7 +54,8 @@
"severity": "error",
"short_name": "RightHandOperandOfAShiftRange",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -73,7 +74,8 @@
"severity": "error",
"short_name": "ObjectAssignedToAnOverlappingObject",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -84,7 +86,8 @@
"severity": "error",
"short_name": "ObjectCopiedToAnOverlappingObject",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/DeadCode.json b/rule_packages/c/DeadCode.json
index 1de7625225..d8e80d14d1 100644
--- a/rule_packages/c/DeadCode.json
+++ b/rule_packages/c/DeadCode.json
@@ -14,7 +14,8 @@
"short_name": "UnreachableCode",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query reports basic blocks in the program which are unreachable. For basic blocks within templates, the block is only consider unreachable if it is unreachable in all templates. Code generated by macros is ignored for this query, because it may be the case that basic blocks are reachable only in some expansions."
@@ -38,22 +39,9 @@
"short_name": "DeadCode",
"tags": [
"readability",
- "maintainability"
- ],
- "implementation_scope": {
- "description": "This query identifies dead statements in the program of the following kinds:",
- "items": [
- "Declarations of a non-static stack variable whose initializing expression is pure (i.e. has no side-effects) and that is never subsequently accessed in live code.",
- "Blocks that contain only dead statements.",
- "Do loops whose condition is pure, and whose body contains only dead statements.",
- "If statements whose condition is pure, and whose then and else clauses (where they exist) only contain dead statements.",
- "Label statements to which the code never jumps.",
- "While loops whose condition is pure, and whose body contains only dead statements.",
- "Expression statements whose expressions are pure.",
- "Writes to a non-static stack variable that is never subsequently read in live code."
- ]
- },
- "shared_implementation_short_name": "DeadCode"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "There shall be no dead code"
@@ -72,7 +60,8 @@
"short_name": "UnusedTypeDeclarations",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"shared_implementation_short_name": "UnusedTypeDeclarations"
}
@@ -93,7 +82,8 @@
"short_name": "UnusedTagDeclaration",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -113,7 +103,8 @@
"short_name": "UnusedMacroDeclaration",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -133,7 +124,8 @@
"short_name": "UnusedLabelDeclaration",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -153,7 +145,8 @@
"short_name": "UnusedParameter",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"shared_implementation_short_name": "UnusedParameter"
}
diff --git a/rule_packages/c/Declarations1.json b/rule_packages/c/Declarations1.json
index 217e1e077c..90202a5b52 100644
--- a/rule_packages/c/Declarations1.json
+++ b/rule_packages/c/Declarations1.json
@@ -1,56 +1,56 @@
{
"CERT-C": {
"DCL31-C": {
- "properties": {
- "obligation": "rule"
- },
- "queries": [
- {
- "description": "Omission of type specifiers may not be supported by some compilers.",
- "kind": "problem",
- "name": "Declare identifiers before using them",
- "precision": "very-high",
- "severity": "error",
- "short_name": "DeclareIdentifiersBeforeUsingThem",
- "shared_implementation_short_name": "TypeOmitted",
- "tags": [
- "correctness",
- "readability"
- ],
- "implementation_scope": {
- "description": "This query does not check for implicitly typed parameters, typedefs or member declarations as this is partially compiler checked.",
- "items": []
- }
+ "properties": {
+ "obligation": "rule"
+ },
+ "queries": [
+ {
+ "description": "Omission of type specifiers may not be supported by some compilers.",
+ "kind": "problem",
+ "name": "Declare identifiers before using them",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "DeclareIdentifiersBeforeUsingThem",
+ "shared_implementation_short_name": "TypeOmitted",
+ "tags": [
+ "correctness",
+ "readability"
+ ],
+ "implementation_scope": {
+ "description": "This query does not check for implicitly typed parameters, typedefs or member declarations as this is partially compiler checked.",
+ "items": []
}
- ],
- "title": "Declare identifiers before using them"
+ }
+ ],
+ "title": "Declare identifiers before using them"
+ },
+ "DCL37-C": {
+ "properties": {
+ "obligation": "rule"
},
- "DCL37-C": {
- "properties": {
- "obligation": "rule"
- },
- "queries": [
- {
- "description": "Declaring a reserved identifier can lead to undefined behaviour.",
- "kind": "problem",
- "name": "Do not declare or define a reserved identifier",
- "precision": "very-high",
- "severity": "warning",
- "short_name": "DoNotDeclareOrDefineAReservedIdentifier",
- "shared_implementation_short_name": "DeclaredAReservedIdentifier",
- "tags": [
- "correctness",
- "maintainability",
- "readability"
- ],
- "implementation_scope": {
- "description": "This query does not consider identifiers described in the future library directions section of the standard. This query also checks for any reserved identifier as declared regardless of whether its header file is included or not.",
- "items": []
- }
+ "queries": [
+ {
+ "description": "Declaring a reserved identifier can lead to undefined behaviour.",
+ "kind": "problem",
+ "name": "Do not declare or define a reserved identifier",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "DoNotDeclareOrDefineAReservedIdentifier",
+ "shared_implementation_short_name": "DeclaredAReservedIdentifier",
+ "tags": [
+ "correctness",
+ "maintainability",
+ "readability"
+ ],
+ "implementation_scope": {
+ "description": "This query does not consider identifiers described in the future library directions section of the standard. This query also checks for any reserved identifier as declared regardless of whether its header file is included or not.",
+ "items": []
}
- ],
- "title": "Do not declare or define a reserved identifier"
- }
+ }
+ ],
+ "title": "Do not declare or define a reserved identifier"
+ }
},
"MISRA-C-2012": {
"RULE-21-2": {
@@ -69,7 +69,8 @@
"tags": [
"correctness",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -91,7 +92,8 @@
"tags": [
"correctness",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query considers the first 31 characters of identifiers as significant, as per C99 and reports the case when names are longer than 31 characters and differ in those characters past the 31 first only. This query does not consider universal or extended source characters.",
@@ -102,41 +104,43 @@
"title": "External identifiers shall be distinct"
},
"RULE-5-4": {
- "properties": {
- "obligation": "required"
+ "properties": {
+ "obligation": "required"
+ },
+ "queries": [
+ {
+ "description": "Declaring multiple macros with the same name leads to undefined behaviour.",
+ "kind": "problem",
+ "name": "Macro identifiers shall be distinct",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "MacroIdentifiersNotDistinct",
+ "tags": [
+ "correctness",
+ "maintainability",
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
+ ],
+ "implementation_scope": {
+ "description": "This query checks the first 63 characters of macro identifiers as significant, as per C99. Distinctness of parameters within the same function like macro are checked by compiler and therefore not checked by this rule.",
+ "items": []
+ }
},
- "queries": [
- {
- "description": "Declaring multiple macros with the same name leads to undefined behaviour.",
- "kind": "problem",
- "name": "Macro identifiers shall be distinct",
- "precision": "very-high",
- "severity": "warning",
- "short_name": "MacroIdentifiersNotDistinct",
- "tags": [
- "correctness",
- "maintainability",
- "readability"
- ],
- "implementation_scope": {
- "description": "This query checks the first 63 characters of macro identifiers as significant, as per C99. Distinctness of parameters within the same function like macro are checked by compiler and therefore not checked by this rule.",
- "items": []
- }
- },
- {
- "description": "Macros with the same name as their parameters are less readable.",
- "kind": "problem",
- "name": "Macro identifiers shall be distinct from paramters",
- "precision": "very-high",
- "severity": "warning",
- "short_name": "MacroIdentifierNotDistinctFromParameter",
- "tags": [
- "maintainability",
- "readability"
- ]
- }
- ],
- "title": "Macro identifiers shall be distinct"
- }
+ {
+ "description": "Macros with the same name as their parameters are less readable.",
+ "kind": "problem",
+ "name": "Macro identifiers shall be distinct from paramters",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "MacroIdentifierNotDistinctFromParameter",
+ "tags": [
+ "maintainability",
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
+ }
+ ],
+ "title": "Macro identifiers shall be distinct"
+ }
}
}
\ No newline at end of file
diff --git a/rule_packages/c/Declarations2.json b/rule_packages/c/Declarations2.json
index 303965b6b6..9acb117d1e 100644
--- a/rule_packages/c/Declarations2.json
+++ b/rule_packages/c/Declarations2.json
@@ -1,98 +1,98 @@
{
"CERT-C": {
"DCL38-C": {
- "properties": {
- "obligation": "rule"
- },
- "queries": [
- {
- "description": "Structures with flexible array members can be declared in ways that will lead to undefined behaviour.",
- "kind": "problem",
- "name": "Use the correct syntax when declaring a flexible array member",
- "precision": "very-high",
- "severity": "error",
- "short_name": "DeclaringAFlexibleArrayMember",
- "tags": [
- "correctness",
- "maintainability",
- "readability"
- ]
- }
- ],
- "title": "Use the correct syntax when declaring a flexible array member"
+ "properties": {
+ "obligation": "rule"
},
+ "queries": [
+ {
+ "description": "Structures with flexible array members can be declared in ways that will lead to undefined behaviour.",
+ "kind": "problem",
+ "name": "Use the correct syntax when declaring a flexible array member",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "DeclaringAFlexibleArrayMember",
+ "tags": [
+ "correctness",
+ "maintainability",
+ "readability"
+ ]
+ }
+ ],
+ "title": "Use the correct syntax when declaring a flexible array member"
+ },
"DCL40-C": {
"properties": {
"obligation": "rule"
},
"queries": [
{
- "description": "Using nondistinct external identifiers results in undefined behaviour.",
- "kind": "problem",
- "name": "External identifiers shall be distinct",
- "precision": "very-high",
- "severity": "warning",
- "short_name": "ExcessLengthNamesIdentifiersNotDistinct",
- "shared_implementation_short_name": "NotDistinctIdentifier",
- "tags": [
- "correctness",
- "maintainability",
- "readability"
- ],
- "implementation_scope": {
- "description": "This query considers the first 31 characters of identifiers as significant, as per C99 and reports the case when names are longer than 31 characters and differ in those characters past the 31 first only. This query does not consider universal or extended source characters.",
- "items": []
- }
- },
- {
- "description": "Declaring incompatible objects, in other words same named objects of different types, then accessing those objects can lead to undefined behaviour.",
- "kind": "problem",
- "name": "Do not create incompatible declarations of the same function or object",
- "precision": "high",
- "severity": "error",
- "short_name": "IncompatibleObjectDeclarations",
- "tags": [
- "correctness",
- "maintainability",
- "readability"
- ]
- },
- {
- "description": "Declaring incompatible functions, in other words same named function of different return types or with different numbers of parameters or parameter types, then accessing those functions can lead to undefined behaviour.",
- "kind": "problem",
- "name": "Do not create incompatible declarations of the same function or object",
- "precision": "high",
- "severity": "error",
- "short_name": "IncompatibleFunctionDeclarations",
- "tags": [
- "correctness",
- "maintainability",
- "readability"
- ]
+ "description": "Using nondistinct external identifiers results in undefined behaviour.",
+ "kind": "problem",
+ "name": "External identifiers shall be distinct",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "ExcessLengthNamesIdentifiersNotDistinct",
+ "shared_implementation_short_name": "NotDistinctIdentifier",
+ "tags": [
+ "correctness",
+ "maintainability",
+ "readability"
+ ],
+ "implementation_scope": {
+ "description": "This query considers the first 31 characters of identifiers as significant, as per C99 and reports the case when names are longer than 31 characters and differ in those characters past the 31 first only. This query does not consider universal or extended source characters.",
+ "items": []
}
+ },
+ {
+ "description": "Declaring incompatible objects, in other words same named objects of different types, then accessing those objects can lead to undefined behaviour.",
+ "kind": "problem",
+ "name": "Do not create incompatible declarations of the same function or object",
+ "precision": "high",
+ "severity": "error",
+ "short_name": "IncompatibleObjectDeclarations",
+ "tags": [
+ "correctness",
+ "maintainability",
+ "readability"
+ ]
+ },
+ {
+ "description": "Declaring incompatible functions, in other words same named function of different return types or with different numbers of parameters or parameter types, then accessing those functions can lead to undefined behaviour.",
+ "kind": "problem",
+ "name": "Do not create incompatible declarations of the same function or object",
+ "precision": "high",
+ "severity": "error",
+ "short_name": "IncompatibleFunctionDeclarations",
+ "tags": [
+ "correctness",
+ "maintainability",
+ "readability"
+ ]
+ }
],
"title": "Do not create incompatible declarations of the same function or object"
},
"DCL41-C": {
- "properties": {
- "obligation": "rule"
- },
- "queries": [
- {
- "description": "Declaring a variable in a switch statement before the first case label can result in reading uninitialized memory which is undefined behaviour.",
- "kind": "problem",
- "name": "Do not declare variables inside a switch statement before the first case label",
- "precision": "very-high",
- "severity": "error",
- "short_name": "VariablesInsideSwitchStatement",
- "tags": [
- "correctness",
- "maintainability",
- "readability"
- ]
- }
- ],
- "title": "Do not declare variables inside a switch statement before the first case label"
- }
+ "properties": {
+ "obligation": "rule"
+ },
+ "queries": [
+ {
+ "description": "Declaring a variable in a switch statement before the first case label can result in reading uninitialized memory which is undefined behaviour.",
+ "kind": "problem",
+ "name": "Do not declare variables inside a switch statement before the first case label",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "VariablesInsideSwitchStatement",
+ "tags": [
+ "correctness",
+ "maintainability",
+ "readability"
+ ]
+ }
+ ],
+ "title": "Do not declare variables inside a switch statement before the first case label"
+ }
}
}
\ No newline at end of file
diff --git a/rule_packages/c/Declarations3.json b/rule_packages/c/Declarations3.json
index a22567b237..8c2e0879ff 100644
--- a/rule_packages/c/Declarations3.json
+++ b/rule_packages/c/Declarations3.json
@@ -14,7 +14,8 @@
"shared_implementation_short_name": "IdentifierHidden",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query does not consider C90 or C99 definitions of significant name and instead uses full name matches only.",
@@ -38,7 +39,8 @@
"short_name": "IdentifiersNotDistinctFromMacroNames",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -58,7 +60,8 @@
"short_name": "TypedefNameNotUnique",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -78,7 +81,8 @@
"short_name": "TagNameNotUnique",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -99,7 +103,8 @@
"shared_implementation_short_name": "TypeOmitted",
"tags": [
"correctness",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query does not check for implicitly typed parameters, typedefs or member declarations as this is partially compiler checked.",
diff --git a/rule_packages/c/Declarations4.json b/rule_packages/c/Declarations4.json
index bfd0b18328..dedc6a73d4 100644
--- a/rule_packages/c/Declarations4.json
+++ b/rule_packages/c/Declarations4.json
@@ -12,8 +12,10 @@
"precision": "medium",
"severity": "error",
"short_name": "FunctionTypesNotInPrototypeForm",
+ "shared_implementation_short_name": "FunctionTypesNotInPrototypeFormShared",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query does not check for implicitly typed parameters and checks function declarations and definitions but not function pointer types. This query cannot determine when the keyword void is used in place of no parameter.",
@@ -36,7 +38,8 @@
"severity": "error",
"short_name": "DeclarationsOfAnObjectSameNameAndType",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -47,7 +50,8 @@
"severity": "error",
"short_name": "DeclarationsOfAFunctionSameNameAndType",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -68,7 +72,8 @@
"tags": [
"readability",
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query does not check for the recommendation of declarations in headers.",
@@ -85,7 +90,8 @@
"tags": [
"readability",
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query does not check for the recommendation of declarations in headers.",
@@ -109,7 +115,8 @@
"short_name": "IdentifierWithExternalLinkageOneDefinition",
"shared_implementation_short_name": "IdentifierWithExternalLinkageOneDefinitionShared",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Declarations5.json b/rule_packages/c/Declarations5.json
index 705f72791c..36591e575b 100644
--- a/rule_packages/c/Declarations5.json
+++ b/rule_packages/c/Declarations5.json
@@ -15,7 +15,8 @@
"tags": [
"correctness",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query considers the first 63 characters of identifiers as significant, as per C99 for nonexternal identifiers and reports the case when names are longer than 63 characters and differ in those characters past the 63 first only. This query does not consider universal or extended source characters.",
@@ -38,7 +39,8 @@
"severity": "warning",
"short_name": "ExternalObjectOrFunctionNotDeclaredInOneFile",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -58,7 +60,8 @@
"short_name": "MissingStaticSpecifierFunctionRedeclarationC",
"shared_implementation_short_name": "MissingStaticSpecifierFunctionRedeclarationShared",
"tags": [
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -68,8 +71,10 @@
"precision": "very-high",
"severity": "warning",
"short_name": "MissingStaticSpecifierObjectRedeclarationC",
+ "shared_implementation_short_name": "MissingStaticSpecifierObjectRedeclarationShared",
"tags": [
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -89,7 +94,8 @@
"short_name": "UnnecessaryExposedIdentifierDeclarationC",
"shared_implementation_short_name": "UnnecessaryExposedIdentifierDeclarationShared",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Declarations6.json b/rule_packages/c/Declarations6.json
index 166d0c568b..198b4e8351 100644
--- a/rule_packages/c/Declarations6.json
+++ b/rule_packages/c/Declarations6.json
@@ -14,7 +14,8 @@
"short_name": "FunctionDeclaredImplicitly",
"tags": [
"correctness",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -33,7 +34,8 @@
"severity": "error",
"short_name": "FlexibleArrayMembersDeclared",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -53,7 +55,8 @@
"short_name": "IdentifiersWithExternalLinkageNotUnique",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -73,7 +76,8 @@
"short_name": "IdentifiersWithInternalLinkageNotUnique",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This rule does not explicitly check for the exception of inline functions in header files across multiple translation units as the CodeQL database already represents these as the same entity."
@@ -95,7 +99,8 @@
"severity": "error",
"short_name": "InlineFunctionNotDeclaredStaticStorage",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -115,7 +120,8 @@
"short_name": "ArrayExternalLinkageSizeExplicitlySpecified",
"tags": [
"correctness",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -136,7 +142,8 @@
"tags": [
"correctness",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Declarations7.json b/rule_packages/c/Declarations7.json
index b1be4f9d55..cdb74123b1 100644
--- a/rule_packages/c/Declarations7.json
+++ b/rule_packages/c/Declarations7.json
@@ -39,7 +39,8 @@
"short_name": "VariableLengthArrayTypesUsed",
"tags": [
"correctness",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -60,7 +61,8 @@
"shared_implementation_short_name": "NonUniqueEnumerationConstant",
"tags": [
"correctness",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/EssentialTypes.json b/rule_packages/c/EssentialTypes.json
index 57c7ace1ba..a8ae26e8c6 100644
--- a/rule_packages/c/EssentialTypes.json
+++ b/rule_packages/c/EssentialTypes.json
@@ -13,7 +13,8 @@
"severity": "warning",
"short_name": "OperandsOfAnInappropriateEssentialType",
"tags": [
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -24,7 +25,8 @@
"severity": "warning",
"short_name": "PointerTypeOnLogicalOperator",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -44,7 +46,8 @@
"short_name": "AdditionSubtractionOnEssentiallyCharType",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -64,7 +67,8 @@
"short_name": "AssignmentOfIncompatibleEssentialType",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -84,7 +88,8 @@
"short_name": "OperandsWithMismatchedEssentialTypeCategory",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -104,7 +109,8 @@
"short_name": "InappropriateEssentialTypeCast",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -124,7 +130,8 @@
"short_name": "AssignmentToWiderEssentialType",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -144,7 +151,8 @@
"short_name": "ImplicitConversionOfCompositeExpression",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -164,7 +172,8 @@
"short_name": "InappropriateCastOfCompositeExpression",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -184,7 +193,8 @@
"short_name": "LoopOverEssentiallyFloatType",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -204,7 +214,8 @@
"short_name": "MemcmpUsedToCompareNullTerminatedStrings",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -224,7 +235,8 @@
"short_name": "MemcmpOnInappropriateEssentialTypeArgs",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/FunctionTypes.json b/rule_packages/c/FunctionTypes.json
new file mode 100644
index 0000000000..d9d8b6496d
--- /dev/null
+++ b/rule_packages/c/FunctionTypes.json
@@ -0,0 +1,24 @@
+{
+ "MISRA-C-2012": {
+ "RULE-17-12": {
+ "properties": {
+ "obligation": "advisory"
+ },
+ "queries": [
+ {
+ "description": "A function identifier should only be called with a parenthesized parameter list or used with a & (address-of).",
+ "kind": "problem",
+ "name": "A function identifier should only be called with a parenthesized parameter list or used with a &",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "FunctionAddressesShouldAddressOperator",
+ "tags": [
+ "readability",
+ "external/misra/c/2012/amendment3"
+ ]
+ }
+ ],
+ "title": "A function identifier should only be called with a parenthesized parameter list or used with a & (address-of)"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rule_packages/c/IO1.json b/rule_packages/c/IO1.json
index 1d90c6f28f..f5b9ec8b0e 100644
--- a/rule_packages/c/IO1.json
+++ b/rule_packages/c/IO1.json
@@ -145,7 +145,8 @@
"short_name": "FileUsedAfterClosed",
"shared_implementation_short_name": "DoNotAccessAClosedFile",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "The rule is enforced in the context of a single function."
diff --git a/rule_packages/c/IO3.json b/rule_packages/c/IO3.json
index 8d1c250eda..52276eb05c 100644
--- a/rule_packages/c/IO3.json
+++ b/rule_packages/c/IO3.json
@@ -60,7 +60,8 @@
"severity": "error",
"short_name": "FileOpenForReadAndWriteOnDifferentStreams",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "The rule is enforced in the context of a single function."
@@ -82,7 +83,8 @@
"severity": "error",
"short_name": "AttemptToWriteToAReadOnlyStream",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -101,7 +103,8 @@
"severity": "error",
"short_name": "PointerToAFileObjectDereferenced",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -120,7 +123,8 @@
"severity": "error",
"short_name": "EofShallBeComparedWithUnmodifiedReturnValues",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/IO4.json b/rule_packages/c/IO4.json
index 0873d2707b..1303f9b50f 100644
--- a/rule_packages/c/IO4.json
+++ b/rule_packages/c/IO4.json
@@ -68,4 +68,4 @@
"title": "Use valid format strings"
}
}
-}
+}
\ No newline at end of file
diff --git a/rule_packages/c/IntegerOverflow.json b/rule_packages/c/IntegerOverflow.json
index 0fb1c5a4e7..a7897fad9e 100644
--- a/rule_packages/c/IntegerOverflow.json
+++ b/rule_packages/c/IntegerOverflow.json
@@ -115,7 +115,8 @@
"shared_implementation_short_name": "ConstantUnsignedIntegerExpressionsWrapAround",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/InvalidMemory1.json b/rule_packages/c/InvalidMemory1.json
index 0d84c1c87e..227ec37558 100644
--- a/rule_packages/c/InvalidMemory1.json
+++ b/rule_packages/c/InvalidMemory1.json
@@ -78,7 +78,8 @@
"short_name": "ObjectWithAutoStorageDurationReadBeforeInit",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Language1.json b/rule_packages/c/Language1.json
index 50aed45c55..6b20822196 100644
--- a/rule_packages/c/Language1.json
+++ b/rule_packages/c/Language1.json
@@ -14,7 +14,8 @@
"short_name": "LanguageNotEncapsulatedAndIsolated",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Language2.json b/rule_packages/c/Language2.json
index 66f219a025..43dbb4ecef 100644
--- a/rule_packages/c/Language2.json
+++ b/rule_packages/c/Language2.json
@@ -15,7 +15,8 @@
"shared_implementation_short_name": "UsageOfAssemblerNotDocumented",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -35,7 +36,8 @@
"short_name": "EmergentLanguageFeaturesUsed",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/amendment2"
]
}
],
diff --git a/rule_packages/c/Language3.json b/rule_packages/c/Language3.json
index d48444a4ab..c19881e05c 100644
--- a/rule_packages/c/Language3.json
+++ b/rule_packages/c/Language3.json
@@ -14,7 +14,8 @@
"short_name": "LanguageExtensionsShouldNotBeUsed",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This implementation attempts to cover a broad section of the compiler specific extensions documented in: https://clang.llvm.org/docs/LanguageExtensions.html and https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html but is not comprehensive. The following topics are addressed in this query: Builtin macros, Variable Attributes, Function Attributes, Statement Expressions, Non-Local Gotos, Conditionals, Extended Integer / Numeric Types, Zero Length Structures, Zero Length Arrays, Variable Length Arrays, Case Attributes, Alignment, __sync and __fetch builtins. Other topics listed in the extension references are not covered by this query."
@@ -37,7 +38,8 @@
"short_name": "OccurrenceOfUndefinedBehavior",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This implementation only considers alternate forms of `main` and the undefined behavior that results. Note that the current version of CodeQL is not able to detect this issue if a function is named `main` since it will assume the return type and formal parameters. Additional cases from Appendix J of the C99 standard are not currently considered."
diff --git a/rule_packages/c/Language4.json b/rule_packages/c/Language4.json
new file mode 100644
index 0000000000..fdc11924f4
--- /dev/null
+++ b/rule_packages/c/Language4.json
@@ -0,0 +1,144 @@
+{
+ "MISRA-C-2012": {
+ "RULE-1-5": {
+ "properties": {
+ "obligation": "required"
+ },
+ "queries": [
+ {
+ "description": "Declaring a function with internal linkage without the static storage class specifier is an obselescent feature.",
+ "kind": "problem",
+ "name": "If a function has internal linkage then all re-declarations shall include the static storage class",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "MissingStaticSpecifierFuncRedeclarationObsolete",
+ "shared_implementation_short_name": "MissingStaticSpecifierFunctionRedeclarationShared",
+ "tags": [
+ "readability",
+ "external/misra/c/2012/amendment3"
+ ]
+ },
+ {
+ "description": "Declaring an identifier with internal linkage without the static storage class specifier is an obselescent feature.",
+ "kind": "problem",
+ "name": "If an object has internal linkage then all re-declarations shall include the static storage class",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "MissingStaticSpecifierObjectRedeclarationObsolete",
+ "shared_implementation_short_name": "MissingStaticSpecifierObjectRedeclarationShared",
+ "tags": [
+ "readability",
+ "external/misra/c/2012/amendment3"
+ ]
+ },
+ {
+ "description": "The use of non-prototype format parameter type declarators is an obsolescent language feature.",
+ "kind": "problem",
+ "name": "Function types shall be in prototype form with named parameters",
+ "precision": "medium",
+ "severity": "error",
+ "short_name": "FunctionTypesNotInPrototypeFormObsolete",
+ "shared_implementation_short_name": "FunctionTypesNotInPrototypeFormShared",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ],
+ "implementation_scope": {
+ "description": "This query does not check for implicitly typed parameters and checks function declarations and definitions but not function pointer types."
+ }
+ },
+ {
+ "description": "The macro ATOMIC_VAR_INIT is has been declared an obsolescent language feature since C18.",
+ "kind": "problem",
+ "name": "Disallowed usage of obsolete macro ATOMIC_VAR_INIT compiled as C18",
+ "precision": "very-high",
+ "severity": "recommendation",
+ "short_name": "UseOfObsoleteMacroAtomicVarInit",
+ "tags": [
+ "maintainability",
+ "readability",
+ "external/misra/c/2012/amendment3"
+ ]
+ },
+ {
+ "description": "Directives that undefine and/or redefine the standard boolean macros has been declared an obsolescent language feature since C99.",
+ "kind": "problem",
+ "name": "Programs may not undefine or redefine the macros bool, true, or false",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "InvalidDefineOrUndefOfStdBoolMacro",
+ "tags": [
+ "maintainability",
+ "readability",
+ "external/misra/c/2012/amendment3"
+ ]
+ },
+ {
+ "description": "The function 'gets' is an obsolescent language feature which was removed in C11.",
+ "kind": "problem",
+ "name": "Disallowed usage of obsolescent function 'gets'",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "CallToObsolescentFunctionGets",
+ "tags": [
+ "external/misra/c/2012/amendment3",
+ "security",
+ "maintainability"
+ ]
+ },
+ {
+ "description": "Calling the function 'ungetc' on a file stream with a position of zero is an obsolescent language feature.",
+ "kind": "path-problem",
+ "name": "Disallowed obsolescent usage of 'ungetc' on a file stream at position zero",
+ "precision": "high",
+ "severity": "error",
+ "short_name": "UngetcCallOnStreamPositionZero",
+ "tags": [
+ "external/misra/c/2012/amendment3",
+ "security",
+ "maintainability"
+ ]
+ },
+ {
+ "description": "Invoking realloc with a size argument set to zero is implementation-defined behavior and declared as an obsolete feature in C18.",
+ "kind": "problem",
+ "name": "Size argument value in realloc call may equal zero",
+ "precision": "medium",
+ "severity": "error",
+ "short_name": "SizeInReallocCallMayBeZero",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ]
+ },
+ {
+ "description": "Invoking realloc with a size argument set to zero is implementation-defined behavior and declared as an obsolete feature in C18.",
+ "kind": "problem",
+ "name": "Size argument value in realloc call is equal zero",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "SizeInReallocCallIsZero",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ]
+ }
+ ],
+ "title": "Obsolencent language features shall not be used",
+ "implementation_scope": {
+ "description": "Not all items from Appendix F are covered by this rule. Some are not supportable and some are covered already by other rules.",
+ "items": [
+ "Appendix F, item ID 1 is reported by both Rule 8.8 and by this implementation of Rule 1.5.",
+ "Appendix F, item ID 2 refers to compiler behavior which cannot be statically analyzed.",
+ "Appendix F, item ID 3, which states that storage-class specifiers may not be used except in the beginning of a declaration, is not supportable without additional changes to the CodeQL CLI.",
+ "Appendix F, item IDs 4 and 5 are reported by both Rule 8.2 and by this implementation of Rule 1.5.",
+ "Appendix F, item ID 6 is reported for all C versions, though the macro ATOMIC_VAR_INIT was not officially declared obsolescent until C18.",
+ "Appendix F, item ID 8 is reported by both Rule 21.6 and by this implementation of Rule 1.5.",
+ "Appendix F, item ID 9 is reported by this implementation of 1.5, though all uses of ungetc() are also reported by Rule 21.3.",
+ "Appendix F, item ID 10 is reported by this implementation of 1.5, though all uses of realloc() are also reported by Rule 21.3.",
+ "Appendix F, item ID 10 is reported for all C versions, as realloc() with a size argument of zero was implementation-defined behavior in C99 and C11."
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/rule_packages/c/Memory1.json b/rule_packages/c/Memory1.json
index 7232b18751..8515fe15e1 100644
--- a/rule_packages/c/Memory1.json
+++ b/rule_packages/c/Memory1.json
@@ -14,8 +14,9 @@
"short_name": "InitializerForAggregateOrUnionNotEnclosedInBraces",
"shared_implementation_short_name": "UseInitializerBracesToMatchAggregateTypeStructure",
"tags": [
- "maintainability",
- "readability"
+ "maintainability",
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -35,7 +36,8 @@
"short_name": "PartiallyInitializedArrayWithExplicitInitializers",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -56,7 +58,8 @@
"tags": [
"correctness",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Memory2.json b/rule_packages/c/Memory2.json
index 677711938a..358d482194 100644
--- a/rule_packages/c/Memory2.json
+++ b/rule_packages/c/Memory2.json
@@ -164,7 +164,8 @@
"shared_implementation_short_name": "FreeMemoryWhenNoLongerNeededShared",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "The rule is enforced in the context of a single function."
@@ -180,7 +181,8 @@
"shared_implementation_short_name": "CloseFileHandleWhenNoLongerNeededShared",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "The rule is enforced in the context of a single function."
@@ -204,7 +206,8 @@
"shared_implementation_short_name": "OnlyFreeMemoryAllocatedDynamicallyShared",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Misc.json b/rule_packages/c/Misc.json
index 323ec17350..bba96db85c 100644
--- a/rule_packages/c/Misc.json
+++ b/rule_packages/c/Misc.json
@@ -12,7 +12,7 @@
"precision": "very-high",
"severity": "error",
"short_name": "RandUsedForGeneratingPseudorandomNumbers",
- "shared_implementation_short_name" : "DoNotUseRandForGeneratingPseudorandomNumbers",
+ "shared_implementation_short_name": "DoNotUseRandForGeneratingPseudorandomNumbers",
"tags": [
"security"
]
diff --git a/rule_packages/c/NoReturn.json b/rule_packages/c/NoReturn.json
new file mode 100644
index 0000000000..f485060095
--- /dev/null
+++ b/rule_packages/c/NoReturn.json
@@ -0,0 +1,65 @@
+{
+ "MISRA-C-2012": {
+ "RULE-17-10": {
+ "properties": {
+ "obligation": "required"
+ },
+ "queries": [
+ {
+ "description": "Function declared with _noreturn will by definition not return a value, and should be declared to return void.",
+ "kind": "problem",
+ "name": "A function declared with _noreturn shall have a return type of void",
+ "precision": "very-high",
+ "severity": "recommendation",
+ "short_name": "NonVoidReturnTypeOfNoreturnFunction",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ]
+ }
+ ],
+ "title": "A function declared with _noreturn shall have a return type of void"
+ },
+ "RULE-17-11": {
+ "properties": {
+ "obligation": "advisory"
+ },
+ "queries": [
+ {
+ "description": "Functions which cannot return should be declared with _Noreturn.",
+ "kind": "problem",
+ "name": "A function without a branch that returns shall be declared with _Noreturn",
+ "precision": "very-high",
+ "severity": "recommendation",
+ "short_name": "FunctionWithNoReturningBranchShouldBeNoreturn",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ]
+ }
+ ],
+ "title": "A function without a branch that returns shall be declared with _Noreturn"
+ },
+ "RULE-17-9": {
+ "properties": {
+ "obligation": "mandatory"
+ },
+ "queries": [
+ {
+ "description": "Returning inside a function declared with _Noreturn is undefined behavior.",
+ "kind": "problem",
+ "name": "Verify that a function declared with _Noreturn does not return",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "ReturnStatementInNoreturnFunction",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ],
+ "shared_implementation_short_name": "FunctionNoReturnAttributeCondition"
+ }
+ ],
+ "title": "Verify that a function declared with _Noreturn does not return"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rule_packages/c/OutOfBounds.json b/rule_packages/c/OutOfBounds.json
index 31d0349a63..759b68e294 100644
--- a/rule_packages/c/OutOfBounds.json
+++ b/rule_packages/c/OutOfBounds.json
@@ -56,7 +56,8 @@
"short_name": "StringFunctionPointerArgumentOutOfBounds",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -76,7 +77,8 @@
"short_name": "StringLibrarySizeArgumentOutOfBounds",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Pointers1.json b/rule_packages/c/Pointers1.json
index 6b2df1595c..29b658d823 100644
--- a/rule_packages/c/Pointers1.json
+++ b/rule_packages/c/Pointers1.json
@@ -13,7 +13,8 @@
"severity": "error",
"short_name": "ConversionBetweenFunctionPointerAndOtherType",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -32,7 +33,8 @@
"severity": "error",
"short_name": "ConversionBetweenIncompleteTypePointerAndOtherType",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -51,7 +53,8 @@
"severity": "error",
"short_name": "CastBetweenObjectPointerAndDifferentObjectType",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -70,7 +73,8 @@
"severity": "error",
"short_name": "ConversionBetweenPointerToObjectAndIntegerType",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -89,7 +93,8 @@
"severity": "error",
"short_name": "ConversionFromPointerToVoidIntoPointerToObject",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -108,7 +113,8 @@
"severity": "error",
"short_name": "CastBetweenPointerToVoidAndArithmeticType",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -127,7 +133,8 @@
"severity": "error",
"short_name": "CastBetweenPointerToObjectAndNonIntArithmeticType",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -146,7 +153,8 @@
"severity": "error",
"short_name": "CastRemovesConstOrVolatileQualification",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -165,7 +173,8 @@
"severity": "error",
"short_name": "MacroNullNotUsedAsIntegerNullPointerConstant",
"tags": [
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This rule allows two forms of null-pointer constants: a Zero literal created by the NULL macro or a Zero literal cast to a void pointer."
@@ -188,7 +197,8 @@
"short_name": "PointerAndDerivedPointerMustAddressSameArray",
"shared_implementation_short_name": "DoNotUsePointerArithmeticToAddressDifferentArrays",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -208,7 +218,8 @@
"short_name": "SubtractionBetweenPointersMustAddressSameArray",
"shared_implementation_short_name": "DoNotSubtractPointersAddressingDifferentArrays",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -228,7 +239,8 @@
"short_name": "RelationalOperatorComparesPointerToDifferentArray",
"shared_implementation_short_name": "DoNotUseRelationalOperatorsWithDifferingArrays",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -248,7 +260,8 @@
"short_name": "DoNotUseAdditionOrSubtractionOperatorsOnPointers",
"shared_implementation_short_name": "UseOnlyArrayIndexingForPointerArithmetic",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -268,7 +281,8 @@
"short_name": "NoMoreThanTwoLevelsOfPointerNestingInDeclarations",
"shared_implementation_short_name": "DoNotUseMoreThanTwoLevelsOfPointerIndirection",
"tags": [
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -288,7 +302,8 @@
"short_name": "AutomaticStorageObjectAddressCopiedToOtherObject",
"shared_implementation_short_name": "DoNotCopyAddressOfAutoStorageObjectToOtherObject",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -308,7 +323,8 @@
"short_name": "ObjectWithNoPointerDereferenceShouldBeOpaque",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This rule considers all cases where a structure or union is referenced as a pointer but has no FieldAccess within a translation unit. Further excluded from this rule are translation units in which the structure or union is declared as a non-pointer variable."
@@ -332,7 +348,8 @@
"tags": [
"correctness",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "To exclude compliant exceptions, this rule only excludes direct assignments of pointers to non-const-qualified types in the context of a single function and does not cover memory-copying functions. This rule also excludes pointers passed to other functions without conversion."
diff --git a/rule_packages/c/Pointers2.json b/rule_packages/c/Pointers2.json
index da275001c4..9abf4c98ce 100644
--- a/rule_packages/c/Pointers2.json
+++ b/rule_packages/c/Pointers2.json
@@ -12,7 +12,7 @@
"precision": "high",
"severity": "error",
"short_name": "DoNotAddOrSubtractAScaledIntegerToAPointer",
- "tags":[
+ "tags": [
"correctness"
]
}
diff --git a/rule_packages/c/Pointers3.json b/rule_packages/c/Pointers3.json
index a694300cd5..f35f5b7bd1 100644
--- a/rule_packages/c/Pointers3.json
+++ b/rule_packages/c/Pointers3.json
@@ -72,6 +72,7 @@
"precision": "medium",
"severity": "error",
"short_name": "DoNotPassAliasedPointerToRestrictQualifiedParam",
+ "shared_implementation_short_name": "DoNotPassAliasedPointerToRestrictQualifiedParamShared",
"tags": [
"correctness"
]
diff --git a/rule_packages/c/Preprocessor1.json b/rule_packages/c/Preprocessor1.json
index b93bc72731..cf4f023023 100644
--- a/rule_packages/c/Preprocessor1.json
+++ b/rule_packages/c/Preprocessor1.json
@@ -14,7 +14,8 @@
"short_name": "IncludeDirectivesPrecededByDirectivesOrComments",
"shared_implementation_short_name": "PreprocessorIncludesPreceded",
"tags": [
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -34,10 +35,10 @@
"short_name": "PreprocessorHashOperatorsShouldNotBeUsed",
"shared_implementation_short_name": "HashOperatorsUsed",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
-
],
"title": "The # and ## preprocessor operators should not be used"
},
@@ -55,7 +56,8 @@
"short_name": "ForbiddenCharactersInHeaderFileName",
"shared_implementation_short_name": "PreprocessorIncludesForbiddenHeaderNames",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query identifies the use of the ', \\, /*, // characters in header file names. The query is not able to detect the use of the \" character in header file names.",
@@ -79,8 +81,9 @@
"short_name": "IdentifiersUsedInPreprocessorExpression",
"shared_implementation_short_name": "UndefinedMacroIdentifiers",
"tags": [
- "correctness",
- "readability"
+ "correctness",
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query does not detect the case where an undefined character is used but not actually evaluated, for example, as a result of the inclusion of a logical AND operator in the #if expression.",
diff --git a/rule_packages/c/Preprocessor2.json b/rule_packages/c/Preprocessor2.json
index 546f426135..62bb0b770a 100644
--- a/rule_packages/c/Preprocessor2.json
+++ b/rule_packages/c/Preprocessor2.json
@@ -14,7 +14,8 @@
"short_name": "MoreThanOneHashOperatorInMacroDefinition",
"shared_implementation_short_name": "MacroParameterFollowingHash",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query applies to function like macros and not object like macros. This rule strictly disallows the use of # operator followed by a ## and other combinations are permitted.",
@@ -39,7 +40,8 @@
"shared_implementation_short_name": "AMixedUseMacroArgumentSubjectToExpansion",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -59,7 +61,8 @@
"short_name": "UndefShouldNotBeUsed",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -81,7 +84,8 @@
"tags": [
"correctness",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query defines header file as any file that is included regardless of file extension. This query does not consider the use of `#pragma once` as a permitted header guard.",
diff --git a/rule_packages/c/Preprocessor3.json b/rule_packages/c/Preprocessor3.json
index 0b0c735a04..79e2aec59c 100644
--- a/rule_packages/c/Preprocessor3.json
+++ b/rule_packages/c/Preprocessor3.json
@@ -1,24 +1,25 @@
{
"MISRA-C-2012": {
"RULE-20-8": {
- "properties": {
- "obligation": "required"
- },
- "queries": [
- {
- "description": "A controlling expression of a #if or #elif preprocessing directive that does not evaluate to 0 or 1 makes code more difficult to understand.",
- "kind": "problem",
- "name": "The controlling expression of a #if or #elif preprocessing directive shall evaluate to 0 or 1",
- "precision": "high",
- "severity": "warning",
- "short_name": "ControllingExpressionIfDirective",
- "tags": [
- "maintainability",
- "readability"
- ]
- }
- ],
- "title": "The controlling expression of a #if or #elif preprocessing directive shall evaluate to 0 or 1"
- }
+ "properties": {
+ "obligation": "required"
+ },
+ "queries": [
+ {
+ "description": "A controlling expression of a #if or #elif preprocessing directive that does not evaluate to 0 or 1 makes code more difficult to understand.",
+ "kind": "problem",
+ "name": "The controlling expression of a #if or #elif preprocessing directive shall evaluate to 0 or 1",
+ "precision": "high",
+ "severity": "warning",
+ "short_name": "ControllingExpressionIfDirective",
+ "tags": [
+ "maintainability",
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
+ }
+ ],
+ "title": "The controlling expression of a #if or #elif preprocessing directive shall evaluate to 0 or 1"
+ }
}
}
\ No newline at end of file
diff --git a/rule_packages/c/Preprocessor4.json b/rule_packages/c/Preprocessor4.json
index 404909c479..608a23d974 100644
--- a/rule_packages/c/Preprocessor4.json
+++ b/rule_packages/c/Preprocessor4.json
@@ -15,7 +15,8 @@
"tags": [
"correctness",
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -36,7 +37,8 @@
"shared_implementation_short_name": "PreprocessingDirectiveWithinMacroArgument",
"tags": [
"readability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -57,7 +59,8 @@
"tags": [
"correctness",
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Preprocessor5.json b/rule_packages/c/Preprocessor5.json
index 29c0156410..ef17b83c00 100644
--- a/rule_packages/c/Preprocessor5.json
+++ b/rule_packages/c/Preprocessor5.json
@@ -65,7 +65,8 @@
"shared_implementation_short_name": "MacroParameterNotEnclosedInParentheses",
"tags": [
"correctness",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "This query checks for every instance of a parameter to be enclosed in parentheses regardless of whether the expansion of that parameter forms an expression or not.",
diff --git a/rule_packages/c/Preprocessor6.json b/rule_packages/c/Preprocessor6.json
index 0bb7f34f90..6d71b8697b 100644
--- a/rule_packages/c/Preprocessor6.json
+++ b/rule_packages/c/Preprocessor6.json
@@ -16,7 +16,8 @@
"tags": [
"external/misra/audit",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/SideEffects1.json b/rule_packages/c/SideEffects1.json
index 821fb24d3c..9ecb79447d 100644
--- a/rule_packages/c/SideEffects1.json
+++ b/rule_packages/c/SideEffects1.json
@@ -83,7 +83,8 @@
"severity": "warning",
"short_name": "UnenclosedSizeofOperand",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -94,7 +95,8 @@
"severity": "warning",
"short_name": "ImplicitPrecedenceOfOperatorsInExpression",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -113,7 +115,8 @@
"severity": "error",
"short_name": "InitializerListsContainPersistentSideEffects",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -134,7 +137,8 @@
"shared_implementation_short_name": "ResultOfAnAssignmentOperatorShouldNotBeUsed",
"tags": [
"correctness",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -153,7 +157,8 @@
"severity": "error",
"short_name": "PossibleSuppressedSideEffectInLogicOperatorOperand",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -172,7 +177,8 @@
"severity": "error",
"short_name": "SizeofOperandWithSideEffect",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/SideEffects2.json b/rule_packages/c/SideEffects2.json
index 42467c2852..b7e1baa901 100644
--- a/rule_packages/c/SideEffects2.json
+++ b/rule_packages/c/SideEffects2.json
@@ -14,7 +14,8 @@
"short_name": "SideEffectAndCrementInFullExpression",
"tags": [
"readability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -33,7 +34,8 @@
"severity": "warning",
"short_name": "ModificationOfFunctionParameter",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/SideEffects3.json b/rule_packages/c/SideEffects3.json
index 2d67df6e2e..2bf91d77b9 100644
--- a/rule_packages/c/SideEffects3.json
+++ b/rule_packages/c/SideEffects3.json
@@ -13,7 +13,8 @@
"severity": "error",
"short_name": "UnsequencedSideEffects",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/StandardLibraryFunctionTypes.json b/rule_packages/c/StandardLibraryFunctionTypes.json
index 274eadbced..ee0d7f5af1 100644
--- a/rule_packages/c/StandardLibraryFunctionTypes.json
+++ b/rule_packages/c/StandardLibraryFunctionTypes.json
@@ -12,7 +12,9 @@
"precision": "very-high",
"severity": "error",
"short_name": "CtypeFunctionArgNotUnsignedCharOrEof",
- "tags": []
+ "tags": [
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "Any value passed to a function in shall be representable as an unsigned char or be the value EOF"
@@ -29,7 +31,9 @@
"precision": "very-high",
"severity": "error",
"short_name": "MemcpyMemmoveMemcmpArgNotPointersToCompatibleTypes",
- "tags": []
+ "tags": [
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "The pointer arguments to the Standard Library functions memcpy, memmove and memcmp shall be pointers to qualified or unqualified versions of compatible types"
diff --git a/rule_packages/c/Statements1.json b/rule_packages/c/Statements1.json
index a8dc1b55ea..c932a8642d 100644
--- a/rule_packages/c/Statements1.json
+++ b/rule_packages/c/Statements1.json
@@ -15,7 +15,8 @@
"shared_implementation_short_name": "NestedLabelInSwitch",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -35,7 +36,8 @@
"short_name": "BreakShallTerminateSwitchClause",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -55,7 +57,8 @@
"short_name": "EverySwitchShallHaveDefaultLabel",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -73,7 +76,9 @@
"precision": "very-high",
"severity": "recommendation",
"short_name": "DefaultNotFirstOrLastOfSwitch",
- "tags": []
+ "tags": [
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "A default label shall appear as either the first or the last switch label of a switch statement"
diff --git a/rule_packages/c/Statements2.json b/rule_packages/c/Statements2.json
index cb616429be..9cd71b69c9 100644
--- a/rule_packages/c/Statements2.json
+++ b/rule_packages/c/Statements2.json
@@ -15,7 +15,8 @@
"shared_implementation_short_name": "GotoStatementCondition",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -36,7 +37,8 @@
"shared_implementation_short_name": "GotoReferenceALabelInSurroundingBlock",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -56,7 +58,8 @@
"short_name": "LoopIterationCondition",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -76,7 +79,8 @@
"short_name": "SwitchClauseNumberCondition",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -96,7 +100,8 @@
"short_name": "SwitchExpressionBoolCondition",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Statements3.json b/rule_packages/c/Statements3.json
index 5471749a49..94206d485f 100644
--- a/rule_packages/c/Statements3.json
+++ b/rule_packages/c/Statements3.json
@@ -14,7 +14,8 @@
"short_name": "SwitchCompoundCondition",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -26,7 +27,8 @@
"short_name": "LoopCompoundCondition",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -38,7 +40,8 @@
"short_name": "SelectionCompoundCondition",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -59,7 +62,8 @@
"short_name": "IfElseEndCondition",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -80,7 +84,8 @@
"short_name": "SwitchCaseStartCondition",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -93,7 +98,8 @@
"short_name": "SwitchStmtNotWellFormed",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -113,7 +119,8 @@
"short_name": "RecursiveFunctionCondition",
"tags": [
"maintainability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Statements4.json b/rule_packages/c/Statements4.json
index 56e13c9de6..5b0cc9be26 100644
--- a/rule_packages/c/Statements4.json
+++ b/rule_packages/c/Statements4.json
@@ -37,7 +37,8 @@
"short_name": "ForLoopNotWellFormed",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -57,7 +58,8 @@
"short_name": "NonBooleanIfCondition",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
},
{
@@ -69,7 +71,8 @@
"short_name": "NonBooleanIterationCondition",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Statements5.json b/rule_packages/c/Statements5.json
index 93a533939b..329819b61f 100644
--- a/rule_packages/c/Statements5.json
+++ b/rule_packages/c/Statements5.json
@@ -15,7 +15,8 @@
"tags": [
"correctness",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -36,7 +37,8 @@
"tags": [
"maintainability",
"readability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -58,11 +60,12 @@
"tags": [
"correctness",
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
"title": "All exit paths from a function with non-void return type shall have an explicit return statement with an expression"
}
}
-}
+}
\ No newline at end of file
diff --git a/rule_packages/c/Statements6.json b/rule_packages/c/Statements6.json
index 8d71f11cfd..c8ab3efe38 100644
--- a/rule_packages/c/Statements6.json
+++ b/rule_packages/c/Statements6.json
@@ -15,7 +15,8 @@
"shared_implementation_short_name": "GotoStatementShouldNotBeUsed",
"tags": [
"correctness",
- "security"
+ "security",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Static.json b/rule_packages/c/Static.json
index 7edf903703..2af2af402a 100644
--- a/rule_packages/c/Static.json
+++ b/rule_packages/c/Static.json
@@ -13,7 +13,8 @@
"severity": "error",
"short_name": "UseOfArrayStatic",
"tags": [
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
],
"implementation_scope": {
"description": "The static keyword is associated with particular array types in our model. This means we can get false positives when two parameter use the same array type and size, but only one of which uses the `static` keyword."
diff --git a/rule_packages/c/Syntax.json b/rule_packages/c/Syntax.json
index b8899ccc97..e588c366c0 100644
--- a/rule_packages/c/Syntax.json
+++ b/rule_packages/c/Syntax.json
@@ -14,7 +14,8 @@
"short_name": "CharacterSequencesAndUsedWithinAComment",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -35,7 +36,8 @@
"tags": [
"maintainability",
"readability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -57,7 +59,8 @@
"tags": [
"maintainability",
"readability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -79,7 +82,8 @@
"tags": [
"maintainability",
"readability",
- "correctness"
+ "correctness",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -100,7 +104,8 @@
"shared_implementation_short_name": "DifferentIdentifiersNotTypographicallyUnambiguous",
"tags": [
"readability",
- "maintainability"
+ "maintainability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
@@ -120,8 +125,12 @@
"short_name": "UOrUSuffixRepresentedInUnsignedType",
"tags": [
"maintainability",
- "readability"
- ]
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
+ ],
+ "implementation_scope": {
+ "description": "This implementation does not consider constants defined in macro bodies."
+ }
}
],
"title": "A 'U' or 'u' suffix shall be applied to all integer constants that are represented in an unsigned type"
@@ -141,7 +150,8 @@
"shared_implementation_short_name": "LowercaseLStartsInLiteralSuffix",
"tags": [
"maintainability",
- "readability"
+ "readability",
+ "external/misra/c/2012/third-edition-first-revision"
]
}
],
diff --git a/rule_packages/c/Types1.json b/rule_packages/c/Types1.json
index fae0339d3c..cbf7f0b632 100644
--- a/rule_packages/c/Types1.json
+++ b/rule_packages/c/Types1.json
@@ -48,7 +48,9 @@
"precision": "high",
"severity": "error",
"short_name": "PlainNumericalTypeUsedOverExplicitTypedef",
- "tags": []
+ "tags": [
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "typedefs that indicate size and signedness should be used in place of the basic numerical types"
@@ -65,7 +67,9 @@
"precision": "very-high",
"severity": "error",
"short_name": "SizeofOperatorUsedOnArrayTypeParam",
- "tags": []
+ "tags": [
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "The sizeof operator shall not have an operand which is a function parameter declared as 'array of type'"
@@ -82,10 +86,12 @@
"precision": "very-high",
"severity": "error",
"short_name": "StringLiteralAssignedToNonConstChar",
- "tags": []
+ "tags": [
+ "external/misra/c/2012/third-edition-first-revision"
+ ]
}
],
"title": "A string literal shall not be assigned to an object unless the object's type is 'pointer to const-qualified char'"
}
}
-}
+}
\ No newline at end of file
diff --git a/rule_packages/c/Types2.json b/rule_packages/c/Types2.json
new file mode 100644
index 0000000000..7e4c0827fe
--- /dev/null
+++ b/rule_packages/c/Types2.json
@@ -0,0 +1,84 @@
+{
+ "MISRA-C-2012": {
+ "RULE-7-5": {
+ "properties": {
+ "obligation": "required"
+ },
+ "queries": [
+ {
+ "description": "Integer constant macros should be given a literal value as an argument.",
+ "kind": "problem",
+ "name": "The argument of an integer constant macro shall be a literal",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "InvalidIntegerConstantMacroArgument",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ]
+ },
+ {
+ "description": "Integer constant macro arguments should be a decimal, hex, or octal literal.",
+ "kind": "problem",
+ "name": "The argument of an integer constant macro shall be a decimal, hex, or octal literal",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "InvalidLiteralForIntegerConstantMacroArgument",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ]
+ },
+ {
+ "description": "Integer constant macros should be used integer literal values with no u/l suffix.",
+ "kind": "problem",
+ "name": "The argument of an integer constant macro shall not use literal suffixes u, l, or ul",
+ "precision": "high",
+ "severity": "warning",
+ "short_name": "IntegerConstantMacroArgumentUsesSuffix",
+ "tags": [
+ "readability",
+ "maintainability",
+ "external/misra/c/2012/amendment3"
+ ]
+ },
+ {
+ "description": "Integer constant macros argument values should be values of a compatible size.",
+ "kind": "problem",
+ "name": "The argument of an integer constant macro shall have an appropriate size",
+ "precision": "very-high",
+ "severity": "error",
+ "short_name": "IncorrectlySizedIntegerConstantMacroArgument",
+ "tags": [
+ "correctness",
+ "external/misra/c/2012/amendment3"
+ ],
+ "implementation_scope": {
+ "description": "This rule can validate integers sized 32 or smaller. When the CodeQL runtime supports big ints, this will be expanded to include 64 bit integer types."
+ }
+ }
+ ],
+ "title": "The argument of an integer constant macro shall have an appropriate form"
+ },
+ "RULE-7-6": {
+ "properties": {
+ "obligation": "required"
+ },
+ "queries": [
+ {
+ "description": "Small integer constant macros expression are promoted to type int, which can lead to unexpected results.",
+ "kind": "problem",
+ "name": "The small integer variants of the minimum-width integer constant macros shall not be used",
+ "precision": "very-high",
+ "severity": "warning",
+ "short_name": "UseOfBannedSmallIntegerConstantMacro",
+ "tags": [
+ "readability",
+ "external/misra/c/2012/amendment3"
+ ]
+ }
+ ],
+ "title": "The small integer variants of the minimum-width integer constant macros shall not be used"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rule_packages/cpp/DeadCode.json b/rule_packages/cpp/DeadCode.json
index 7eb5c9f6f9..4746f86dee 100644
--- a/rule_packages/cpp/DeadCode.json
+++ b/rule_packages/cpp/DeadCode.json
@@ -194,6 +194,21 @@
"readability",
"maintainability"
]
+ },
+ {
+ "description": "Uncalled functions complicate the program and can indicate a possible mistake on the part of the programmer.",
+ "kind": "problem",
+ "name": "Every defined function should be called at least once",
+ "precision": "medium",
+ "severity": "warning",
+ "short_name": "UnusedSplMemberFunction",
+ "tags": [
+ "readability",
+ "maintainability"
+ ],
+ "implementation_scope": {
+ "description": "In limited cases, this query can raise false-positives for special member function calls invoked from the C++ Metaprogramming library."
+ }
}
],
"title": "Every defined function should be called at least once."
diff --git a/rule_packages/cpp/Representation.json b/rule_packages/cpp/Representation.json
index c87094ea4b..0284d8098f 100644
--- a/rule_packages/cpp/Representation.json
+++ b/rule_packages/cpp/Representation.json
@@ -53,6 +53,18 @@
"tags": [
"correctness"
]
+ },
+ {
+ "description": "Passing a aliased pointers as parameters of certain functions is undefined behavior.",
+ "kind": "problem",
+ "name": "Do not pass aliased pointers as parameters of functions where it is undefined behaviour for those pointers to overlap",
+ "precision": "medium",
+ "severity": "error",
+ "short_name": "DoNotPassAliasedPointerToParam",
+ "shared_implementation_short_name": "DoNotPassAliasedPointerToRestrictQualifiedParamShared",
+ "tags": [
+ "correctness"
+ ]
}
],
"title": "An object shall not be assigned to an overlapping object."
diff --git a/rules.csv b/rules.csv
index e494a82ea3..475ea1d66c 100644
--- a/rules.csv
+++ b/rules.csv
@@ -616,10 +616,15 @@ c,MISRA-C-2012,DIR-4-11,Yes,Required,,,The validity of values passed to library
c,MISRA-C-2012,DIR-4-12,Yes,Required,,,Dynamic memory allocation shall not be used,,Banned,Medium,
c,MISRA-C-2012,DIR-4-13,No,Advisory,,,Functions which are designed to provide operations on a resource should be called in an appropriate sequence,,,,"Rule 22.1, 22.2 and 22.6 cover aspects of this rule. In other cases this is a design issue and needs to be checked manually."
c,MISRA-C-2012,DIR-4-14,Yes,Required,,,The validity of values received from external sources shall be checked,,Contracts,Hard,This is supported by CodeQLs default C security queries.
+c,MISRA-C-2012,DIR-4-15,Yes,Required,,,Evaluation of floating-point expressions shall not lead to the undetected generation of infinities and NaNs,FLP32-C and FLP04-C,FloatingTypes2,Medium,
+c,MISRA-C-2012,DIR-5-1,Yes,Required,,,There shall be no data races between threads,CON43-C and CON32-C,Concurrency6,Very Hard,
+c,MISRA-C-2012,DIR-5-2,Yes,Required,,,There shall be no deadlocks between threads,CON35-C,Concurrency6,Import,
+c,MISRA-C-2012,DIR-5-3,Yes,Required,,,There shall be no dynamic thread creation,,Concurrency6,Easy,
c,MISRA-C-2012,RULE-1-1,No,Required,,,"The program shall contain no violations of the standard C syntax and constraints, and shall not exceed the implementation's translation limits",,,Easy,"This should be checked via the compiler output, rather than CodeQL, which adds unnecessary steps."
c,MISRA-C-2012,RULE-1-2,Yes,Advisory,,,Language extensions should not be used,,Language3,Hard,
c,MISRA-C-2012,RULE-1-3,Yes,Required,,,There shall be no occurrence of undefined or critical unspecified behaviour,,Language3,Hard,
c,MISRA-C-2012,RULE-1-4,Yes,Required,,,Emergent language features shall not be used,,Language2,Medium,
+c,MISRA-C-2012,RULE-1-5,Yes,Required,,,Obsolencent language features shall not be used,,Language4,Medium,
c,MISRA-C-2012,RULE-2-1,Yes,Required,,,A project shall not contain unreachable code,M0-1-1,DeadCode,Import,
c,MISRA-C-2012,RULE-2-2,Yes,Required,,,There shall be no dead code,M0-1-9,DeadCode,Import,
c,MISRA-C-2012,RULE-2-3,Yes,Advisory,,,A project should not contain unused type declarations,A0-1-6,DeadCode,Import,
@@ -627,6 +632,7 @@ c,MISRA-C-2012,RULE-2-4,Yes,Advisory,,,A project should not contain unused tag d
c,MISRA-C-2012,RULE-2-5,Yes,Advisory,,,A project should not contain unused macro declarations,,DeadCode,Easy,
c,MISRA-C-2012,RULE-2-6,Yes,Advisory,,,A function should not contain unused label declarations,,DeadCode,Easy,
c,MISRA-C-2012,RULE-2-7,Yes,Advisory,,,There should be no unused parameters in functions,A0-1-4 A0-1-5,DeadCode,Easy,
+c,MISRA-C-2012,RULE-2-8,Yes,Advisory,,,A project should not contain unused object definitions,Rules 2.3-2.7,DeadCode2,Medium,
c,MISRA-C-2012,RULE-3-1,Yes,Required,,,The character sequences /* and // shall not be used within a comment,M2-7-1,Syntax,Easy,
c,MISRA-C-2012,RULE-3-2,Yes,Required,,,Line-splicing shall not be used in // comments,,Syntax,Easy,
c,MISRA-C-2012,RULE-4-1,Yes,Required,,,Octal and hexadecimal escape sequences shall be terminated,A2-13-1 M2-13-2,Syntax,Medium,
@@ -642,10 +648,13 @@ c,MISRA-C-2012,RULE-5-8,Yes,Required,,,Identifiers that define objects or functi
c,MISRA-C-2012,RULE-5-9,Yes,Advisory,,,Identifiers that define objects or functions with internal linkage should be unique,,Declarations6,Easy,
c,MISRA-C-2012,RULE-6-1,Yes,Required,,,Bit-fields shall only be declared with an appropriate type,M9-6-4,BitfieldTypes,Medium,
c,MISRA-C-2012,RULE-6-2,Yes,Required,,,Single-bit named bit fields shall not be of a signed type,M9-6-4,BitfieldTypes,Import,
+c,MISRA-C-2012,RULE-6-3,Yes,Required,,,A bit field shall not be declared as a member of a union,DCL39-C,BitfieldTypes2,Easy,
c,MISRA-C-2012,RULE-7-1,Yes,Required,,,Octal constants shall not be used,M2-13-2,Banned,Import,
c,MISRA-C-2012,RULE-7-2,Yes,Required,,,A 'u' or 'U' suffix shall be applied to all integer constants that are represented in an unsigned type,M2-13-3,Syntax,Easy,
c,MISRA-C-2012,RULE-7-3,Yes,Required,,,The lowercase character 'l' shall not be used in a literal suffix,M2-13-4,Syntax,Easy,
c,MISRA-C-2012,RULE-7-4,Yes,Required,,,A string literal shall not be assigned to an object unless the object's type is 'pointer to const-qualified char',A2-13-4,Types1,Easy,
+c,MISRA-C-2012,RULE-7-5,Yes,Required,,,The argument of an integer constant macro shall have an appropriate form,,Types2,Medium,
+c,MISRA-C-2012,RULE-7-6,Yes,Required,,,The small integer variants of the minimum-width integer constant macros shall not be used,,Types2,Easy,
c,MISRA-C-2012,RULE-8-1,Yes,Required,,,Types shall be explicitly specified,,Declarations3,Medium,
c,MISRA-C-2012,RULE-8-2,Yes,Required,,,Function types shall be in prototype form with named parameters,,Declarations4,Medium,
c,MISRA-C-2012,RULE-8-3,Yes,Required,,,All declarations of an object or function shall use the same names and type qualifiers,M3-2-1,Declarations4,Medium,
@@ -660,11 +669,16 @@ c,MISRA-C-2012,RULE-8-11,Yes,Advisory,,,"When an array with external linkage is
c,MISRA-C-2012,RULE-8-12,Yes,Required,,,"Within an enumerator list, the value of an implicitly-specified enumeration constant shall be unique",,Declarations7,Medium,
c,MISRA-C-2012,RULE-8-13,Yes,Advisory,,,A pointer should point to a const-qualified type whenever possible,,Pointers1,Medium,
c,MISRA-C-2012,RULE-8-14,Yes,Required,,,The restrict type qualifier shall not be used,,Banned,Easy,
+c,MISRA-C-2012,RULE-8-15,Yes,Required,,,All declarations of an object with an explicit alignment specification shall specify the same alignment,,Alignment,Easy,
+c,MISRA-C-2012,RULE-8-16,Yes,Advisory,,,The alignment specification of zero should not appear in an object declaration,,Alignment,Easy,
+c,MISRA-C-2012,RULE-8-17,Yes,Advisory,,,At most one explicit alignment specifier should appear in an object declaration,,Alignment,Easy,
c,MISRA-C-2012,RULE-9-1,Yes,Mandatory,,,The value of an object with automatic storage duration shall not be read before it has been set,,InvalidMemory1,Import,
c,MISRA-C-2012,RULE-9-2,Yes,Required,,,The initializer for an aggregate or union shall be enclosed in braces,,Memory1,Easy,
c,MISRA-C-2012,RULE-9-3,Yes,Required,,,Arrays shall not be partially initialized,,Memory1,Medium,
c,MISRA-C-2012,RULE-9-4,Yes,Required,,,An element of an object shall not be initialized more than once,,Memory1,Medium,
c,MISRA-C-2012,RULE-9-5,No,Required,,,Where designated initializers are used to initialize an array object the size of the array shall be specified explicitly,,,Medium,
+c,MISRA-C-2012,RULE-9-6,Yes,Required,,,An initializer using chained designators shall not contain initializers without designators,,Declarations9,Hard,
+c,MISRA-C-2012,RULE-9-7,Yes,Mandatory,,,Atomic objects shall be appropriately initialized before being accessed,,Concurrency6,Hard,
c,MISRA-C-2012,RULE-10-1,Yes,Required,,,Operands shall not be of an inappropriate essential type,,EssentialTypes,Hard,
c,MISRA-C-2012,RULE-10-2,Yes,Required,,,Expressions of essentially character type shall not be used inappropriately in addition and subtraction operations,,EssentialTypes,Medium,
c,MISRA-C-2012,RULE-10-3,Yes,Required,,,The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type category,,EssentialTypes,Hard,
@@ -682,11 +696,13 @@ c,MISRA-C-2012,RULE-11-6,Yes,Required,,,A cast shall not be performed between po
c,MISRA-C-2012,RULE-11-7,Yes,Required,,,A cast shall not be performed between pointer to object and a non- integer arithmetic type,,Pointers1,Easy,
c,MISRA-C-2012,RULE-11-8,Yes,Required,,,A cast shall not remove any const or volatile qualification from the type pointed to by a pointer,,Pointers1,Easy,
c,MISRA-C-2012,RULE-11-9,Yes,Required,,,The macro NULL shall be the only permitted form of integer null pointer constant,,Pointers1,Easy,
+c,MISRA-C-2012,RULE-11-10,Yes,Required,,,The _Atomic qualifier shall not be applied to the incomplete type void,,Declarations9,Easy,
c,MISRA-C-2012,RULE-12-1,Yes,Advisory,,,The precedence of operators within expressions should be made explicit,,SideEffects1,Medium,
c,MISRA-C-2012,RULE-12-2,Yes,Required,,,The right hand operand of a shift operator shall lie in the range zero to one less than the width in bits of the essential type of the left hand operand,,Contracts7,Medium,
c,MISRA-C-2012,RULE-12-3,Yes,Advisory,,,The comma operator should not be used,M5-18-1,Banned,Import,
c,MISRA-C-2012,RULE-12-4,Yes,Advisory,,,Evaluation of constant expressions should not lead to unsigned integer wrap-around,INT30-C,IntegerOverflow,Easy,
c,MISRA-C-2012,RULE-12-5,Yes,Mandatory,,,The sizeof operator shall not have an operand which is a function parameter declared as 'array of type',,Types1,Medium,
+c,MISRA-C-2012,RULE-12-6,Yes,Required,,,Structure and union members of atomic objects shall not be directly accessed,,Concurrency6,Easy,
c,MISRA-C-2012,RULE-13-1,Yes,Required,,,Initializer lists shall not contain persistent side effects,,SideEffects1,Medium,
c,MISRA-C-2012,RULE-13-2,Yes,Required,,,The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders,PRE31-C,SideEffects3,Medium,
c,MISRA-C-2012,RULE-13-3,Yes,Advisory,,,A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that caused by the increment or decrement operator,,SideEffects2,Medium,
@@ -719,6 +735,11 @@ c,MISRA-C-2012,RULE-17-5,Yes,Advisory,,,The function argument corresponding to a
c,MISRA-C-2012,RULE-17-6,Yes,Mandatory,,,The declaration of an array parameter shall not contain the static keyword between the [ ],,Static,Easy,
c,MISRA-C-2012,RULE-17-7,Yes,Required,,,The value returned by a function having non-void return type shall be used,A0-1-2,Contracts6,Easy,
c,MISRA-C-2012,RULE-17-8,Yes,Advisory,,,A function parameter should not be modified,,SideEffects2,Medium,
+c,MISRA-C-2012,RULE-17-9,Yes,Mandatory,,,Verify that a function declared with _Noreturn does not return,,NoReturn,Easy,
+c,MISRA-C-2012,RULE-17-10,Yes,Required,,,A function declared with _noreturn shall have a return type of void,,NoReturn,Easy,
+c,MISRA-C-2012,RULE-17-11,Yes,Advisory,,,A function without a branch that returns shall be declared with _Noreturn,,NoReturn,Easy,
+c,MISRA-C-2012,RULE-17-12,Yes,Advisory,,,A function identifier should only be called with a parenthesized parameter list or used with a & (address-of),,FunctionTypes,Easy,
+c,MISRA-C-2012,RULE-17-13,No,Required,,,"A function type shall not include any type qualifiers (const, volatile, restrict, or _Atomic)",,,Easy,
c,MISRA-C-2012,RULE-18-1,Yes,Required,,,A pointer resulting from arithmetic on a pointer operand shall address an element of the same array as that pointer operand,M5-0-16,Pointers1,Import,
c,MISRA-C-2012,RULE-18-2,Yes,Required,,,Subtraction between pointers shall only be applied to pointers that address elements of the same array,M5-0-17,Pointers1,Import,
c,MISRA-C-2012,RULE-18-3,Yes,Required,,,"The relational operators >, >=, < and <= shall not be applied to objects of pointer type except where they point into the same object",M5-0-18,Pointers1,Import,
@@ -727,6 +748,8 @@ c,MISRA-C-2012,RULE-18-5,Yes,Advisory,,,Declarations should contain no more than
c,MISRA-C-2012,RULE-18-6,Yes,Required,,,The address of an object with automatic storage shall not be copied to another object that persists after the first object has ceased to exist,M7-5-2,Pointers1,Import,
c,MISRA-C-2012,RULE-18-7,Yes,Required,,,Flexible array members shall not be declared,,Declarations6,Medium,
c,MISRA-C-2012,RULE-18-8,Yes,Required,,,Variable-length array types shall not be used,,Declarations7,Medium,
+c,MISRA-C-2012,RULE-18-9,Yes,Required,,,An object with temporary lifetime shall not undergo array to pointer conversion,EXP35-C,InvalidMemory3,Hard,
+c,MISRA-C-2012,RULE-18-10,Yes,Mandatory,,,Pointers to variably-modified array types shall not be used,,InvalidMemory3,Import,
c,MISRA-C-2012,RULE-19-1,Yes,Mandatory,,,An object shall not be assigned or copied to an overlapping object,M0-2-1,Contracts7,Hard,
c,MISRA-C-2012,RULE-19-2,Yes,Advisory,,,The union keyword should not be used,A9-5-1,Banned,Import,
c,MISRA-C-2012,RULE-20-1,Yes,Advisory,,,#include directives should only be preceded by preprocessor directives or comments,M16-0-1,Preprocessor1,Import,
@@ -764,6 +787,11 @@ c,MISRA-C-2012,RULE-21-18,Yes,Mandatory,,,The size_t argument passed to any func
c,MISRA-C-2012,RULE-21-19,Yes,Mandatory,,,"The pointers returned by the Standard Library functions localeconv, getenv, setlocale or, strerror shall only be used as if they have pointer to const-qualified type",ENV30-C,Contracts2,Medium,
c,MISRA-C-2012,RULE-21-20,Yes,Mandatory,,,"The pointer returned by the Standard Library functions asctime, ctime, gmtime, localtime, localeconv, getenv, setlocale or strerror shall not be used following a subsequent call to the same function",ENV34-C,Contracts2,Import,
c,MISRA-C-2012,RULE-21-21,Yes,Required,,,The Standard Library function system of shall not be used,ENV33-C,Banned,Import,
+c,MISRA-C-2012,RULE-21-22,Yes,Mandatory,,,All operand arguments to any type-generic macros in shall have an appropriate essential type,EXP37-C,EssentialTypes2,Hard,
+c,MISRA-C-2012,RULE-21-23,Yes,Required,,,All operand arguments to any multi-argument type-generic macros in shall have the same standard type,Rule-21-22,EssentialTypes2,Easy,
+c,MISRA-C-2012,RULE-21-24,Yes,Required,,,The random number generator functions of shall not be used,MSC30-C,Banned2,Easy,
+c,MISRA-C-2012,RULE-21-25,Yes,Required,,,All memory synchronization operations shall be executed in sequentially consistent order,,Concurrency6,Medium,
+c,MISRA-C-2012,RULE-21-26,Yes,Required,,,The Standard Library function mtx_timedlock() shall only be invoked on mutex objects of appropriate mutex type,,Concurrency6,Hard,
c,MISRA-C-2012,RULE-22-1,Yes,Required,,,All resources obtained dynamically by means of Standard Library functions shall be explicitly released,,Memory2,Hard,
c,MISRA-C-2012,RULE-22-2,Yes,Mandatory,,,A block of memory shall only be freed if it was allocated by means of a Standard Library function,,Memory2,Hard,
c,MISRA-C-2012,RULE-22-3,Yes,Required,,,The same file shall not be open for read and write access at the same time on different streams,,IO3,Hard,
@@ -774,182 +802,200 @@ c,MISRA-C-2012,RULE-22-7,Yes,Required,,,The macro EOF shall only be compared wit
c,MISRA-C-2012,RULE-22-8,Yes,Required,,,The value of errno shall be set to zero prior to a call to an errno-setting-function,ERR30-C,Contracts3,Medium,
c,MISRA-C-2012,RULE-22-9,Yes,Required,,,The value of errno shall be tested against zero after calling an errno-setting-function,,Contracts3,Medium,
c,MISRA-C-2012,RULE-22-10,Yes,Required,,,The value of errno shall only be tested when the last function to be called was an errno-setting-function,,Contracts3,Medium,
-cpp,MISRA-C++-2023,RULE-0-0-1,Yes,Required,Decidable,Single Translation Unit,A function shall not contain unreachable statements,M0-1-1,,Medium,
-cpp,MISRA-C++-2023,RULE-0-0-2,Yes,Advisory,Undecidable,System,Controlling expressions should not be invariant,M0-1-2,,Easy,
-cpp,MISRA-C++-2023,RULE-0-1-1,Yes,Advisory,Undecidable,System,A value should not be unnecessarily written to a local object,A0-1-1,,Medium,
-cpp,MISRA-C++-2023,RULE-0-1-2,Yes,Required,Decidable,Single Translation Unit,The value returned by a function shall be used,A0-1-2,,Easy,
-cpp,MISRA-C++-2023,RULE-0-2-1,Yes,Advisory,Decidable,Single Translation Unit,Variables with limited visibility should be used at least once,M0-1-3,,Easy,
-cpp,MISRA-C++-2023,RULE-0-2-2,Yes,Required,Decidable,Single Translation Unit,A named function parameter shall be used at least once,"A0-1-4, A0-1-5",,Easy,
-cpp,MISRA-C++-2023,RULE-0-2-3,Yes,Advisory,Decidable,Single Translation Unit,Types with limited visibility should be used at least once,A0-1-6,,Easy,
-cpp,MISRA-C++-2023,RULE-0-2-4,Yes,Advisory,Decidable,System,Functions with limited visibility should be used at least once,A0-1-3,,Easy,
-cpp,MISRA-C++-2023,DIR-0-3-1,Yes,Advisory,,,Floating-point arithmetic should be used appropriately,,,Hard,
-cpp,MISRA-C++-2023,DIR-0-3-2,Yes,Required,,,A function call shall not violate the function’s preconditions,,,Hard,
-cpp,MISRA-C++-2023,RULE-4-1-1,Yes,Required,Undecidable,System,A program shall conform to ISO/IEC 14882:2017 (C++17),,,Hard,
-cpp,MISRA-C++-2023,RULE-4-1-2,Yes,Advisory,Decidable,Single Translation Unit,Deprecated features should not be used,,,Very Hard,
-cpp,MISRA-C++-2023,RULE-4-1-3,Yes,Required,Undecidable,System,There shall be no occurrence of undefined or critical unspecified behaviour,,,Very Hard,
-cpp,MISRA-C++-2023,RULE-4-6-1,Yes,Required,Undecidable,System,Operations on a memory location shall be sequenced appropriately,RULE-13-2,,Easy,
-cpp,MISRA-C++-2023,RULE-5-0-1,Yes,Advisory,Decidable,Single Translation Unit,Trigraph-like sequences should not be used,A2-5-1,,Very Hard,
+c,MISRA-C-2012,RULE-22-11,Yes,Required,,,A thread that was previously either joined or detached shall not be subsequently joined nor detached,CON39-C,Concurrency6,Import,
+c,MISRA-C-2012,RULE-22-12,Yes,Mandatory,,,"Thread objects, thread synchronization objects, and thread-specific storage pointers shall only be accessed by the appropriate Standard Library functions",,Concurrency6,Medium,
+c,MISRA-C-2012,RULE-22-13,Yes,Required,,,"Thread objects, thread synchronization objects, and thread specific storage pointers shall have appropriate storage duration",EXP54-CPP and CON34-C,Concurrency6,Medium,
+c,MISRA-C-2012,RULE-22-14,Yes,Mandatory,,,Thread synchronization objects shall be initialized before being accessed,EXP53-CPP,Concurrency6,Hard,
+c,MISRA-C-2012,RULE-22-15,Yes,Required,,,Thread synchronization objects and thread-specific storage pointers shall not be destroyed until after all threads accessing them have terminated,,Concurrency6,Hard,
+c,MISRA-C-2012,RULE-22-16,Yes,Required,,,All mutex objects locked by a thread shall be explicitly unlocked by the same thread,MEM51-CPP,Concurrency6,Hard,
+c,MISRA-C-2012,RULE-22-17,Yes,Required,,,No thread shall unlock a mutex or call cnd_wait() or cnd_timedwait() for a mutex it has not locked before,Rule 22.2,Concurrency6,Medium,
+c,MISRA-C-2012,RULE-22-18,Yes,Required,,,Non-recursive mutexes shall not be recursively locked,CON56-CPP,Concurrency6,Medium,
+c,MISRA-C-2012,RULE-22-19,Yes,Required,,,A condition variable shall be associated with at most one mutex object,,Concurrency6,Medium,
+c,MISRA-C-2012,RULE-22-20,Yes,Mandatory,,,Thread-specific storage pointers shall be created before being accessed,,Concurrency6,Hard,
+c,MISRA-C-2012,RULE-23-1,Yes,Advisory,,,A generic selection should only be expanded from a macro,,Generics,Medium,
+c,MISRA-C-2012,RULE-23-2,Yes,Required,,,A generic selection that is not expanded from a macro shall not contain potential side effects in the controlling expression,,Generics,Hard,
+c,MISRA-C-2012,RULE-23-3,Yes,Advisory,,,A generic selection should contain at least one non-default association,,Generics,Easy,
+c,MISRA-C-2012,RULE-23-4,Yes,Required,,,A generic association shall list an appropriate type,,Generics,Medium,
+c,MISRA-C-2012,RULE-23-5,Yes,Advisory,,,A generic selection should not depend on implicit pointer type conversion,,Generics,Medium,
+c,MISRA-C-2012,RULE-23-6,Yes,Required,,,The controlling expression of a generic selection shall have an essential type that matches its standard type,,Generics,Medium,
+c,MISRA-C-2012,RULE-23-7,Yes,Advisory,,,A generic selection that is expanded from a macro should evaluate its argument only once,,Generics,Medium,
+c,MISRA-C-2012,RULE-23-8,Yes,Required,,,A default association shall appear as either the first or the last association of a generic selection,,Generics,Easy,
+cpp,MISRA-C++-2023,RULE-0-0-1,Yes,Required,Decidable,Single Translation Unit,A function shall not contain unreachable statements,M0-1-1,DeadCode2,Medium,
+cpp,MISRA-C++-2023,RULE-0-0-2,Yes,Advisory,Undecidable,System,Controlling expressions should not be invariant,M0-1-2,DeadCode2,Easy,
+cpp,MISRA-C++-2023,RULE-0-1-1,Yes,Advisory,Undecidable,System,A value should not be unnecessarily written to a local object,A0-1-1,DeadCode2,Medium,
+cpp,MISRA-C++-2023,RULE-0-1-2,Yes,Required,Decidable,Single Translation Unit,The value returned by a function shall be used,A0-1-2,DeadCode2,Easy,
+cpp,MISRA-C++-2023,RULE-0-2-1,Yes,Advisory,Decidable,Single Translation Unit,Variables with limited visibility should be used at least once,M0-1-3,DeadCode2,Easy,
+cpp,MISRA-C++-2023,RULE-0-2-2,Yes,Required,Decidable,Single Translation Unit,A named function parameter shall be used at least once,"A0-1-4, A0-1-5",DeadCode2,Easy,
+cpp,MISRA-C++-2023,RULE-0-2-3,Yes,Advisory,Decidable,Single Translation Unit,Types with limited visibility should be used at least once,A0-1-6,DeadCode2,Easy,
+cpp,MISRA-C++-2023,RULE-0-2-4,Yes,Advisory,Decidable,System,Functions with limited visibility should be used at least once,A0-1-3,DeadCode2,Easy,
+cpp,MISRA-C++-2023,DIR-0-3-1,Yes,Advisory,,,Floating-point arithmetic should be used appropriately,,FloatingPoint,Hard,
+cpp,MISRA-C++-2023,DIR-0-3-2,Yes,Required,,,A function call shall not violate the function’s preconditions,,Preconditions,Hard,
+cpp,MISRA-C++-2023,RULE-4-1-1,Yes,Required,Undecidable,System,A program shall conform to ISO/IEC 14882:2017 (C++17),,Toolchain2,Hard,
+cpp,MISRA-C++-2023,RULE-4-1-2,Yes,Advisory,Decidable,Single Translation Unit,Deprecated features should not be used,,Toolchain2,Very Hard,
+cpp,MISRA-C++-2023,RULE-4-1-3,Yes,Required,Undecidable,System,There shall be no occurrence of undefined or critical unspecified behaviour,,Undefined,Very Hard,
+cpp,MISRA-C++-2023,RULE-4-6-1,Yes,Required,Undecidable,System,Operations on a memory location shall be sequenced appropriately,RULE-13-2,SideEffects3,Easy,
+cpp,MISRA-C++-2023,RULE-5-0-1,Yes,Advisory,Decidable,Single Translation Unit,Trigraph-like sequences should not be used,A2-5-1,Trigraph,Very Hard,
cpp,MISRA-C++-2023,RULE-5-7-1,Yes,Required,Decidable,Single Translation Unit,The character sequence /* shall not be used within a C-style comment,M2-7-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,DIR-5-7-2,Yes,Advisory,,,Sections of code should not be “commented out”,A2-7-2,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-5-7-3,Yes,Required,Decidable,Single Translation Unit,Line-splicing shall not be used in // comments,A2-7-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-5-10-1,Yes,Required,Decidable,Single Translation Unit,User-defined identifiers shall have an appropriate form,,,Easy,
+cpp,MISRA-C++-2023,RULE-5-10-1,Yes,Required,Decidable,Single Translation Unit,User-defined identifiers shall have an appropriate form,,Naming2,Easy,
cpp,MISRA-C++-2023,RULE-5-13-1,Yes,Required,Decidable,Single Translation Unit,"In character literals and non-raw string literals, \ shall only be used to form a defined escape sequence or universal character name",A2-13-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-5-13-2,Yes,Required,Decidable,Single Translation Unit,"Octal escape sequences, hexadecimal escape sequences, and universal character names shall be terminated",RULE-4-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-5-13-3,Yes,Required,Decidable,Single Translation Unit,Octal constants shall not be used,M2-13-2,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-5-13-4,Yes,Required,Decidable,Single Translation Unit,Unsigned integer literals shall be appropriately suffixed,M2-13-3,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-5-13-5,Yes,Required,Decidable,Single Translation Unit,The lowercase form of L shall not be used as the first character in a literal suffix,RULE-7-3,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-5-13-6,Yes,Required,Decidable,Single Translation Unit,An integer-literal of type long long shall not use a single L or l in any suffix,,,Easy,
+cpp,MISRA-C++-2023,RULE-5-13-6,Yes,Required,Decidable,Single Translation Unit,An integer-literal of type long long shall not use a single L or l in any suffix,,Expressions2,Easy,
cpp,MISRA-C++-2023,RULE-5-13-7,No,Required,Decidable,Single Translation Unit,String literals with different encoding prefixes shall not be concatenated,A2-13-2,,,
-cpp,MISRA-C++-2023,RULE-6-0-1,Yes,Required,Decidable,Single Translation Unit,Block scope declarations shall not be visually ambiguous,"M3-1-2,DCL53-CPP",,Easy,
-cpp,MISRA-C++-2023,RULE-6-0-2,Yes,Advisory,Decidable,Single Translation Unit,"When an array with external linkage is declared, its size should be explicitly specified",RULE-18-8,,Easy,
+cpp,MISRA-C++-2023,RULE-6-0-1,Yes,Required,Decidable,Single Translation Unit,Block scope declarations shall not be visually ambiguous,"M3-1-2,DCL53-CPP",Declarations2,Easy,
+cpp,MISRA-C++-2023,RULE-6-0-2,Yes,Advisory,Decidable,Single Translation Unit,"When an array with external linkage is declared, its size should be explicitly specified",RULE-18-8,Linkage,Easy,
cpp,MISRA-C++-2023,RULE-6-0-3,Yes,Advisory,Decidable,Single Translation Unit,"The only declarations in the global namespace should be main, namespace declarations and extern ""C"" declarations",M7-3-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-6-0-4,Yes,Required,Decidable,Single Translation Unit,The identifier main shall not be used for a function other than the global function main,M7-3-2,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-6-2-1,Yes,Required,Decidable,System,The one-definition rule shall not be violated,M3-2-2,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-6-2-2,Yes,Required,Decidable,System,All declarations of a variable or function shall have the same type,"M3-9-1,DCL40-C",,Easy,
-cpp,MISRA-C++-2023,RULE-6-2-3,Yes,Required,Decidable,System,The source code used to implement an entity shall appear only once,,,Medium,
-cpp,MISRA-C++-2023,RULE-6-2-4,Yes,Required,Decidable,Single Translation Unit,A header file shall not contain definitions of functions or objects that are non-inline and have external linkage,,,Easy,
+cpp,MISRA-C++-2023,RULE-6-2-2,Yes,Required,Decidable,System,All declarations of a variable or function shall have the same type,"M3-9-1,DCL40-C",Declarations2,Easy,
+cpp,MISRA-C++-2023,RULE-6-2-3,Yes,Required,Decidable,System,The source code used to implement an entity shall appear only once,,Declarations2,Medium,
+cpp,MISRA-C++-2023,RULE-6-2-4,Yes,Required,Decidable,Single Translation Unit,A header file shall not contain definitions of functions or objects that are non-inline and have external linkage,,Linkage,Easy,
cpp,MISRA-C++-2023,RULE-6-4-1,Yes,Required,Decidable,Single Translation Unit,A variable declared in an inner scope shall not hide a variable declared in an outer scope,A2-10-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-6-4-2,Yes,Required,Decidable,Single Translation Unit,Derived classes shall not conceal functions that are inherited from their bases,A7-3-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-6-4-3,Yes,Required,Decidable,Single Translation Unit,A name that is present in a dependent base shall not be resolved by unqualified lookup,M14-6-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-6-5-1,Yes,Advisory,Decidable,Single Translation Unit,A function or object with external linkage should be introduced in a header file,,,Medium,
-cpp,MISRA-C++-2023,RULE-6-5-2,Yes,Advisory,Decidable,Single Translation Unit,Internal linkage should be specified appropriately,,,Medium,
-cpp,MISRA-C++-2023,RULE-6-7-1,Yes,Required,Decidable,Single Translation Unit,Local variables shall not have static storage duration,,,Easy,
-cpp,MISRA-C++-2023,RULE-6-7-2,Yes,Required,Decidable,Single Translation Unit,Global variables shall not be used,,,Easy,
+cpp,MISRA-C++-2023,RULE-6-5-1,Yes,Advisory,Decidable,Single Translation Unit,A function or object with external linkage should be introduced in a header file,,Linkage,Medium,
+cpp,MISRA-C++-2023,RULE-6-5-2,Yes,Advisory,Decidable,Single Translation Unit,Internal linkage should be specified appropriately,,Linkage,Medium,
+cpp,MISRA-C++-2023,RULE-6-7-1,Yes,Required,Decidable,Single Translation Unit,Local variables shall not have static storage duration,,Declarations2,Easy,
+cpp,MISRA-C++-2023,RULE-6-7-2,Yes,Required,Decidable,Single Translation Unit,Global variables shall not be used,,Banned,Easy,
cpp,MISRA-C++-2023,RULE-6-8-1,Yes,Required,Undecidable,System,An object shall not be accessed outside of its lifetime,A3-8-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-6-8-2,Yes,Mandatory,Decidable,Single Translation Unit,A function must not return a reference or a pointer to a local variable with automatic storage duration,M7-5-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-6-8-3,Yes,Required,Decidable,Single Translation Unit,An assignment operator shall not assign the address of an object with automatic storage duration to an object with a greater lifetime,,,Medium,
-cpp,MISRA-C++-2023,RULE-6-8-4,Yes,Advisory,Decidable,Single Translation Unit,Member functions returning references to their object should be refqualified appropriately,,,Medium,
-cpp,MISRA-C++-2023,RULE-6-9-1,Yes,Required,Decidable,Single Translation Unit,The same type aliases shall be used in all declarations of the same entity,,,Medium,
-cpp,MISRA-C++-2023,RULE-6-9-2,Yes,Advisory,Decidable,Single Translation Unit,The names of the standard signed integer types and standard unsigned integer types should not be used,A3-9-1,,Easy,
-cpp,MISRA-C++-2023,RULE-7-0-1,Yes,Required,Decidable,Single Translation Unit,There shall be no conversion from type bool,,,Easy,
-cpp,MISRA-C++-2023,RULE-7-0-2,Yes,Required,Decidable,Single Translation Unit,There shall be no conversion to type bool,,,Easy,
-cpp,MISRA-C++-2023,RULE-7-0-3,Yes,Required,Decidable,Single Translation Unit,The numerical value of a character shall not be used,M5-0-11,,Medium,
-cpp,MISRA-C++-2023,RULE-7-0-4,Yes,Required,Decidable,Single Translation Unit,The operands of bitwise operators and shift operators shall be appropriate,RULE-10-1,,Medium,
-cpp,MISRA-C++-2023,RULE-7-0-5,Yes,Required,Decidable,Single Translation Unit,Integral promotion and the usual arithmetic conversions shall not change the signedness or the type category of an operand,"M5-0-4,M5-0-9,INT31-C",,Medium,
-cpp,MISRA-C++-2023,RULE-7-0-6,Yes,Required,Decidable,Single Translation Unit,Assignment between numeric types shall be appropriate,,,Hard,
+cpp,MISRA-C++-2023,RULE-6-8-3,Yes,Required,Decidable,Single Translation Unit,An assignment operator shall not assign the address of an object with automatic storage duration to an object with a greater lifetime,,Lifetime,Medium,
+cpp,MISRA-C++-2023,RULE-6-8-4,Yes,Advisory,Decidable,Single Translation Unit,Member functions returning references to their object should be refqualified appropriately,,Declarations2,Medium,
+cpp,MISRA-C++-2023,RULE-6-9-1,Yes,Required,Decidable,Single Translation Unit,The same type aliases shall be used in all declarations of the same entity,,Declarations2,Medium,
+cpp,MISRA-C++-2023,RULE-6-9-2,Yes,Advisory,Decidable,Single Translation Unit,The names of the standard signed integer types and standard unsigned integer types should not be used,A3-9-1,BannedAPIs,Easy,
+cpp,MISRA-C++-2023,RULE-7-0-1,Yes,Required,Decidable,Single Translation Unit,There shall be no conversion from type bool,,Conversions,Easy,
+cpp,MISRA-C++-2023,RULE-7-0-2,Yes,Required,Decidable,Single Translation Unit,There shall be no conversion to type bool,,Conversions,Easy,
+cpp,MISRA-C++-2023,RULE-7-0-3,Yes,Required,Decidable,Single Translation Unit,The numerical value of a character shall not be used,M5-0-11,Conversions,Medium,
+cpp,MISRA-C++-2023,RULE-7-0-4,Yes,Required,Decidable,Single Translation Unit,The operands of bitwise operators and shift operators shall be appropriate,RULE-10-1,Preconditions,Medium,
+cpp,MISRA-C++-2023,RULE-7-0-5,Yes,Required,Decidable,Single Translation Unit,Integral promotion and the usual arithmetic conversions shall not change the signedness or the type category of an operand,"M5-0-4,M5-0-9,INT31-C",Conversions,Medium,
+cpp,MISRA-C++-2023,RULE-7-0-6,Yes,Required,Decidable,Single Translation Unit,Assignment between numeric types shall be appropriate,,Conversions,Hard,
cpp,MISRA-C++-2023,RULE-7-11-1,Yes,Required,Decidable,Single Translation Unit,nullptr shall be the only form of the null-pointer-constant,A4-10-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-7-11-2,Yes,Required,Decidable,Single Translation Unit,An array passed as a function argument shall not decay to a pointer,M5-2-12,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-7-11-3,Yes,Required,Decidable,Single Translation Unit,A conversion from function type to pointer-to-function type shall only occur in appropriate contexts,,,Easy,
-cpp,MISRA-C++-2023,RULE-8-0-1,Yes,Advisory,Decidable,Single Translation Unit,Parentheses should be used to make the meaning of an expression appropriately explicit,M5-0-2,,Medium,
-cpp,MISRA-C++-2023,RULE-8-1-1,Yes,Required,Decidable,Single Translation Unit,A non-transient lambda shall not implicitly capture this,,,Easy,
-cpp,MISRA-C++-2023,RULE-8-1-2,Yes,Advisory,Decidable,Single Translation Unit,Variables should be captured explicitly in a non-transient lambda,A5-1-2,,Easy,
-cpp,MISRA-C++-2023,RULE-8-2-1,Yes,Required,Decidable,Single Translation Unit,A virtual base class shall only be cast to a derived class by means of dynamic_cast,,,Easy,
-cpp,MISRA-C++-2023,RULE-8-2-2,Yes,Required,Decidable,Single Translation Unit,C-style casts and functional notation casts shall not be used,A5-2-2,,Easy,
+cpp,MISRA-C++-2023,RULE-7-11-3,Yes,Required,Decidable,Single Translation Unit,A conversion from function type to pointer-to-function type shall only occur in appropriate contexts,,Conversions,Easy,
+cpp,MISRA-C++-2023,RULE-8-0-1,Yes,Advisory,Decidable,Single Translation Unit,Parentheses should be used to make the meaning of an expression appropriately explicit,M5-0-2,Expressions2,Medium,
+cpp,MISRA-C++-2023,RULE-8-1-1,Yes,Required,Decidable,Single Translation Unit,A non-transient lambda shall not implicitly capture this,,Expressions2,Easy,
+cpp,MISRA-C++-2023,RULE-8-1-2,Yes,Advisory,Decidable,Single Translation Unit,Variables should be captured explicitly in a non-transient lambda,A5-1-2,Expressions2,Easy,
+cpp,MISRA-C++-2023,RULE-8-2-1,Yes,Required,Decidable,Single Translation Unit,A virtual base class shall only be cast to a derived class by means of dynamic_cast,,Conversions,Easy,
+cpp,MISRA-C++-2023,RULE-8-2-2,Yes,Required,Decidable,Single Translation Unit,C-style casts and functional notation casts shall not be used,A5-2-2,Conversions,Easy,
cpp,MISRA-C++-2023,RULE-8-2-3,Yes,Required,Decidable,Single Translation Unit,A cast shall not remove any const or volatile qualification from the type accessed via a pointer or by reference,A5-2-3,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-8-2-4,Yes,Required,Decidable,Single Translation Unit,Casts shall not be performed between a pointer to function and any other type,M5-2-6,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-8-2-5,Yes,Required,Decidable,Single Translation Unit,reinterpret_cast shall not be used,A5-2-4,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-8-2-6,Yes,Required,Decidable,Single Translation Unit,"An object with integral, enumerated, or pointer to void type shall not be cast to a pointer type","RULE-11-6, INT36-C",,Easy,
-cpp,MISRA-C++-2023,RULE-8-2-7,Yes,Advisory,Decidable,Single Translation Unit,A cast should not convert a pointer type to an integral type,"RULE-11-6, INT36-C",,Easy,
-cpp,MISRA-C++-2023,RULE-8-2-8,Yes,Required,Decidable,Single Translation Unit,An object pointer type shall not be cast to an integral type other than std::uintptr_t or std::intptr_t,"RULE-11-6, INT36-C",,Easy,
-cpp,MISRA-C++-2023,RULE-8-2-9,Yes,Required,Decidable,Single Translation Unit,The operand to typeid shall not be an expression of polymorphic class type,,,Easy,
+cpp,MISRA-C++-2023,RULE-8-2-6,Yes,Required,Decidable,Single Translation Unit,"An object with integral, enumerated, or pointer to void type shall not be cast to a pointer type","RULE-11-6, INT36-C",Conversions,Easy,
+cpp,MISRA-C++-2023,RULE-8-2-7,Yes,Advisory,Decidable,Single Translation Unit,A cast should not convert a pointer type to an integral type,"RULE-11-6, INT36-C",Conversions,Easy,
+cpp,MISRA-C++-2023,RULE-8-2-8,Yes,Required,Decidable,Single Translation Unit,An object pointer type shall not be cast to an integral type other than std::uintptr_t or std::intptr_t,"RULE-11-6, INT36-C",Conversions,Easy,
+cpp,MISRA-C++-2023,RULE-8-2-9,Yes,Required,Decidable,Single Translation Unit,The operand to typeid shall not be an expression of polymorphic class type,,Preconditions,Easy,
cpp,MISRA-C++-2023,RULE-8-2-10,Yes,Required,Undecidable,System,"Functions shall not call themselves, either directly or indirectly",A7-5-2,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-8-2-11,Yes,Required,Decidable,Single Translation Unit,An argument passed via ellipsis shall have an appropriate type,,,Easy,
+cpp,MISRA-C++-2023,RULE-8-2-11,Yes,Required,Decidable,Single Translation Unit,An argument passed via ellipsis shall have an appropriate type,,Preconditions,Easy,
cpp,MISRA-C++-2023,RULE-8-3-1,Yes,Advisory,Decidable,Single Translation Unit,The built-in unary - operator should not be applied to an expression of unsigned type,M5-3-2,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-8-3-2,Yes,Advisory,Decidable,Single Translation Unit,The built-in unary + operator should not be used,,,Easy,
-cpp,MISRA-C++-2023,RULE-8-7-1,Yes,Required,Undecidable,System,Pointer arithmetic shall not form an invalid pointer,ARR30-C,,Easy,
-cpp,MISRA-C++-2023,RULE-8-7-2,Yes,Required,Undecidable,System,Subtraction between pointers shall only be applied to pointers that address elements of the same array,ARR36-C,,Easy,
-cpp,MISRA-C++-2023,RULE-8-9-1,Yes,Required,Undecidable,System,"The built-in relational operators >, >=, < and <= shall not be applied to objects of pointer type, except where they point to elements of the same array",ARR36-C,,Easy,
-cpp,MISRA-C++-2023,RULE-8-14-1,Yes,Advisory,Undecidable,System,The right-hand operand of a logical && or operator should not contain persistent side effects,"M5-14-1, RULE-13-5",,Medium,
-cpp,MISRA-C++-2023,RULE-8-18-1,Yes,Mandatory,Undecidable,System,An object or subobject must not be copied to an overlapping object,"M0-2-1, RULE-19-1",,Hard,
+cpp,MISRA-C++-2023,RULE-8-3-2,Yes,Advisory,Decidable,Single Translation Unit,The built-in unary + operator should not be used,,Banned,Easy,
+cpp,MISRA-C++-2023,RULE-8-7-1,Yes,Required,Undecidable,System,Pointer arithmetic shall not form an invalid pointer,ARR30-C,Memory,Easy,
+cpp,MISRA-C++-2023,RULE-8-7-2,Yes,Required,Undecidable,System,Subtraction between pointers shall only be applied to pointers that address elements of the same array,ARR36-C,Memory,Easy,
+cpp,MISRA-C++-2023,RULE-8-9-1,Yes,Required,Undecidable,System,"The built-in relational operators >, >=, < and <= shall not be applied to objects of pointer type, except where they point to elements of the same array",ARR36-C,Memory,Easy,
+cpp,MISRA-C++-2023,RULE-8-14-1,Yes,Advisory,Undecidable,System,The right-hand operand of a logical && or operator should not contain persistent side effects,"M5-14-1, RULE-13-5",SideEffects3,Medium,
+cpp,MISRA-C++-2023,RULE-8-18-1,Yes,Mandatory,Undecidable,System,An object or subobject must not be copied to an overlapping object,"M0-2-1, RULE-19-1",Memory,Hard,
cpp,MISRA-C++-2023,RULE-8-18-2,Yes,Advisory,Decidable,Single Translation Unit,The result of an assignment operator should not be used,RULE-13-4,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-8-19-1,Yes,Advisory,Decidable,Single Translation Unit,The comma operator should not be used,M5-18-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-8-20-1,Yes,Advisory,Decidable,Single Translation Unit,An unsigned arithmetic operation with constant operands should not wrap,INT30-C,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-9-2-1,Yes,Required,Decidable,Single Translation Unit,An explicit type conversion shall not be an expression statement,DCL53-CPP,,Easy,
+cpp,MISRA-C++-2023,RULE-9-2-1,Yes,Required,Decidable,Single Translation Unit,An explicit type conversion shall not be an expression statement,DCL53-CPP,Conversions,Easy,
cpp,MISRA-C++-2023,RULE-9-3-1,Yes,Required,Decidable,Single Translation Unit,The body of an iteration-statement or a selection-statement shall be a compound-statement,RULE-15-6,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-9-4-1,Yes,Required,Decidable,Single Translation Unit,All if ... else if constructs shall be terminated with an else statement,RULE-15-7,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-9-4-2,Yes,Required,Decidable,Single Translation Unit,The structure of a switch statement shall be appropriate,"RULE-16-1, RULE-16-2,RULE-16-3,RULE-16-4,RULE-16-5,RULE-16-6,RULE-16-7",,Medium,
-cpp,MISRA-C++-2023,RULE-9-5-1,Yes,Advisory,Decidable,Single Translation Unit,Legacy for statements should be simple,,,Hard,
-cpp,MISRA-C++-2023,RULE-9-5-2,Yes,Required,Decidable,Single Translation Unit,A for-range-initializer shall contain at most one function call,,,Easy,
+cpp,MISRA-C++-2023,RULE-9-4-2,Yes,Required,Decidable,Single Translation Unit,The structure of a switch statement shall be appropriate,"RULE-16-1, RULE-16-2,RULE-16-3,RULE-16-4,RULE-16-5,RULE-16-6,RULE-16-7",Statements,Medium,
+cpp,MISRA-C++-2023,RULE-9-5-1,Yes,Advisory,Decidable,Single Translation Unit,Legacy for statements should be simple,,Statements,Hard,
+cpp,MISRA-C++-2023,RULE-9-5-2,Yes,Required,Decidable,Single Translation Unit,A for-range-initializer shall contain at most one function call,,Statements,Easy,
cpp,MISRA-C++-2023,RULE-9-6-1,Yes,Advisory,Decidable,Single Translation Unit,The goto statement should not be used,RULE-15-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-9-6-2,Yes,Required,Decidable,Single Translation Unit,A goto statement shall reference a label in a surrounding block,RULE-15-3,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-9-6-3,Yes,Required,Decidable,Single Translation Unit,The goto statement shall jump to a label declared later in the function body,RULE-15-2,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-9-6-4,Yes,Required,Undecidable,System,A function declared with the [[noreturn]] attribute shall not return,MSC53-CPP,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-9-6-5,Yes,Required,Decidable,Single Translation Unit,A function with non-void return type shall return a value on all paths,MSC52-CPP,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-10-0-1,Yes,Advisory,Decidable,Single Translation Unit,A declaration should not declare more than one variable or member variable,M8-0-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-10-1-1,Yes,Advisory,Decidable,Single Translation Unit,The target type of a pointer or lvalue reference parameter should be const-qualified appropriately,RULE-8-13,,Hard,
-cpp,MISRA-C++-2023,RULE-10-1-2,Yes,Required,Decidable,Single Translation Unit,The volatile qualifier shall be used appropriately,,,Easy,
+cpp,MISRA-C++-2023,RULE-10-1-1,Yes,Advisory,Decidable,Single Translation Unit,The target type of a pointer or lvalue reference parameter should be const-qualified appropriately,RULE-8-13,Declarations2,Hard,
+cpp,MISRA-C++-2023,RULE-10-1-2,Yes,Required,Decidable,Single Translation Unit,The volatile qualifier shall be used appropriately,,Declarations2,Easy,
cpp,MISRA-C++-2023,RULE-10-2-1,Yes,Required,Decidable,Single Translation Unit,An enumeration shall be defined with an explicit underlying type,A7-2-2,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-10-2-2,Yes,Advisory,Decidable,Single Translation Unit,Unscoped enumerations should not be declared,A7-2-3,,Easy,
-cpp,MISRA-C++-2023,RULE-10-2-3,Yes,Required,Decidable,Single Translation Unit,The numeric value of an unscoped enumeration with no fixed underlying type shall not be used,A4-5-1,,Easy,
-cpp,MISRA-C++-2023,RULE-10-3-1,Yes,Advisory,Decidable,Single Translation Unit,There should be no unnamed namespaces in header files,"DCL59-CPP, M7-3-3",,Easy,
+cpp,MISRA-C++-2023,RULE-10-2-2,Yes,Advisory,Decidable,Single Translation Unit,Unscoped enumerations should not be declared,A7-2-3,Banned,Easy,
+cpp,MISRA-C++-2023,RULE-10-2-3,Yes,Required,Decidable,Single Translation Unit,The numeric value of an unscoped enumeration with no fixed underlying type shall not be used,A4-5-1,Banned,Easy,
+cpp,MISRA-C++-2023,RULE-10-3-1,Yes,Advisory,Decidable,Single Translation Unit,There should be no unnamed namespaces in header files,"DCL59-CPP, M7-3-3",Banned,Easy,
cpp,MISRA-C++-2023,RULE-10-4-1,Yes,Required,Decidable,Single Translation Unit,The asm declaration shall not be used,A7-4-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-11-3-1,Yes,Advisory,Decidable,Single Translation Unit,Variables of array type should not be declared,,,Easy,
+cpp,MISRA-C++-2023,RULE-11-3-1,Yes,Advisory,Decidable,Single Translation Unit,Variables of array type should not be declared,,Declarations2,Easy,
cpp,MISRA-C++-2023,RULE-11-3-2,Yes,Advisory,Decidable,Single Translation Unit,The declaration of an object should contain no more than two levels of pointer indirection,A5-0-3,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-11-6-1,Yes,Advisory,Decidable,Single Translation Unit,All variables should be initialized,,,Easy,
-cpp,MISRA-C++-2023,RULE-11-6-2,Yes,Mandatory,Undecidable,System,The value of an object must not be read before it has been set,A8-5-0,,Very Hard,
+cpp,MISRA-C++-2023,RULE-11-6-1,Yes,Advisory,Decidable,Single Translation Unit,All variables should be initialized,,Declarations2,Easy,
+cpp,MISRA-C++-2023,RULE-11-6-2,Yes,Mandatory,Undecidable,System,The value of an object must not be read before it has been set,A8-5-0,Lifetime,Very Hard,
cpp,MISRA-C++-2023,RULE-11-6-3,Yes,Required,Decidable,Single Translation Unit,"Within an enumerator list, the value of an implicitly-specified enumeration constant shall be unique",RULE-8-12,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-12-2-1,Yes,Advisory,Decidable,Single Translation Unit,Bit-fields should not be declared,A9-6-2,,Easy,
+cpp,MISRA-C++-2023,RULE-12-2-1,Yes,Advisory,Decidable,Single Translation Unit,Bit-fields should not be declared,A9-6-2,Banned,Easy,
cpp,MISRA-C++-2023,RULE-12-2-2,Yes,Required,Decidable,Single Translation Unit,A bit-field shall have an appropriate type,RULE-6-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-12-2-3,Yes,Required,Decidable,Single Translation Unit,A named bit-field with signed integer type shall not have a length of one bit,M9-6-4,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-12-3-1,Yes,Required,Decidable,Single Translation Unit,The union keyword shall not be used,RULE-19-2,,Easy,
-cpp,MISRA-C++-2023,RULE-13-1-1,Yes,Advisory,Decidable,Single Translation Unit,Classes should not be inherited virtually,,,Easy,
+cpp,MISRA-C++-2023,RULE-12-3-1,Yes,Required,Decidable,Single Translation Unit,The union keyword shall not be used,RULE-19-2,Banned,Easy,
+cpp,MISRA-C++-2023,RULE-13-1-1,Yes,Advisory,Decidable,Single Translation Unit,Classes should not be inherited virtually,,Classes2,Easy,
cpp,MISRA-C++-2023,RULE-13-1-2,Yes,Required,Decidable,Single Translation Unit,An accessible base class shall not be both virtual and non-virtual in the same hierarchy,M10-1-3,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-13-3-1,Yes,Required,Decidable,Single Translation Unit,"User-declared member functions shall use the virtual, override and final specifiers appropriately",,,Easy,
+cpp,MISRA-C++-2023,RULE-13-3-1,Yes,Required,Decidable,Single Translation Unit,"User-declared member functions shall use the virtual, override and final specifiers appropriately",,Classes2,Easy,
cpp,MISRA-C++-2023,RULE-13-3-2,Yes,Required,Decidable,Single Translation Unit,Parameters in an overriding virtual function shall not specify different default arguments,M8-3-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-13-3-3,Yes,Required,Decidable,System,The parameters in all declarations or overrides of a function shall either be unnamed or have identical names,RULE-8-3,,Easy,
+cpp,MISRA-C++-2023,RULE-13-3-3,Yes,Required,Decidable,System,The parameters in all declarations or overrides of a function shall either be unnamed or have identical names,RULE-8-3,Declarations2,Easy,
cpp,MISRA-C++-2023,RULE-13-3-4,Yes,Required,Decidable,Single Translation Unit,A comparison of a potentially virtual pointer to member function shall only be with nullptr,A5-10-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-14-1-1,Yes,Advisory,Decidable,Single Translation Unit,Non-static data members should be either all private or all public,,,Easy,
-cpp,MISRA-C++-2023,RULE-15-0-1,Yes,Required,Decidable,Single Translation Unit,Special member functions shall be provided appropriately,A12-0-1,,Medium,
-cpp,MISRA-C++-2023,RULE-15-0-2,Yes,Advisory,Decidable,Single Translation Unit,User-provided copy and move member functions of a class should have appropriate signatures,,,Easy,
+cpp,MISRA-C++-2023,RULE-14-1-1,Yes,Advisory,Decidable,Single Translation Unit,Non-static data members should be either all private or all public,,Classes2,Easy,
+cpp,MISRA-C++-2023,RULE-15-0-1,Yes,Required,Decidable,Single Translation Unit,Special member functions shall be provided appropriately,A12-0-1,Classes2,Medium,
+cpp,MISRA-C++-2023,RULE-15-0-2,Yes,Advisory,Decidable,Single Translation Unit,User-provided copy and move member functions of a class should have appropriate signatures,,Classes2,Easy,
cpp,MISRA-C++-2023,RULE-15-1-1,Yes,Required,Undecidable,System,An object’s dynamic type shall not be used from within its constructor or destructor,M12-1-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-15-1-2,Yes,Advisory,Decidable,Single Translation Unit,All constructors of a class should explicitly initialize all of its virtual base classes and immediate base classes,A12-1-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-15-1-3,Yes,Required,Decidable,Single Translation Unit,Conversion operators and constructors that are callable with a single argument shall be explicit,"A12-1-4,A13-5-2",,Easy,
-cpp,MISRA-C++-2023,RULE-15-1-4,Yes,Advisory,Decidable,Single Translation Unit,"All direct, non-static data members of a class should be initialized before the class object is accessible",,,Hard,
+cpp,MISRA-C++-2023,RULE-15-1-3,Yes,Required,Decidable,Single Translation Unit,Conversion operators and constructors that are callable with a single argument shall be explicit,"A12-1-4,A13-5-2",Classes2,Easy,
+cpp,MISRA-C++-2023,RULE-15-1-4,Yes,Advisory,Decidable,Single Translation Unit,"All direct, non-static data members of a class should be initialized before the class object is accessible",,Classes2,Hard,
cpp,MISRA-C++-2023,RULE-15-1-5,Yes,Required,Decidable,Single Translation Unit,A class shall only define an initializer-list constructor when it is the only constructor,A8-5-4,ImportMisra23,Import,
cpp,MISRA-C++-2023,DIR-15-8-1,Yes,Required,Decidable,Implementation,User-provided copy assignment operators and move assignment operators shall handle self-assignment,A12-8-5,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-16-5-1,Yes,Required,Decidable,Single Translation Unit,The logical AND and logical OR operators shall not be overloaded,M5-2-11,,Easy,
+cpp,MISRA-C++-2023,RULE-16-5-1,Yes,Required,Decidable,Single Translation Unit,The logical AND and logical OR operators shall not be overloaded,M5-2-11,Classes2,Easy,
cpp,MISRA-C++-2023,RULE-16-5-2,Yes,Required,Decidable,Single Translation Unit,The address-of operator shall not be overloaded,M5-3-3,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-16-6-1,Yes,Advisory,Decidable,Single Translation Unit,Symmetrical operators should only be implemented as non-member functions,,,Medium,
+cpp,MISRA-C++-2023,RULE-16-6-1,Yes,Advisory,Decidable,Single Translation Unit,Symmetrical operators should only be implemented as non-member functions,,Classes2,Medium,
cpp,MISRA-C++-2023,RULE-17-8-1,Yes,Required,Decidable,Single Translation Unit,Function templates shall not be explicitly specialized,A14-8-2,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-18-1-1,Yes,Required,Decidable,Single Translation Unit,An exception object shall not have pointer type,A15-1-2,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-18-1-2,Yes,Required,Decidable,Single Translation Unit,An empty throw shall only occur within the compound-statement of a catch handler,M15-1-3,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-18-3-1,Yes,Advisory,Decidable,Single Translation Unit,There should be at least one exception handler to catch all otherwise unhandled exceptions,A15-3-3,,Easy,
-cpp,MISRA-C++-2023,RULE-18-3-2,Yes,Required,Decidable,Single Translation Unit,An exception of class type shall be caught by const reference or reference,A15-3-5,,Easy,
+cpp,MISRA-C++-2023,RULE-18-3-1,Yes,Advisory,Decidable,Single Translation Unit,There should be at least one exception handler to catch all otherwise unhandled exceptions,A15-3-3,Exceptions3,Easy,
+cpp,MISRA-C++-2023,RULE-18-3-2,Yes,Required,Decidable,Single Translation Unit,An exception of class type shall be caught by const reference or reference,A15-3-5,Exceptions3,Easy,
cpp,MISRA-C++-2023,RULE-18-3-3,Yes,Required,Decidable,Single Translation Unit,Handlers for a function-try-block of a constructor or destructor shall not refer to non-static members from their class or its bases,M15-3-3,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-18-4-1,Yes,Required,Decidable,Single Translation Unit,Exception-unfriendly functions shall be noexcept,A15-5-1,,Easy,
+cpp,MISRA-C++-2023,RULE-18-4-1,Yes,Required,Decidable,Single Translation Unit,Exception-unfriendly functions shall be noexcept,A15-5-1,Exceptions3,Easy,
cpp,MISRA-C++-2023,RULE-18-5-1,Yes,Advisory,Undecidable,System,A noexcept function should not attempt to propagate an exception to the calling function,A15-4-2,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-18-5-2,Yes,Advisory,Decidable,Single Translation Unit,Program-terminating functions should not be used,,,Easy,
+cpp,MISRA-C++-2023,RULE-18-5-2,Yes,Advisory,Decidable,Single Translation Unit,Program-terminating functions should not be used,,BannedAPIs,Easy,
cpp,MISRA-C++-2023,RULE-19-0-1,No,Required,Decidable,Single Translation Unit,A line whose first token is # shall be a valid preprocessing directive,,,,
cpp,MISRA-C++-2023,RULE-19-0-2,Yes,Required,Decidable,Single Translation Unit,Function-like macros shall not be defined,DIR-4-9,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-19-0-3,Yes,Advisory,Decidable,Single Translation Unit,#include directives should only be preceded by preprocessor directives or comments,RULE-20-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-19-0-4,Yes,Advisory,Decidable,Single Translation Unit,#undef should only be used for macros defined previously in the same file,,,Easy,
-cpp,MISRA-C++-2023,RULE-19-1-1,Yes,Required,Decidable,Single Translation Unit,The defined preprocessor operator shall be used appropriately,M16-1-1,,Easy,
+cpp,MISRA-C++-2023,RULE-19-0-4,Yes,Advisory,Decidable,Single Translation Unit,#undef should only be used for macros defined previously in the same file,,Preprocessor,Easy,
+cpp,MISRA-C++-2023,RULE-19-1-1,Yes,Required,Decidable,Single Translation Unit,The defined preprocessor operator shall be used appropriately,M16-1-1,Preprocessor,Easy,
cpp,MISRA-C++-2023,RULE-19-1-2,No,Required,Decidable,Single Translation Unit,"All #else, #elif and #endif preprocessor directives shall reside in the same file as the #if, #ifdef or #ifndef directive to which they are related",M16-1-2,,,
cpp,MISRA-C++-2023,RULE-19-1-3,Yes,Required,Decidable,Single Translation Unit,All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be defined prior to evaluation,M16-0-7,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-19-2-1,Yes,Required,Decidable,Single Translation Unit,Precautions shall be taken in order to prevent the contents of a header file being included more than once,M16-2-3,,Easy,
-cpp,MISRA-C++-2023,RULE-19-2-2,Yes,Required,Decidable,Single Translation Unit,"The #include directive shall be followed by either a or ""filename"" sequence",,,Easy,
+cpp,MISRA-C++-2023,RULE-19-2-1,Yes,Required,Decidable,Single Translation Unit,Precautions shall be taken in order to prevent the contents of a header file being included more than once,M16-2-3,Preprocessor,Easy,
+cpp,MISRA-C++-2023,RULE-19-2-2,Yes,Required,Decidable,Single Translation Unit,"The #include directive shall be followed by either a or ""filename"" sequence",,Preprocessor,Easy,
cpp,MISRA-C++-2023,RULE-19-2-3,Yes,Required,Decidable,Single Translation Unit,"The ' or "" or \ characters and the /* or // character sequences shall not occur in a header file name",A16-2-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-19-3-1,Yes,Advisory,Decidable,Single Translation Unit,The # and ## preprocessor operators should not be used,M16-3-2,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-19-3-2,Yes,Required,Decidable,Single Translation Unit,A macro parameter immediately following a # operator shall not be immediately followed by a ## operator,RULE-20-11,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-19-3-3,Yes,Required,Decidable,Single Translation Unit,The argument to a mixed-use macro parameter shall not be subject to further expansion,RULE-20-12,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-19-3-4,Yes,Required,Decidable,Single Translation Unit,Parentheses shall be used to ensure macro arguments are expanded appropriately,M16-0-6,,Medium,
+cpp,MISRA-C++-2023,RULE-19-3-4,Yes,Required,Decidable,Single Translation Unit,Parentheses shall be used to ensure macro arguments are expanded appropriately,M16-0-6,Preprocessor,Medium,
cpp,MISRA-C++-2023,RULE-19-3-5,Yes,Required,Decidable,Single Translation Unit,Tokens that look like a preprocessing directive shall not occur within a macro argument,RULE-20-6,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-19-6-1,Yes,Advisory,Decidable,Single Translation Unit,The #pragma directive and the _Pragma operator should not be used,A16-7-1,,Easy,
+cpp,MISRA-C++-2023,RULE-19-6-1,Yes,Advisory,Decidable,Single Translation Unit,The #pragma directive and the _Pragma operator should not be used,A16-7-1,Preprocessor,Easy,
cpp,MISRA-C++-2023,RULE-21-2-1,Yes,Required,Decidable,Single Translation Unit,"The library functions atof, atoi, atol and atoll from shall not be used",RULE-21-7,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-21-2-2,Yes,Required,Decidable,Single Translation Unit,"The string handling functions from , , and shall not be used",M18-0-5,,Easy,
-cpp,MISRA-C++-2023,RULE-21-2-3,Yes,Required,Decidable,Single Translation Unit,The library function system from shall not be used,M18-0-3,,Easy,
+cpp,MISRA-C++-2023,RULE-21-2-2,Yes,Required,Decidable,Single Translation Unit,"The string handling functions from , , and shall not be used",M18-0-5,BannedAPIs,Easy,
+cpp,MISRA-C++-2023,RULE-21-2-3,Yes,Required,Decidable,Single Translation Unit,The library function system from shall not be used,M18-0-3,BannedAPIs,Easy,
cpp,MISRA-C++-2023,RULE-21-2-4,Yes,Required,Decidable,Single Translation Unit,The macro offsetof shall not be used,M18-2-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-21-6-1,Yes,Advisory,Undecidable,Single Translation Unit,Dynamic memory should not be used,DIR-4-12,,Easy,
-cpp,MISRA-C++-2023,RULE-21-6-2,Yes,Required,Decidable,Single Translation Unit,Dynamic memory shall be managed automatically,,,Easy,
-cpp,MISRA-C++-2023,RULE-21-6-3,Yes,Required,Decidable,Single Translation Unit,Advanced memory management shall not be used,,,Medium,
+cpp,MISRA-C++-2023,RULE-21-6-1,Yes,Advisory,Undecidable,Single Translation Unit,Dynamic memory should not be used,DIR-4-12,Banned,Easy,
+cpp,MISRA-C++-2023,RULE-21-6-2,Yes,Required,Decidable,Single Translation Unit,Dynamic memory shall be managed automatically,,Memory,Easy,
+cpp,MISRA-C++-2023,RULE-21-6-3,Yes,Required,Decidable,Single Translation Unit,Advanced memory management shall not be used,,Memory,Medium,
cpp,MISRA-C++-2023,RULE-21-6-4,Yes,Required,Decidable,System,"If a project defines either a sized or unsized version of a global operator delete, then both shall be defined",A18-5-4,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-21-6-5,Yes,Required,Decidable,Single Translation Unit,A pointer to an incomplete class type shall not be deleted,A5-3-3,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-21-10-1,Yes,Required,Decidable,Single Translation Unit,The features of shall not be used,DCL50-CPP,,Easy,
-cpp,MISRA-C++-2023,RULE-21-10-2,Yes,Required,Decidable,Single Translation Unit,The standard header file shall not be used,ERR52-CPP,,Easy,
+cpp,MISRA-C++-2023,RULE-21-10-1,Yes,Required,Decidable,Single Translation Unit,The features of shall not be used,DCL50-CPP,BannedAPIs,Easy,
+cpp,MISRA-C++-2023,RULE-21-10-2,Yes,Required,Decidable,Single Translation Unit,The standard header file shall not be used,ERR52-CPP,BannedAPIs,Easy,
cpp,MISRA-C++-2023,RULE-21-10-3,Yes,Required,Decidable,Single Translation Unit,The facilities provided by the standard header file shall not be used,M18-7-1,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-22-3-1,Yes,Required,Decidable,Single Translation Unit,The assert macro shall not be used with a constant-expression,,,Easy,
-cpp,MISRA-C++-2023,RULE-22-4-1,Yes,Required,Decidable,Single Translation Unit,The literal value zero shall be the only value assigned to errno,,,Easy,
-cpp,MISRA-C++-2023,RULE-23-11-1,Yes,Advisory,Decidable,Single Translation Unit,The raw pointer constructors of std::shared_ptr and std::unique_ptr should not be used,,,Easy,
-cpp,MISRA-C++-2023,RULE-24-5-1,Yes,Required,Decidable,Single Translation Unit,The character handling functions from and shall not be used,,,Easy,
-cpp,MISRA-C++-2023,RULE-24-5-2,Yes,Required,Decidable,Single Translation Unit,"The C++ Standard Library functions memcpy, memmove and memcmp from shall not be used",,,Easy,
-cpp,MISRA-C++-2023,RULE-25-5-1,Yes,Required,Decidable,Single Translation Unit,The setlocale and std::locale::global functions shall not be called,,,Easy,
+cpp,MISRA-C++-2023,RULE-22-3-1,Yes,Required,Decidable,Single Translation Unit,The assert macro shall not be used with a constant-expression,,Preconditions,Easy,
+cpp,MISRA-C++-2023,RULE-22-4-1,Yes,Required,Decidable,Single Translation Unit,The literal value zero shall be the only value assigned to errno,,Preconditions,Easy,
+cpp,MISRA-C++-2023,RULE-23-11-1,Yes,Advisory,Decidable,Single Translation Unit,The raw pointer constructors of std::shared_ptr and std::unique_ptr should not be used,,BannedAPIs,Easy,
+cpp,MISRA-C++-2023,RULE-24-5-1,Yes,Required,Decidable,Single Translation Unit,The character handling functions from and shall not be used,,BannedAPIs,Easy,
+cpp,MISRA-C++-2023,RULE-24-5-2,Yes,Required,Decidable,Single Translation Unit,"The C++ Standard Library functions memcpy, memmove and memcmp from shall not be used",,BannedAPIs,Easy,
+cpp,MISRA-C++-2023,RULE-25-5-1,Yes,Required,Decidable,Single Translation Unit,The setlocale and std::locale::global functions shall not be called,,BannedAPIs,Easy,
cpp,MISRA-C++-2023,RULE-25-5-2,Yes,Mandatory,Decidable,Single Translation Unit,"The pointers returned by the C++ Standard Library functions localeconv, getenv, setlocale or strerror must only be used as if they have pointer to const-qualified type",RULE-21-19,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-25-5-3,Yes,Mandatory,Undecidable,System,"The pointer returned by the C++ Standard Library functions asctime, ctime, gmtime, localtime, localeconv, getenv, setlocale or strerror must not be used following a subsequent call to the same function",RULE-21-20,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-26-3-1,Yes,Advisory,Decidable,Single Translation Unit,std::vector should not be specialized with bool,A18-1-2,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-28-3-1,Yes,Required,Undecidable,System,Predicates shall not have persistent side effects,A25-1-1,,Easy,
-cpp,MISRA-C++-2023,RULE-28-6-1,Yes,Required,Decidable,Single Translation Unit,The argument to std::move shall be a non-const lvalue,A18-9-3,,Easy,
+cpp,MISRA-C++-2023,RULE-28-3-1,Yes,Required,Undecidable,System,Predicates shall not have persistent side effects,A25-1-1,SideEffects3,Easy,
+cpp,MISRA-C++-2023,RULE-28-6-1,Yes,Required,Decidable,Single Translation Unit,The argument to std::move shall be a non-const lvalue,A18-9-3,Preconditions,Easy,
cpp,MISRA-C++-2023,RULE-28-6-2,Yes,Required,Decidable,Single Translation Unit,Forwarding references and std::forward shall be used together,A18-9-2,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-28-6-3,Yes,Required,Decidable,Single Translation Unit,An object shall not be used while in a potentially moved-from state,A12-8-3,ImportMisra23,Import,
-cpp,MISRA-C++-2023,RULE-28-6-4,Yes,Required,Decidable,Single Translation Unit,"The result of std::remove, std::remove_if, std::unique and empty shall be used",,,Easy,
+cpp,MISRA-C++-2023,RULE-28-6-4,Yes,Required,Decidable,Single Translation Unit,"The result of std::remove, std::remove_if, std::unique and empty shall be used",,DeadCode2,Easy,
cpp,MISRA-C++-2023,RULE-30-0-1,Yes,Required,Decidable,Single Translation Unit,The C Library input/output functions shall not be used,M27-0-1,ImportMisra23,Import,
cpp,MISRA-C++-2023,RULE-30-0-2,Yes,Required,Undecidable,System,Reads and writes on the same file stream shall be separated by a positioning operation,A27-0-3,ImportMisra23,Import,
diff --git a/schemas/rule-package.schema.json b/schemas/rule-package.schema.json
index daeb1ade51..a43deb2141 100644
--- a/schemas/rule-package.schema.json
+++ b/schemas/rule-package.schema.json
@@ -207,6 +207,9 @@
},
"title": {
"type": "string"
+ },
+ "implementation_scope": {
+ "$ref": "#/$defs/implementation_scope"
}
},
"required": [
@@ -338,27 +341,17 @@
"external/cert/default-disabled",
"external/autosar/strict",
"scope/single-translation-unit",
- "scope/system"
+ "scope/system",
+ "external/misra/c/2012/third-edition-first-revision",
+ "external/misra/c/2012/amendment2",
+ "external/misra/c/2012/amendment3",
+ "external/misra/c/2012/amendment4"
]
},
"minLength": 1
},
"implementation_scope": {
- "type": "object",
- "properties": {
- "description": {
- "kind": "string"
- },
- "items": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "required": [
- "description"
- ]
+ "$ref": "/schemas/implementation_scope"
}
},
"required": [
@@ -369,6 +362,25 @@
"short_name",
"tags"
]
+ },
+ "implementation_scope": {
+ "$id": "/schemas/implementation_scope",
+ "type": "object",
+ "properties": {
+ "description": {
+ "kind": "string"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [
+ "description"
+ ],
+ "additionalProperties": false
}
}
}
\ No newline at end of file
diff --git a/scripts/PSCodingStandards/Config.ps1 b/scripts/PSCodingStandards/Config.ps1
index 2dc8d8e5bc..53605c89f3 100644
--- a/scripts/PSCodingStandards/Config.ps1
+++ b/scripts/PSCodingStandards/Config.ps1
@@ -1,2 +1,2 @@
-$AVAILABLE_SUITES = @("CERT-C++", "AUTOSAR", "MISRA-C-2012", "CERT-C")
+$AVAILABLE_SUITES = @("CERT-C++", "AUTOSAR", "MISRA-C-2012", "CERT-C", "MISRA-C++-2023")
$AVAILABLE_LANGUAGES = @("c", "cpp")
\ No newline at end of file
diff --git a/scripts/PSCodingStandards/Get-TestDirectory.ps1 b/scripts/PSCodingStandards/Get-TestDirectory.ps1
index 341cb3d7d9..154a49dabe 100644
--- a/scripts/PSCodingStandards/Get-TestDirectory.ps1
+++ b/scripts/PSCodingStandards/Get-TestDirectory.ps1
@@ -27,6 +27,9 @@ function Get-TestDirectory {
elseif ($RuleObject.__memberof_suite -eq "MISRA-C-2012") {
$standardString = "misra"
}
+ elseif ($RuleObject.__memberof_suite -eq "MISRA-C++-2023") {
+ $standardString = "misra"
+ }
else {
throw "Unknown standard $($RuleObject.__memberof_suite)"
}
diff --git a/scripts/generate_modules/queries/codeql-pack.lock.yml b/scripts/generate_modules/queries/codeql-pack.lock.yml
index 514e6963d0..2cbbccee53 100644
--- a/scripts/generate_modules/queries/codeql-pack.lock.yml
+++ b/scripts/generate_modules/queries/codeql-pack.lock.yml
@@ -2,13 +2,17 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 0.12.9
codeql/dataflow:
- version: 0.0.4
+ version: 0.2.3
+ codeql/rangeanalysis:
+ version: 0.0.11
codeql/ssa:
- version: 0.1.5
+ version: 0.2.12
codeql/tutorial:
- version: 0.1.5
+ version: 0.2.12
+ codeql/typetracking:
+ version: 0.2.12
codeql/util:
- version: 0.1.5
+ version: 0.2.12
compiled: false
diff --git a/scripts/generate_modules/queries/qlpack.yml b/scripts/generate_modules/queries/qlpack.yml
index 4f3768cd79..fea871b973 100644
--- a/scripts/generate_modules/queries/qlpack.yml
+++ b/scripts/generate_modules/queries/qlpack.yml
@@ -2,4 +2,4 @@ name: codeql/standard-library-extraction-cpp-coding-standards
version: 0.0.0
license: MIT
dependencies:
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 0.12.9
diff --git a/scripts/generate_rules/generate_package_description.py b/scripts/generate_rules/generate_package_description.py
index bf993af574..843d3bd78f 100644
--- a/scripts/generate_rules/generate_package_description.py
+++ b/scripts/generate_rules/generate_package_description.py
@@ -197,11 +197,10 @@ def generate_short_name(title):
json.dump(package_description, rule_package_file, indent=2, sort_keys=True)
print("Rule package file generated at " + str(rule_package_file_path) + ".")
print("")
- print("A default query has been generated for each for each rule. Please review each rule in the generated JSON file and:")
+ print("A default query has been generated for each rule. Please review each rule in the generated JSON file and:")
print(" (1) Add additional queries as required")
print(" (2) Confirm that the following auto-generated properties are appropriate:")
- print(" - 'camel_name'.")
print(" - 'precision'.")
- print(" - 'query_name'.")
+ print(" - 'short_name'.")
print(" - 'severity'.")
print(" (3) Add additional 'tags' as required, particularly 'security' or 'correctness'.")
diff --git a/scripts/matrix_testing/CreateMatrixTestReport.ps1 b/scripts/matrix_testing/CreateMatrixTestReport.ps1
index 6f570c1b82..a8de5034ce 100644
--- a/scripts/matrix_testing/CreateMatrixTestReport.ps1
+++ b/scripts/matrix_testing/CreateMatrixTestReport.ps1
@@ -147,9 +147,9 @@ param(
$Configuration,
# For a suite, the suites we support. Valid values are 'CERT-C++' and
- # 'AUTOSAR' and MISRA-C-2012 and CERT-C
+ # 'AUTOSAR' and MISRA-C-2012, MISRA-C++-2023 and CERT-C
[Parameter(Mandatory, ParameterSetName = 'Suite')]
- [ValidateSet("CERT-C++", "AUTOSAR", "MISRA-C-2012", "CERT-C")]
+ [ValidateSet("CERT-C++", "AUTOSAR", "MISRA-C-2012", "CERT-C", "MISRA-C++-2023")]
[string]
$SuiteName,
diff --git a/scripts/release/bump-version.sh b/scripts/release/bump-version.sh
index fd5ab5ea0d..5bbd0eeae0 100755
--- a/scripts/release/bump-version.sh
+++ b/scripts/release/bump-version.sh
@@ -15,6 +15,7 @@ find . -name 'qlpack.yml' | grep -v './codeql_modules' | grep -v './scripts' | x
# update the documentation.
find docs -name 'user_manual.md' -print0 | xargs -0 sed -i "s/code-scanning-cpp-query-pack-.*\.zip\`/code-scanning-cpp-query-pack-${1}.zip\`/"
+find docs -name 'user_manual.md' -print0 | xargs -0 sed -i "s/coding-standard-codeql-pack-.*\.zip\`/coding-standard-codeql-pack-${1}.zip\`/"
find docs -name 'user_manual.md' -print0 | xargs -0 sed -i "s/supported_rules_list_.*\.csv\`/supported_rules_list_${1}.csv\`/"
find docs -name 'user_manual.md' -print0 | xargs -0 sed -i "s/supported_rules_list_.*\.md\`/supported_rules_list_${1}.md\`/"
find docs -name 'user_manual.md' -print0 | xargs -0 sed -i "s/user_manual_.*\.md\`/user_manual_${1}.md\`/"
diff --git a/scripts/release/create_supported_rules_list.py b/scripts/release/create_supported_rules_list.py
index e3294ed3b1..6d8f3e0991 100644
--- a/scripts/release/create_supported_rules_list.py
+++ b/scripts/release/create_supported_rules_list.py
@@ -27,7 +27,7 @@
repo_root = Path(__file__).parent.parent.parent
-rules_covered = {"AUTOSAR" : {}, "CERT-C++" : {}, "MISRA-C-2012" : {}, "CERT-C" : {}}
+rules_covered = {"AUTOSAR" : {}, "CERT-C++" : {}, "MISRA-C-2012" : {}, "CERT-C" : {}, "MISRA-C++-2023" : {},}
# Iterate over rule packages
for language_name in ["cpp", "c"]:
diff --git a/scripts/release/generate_release_notes.py b/scripts/release/generate_release_notes.py
index c6cea8d19f..3852a5eeb7 100644
--- a/scripts/release/generate_release_notes.py
+++ b/scripts/release/generate_release_notes.py
@@ -79,7 +79,7 @@ def transform_legacy_rule_path(p):
diff_from_last_release = latest_release_commit.diff(head_commit)
# Store a mapping from standard -> rules with new queries -> new queries for those rules
-new_rules = {"AUTOSAR" : {}, "CERT-C++" : {}, "MISRA-C-2012" : {}, "CERT-C" : {}}
+new_rules = {"AUTOSAR" : {}, "CERT-C++" : {}, "MISRA-C-2012" : {}, "CERT-C" : {}, "MISRA-C++-2023" : {}}
# Store the text of the newly added change notes
change_notes = []
# Store the names of the rule packages with new queries
diff --git a/scripts/release/release-layout.yml b/scripts/release/release-layout.yml
index 5e496120f2..4ced0b4d30 100644
--- a/scripts/release/release-layout.yml
+++ b/scripts/release/release-layout.yml
@@ -10,6 +10,10 @@ layout:
- workflow-artifact:
name: "Code Scanning Query Pack Generation"
artifact: code-scanning-cpp-query-pack.zip
+ coding-standards-codeql-packs.zip:
+ - workflow-artifact:
+ name: "Code Scanning Query Pack Generation"
+ artifact: coding-standards-codeql-packs
supported_rules_list.csv:
- shell: |
python ${{ coding-standards.root }}/scripts/release/create_supported_rules_list.py --csv > supported_rules_list.csv
diff --git a/scripts/release/requirements.txt b/scripts/release/requirements.txt
index 5cdcc51546..653323eaaa 100644
--- a/scripts/release/requirements.txt
+++ b/scripts/release/requirements.txt
@@ -1,5 +1,5 @@
semantic-version==2.10.0
PyGithub==1.59.1
PyYAML==6.0.1
-GitPython==3.1.37
+GitPython==3.1.41
pytest==7.4.3
diff --git a/scripts/release/webhook-handler.js b/scripts/release/webhook-handler.js
new file mode 100644
index 0000000000..6197bedb48
--- /dev/null
+++ b/scripts/release/webhook-handler.js
@@ -0,0 +1,229 @@
+/**
+ * This function should be installed as an Azure Function with a HTTP trigger and configured as a GitHub webhook.
+ * It expects the following environment variables to be set:
+ * - GITHUB_APP_ID: the ID of the GitHub App used to authenticate
+ * - GITHUB_APP_INSTALLATION_ID: the ID of the GitHub App installation
+ * - GITHUB_APP_PRIVATE_KEY: the private key of the GitHub App
+ * - GITHUB_WEBHOOK_SECRET: the secret used to sign the webhook
+ * - GITHUB_WORKFLOW_ID: the ID of the workflow to trigger, this should be the id of the workflow `update-release-status.yml`
+ */
+const crypto = require('crypto');
+const { Buffer } = require('buffer');
+const https = require('https');
+
+function encode(obj) {
+ return Buffer.from(JSON.stringify(obj)).toString('base64url');
+}
+
+function createJwtToken() {
+
+ const signingKey = crypto.createPrivateKey(Buffer.from(process.env['GITHUB_APP_PRIVATE_KEY'], 'base64'));
+
+ const claims = {
+ // Issue 60 seconds in the past to account for clock drift.
+ iat: Math.floor(Date.now() / 1000) - 60,
+ // The token is valid for 1 minute(s).
+ exp: Math.floor(Date.now() / 1000) + (1 * 60),
+ iss: process.env["GITHUB_APP_ID"]
+ };
+
+ const header = {
+ alg: "RS256",
+ typ: "JWT"
+ };
+
+ const payload = `${encode(header)}.${encode(claims)}`;
+ const signer = crypto.createSign('RSA-SHA256');
+ const signature = (signer.update(payload), signer.sign(signingKey, 'base64url'));
+
+ return `${payload}.${signature}`;
+}
+
+function createAccessToken(context) {
+ return new Promise((resolve, reject) => {
+ const options = {
+ hostname: 'api.github.com',
+ path: `/app/installations/${process.env["GITHUB_APP_INSTALLATION_ID"]}/access_tokens`,
+ method: 'POST'
+ };
+
+ const req = https.request(options, (res) => {
+ res.on('data', (data) => {
+ const body = JSON.parse(data.toString('utf8'));
+ access_token = body.token;
+ //context.log(access_token);
+ resolve(access_token);
+ });
+
+ res.on('error', (error) => {
+ reject(error);
+ })
+ });
+
+ req.setHeader('Accept', 'application/vnd.github+json');
+ const token = createJwtToken();
+ //context.log(`JWT Token ${token}`);
+ req.setHeader('Authorization', `Bearer ${token}`);
+ req.setHeader('X-GitHub-Api-Version', '2022-11-28');
+ req.setHeader('User-Agent', 'CodeQL Coding Standards Automation');
+
+ req.end();
+ });
+}
+
+function triggerReleaseUpdate(context, access_token, head_sha) {
+ context.log(`Triggering release update for head sha ${head_sha}`)
+ return new Promise((resolve, reject) => {
+ const options = {
+ hostname: 'api.github.com',
+ path: `/repos/github/codeql-coding-standards/actions/workflows/${process.env["GITHUB_WORKFLOW_ID"]}/dispatches`,
+ method: 'POST'
+ };
+
+ const req = https.request(options, (res) => {
+ res.on('error', (error) => {
+ reject(error);
+ })
+ });
+
+ req.setHeader('Accept', 'application/vnd.github+json');
+ req.setHeader('Authorization', `Bearer ${access_token}`);
+ req.setHeader('X-GitHub-Api-Version', '2022-11-28');
+ req.setHeader('User-Agent', 'CodeQL Coding Standards Automation');
+
+ const params = {
+ ref: 'main',
+ inputs: {
+ "head-sha": head_sha
+ }
+ };
+ req.on('response', (response) => {
+ context.log(`Received status code ${response.statusCode} with message ${response.statusMessage}`);
+ resolve();
+ });
+ req.end(JSON.stringify(params));
+ });
+}
+
+function listCheckRunsForRefPerPage(context, access_token, ref, page = 1) {
+ context.log(`Listing check runs for ${ref}`)
+ return new Promise((resolve, reject) => {
+ const options = {
+ hostname: 'api.github.com',
+ path: `/repos/github/codeql-coding-standards/commits/${ref}/check-runs?page=${page}&per_page=100`,
+ method: 'GET',
+ headers: {
+ 'Accept': 'application/vnd.github+json',
+ 'Authorization': `Bearer ${access_token}`,
+ 'X-GitHub-Api-Version': '2022-11-28',
+ 'User-Agent': 'CodeQL Coding Standards Automation'
+ }
+ };
+
+ const req = https.request(options, (res) => {
+ if (res.statusCode != 200) {
+ reject(`Received status code ${res.statusCode} with message ${res.statusMessage}`);
+ } else {
+ var body = [];
+ res.on('data', (chunk) => {
+ body.push(chunk);
+ });
+ res.on('end', () => {
+ try {
+ body = JSON.parse(Buffer.concat(body).toString('utf8'));
+ resolve(body);
+ } catch (error) {
+ reject(error);
+ }
+ });
+ }
+ });
+ req.on('error', (error) => {
+ reject(error);
+ });
+
+ req.end();
+ });
+}
+
+async function listCheckRunsForRef(context, access_token, ref) {
+ let page = 1;
+ let check_runs = [];
+ const first_page = await listCheckRunsForRefPerPage(context, access_token, ref, page);
+ check_runs = check_runs.concat(first_page.check_runs);
+ while (first_page.total_count > check_runs.length) {
+ page++;
+ const next_page = await listCheckRunsForRefPerPage(context, access_token, ref, page);
+ check_runs = check_runs.concat(next_page.check_runs);
+ }
+ return check_runs;
+}
+
+function hasReleaseStatusCheckRun(check_runs) {
+ return check_runs.some(check_run => check_run.name == 'release-status');
+}
+
+function isValidSignature(req) {
+ const hmac = crypto.createHmac("sha256", process.env["GITHUB_WEBHOOK_SECRET"]);
+ const signature = hmac.update(JSON.stringify(req.body)).digest('hex');
+ const shaSignature = `sha256=${signature}`;
+ const gitHubSignature = req.headers['x-hub-signature-256'];
+
+ return !shaSignature.localeCompare(gitHubSignature);
+}
+
+module.exports = async function (context, req) {
+ context.log('Webhook received.');
+
+ if (isValidSignature(req)) {
+ const event = req.headers['x-github-event'];
+
+ if (event == 'check_run') {
+ webhook = req.body;
+
+ // To avoid infinite loops, we skip triggering the workflow for the following checkruns.
+ const check_runs_to_skip = [
+ // check run created by manual dispatch of Update Release workflow
+ 'Update release',
+ // check runs created by job in Update release status workflow
+ 'update-release',
+ // when update-release calls reusable workflow Update release
+ 'update-release / Update release',
+ 'validate-check-runs',
+ // check run that validates the whole release
+ 'release-status'];
+ const update_release_actions = ['completed', 'rerequested'];
+
+ if (update_release_actions.includes(webhook.action) && !check_runs_to_skip.includes(webhook.check_run.name)) {
+ context.log(`Triggering update release status because ${webhook.check_run.name} received action ${webhook.action}`);
+
+ try {
+ const access_token = await createAccessToken(context);
+ const check_runs = await listCheckRunsForRef(context, access_token, webhook.check_run.head_sha);
+ if (hasReleaseStatusCheckRun(check_runs)) {
+ context.log(`Release status check run found for ${webhook.check_run.head_sha}`);
+ await triggerReleaseUpdate(context, access_token, webhook.check_run.head_sha);
+ } else {
+ context.log(`Skippping, no release status check run found for ${webhook.check_run.head_sha}`);
+ }
+ } catch (error) {
+ context.log(`Failed with error: ${error}`);
+ }
+ } else {
+ context.log(`Skipping action ${webhook.action} for ${webhook.check_run.name}`)
+ }
+ } else {
+ context.log(`Skipping event: ${event}`)
+ }
+
+ context.res = {
+ status: 200
+ };
+ } else {
+ context.log('Received invalid GitHub signature')
+ context.res = {
+ status: 401,
+ body: 'Invalid x-hub-signature-256 value'
+ };
+ }
+}
\ No newline at end of file
diff --git a/scripts/requirements.txt b/scripts/requirements.txt
index b5b9cbaf42..e9667a460e 100644
--- a/scripts/requirements.txt
+++ b/scripts/requirements.txt
@@ -2,7 +2,7 @@ beautifulsoup4==4.9.3
certifi==2023.7.22
chardet==3.0.4
gitdb==4.0.5
-GitPython==3.1.37
+GitPython==3.1.41
idna==2.10
Jinja2==3.1.3
MarkupSafe==1.1.1
diff --git a/scripts/upgrade-codeql-dependencies/requirements.txt b/scripts/upgrade-codeql-dependencies/requirements.txt
index 009d2dc5aa..55b810e4aa 100644
--- a/scripts/upgrade-codeql-dependencies/requirements.txt
+++ b/scripts/upgrade-codeql-dependencies/requirements.txt
@@ -4,3 +4,4 @@ idna==3.4
requests==2.31.0
semantic-version==2.10.0
urllib3==1.26.18
+pyyaml==6.0.1
\ No newline at end of file
diff --git a/scripts/upgrade-codeql-dependencies/upgrade-codeql-dependencies.py b/scripts/upgrade-codeql-dependencies/upgrade-codeql-dependencies.py
index 6c98216ca0..c76303e654 100644
--- a/scripts/upgrade-codeql-dependencies/upgrade-codeql-dependencies.py
+++ b/scripts/upgrade-codeql-dependencies/upgrade-codeql-dependencies.py
@@ -1,18 +1,23 @@
import json
import requests
-from typing import Optional, Dict, List
+from typing import Optional, Dict, List, Tuple
from semantic_version import Version
from pathlib import Path
+import yaml
SCRIPT_PATH = Path(__file__)
-SUPPORTED_VERSIONS_PATH = SCRIPT_PATH.parent.parent.parent / "supported_codeql_configs.json"
+CODING_STANDARDS_ROOT = SCRIPT_PATH.parent.parent.parent
+SUPPORTED_VERSIONS_PATH = CODING_STANDARDS_ROOT / "supported_codeql_configs.json"
-def get_compatible_stdlib(version: Version) -> Optional[str]:
+def get_compatible_stdlib(version: Version) -> Optional[Tuple[str, str]]:
tag = f"codeql-cli/v{version}"
response = requests.get(f"https://raw.githubusercontent.com/github/codeql/{tag}/cpp/ql/lib/qlpack.yml")
if response.status_code == 200:
- return tag
+ # Parse the qlpack.yml returned in the response as a yaml file to read the version property
+ qlpack = yaml.safe_load(response.text)
+ if qlpack is not None and "version" in qlpack:
+ return (tag, qlpack["version"])
return None
def get_compatible_bundle(version: Version, token: str) -> Optional[str]:
@@ -30,8 +35,8 @@ def get_compatible_bundle(version: Version, token: str) -> Optional[str]:
def main(cli_version : str, github_token: str) -> None:
try:
parsed_cli_version = Version(cli_version)
- compatible_stdlib = get_compatible_stdlib(parsed_cli_version)
- if compatible_stdlib is None:
+ compatible_stdlib_return = get_compatible_stdlib(parsed_cli_version)
+ if compatible_stdlib_return is None:
print(f"Unable to find compatible standard library for: {parsed_cli_version}")
exit(1)
compatible_bundle = get_compatible_bundle(parsed_cli_version, github_token)
@@ -39,6 +44,8 @@ def main(cli_version : str, github_token: str) -> None:
print(f"Unable to find compatible bundle for: {parsed_cli_version}")
exit(1)
+ compatible_stdlib_tag, compatible_stdlib_version = compatible_stdlib_return
+
with SUPPORTED_VERSIONS_PATH.open("r") as f:
supported_versions = json.load(f)
@@ -49,10 +56,37 @@ def main(cli_version : str, github_token: str) -> None:
supported_env = supported_envs[0]
supported_env["codeql_cli"] = str(parsed_cli_version)
supported_env["codeql_cli_bundle"] = compatible_bundle
- supported_env["codeql_standard_library"] = compatible_stdlib
+ supported_env["codeql_standard_library"] = compatible_stdlib_tag
with SUPPORTED_VERSIONS_PATH.open("w") as f:
json.dump(supported_versions, f, indent=2)
+
+ # Find every qlpack.yml file in the repository
+ qlpack_files = list(CODING_STANDARDS_ROOT.rglob("qlpack.yml"))
+ # Filter out any files that are in a hidden directory
+ qlpack_files = [f for f in qlpack_files if not any(part for part in f.parts if part.startswith("."))]
+
+ # Update the "codeql/cpp-all" entries in the "dependencies" property in every qlpack.yml file
+ for qlpack_file in qlpack_files:
+ with qlpack_file.open("r") as f:
+ qlpack = yaml.safe_load(f)
+ print("Updating dependencies in " + str(qlpack_file))
+ if "codeql/cpp-all" in qlpack["dependencies"]:
+ qlpack["dependencies"]["codeql/cpp-all"] = compatible_stdlib_version
+ with qlpack_file.open("w") as f:
+ yaml.safe_dump(qlpack, f, sort_keys=False)
+
+ # Call CodeQL to update the lock files by running codeql pack upgrade
+ # Note: we need to do this after updating all the qlpack files,
+ # otherwise we may get dependency resolution errors
+ # Note: we need to update all qlpack files, because they may
+ # transitively depend on the packs we changed
+ for qlpack_file in qlpack_files:
+ qlpack = qlpack_file.parent
+ print("Updating lock files for " + str(qlpack))
+ os.system(f"codeql pack upgrade {qlpack}")
+
+
except ValueError as e:
print(e)
exit(1)
diff --git a/scripts/validate-amendments-csv.py b/scripts/validate-amendments-csv.py
new file mode 100644
index 0000000000..9d83b7d0c9
--- /dev/null
+++ b/scripts/validate-amendments-csv.py
@@ -0,0 +1,128 @@
+from collections import defaultdict
+import csv
+import os
+from pathlib import Path
+import sys
+import json
+
+help_statement = """
+Usage: {script_name}
+
+A script which detects invalid entries in amendments.csv.
+"""
+
+if (len(sys.argv) == 2 and sys.argv[1] == "--help"):
+ print(help_statement.format(script_name=sys.argv[0]))
+ sys.exit(0)
+
+if not len(sys.argv) == 2:
+ print("Error: incorrect number of arguments", file=sys.stderr)
+ print("Usage: " + sys.argv[0] + " [--help]", file=sys.stderr)
+ sys.exit(1)
+
+repo_root = Path(__file__).parent.parent
+rules_file_path = repo_root.joinpath('rules.csv')
+amendments_file_path = repo_root.joinpath('amendments.csv')
+language_name = sys.argv[1]
+
+failed = False
+
+rules_from_csv = {}
+try:
+ rules_file = open(rules_file_path, "r")
+except PermissionError:
+ print("Error: No permission to read the rules file located at '" + str(rules_file_path) + "'")
+ sys.exit(1)
+else:
+ with rules_file:
+ rules_reader = csv.reader(rules_file)
+ # Skip header row
+ next(rules_reader, None)
+ for rule in rules_reader:
+ language = rule[0]
+ rule_id = rule[2]
+
+ # only validate rules for the specified language
+ if not language == language_name:
+ continue
+
+ rule_dict = {
+ "standard": rule[1],
+ "rule_id": rule_id,
+ "supportable": rule[3]
+ }
+ rules_from_csv[rule_id] = rule_dict
+
+print(f"Found {len(rules_from_csv)} rules.")
+print(f"Verifying amendments")
+
+seen_amendments = set()
+try:
+ amendments_file = open(amendments_file_path, "r")
+except PermissionError:
+ print("Error: No permission to read the amendments file located at '" + str(amendments_file_path) + "'")
+ sys.exit(1)
+else:
+ with amendments_file:
+ amendments_reader = csv.reader(amendments_file)
+ # Skip header row
+ next(amendments_reader, None)
+ for amendment in amendments_reader:
+ language = amendment[0]
+
+ # only validate rules for the specified language
+ if not language == language_name:
+ continue
+
+ if len(amendment) != 8:
+ print(f"🔴 Error: amendment {amendment} has wrong number of fields")
+ failed = True
+ continue
+
+ standard = amendment[1]
+ amendment_name = amendment[2]
+ rule_id = amendment[3]
+ supportable = amendment[4]
+ implemented = amendment[6]
+ amendment_id = f"{rule_id}-{amendment_name}"
+
+ if not rule_id in rules_from_csv:
+ print(f"🔴 Error: Amendment {amendment_id} references rule {rule_id}, not found in rules.csv")
+ failed = True
+ continue
+
+ rule = rules_from_csv[rule_id]
+
+ if rule["standard"] != standard:
+ print(f"🟡 Invalid: {amendment_id} has a different standard than the {rule_id} in rules.csv")
+ print(f" '{standard}' vs '{rule['standard']}'")
+ failed = True
+
+ if supportable not in {"Yes", "No"}:
+ print(f"🟡 Invalid: {amendment_id} 'supportable' field should be 'Yes' or 'No'.")
+ print(f" got '{supportable}'")
+ failed = True
+
+ if rule["supportable"] != supportable:
+ print(f"🟡 Invalid: {amendment_id} supportable does not match rules.csv supportable.")
+ print(f" '{supportable}' vs '{rule['supportable']}'")
+ failed = True
+
+ if implemented not in {"Yes", "No"}:
+ print(f"🟡 Invalid: {amendment_id} 'implemented' field should be 'Yes' or 'No'.")
+ print(f" got '{implemented}'")
+ failed = True
+
+ if amendment_id in seen_amendments:
+ print(f"🔴 Error: {amendment_id} has duplicate entries")
+ failed = True
+
+ seen_amendments.add(amendment_id)
+
+print(f"Checked {len(seen_amendments)} amendments.")
+
+if failed:
+ print("❌ FAILED: Validity issues found in amendments.csv!")
+ sys.exit(1)
+else:
+ print("✅ PASSED: No validity issues found in amendments.csv! 🎉")
diff --git a/scripts/verify_rule_package_consistency.py b/scripts/verify_rule_package_consistency.py
index 7d111e81bc..034e367db2 100644
--- a/scripts/verify_rule_package_consistency.py
+++ b/scripts/verify_rule_package_consistency.py
@@ -100,6 +100,15 @@
print(
f" - ERROR: Rule {rule_id} included in {package_name}.json but not marked as supportable in rules.csv.")
failed = True
+ for query in rule_details["queries"]:
+ if standard_name == "MISRA-C-2012" and not any(tag for tag in query["tags"] if tag.startswith("external/misra/c/2012/")):
+ print(
+ f' - ERROR: MISRA C 2012 query {query["short_name"]}.ql for Rule {rule_id} in {package_name}.json is missing a `external/misra/c/2012/...` tag.')
+ failed = True
+ if not standard_name == "MISRA-C-2012" and any(tag for tag in query["tags"] if tag.startswith("external/misra/c/2012/")):
+ print(
+ f' - ERROR: {standard_name} query {query["short_name"]}.ql for Rule {rule_id} in {package_name}.json has a spurious `external/misra/c/2012/...` tag.')
+ failed = True
rules_csv_rule_ids = package_rules_from_csv[package_name]
json_missing_rules = rules_csv_rule_ids.difference(package_json_rule_ids)
diff --git a/supported_codeql_configs.json b/supported_codeql_configs.json
index 227f41babd..e8b2597100 100644
--- a/supported_codeql_configs.json
+++ b/supported_codeql_configs.json
@@ -1,9 +1,9 @@
{
"supported_environment": [
{
- "codeql_cli": "2.14.6",
- "codeql_standard_library": "codeql-cli/v2.14.6",
- "codeql_cli_bundle": "codeql-bundle-v2.14.6"
+ "codeql_cli": "2.16.6",
+ "codeql_standard_library": "codeql-cli/v2.16.6",
+ "codeql_cli_bundle": "codeql-bundle-v2.16.6"
}
],
"supported_language": [