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..1b620260c3 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 }}
@@ -69,15 +68,17 @@ jobs:
- name: Determine ref for external help files
id: determine-ref
run: |
- if [[ $GITHUB_EVENT_NAME == "pull_request" || $GITHUB_EVENT_NAME == "merge_group" ]]; then
- echo "EXTERNAL_HELP_REF=$GITHUB_HEAD_REF" >> "$GITHUB_ENV"
+ if [[ $GITHUB_EVENT_NAME == "pull_request" ]]; then
+ EXTERNAL_HELP_REF="${{ github.event.pull_request.base.ref }}"
+ elif [[ $GITHUB_EVENT_NAME == "merge_group" ]]; then
+ EXTERNAL_HELP_REF="${{ github.event.merge_group.base_ref }}"
else
- echo "EXTERNAL_HELP_REF=$GITHUB_REF" >> "$GITHUB_ENV"
+ EXTERNAL_HELP_REF="$GITHUB_REF"
fi
+ echo "EXTERNAL_HELP_REF=$EXTERNAL_HELP_REF" >> "$GITHUB_ENV"
echo "Using ref $EXTERNAL_HELP_REF for external help files."
- name: Checkout external help files
- continue-on-error: true
id: checkout-external-help-files
uses: actions/checkout@v4
with:
@@ -98,15 +99,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..2fc28fc900 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@v7
+ 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..964fb7e9f3 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: Dispatch Matrix Testing Job
- if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-matrix') }}
- 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: matrix-test
- client-payload: '{"pr": "${{ github.event.issue.number }}"}'
+ minimum-permission: "write"
- - uses: actions/github-script@v6
- if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-matrix') }}
+ - 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 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@v7
+ 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..a8df297f7d 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"
- - uses: actions/github-script@v6
- if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-performance') }}
+ - 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@v7
+ 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..ce285a29ba
--- /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,Yes,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..910a6e060e 100644
--- a/c/cert/src/codeql-pack.lock.yml
+++ b/c/cert/src/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/c/cert/src/qlpack.yml b/c/cert/src/qlpack.yml
index fbae0e71e0..2778e44435 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.40.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: 1.4.2
diff --git a/c/cert/src/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.ql b/c/cert/src/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.ql
index 2f8ecec25d..0ddf56150c 100644
--- a/c/cert/src/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.ql
+++ b/c/cert/src/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.c.cert
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import NonArrayPointerToArrayIndexingExprFlow::PathGraph
/**
diff --git a/c/cert/src/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.ql b/c/cert/src/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.ql
index c641c17124..fd57bd6f75 100644
--- a/c/cert/src/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.ql
+++ b/c/cert/src/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.ql
@@ -13,8 +13,8 @@
import cpp
import codingstandards.c.cert
-import codingstandards.c.Pointers
-import codingstandards.cpp.dataflow.TaintTracking
+import codingstandards.cpp.Pointers
+import semmle.code.cpp.dataflow.TaintTracking
import ScaledIntegerPointerArithmeticFlow::PathGraph
/**
diff --git a/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql b/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql
index 59fab6e455..d55f1326bf 100644
--- a/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql
+++ b/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql
@@ -15,8 +15,8 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.Concurrency
-import codingstandards.cpp.dataflow.TaintTracking
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.DataFlow
module TssCreateToTssDeleteConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
diff --git a/c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.ql b/c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.ql
index e0617c266d..71138f4ff8 100644
--- a/c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.ql
+++ b/c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.ql
@@ -15,8 +15,8 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.Concurrency
-import codingstandards.cpp.dataflow.TaintTracking
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.commons.Alloc
from C11ThreadCreateCall tcc, StackVariable sv, Expr arg, Expr acc
diff --git a/c/cert/src/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.ql b/c/cert/src/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.ql
index 0fd94911ec..ddcddb8dc5 100644
--- a/c/cert/src/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.ql
+++ b/c/cert/src/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.ql
@@ -16,8 +16,8 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.Concurrency
-import codingstandards.cpp.dataflow.TaintTracking
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.DataFlow
from TSSGetFunctionCall tsg, ThreadedFunction tf
where
diff --git a/c/cert/src/rules/DCL30-C/AppropriateStorageDurationsFunctionReturn.ql b/c/cert/src/rules/DCL30-C/AppropriateStorageDurationsFunctionReturn.ql
index 9097f14297..b5d7e5e378 100644
--- a/c/cert/src/rules/DCL30-C/AppropriateStorageDurationsFunctionReturn.ql
+++ b/c/cert/src/rules/DCL30-C/AppropriateStorageDurationsFunctionReturn.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.c.cert
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
class Source extends StackVariable {
Source() { not this instanceof Parameter }
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/ERR30-C/FunctionCallBeforeErrnoCheck.ql b/c/cert/src/rules/ERR30-C/FunctionCallBeforeErrnoCheck.ql
index 8d63bb5d06..dd2e2175f7 100644
--- a/c/cert/src/rules/ERR30-C/FunctionCallBeforeErrnoCheck.ql
+++ b/c/cert/src/rules/ERR30-C/FunctionCallBeforeErrnoCheck.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.c.cert
import codingstandards.c.Errno
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* A call to an `OutOfBandErrnoSettingFunction`
diff --git a/c/cert/src/rules/EXP30-C/DependenceOnOrderOfFunctionArgumentsForSideEffects.ql b/c/cert/src/rules/EXP30-C/DependenceOnOrderOfFunctionArgumentsForSideEffects.ql
index bf8f99fd27..fb14515c61 100644
--- a/c/cert/src/rules/EXP30-C/DependenceOnOrderOfFunctionArgumentsForSideEffects.ql
+++ b/c/cert/src/rules/EXP30-C/DependenceOnOrderOfFunctionArgumentsForSideEffects.ql
@@ -14,8 +14,8 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.SideEffect
-import codingstandards.cpp.dataflow.DataFlow
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/** Holds if the function's return value is derived from the `AliasParamter` p. */
diff --git a/c/cert/src/rules/EXP35-C/DoNotModifyObjectsWithTemporaryLifetime.ql b/c/cert/src/rules/EXP35-C/DoNotModifyObjectsWithTemporaryLifetime.ql
index 2d66b8643c..6a018ed8c4 100644
--- a/c/cert/src/rules/EXP35-C/DoNotModifyObjectsWithTemporaryLifetime.ql
+++ b/c/cert/src/rules/EXP35-C/DoNotModifyObjectsWithTemporaryLifetime.ql
@@ -13,18 +13,7 @@
import cpp
import codingstandards.c.cert
-
-/**
- * A struct or union type that contains an array type
- */
-class StructOrUnionTypeWithArrayField extends Struct {
- StructOrUnionTypeWithArrayField() {
- this.getAField().getUnspecifiedType() instanceof ArrayType
- or
- // nested struct or union containing an array type
- this.getAField().getUnspecifiedType().(Struct) instanceof StructOrUnionTypeWithArrayField
- }
-}
+import codingstandards.cpp.lifetimes.CLifetimes
// Note: Undefined behavior is possible regardless of whether the accessed field from the returned
// struct is an array or a scalar (i.e. arithmetic and pointer types) member, according to the standard.
diff --git a/c/cert/src/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.ql b/c/cert/src/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.ql
index e5735a5fda..f3b3aa364d 100644
--- a/c/cert/src/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.ql
+++ b/c/cert/src/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.Alignment
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
import ExprWithAlignmentToCStyleCastFlow::PathGraph
diff --git a/c/cert/src/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.ql b/c/cert/src/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.ql
index e28dbddaaf..9bbe27aa31 100644
--- a/c/cert/src/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.ql
+++ b/c/cert/src/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.c.cert
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import SuspectFunctionPointerToCallFlow::PathGraph
/**
diff --git a/c/cert/src/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.ql b/c/cert/src/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.ql
index 825f85b0bd..fde564665c 100644
--- a/c/cert/src/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.ql
+++ b/c/cert/src/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.c.cert
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.controlflow.Dominance
import IndirectCastFlow::PathGraph
diff --git a/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql
index d79224435f..20c9f1bcc8 100644
--- a/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql
+++ b/c/cert/src/rules/EXP40-C/DoNotModifyConstantObjects.ql
@@ -12,7 +12,7 @@
import cpp
import codingstandards.c.cert
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import CastFlow::PathGraph
import codingstandards.cpp.SideEffect
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..1d740ec4f3 100644
--- a/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql
+++ b/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql
@@ -11,10 +11,10 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.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/FIO37-C/SuccessfulFgetsOrFgetwsMayReturnAnEmptyString.ql b/c/cert/src/rules/FIO37-C/SuccessfulFgetsOrFgetwsMayReturnAnEmptyString.ql
index 2dce0d465c..54f555d7cb 100644
--- a/c/cert/src/rules/FIO37-C/SuccessfulFgetsOrFgetwsMayReturnAnEmptyString.ql
+++ b/c/cert/src/rules/FIO37-C/SuccessfulFgetsOrFgetwsMayReturnAnEmptyString.ql
@@ -14,7 +14,7 @@ import cpp
import codingstandards.c.cert
import codingstandards.cpp.FgetsErrorManagement
import codingstandards.cpp.Dereferenced
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
/*
* CFG nodes that follows a successful call to `fgets`
diff --git a/c/cert/src/rules/FIO44-C/OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.ql b/c/cert/src/rules/FIO44-C/OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.ql
index 33a906136f..7ed5887e42 100644
--- a/c/cert/src/rules/FIO44-C/OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.ql
+++ b/c/cert/src/rules/FIO44-C/OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.ql
@@ -12,7 +12,7 @@
import cpp
import codingstandards.c.cert
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
class FgetposCall extends FunctionCall {
FgetposCall() { this.getTarget().hasGlobalOrStdName("fgetpos") }
diff --git a/c/cert/src/rules/FIO45-C/ToctouRaceConditionsWhileAccessingFiles.ql b/c/cert/src/rules/FIO45-C/ToctouRaceConditionsWhileAccessingFiles.ql
index 2ddfa6cf4c..b02ce2f58d 100644
--- a/c/cert/src/rules/FIO45-C/ToctouRaceConditionsWhileAccessingFiles.ql
+++ b/c/cert/src/rules/FIO45-C/ToctouRaceConditionsWhileAccessingFiles.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.standardlibrary.FileAccess
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
diff --git a/c/cert/src/rules/INT30-C/UnsignedIntegerOperationsWrapAround.ql b/c/cert/src/rules/INT30-C/UnsignedIntegerOperationsWrapAround.ql
index 3d25313915..1c7ae3e31b 100644
--- a/c/cert/src/rules/INT30-C/UnsignedIntegerOperationsWrapAround.ql
+++ b/c/cert/src/rules/INT30-C/UnsignedIntegerOperationsWrapAround.ql
@@ -15,24 +15,11 @@
import cpp
import codingstandards.c.cert
-import codingstandards.cpp.Overflow
-import semmle.code.cpp.controlflow.Guards
-import semmle.code.cpp.valuenumbering.GlobalValueNumbering
+import codingstandards.cpp.rules.unsignedoperationwithconstantoperandswraps.UnsignedOperationWithConstantOperandsWraps
-from InterestingOverflowingOperation op
-where
- not isExcluded(op, IntegerOverflowPackage::unsignedIntegerOperationsWrapAroundQuery()) and
- op.getType().getUnderlyingType().(IntegralType).isUnsigned() and
- // Not within a guard condition
- not exists(GuardCondition gc | gc.getAChild*() = op) and
- // Not guarded by a check, where the check is not an invalid overflow check
- not op.hasValidPreCheck() and
- // Is not checked after the operation
- not op.hasValidPostCheck() and
- // Permitted by exception 3
- not op instanceof LShiftExpr and
- // Permitted by exception 2 - zero case is handled in separate query
- not op instanceof DivExpr and
- not op instanceof RemExpr
-select op,
- "Operation " + op.getOperator() + " of type " + op.getType().getUnderlyingType() + " may wrap."
+class UnsignedIntegerOperationsWrapAroundQuery extends UnsignedOperationWithConstantOperandsWrapsSharedQuery
+{
+ UnsignedIntegerOperationsWrapAroundQuery() {
+ this = IntegerOverflowPackage::unsignedIntegerOperationsWrapAroundQuery()
+ }
+}
diff --git a/c/cert/src/rules/MEM35-C/InsufficientMemoryAllocatedForObject.ql b/c/cert/src/rules/MEM35-C/InsufficientMemoryAllocatedForObject.ql
index 7683140327..5ff1725269 100644
--- a/c/cert/src/rules/MEM35-C/InsufficientMemoryAllocatedForObject.ql
+++ b/c/cert/src/rules/MEM35-C/InsufficientMemoryAllocatedForObject.ql
@@ -16,7 +16,7 @@ import cpp
import codingstandards.c.cert
import codingstandards.cpp.Overflow
import semmle.code.cpp.controlflow.Guards
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.models.Models
/**
diff --git a/c/cert/src/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.ql b/c/cert/src/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.ql
index 512b783030..df0eb3b1e3 100644
--- a/c/cert/src/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.ql
+++ b/c/cert/src/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.ql
@@ -15,7 +15,7 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.Alignment
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import AlignedAllocToReallocFlow::PathGraph
int getStatedValue(Expr e) {
diff --git a/c/cert/src/rules/MSC33-C/DoNotPassInvalidDataToTheAsctimeFunction.ql b/c/cert/src/rules/MSC33-C/DoNotPassInvalidDataToTheAsctimeFunction.ql
index 52dd0b1046..fa4a29cb3d 100644
--- a/c/cert/src/rules/MSC33-C/DoNotPassInvalidDataToTheAsctimeFunction.ql
+++ b/c/cert/src/rules/MSC33-C/DoNotPassInvalidDataToTheAsctimeFunction.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.c.cert
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* The argument of a call to `asctime`
diff --git a/c/cert/src/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql b/c/cert/src/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql
index 821b79c8e4..1c706a8e3f 100644
--- a/c/cert/src/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql
+++ b/c/cert/src/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.Macro
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
abstract class VaAccess extends Expr { }
@@ -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/SIG30-C/CallOnlyAsyncSafeFunctionsWithinSignalHandlers.ql b/c/cert/src/rules/SIG30-C/CallOnlyAsyncSafeFunctionsWithinSignalHandlers.ql
index 19730b4677..0da48daa70 100644
--- a/c/cert/src/rules/SIG30-C/CallOnlyAsyncSafeFunctionsWithinSignalHandlers.ql
+++ b/c/cert/src/rules/SIG30-C/CallOnlyAsyncSafeFunctionsWithinSignalHandlers.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.c.cert
import codingstandards.c.Signal
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* Does not access an external variable except
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/src/rules/SIG35-C/DoNotReturnFromAComputationalExceptionHandler.ql b/c/cert/src/rules/SIG35-C/DoNotReturnFromAComputationalExceptionHandler.ql
index 5a064c0904..fa3cc3bf14 100644
--- a/c/cert/src/rules/SIG35-C/DoNotReturnFromAComputationalExceptionHandler.ql
+++ b/c/cert/src/rules/SIG35-C/DoNotReturnFromAComputationalExceptionHandler.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.c.cert
import codingstandards.c.Signal
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* CFG nodes preceeding a `ReturnStmt`
diff --git a/c/cert/src/rules/STR30-C/DoNotAttemptToModifyStringLiterals.ql b/c/cert/src/rules/STR30-C/DoNotAttemptToModifyStringLiterals.ql
index 40f19ed4a0..244fe6d8e5 100644
--- a/c/cert/src/rules/STR30-C/DoNotAttemptToModifyStringLiterals.ql
+++ b/c/cert/src/rules/STR30-C/DoNotAttemptToModifyStringLiterals.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.c.cert
import semmle.code.cpp.security.BufferWrite
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* Class that includes into `BufferWrite` functions that will modify their
diff --git a/c/cert/src/rules/STR31-C/StringsHasSufficientSpaceForTheNullTerminator.ql b/c/cert/src/rules/STR31-C/StringsHasSufficientSpaceForTheNullTerminator.ql
index 4e2e48708a..3742207720 100644
--- a/c/cert/src/rules/STR31-C/StringsHasSufficientSpaceForTheNullTerminator.ql
+++ b/c/cert/src/rules/STR31-C/StringsHasSufficientSpaceForTheNullTerminator.ql
@@ -15,7 +15,7 @@
import cpp
import codingstandards.c.cert
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import codingstandards.cpp.PossiblyUnsafeStringOperation
/**
diff --git a/c/cert/src/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.ql b/c/cert/src/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.ql
index b5f246ca65..8b9b23cd4c 100644
--- a/c/cert/src/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.ql
+++ b/c/cert/src/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.ql
@@ -15,7 +15,7 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.Naming
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import codingstandards.cpp.PossiblyUnsafeStringOperation
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
diff --git a/c/cert/test/codeql-pack.lock.yml b/c/cert/test/codeql-pack.lock.yml
index 514e6963d0..910a6e060e 100644
--- a/c/cert/test/codeql-pack.lock.yml
+++ b/c/cert/test/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/c/cert/test/qlpack.yml b/c/cert/test/qlpack.yml
index 9b878b7b5c..461ebe9677 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.40.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/c/cert/test/rules/ARR32-C/VariableLengthArraySizeNotInValidRange.expected b/c/cert/test/rules/ARR32-C/VariableLengthArraySizeNotInValidRange.expected
index 25153f195b..083e7dfb87 100644
--- a/c/cert/test/rules/ARR32-C/VariableLengthArraySizeNotInValidRange.expected
+++ b/c/cert/test/rules/ARR32-C/VariableLengthArraySizeNotInValidRange.expected
@@ -1,3 +1,5 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (VariableLengthArraySizeNotInValidRange.ql:104,11-19)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (VariableLengthArraySizeNotInValidRange.ql:87,5-18)
| test.c:14:8:14:8 | VLA declaration | Variable-length array dimension size may be in an invalid range. |
| test.c:15:8:15:8 | VLA declaration | Variable-length array dimension size may be in an invalid range. |
| test.c:16:8:16:8 | VLA declaration | Variable-length array dimension size may be in an invalid range. |
diff --git a/c/cert/test/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.expected b/c/cert/test/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.expected
index 8a7bfe553b..ca4ef2a7a0 100644
--- a/c/cert/test/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.expected
+++ b/c/cert/test/rules/ARR37-C/DoNotUsePointerArithmeticOnNonArrayObjectPointers.expected
@@ -1,13 +1,18 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUsePointerArithmeticOnNonArrayObjectPointers.ql:23,60-68)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUsePointerArithmeticOnNonArrayObjectPointers.ql:24,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUsePointerArithmeticOnNonArrayObjectPointers.ql:36,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUsePointerArithmeticOnNonArrayObjectPointers.ql:44,26-34)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUsePointerArithmeticOnNonArrayObjectPointers.ql:65,3-11)
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..d343811aaf 100644
--- a/c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected
+++ b/c/cert/test/rules/ARR39-C/DoNotAddOrSubtractAScaledIntegerToAPointer.expected
@@ -1,9 +1,13 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAddOrSubtractAScaledIntegerToAPointer.ql:72,56-64)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAddOrSubtractAScaledIntegerToAPointer.ql:73,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAddOrSubtractAScaledIntegerToAPointer.ql:75,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAddOrSubtractAScaledIntegerToAPointer.ql:84,45-53)
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/CON30-C/CleanUpThreadSpecificStorage.expected b/c/cert/test/rules/CON30-C/CleanUpThreadSpecificStorage.expected
index e03b665a1c..2706474f29 100644
--- a/c/cert/test/rules/CON30-C/CleanUpThreadSpecificStorage.expected
+++ b/c/cert/test/rules/CON30-C/CleanUpThreadSpecificStorage.expected
@@ -1,3 +1,9 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:21,46-54)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:22,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:31,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:41,35-43)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:49,36-44)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:51,36-44)
| test.c:27:3:27:12 | call to tss_create | Resources used by thread specific storage may not be cleaned up. |
| test.c:49:3:49:12 | call to tss_create | Resources used by thread specific storage may not be cleaned up. |
| test.c:71:3:71:12 | call to tss_create | Resources used by thread specific storage may not be cleaned up. |
diff --git a/c/cert/test/rules/CON34-C/AppropriateThreadObjectStorageDurations.expected b/c/cert/test/rules/CON34-C/AppropriateThreadObjectStorageDurations.expected
index c3cdc8bd7b..25cb74d7fa 100644
--- a/c/cert/test/rules/CON34-C/AppropriateThreadObjectStorageDurations.expected
+++ b/c/cert/test/rules/CON34-C/AppropriateThreadObjectStorageDurations.expected
@@ -1,3 +1,11 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:28,29-37)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:28,54-62)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:35,62-70)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:40,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:40,30-38)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:41,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:41,30-38)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:28,3-16)
| test.c:23:3:23:13 | call to thrd_create | $@ not declared with appropriate storage duration | test.c:23:24:23:29 | & ... | Shared object |
| test.c:74:3:74:13 | call to thrd_create | $@ not declared with appropriate storage duration | test.c:74:24:74:24 | p | Shared object |
| test.c:85:3:85:13 | call to thrd_create | $@ not declared with appropriate storage duration | test.c:85:24:85:24 | p | Shared object |
diff --git a/c/cert/test/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.expected b/c/cert/test/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.expected
index 95d0a20041..d6b6548581 100644
--- a/c/cert/test/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.expected
+++ b/c/cert/test/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.expected
@@ -1 +1,6 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:28,38-46)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:31,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:31,30-38)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:32,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:32,30-38)
| test.c:14:7:14:13 | call to tss_get | Call to a thread specific storage function from within a threaded context on an object that may not be owned by this thread. |
diff --git a/c/cert/test/rules/DCL30-C/AppropriateStorageDurationsFunctionReturn.expected b/c/cert/test/rules/DCL30-C/AppropriateStorageDurationsFunctionReturn.expected
index ff842ddcad..905c9cc22b 100644
--- a/c/cert/test/rules/DCL30-C/AppropriateStorageDurationsFunctionReturn.expected
+++ b/c/cert/test/rules/DCL30-C/AppropriateStorageDurationsFunctionReturn.expected
@@ -1,2 +1,7 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateStorageDurationsFunctionReturn.ql:22,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateStorageDurationsFunctionReturn.ql:26,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateStorageDurationsFunctionReturn.ql:39,6-14)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateStorageDurationsFunctionReturn.ql:39,26-34)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateStorageDurationsFunctionReturn.ql:45,3-11)
| test.c:3:10:3:10 | a | $@ with automatic storage may be accessible outside of its lifetime. | test.c:3:10:3:10 | a | a |
| test.c:15:4:15:8 | param [inner post update] | $@ with automatic storage may be accessible outside of its lifetime. | test.c:15:12:15:13 | a2 | a2 |
diff --git a/c/cert/test/rules/ERR30-C/ErrnoReadBeforeReturn.expected b/c/cert/test/rules/ERR30-C/ErrnoReadBeforeReturn.expected
index b6d7caa513..659a731d7c 100644
--- a/c/cert/test/rules/ERR30-C/ErrnoReadBeforeReturn.expected
+++ b/c/cert/test/rules/ERR30-C/ErrnoReadBeforeReturn.expected
@@ -1,3 +1,4 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ErrnoReadBeforeReturn.ql:40,7-15)
| test.c:69:7:69:11 | * ... | Do not read `errno` before checking the return value of function $@. | test.c:68:3:68:7 | call to ftell | call to ftell |
| test.c:69:7:69:11 | call to __errno_location | Do not read `errno` before checking the return value of function $@. | test.c:68:3:68:7 | call to ftell | call to ftell |
| test.c:70:5:70:10 | call to perror | Do not read `errno` before checking the return value of function $@. | test.c:68:3:68:7 | call to ftell | call to ftell |
diff --git a/c/cert/test/rules/ERR30-C/SetlocaleMightSetErrno.expected b/c/cert/test/rules/ERR30-C/SetlocaleMightSetErrno.expected
index 9ab88a3395..d20f4a4e34 100644
--- a/c/cert/test/rules/ERR30-C/SetlocaleMightSetErrno.expected
+++ b/c/cert/test/rules/ERR30-C/SetlocaleMightSetErrno.expected
@@ -1,2 +1,3 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (SetlocaleMightSetErrno.ql:64,7-15)
| test.c:98:3:98:11 | call to setlocale | Do not read `errno` before checking the return value of a call to `setlocale`. |
| test.c:104:7:104:15 | call to setlocale | The value of `errno` may be different than `0` when `setlocale` is called. The following `errno` check might be invalid. |
diff --git a/c/cert/test/rules/ERR32-C/DoNotRelyOnIndeterminateValuesOfErrno.expected b/c/cert/test/rules/ERR32-C/DoNotRelyOnIndeterminateValuesOfErrno.expected
index da9122cfd4..a90dd6b7f5 100644
--- a/c/cert/test/rules/ERR32-C/DoNotRelyOnIndeterminateValuesOfErrno.expected
+++ b/c/cert/test/rules/ERR32-C/DoNotRelyOnIndeterminateValuesOfErrno.expected
@@ -1,3 +1,7 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotRelyOnIndeterminateValuesOfErrno.ql:50,7-15)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotRelyOnIndeterminateValuesOfErrno.ql:50,27-35)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotRelyOnIndeterminateValuesOfErrno.ql:51,9-17)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotRelyOnIndeterminateValuesOfErrno.ql:54,9-17)
| test.c:12:5:12:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:10:21:10:26 | call to signal | call to signal |
| test.c:30:5:30:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:26:21:26:26 | call to signal | call to signal |
| test.c:49:5:49:10 | call to perror | `errno` has indeterminate value after this $@. | test.c:45:21:45:26 | call to signal | call to signal |
diff --git a/c/cert/test/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.expected b/c/cert/test/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.expected
index fbcc44b856..030596976e 100644
--- a/c/cert/test/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.expected
+++ b/c/cert/test/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.expected
@@ -1,3 +1,4 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DetectAndHandleStandardLibraryErrors.ql:453,5-13)
| test.c:18:3:18:11 | call to setlocale | Missing error detection for the call to function `setlocale`. |
| test.c:24:23:24:31 | call to setlocale | Missing error detection for the call to function `setlocale`. |
| test.c:29:22:29:27 | call to calloc | Missing error detection for the call to function `calloc`. |
diff --git a/c/cert/test/rules/EXP30-C/DependenceOnOrderOfFunctionArgumentsForSideEffects.expected b/c/cert/test/rules/EXP30-C/DependenceOnOrderOfFunctionArgumentsForSideEffects.expected
index 3ea1a05fd7..6567ef6fd1 100644
--- a/c/cert/test/rules/EXP30-C/DependenceOnOrderOfFunctionArgumentsForSideEffects.expected
+++ b/c/cert/test/rules/EXP30-C/DependenceOnOrderOfFunctionArgumentsForSideEffects.expected
@@ -1 +1,25 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:24,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:24,59-67)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:27,33-41)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:27,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:31,33-41)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:31,59-67)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:40,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:40,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:40,53-61)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:43,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:43,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:52,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:52,55-63)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:59,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:59,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:71,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:71,55-63)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:24,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:27,7-20)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:31,7-20)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:43,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:52,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:59,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DependenceOnOrderOfFunctionArgumentsForSideEffects.ql:71,5-18)
| test.c:20:3:20:4 | call to f1 | Depending on the order of evaluation for the arguments $@ and $@ for side effects on shared state is unspecified and can result in unexpected behavior. | test.c:20:6:20:7 | call to f2 | call to f2 | test.c:20:12:20:13 | call to f3 | call to f3 |
diff --git a/c/cert/test/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.expected b/c/cert/test/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.expected
index a1c9a14fa2..eed9fb4585 100644
--- a/c/cert/test/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.expected
+++ b/c/cert/test/rules/EXP36-C/DoNotCastPointerToMoreStrictlyAlignedPointerType.expected
@@ -1,67 +1,77 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:98,86-94)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:120,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:122,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:127,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:133,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:139,55-63)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:140,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:142,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:149,26-34)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCastPointerToMoreStrictlyAlignedPointerType.ql:164,44-52)
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..229bd74165 100644
--- a/c/cert/test/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.expected
+++ b/c/cert/test/rules/EXP37-C/DoNotCallFunctionPointerWithIncompatibleType.expected
@@ -1,11 +1,15 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallFunctionPointerWithIncompatibleType.ql:40,54-62)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallFunctionPointerWithIncompatibleType.ql:41,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallFunctionPointerWithIncompatibleType.ql:45,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallFunctionPointerWithIncompatibleType.ql:50,43-51)
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..9f0880455f 100644
--- a/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected
+++ b/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected
@@ -1,15 +1,22 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:61,38-46)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:64,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:69,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:102,23-31)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:111,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:111,45-53)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:133,27-35)
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 | Config |
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..6dd4ec261a 100644
--- a/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected
+++ b/c/cert/test/rules/EXP40-C/DoNotModifyConstantObjects.expected
@@ -1,11 +1,15 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotModifyConstantObjects.ql:35,30-38)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotModifyConstantObjects.ql:36,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotModifyConstantObjects.ql:42,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotModifyConstantObjects.ql:47,19-27)
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/EXP43-C/RestrictPointerReferencesOverlappingObject.expected b/c/cert/test/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.expected
index 3746991c09..b9765e77fb 100644
--- a/c/cert/test/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.expected
+++ b/c/cert/test/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.expected
@@ -1,3 +1,10 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:42,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:43,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:47,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:53,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:56,58-66)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:72,64-72)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:73,64-72)
| test.c:18:22:18:23 | i2 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:18:17:18:18 | i3 | i3 | test.c:18:22:18:23 | i2 | the object pointed to by i2 |
| test.c:19:8:19:9 | g2 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:5:15:5:16 | g1 | g1 | test.c:19:8:19:9 | g2 | the object pointed to by g2 |
| test.c:20:8:20:9 | i2 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:16:17:16:18 | i1 | i1 | test.c:20:8:20:9 | i2 | the object pointed to by i2 |
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/FIO40-C/ResetStringsOnFgetsOrFgetwsFailure.expected b/c/cert/test/rules/FIO40-C/ResetStringsOnFgetsOrFgetwsFailure.expected
index 20c108cfa0..669dd829c8 100644
--- a/c/cert/test/rules/FIO40-C/ResetStringsOnFgetsOrFgetwsFailure.expected
+++ b/c/cert/test/rules/FIO40-C/ResetStringsOnFgetsOrFgetwsFailure.expected
@@ -1,3 +1,6 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ResetStringsOnFgetsOrFgetwsFailure.ql:42,11-19)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ResetStringsOnFgetsOrFgetwsFailure.ql:42,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ResetStringsOnFgetsOrFgetwsFailure.ql:43,13-21)
| test.c:20:10:20:12 | buf | The buffer is not reset before being referenced following a failed $@. | test.c:15:7:15:11 | call to fgets | call to fgets |
| test.c:57:10:57:12 | buf | The buffer is not reset before being referenced following a failed $@. | test.c:52:7:52:11 | call to fgets | call to fgets |
| test.c:66:18:66:20 | buf | The buffer is not reset before being referenced following a failed $@. | test.c:61:7:61:11 | call to fgets | call to fgets |
diff --git a/c/cert/test/rules/FIO44-C/OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.expected b/c/cert/test/rules/FIO44-C/OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.expected
index 8074710738..5bff6016e4 100644
--- a/c/cert/test/rules/FIO44-C/OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.expected
+++ b/c/cert/test/rules/FIO44-C/OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.expected
@@ -1,2 +1,7 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.ql:25,32-40)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.ql:26,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.ql:28,14-22)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.ql:31,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (OnlyUseValuesForFsetposThatAreReturnedFromFgetpos.ql:37,21-29)
| test.c:7:24:7:30 | & ... | The position argument of a call to `fsetpos()` should be obtained from a call to `fgetpos()`. |
| test.c:33:24:33:30 | & ... | The position argument of a call to `fsetpos()` should be obtained from a call to `fgetpos()`. |
diff --git a/c/cert/test/rules/FIO45-C/ToctouRaceConditionsWhileAccessingFiles.expected b/c/cert/test/rules/FIO45-C/ToctouRaceConditionsWhileAccessingFiles.expected
index 1b2923b780..71df14e907 100644
--- a/c/cert/test/rules/FIO45-C/ToctouRaceConditionsWhileAccessingFiles.expected
+++ b/c/cert/test/rules/FIO45-C/ToctouRaceConditionsWhileAccessingFiles.expected
@@ -1,2 +1,3 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ToctouRaceConditionsWhileAccessingFiles.ql:27,35-43)
| test.c:4:13:4:17 | call to fopen | This call is trying to prevent an existing file from being overwritten by $@. An attacker might be able to exploit the race window between the two calls. | test.c:11:9:11:13 | call to fopen | another call |
| test.c:88:13:88:17 | call to fopen | This call is trying to prevent an existing file from being overwritten by $@. An attacker might be able to exploit the race window between the two calls. | test.c:95:9:95:13 | call to fopen | another call |
diff --git a/c/cert/test/rules/INT30-C/UnsignedIntegerOperationsWrapAround.expected b/c/cert/test/rules/INT30-C/UnsignedIntegerOperationsWrapAround.expected
deleted file mode 100644
index 76594d944b..0000000000
--- a/c/cert/test/rules/INT30-C/UnsignedIntegerOperationsWrapAround.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-| test.c:4:3:4:9 | ... + ... | Operation + of type unsigned int may wrap. |
-| test.c:5:3:5:10 | ... += ... | Operation += of type unsigned int may wrap. |
-| test.c:58:3:58:9 | ... - ... | Operation - of type unsigned int may wrap. |
-| test.c:59:3:59:10 | ... -= ... | Operation -= of type unsigned int may wrap. |
diff --git a/c/cert/test/rules/INT30-C/UnsignedIntegerOperationsWrapAround.qlref b/c/cert/test/rules/INT30-C/UnsignedIntegerOperationsWrapAround.qlref
deleted file mode 100644
index 045890904c..0000000000
--- a/c/cert/test/rules/INT30-C/UnsignedIntegerOperationsWrapAround.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/INT30-C/UnsignedIntegerOperationsWrapAround.ql
\ No newline at end of file
diff --git a/c/cert/test/rules/INT30-C/UnsignedIntegerOperationsWrapAround.testref b/c/cert/test/rules/INT30-C/UnsignedIntegerOperationsWrapAround.testref
new file mode 100644
index 0000000000..c9bc9d9637
--- /dev/null
+++ b/c/cert/test/rules/INT30-C/UnsignedIntegerOperationsWrapAround.testref
@@ -0,0 +1 @@
+c/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.ql
\ No newline at end of file
diff --git a/c/cert/test/rules/MEM35-C/InsufficientMemoryAllocatedForObject.expected b/c/cert/test/rules/MEM35-C/InsufficientMemoryAllocatedForObject.expected
index 30dece9299..6bfbbefc14 100644
--- a/c/cert/test/rules/MEM35-C/InsufficientMemoryAllocatedForObject.expected
+++ b/c/cert/test/rules/MEM35-C/InsufficientMemoryAllocatedForObject.expected
@@ -1,3 +1,5 @@
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (InsufficientMemoryAllocatedForObject.ql:85,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (InsufficientMemoryAllocatedForObject.ql:143,5-18)
| test.c:12:19:12:24 | call to malloc | Allocation size (32 bytes) is not a multiple of the size of 'S1' (36 bytes). | test.c:12:26:12:32 | 32 | |
| test.c:15:19:15:24 | call to malloc | Allocation size calculated from the size of a different type ($@). | test.c:15:26:15:35 | sizeof() | sizeof(S1 *) |
| test.c:20:19:20:24 | call to malloc | Allocation size (128 bytes) is not a multiple of the size of 'S1' (36 bytes). | test.c:20:26:20:36 | ... * ... | |
diff --git a/c/cert/test/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.expected b/c/cert/test/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.expected
index 0592cb038d..2f5889c4c6 100644
--- a/c/cert/test/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.expected
+++ b/c/cert/test/rules/MEM36-C/DoNotModifyAlignmentOfMemoryWithRealloc.expected
@@ -1,9 +1,14 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotModifyAlignmentOfMemoryWithRealloc.ql:26,36-44)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotModifyAlignmentOfMemoryWithRealloc.ql:40,47-55)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotModifyAlignmentOfMemoryWithRealloc.ql:41,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotModifyAlignmentOfMemoryWithRealloc.ql:45,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotModifyAlignmentOfMemoryWithRealloc.ql:50,36-44)
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/MSC30-C/RandUsedForGeneratingPseudorandomNumbers.testref b/c/cert/test/rules/MSC30-C/RandUsedForGeneratingPseudorandomNumbers.testref
index 31cba60b74..726f27535d 100644
--- a/c/cert/test/rules/MSC30-C/RandUsedForGeneratingPseudorandomNumbers.testref
+++ b/c/cert/test/rules/MSC30-C/RandUsedForGeneratingPseudorandomNumbers.testref
@@ -1 +1 @@
-cpp/common/test/rules/donotuserandforgeneratingpseudorandomnumbers/DoNotUseRandForGeneratingPseudorandomNumbers.ql
\ No newline at end of file
+c/common/test/rules/donotuserandforgeneratingpseudorandomnumbers/DoNotUseRandForGeneratingPseudorandomNumbers.ql
\ No newline at end of file
diff --git a/c/cert/test/rules/MSC33-C/DoNotPassInvalidDataToTheAsctimeFunction.expected b/c/cert/test/rules/MSC33-C/DoNotPassInvalidDataToTheAsctimeFunction.expected
index 70d60c528a..853d999d4e 100644
--- a/c/cert/test/rules/MSC33-C/DoNotPassInvalidDataToTheAsctimeFunction.expected
+++ b/c/cert/test/rules/MSC33-C/DoNotPassInvalidDataToTheAsctimeFunction.expected
@@ -1 +1,5 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotPassInvalidDataToTheAsctimeFunction.ql:33,38-46)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotPassInvalidDataToTheAsctimeFunction.ql:34,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotPassInvalidDataToTheAsctimeFunction.ql:41,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotPassInvalidDataToTheAsctimeFunction.ql:44,27-35)
| test.c:6:24:6:30 | time_tm | The function `asctime` and `asctime_r` should be discouraged. Unsanitized input can overflow the output buffer. |
diff --git a/c/cert/test/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.expected b/c/cert/test/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.expected
index 2b7bb2bdbc..4eaa05b179 100644
--- a/c/cert/test/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.expected
+++ b/c/cert/test/rules/MSC39-C/DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.expected
@@ -1,3 +1,10 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql:38,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql:39,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql:44,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql:47,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql:68,10-18)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql:69,29-37)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotCallVaArgOnAVaListThatHasAnIndeterminateValue.ql:70,29-37)
| test.c:23:32:23:33 | ap | The value of ap is indeterminate after the $@. | test.c:17:7:17:19 | call to contains_zero | call to contains_zero |
| test.c:26:10:26:11 | ap | The value of ap is indeterminate after the $@. | test.c:17:7:17:19 | call to contains_zero | call to contains_zero |
| test.c:39:12:39:13 | ap | The value of ap is indeterminate after the $@. | test.c:35:7:35:19 | call to contains_zero | call to contains_zero |
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/cert/test/rules/SIG30-C/CallOnlyAsyncSafeFunctionsWithinSignalHandlers.expected b/c/cert/test/rules/SIG30-C/CallOnlyAsyncSafeFunctionsWithinSignalHandlers.expected
index a601fe63f4..6190259408 100644
--- a/c/cert/test/rules/SIG30-C/CallOnlyAsyncSafeFunctionsWithinSignalHandlers.expected
+++ b/c/cert/test/rules/SIG30-C/CallOnlyAsyncSafeFunctionsWithinSignalHandlers.expected
@@ -1,3 +1,6 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CallOnlyAsyncSafeFunctionsWithinSignalHandlers.ql:105,11-19)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CallOnlyAsyncSafeFunctionsWithinSignalHandlers.ql:105,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CallOnlyAsyncSafeFunctionsWithinSignalHandlers.ql:106,9-17)
| test.c:10:3:10:18 | call to log_local_unsafe | Asyncronous-unsafe function calls within a $@ can lead to undefined behavior. | test.c:16:7:16:12 | call to signal | signal handler |
| test.c:11:3:11:6 | call to free | Asyncronous-unsafe function calls within a $@ can lead to undefined behavior. | test.c:16:7:16:12 | call to signal | signal handler |
| test.c:46:3:46:9 | call to longjmp | Asyncronous-unsafe function calls within a $@ can lead to undefined behavior. | test.c:50:7:50:12 | call to signal | signal handler |
diff --git a/c/cert/test/rules/SIG35-C/DoNotReturnFromAComputationalExceptionHandler.expected b/c/cert/test/rules/SIG35-C/DoNotReturnFromAComputationalExceptionHandler.expected
index 31412c466a..e861e90e9e 100644
--- a/c/cert/test/rules/SIG35-C/DoNotReturnFromAComputationalExceptionHandler.expected
+++ b/c/cert/test/rules/SIG35-C/DoNotReturnFromAComputationalExceptionHandler.expected
@@ -1 +1,2 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotReturnFromAComputationalExceptionHandler.ql:39,5-13)
| test.c:10:1:10:1 | return ... | Do not return from a $@ signal handler. | test.c:13:10:13:15 | SIGFPE | computational exception |
diff --git a/c/cert/test/rules/STR30-C/DoNotAttemptToModifyStringLiterals.expected b/c/cert/test/rules/STR30-C/DoNotAttemptToModifyStringLiterals.expected
index 27ef66bc7a..2a45193a17 100644
--- a/c/cert/test/rules/STR30-C/DoNotAttemptToModifyStringLiterals.expected
+++ b/c/cert/test/rules/STR30-C/DoNotAttemptToModifyStringLiterals.expected
@@ -1,3 +1,18 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:42,65-73)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:43,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:64,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:77,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:101,11-19)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:101,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:101,55-63)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:106,11-19)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:106,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:106,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:139,11-19)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:139,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:139,55-63)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:150,53-61)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAttemptToModifyStringLiterals.ql:151,5-13)
| test.c:7:3:7:3 | a | This operation may write to a string that may be a string literal that was $@. | test.c:6:13:6:20 | codeql | created here |
| test.c:30:3:30:3 | a | This operation may write to a string that may be a string literal that was $@. | test.c:29:13:29:18 | call to strchr | created here |
| test.c:36:3:36:3 | b | This operation may write to a string that may be a string literal that was $@. | test.c:35:13:35:18 | call to strchr | created here |
diff --git a/c/cert/test/rules/STR31-C/StringsHasSufficientSpaceForTheNullTerminator.expected b/c/cert/test/rules/STR31-C/StringsHasSufficientSpaceForTheNullTerminator.expected
index 71e713d120..9012a2d78a 100644
--- a/c/cert/test/rules/STR31-C/StringsHasSufficientSpaceForTheNullTerminator.expected
+++ b/c/cert/test/rules/STR31-C/StringsHasSufficientSpaceForTheNullTerminator.expected
@@ -1,3 +1,9 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (StringsHasSufficientSpaceForTheNullTerminator.ql:57,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (StringsHasSufficientSpaceForTheNullTerminator.ql:57,55-63)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (StringsHasSufficientSpaceForTheNullTerminator.ql:63,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (StringsHasSufficientSpaceForTheNullTerminator.ql:63,54-62)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (StringsHasSufficientSpaceForTheNullTerminator.ql:57,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (StringsHasSufficientSpaceForTheNullTerminator.ql:63,5-18)
| test.c:10:20:10:24 | Cod | Expression produces or consumes a string that may not have sufficient space for a null-terminator. |
| test.c:16:3:16:9 | call to strncpy | Expression produces or consumes a string that may not have sufficient space for a null-terminator. |
| test.c:26:3:26:10 | call to snprintf | Expression produces or consumes a string that may not have sufficient space for a null-terminator. |
diff --git a/c/cert/test/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.expected b/c/cert/test/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.expected
index 8409d95628..da86e69b88 100644
--- a/c/cert/test/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.expected
+++ b/c/cert/test/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.expected
@@ -1,3 +1,13 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:64,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:66,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:74,39-47)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:75,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:81,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:83,34-42)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:83,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:123,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:123,26-34)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (NonNullTerminatedToFunctionThatExpectsAString.ql:120,17-30)
| test.c:20:3:20:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:8:20:8:24 | Cod | this expression |
| test.c:21:3:21:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:8:20:8:24 | Cod | this expression |
| test.c:23:3:23:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:14:3:14:9 | call to strncpy | this expression |
diff --git a/c/common/src/codeql-pack.lock.yml b/c/common/src/codeql-pack.lock.yml
index 514e6963d0..910a6e060e 100644
--- a/c/common/src/codeql-pack.lock.yml
+++ b/c/common/src/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/c/common/src/codingstandards/c/Errno.qll b/c/common/src/codingstandards/c/Errno.qll
index 86ecabe8f1..d606593a1e 100644
--- a/c/common/src/codingstandards/c/Errno.qll
+++ b/c/common/src/codingstandards/c/Errno.qll
@@ -1,7 +1,7 @@
/** Provides a library for errno-setting functions. */
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* An errno-setting function
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/Literals.qll b/c/common/src/codingstandards/c/Literals.qll
deleted file mode 100644
index beeeccb8cc..0000000000
--- a/c/common/src/codingstandards/c/Literals.qll
+++ /dev/null
@@ -1,4 +0,0 @@
-// Reuse the `IntegerLiteral` class
-import codingstandards.cpp.Cpp14Literal
-
-class IntegerLiteral = Cpp14Literal::IntegerLiteral;
diff --git a/c/common/src/codingstandards/c/OutOfBounds.qll b/c/common/src/codingstandards/c/OutOfBounds.qll
index 87c7c17870..220cf5a0a0 100644
--- a/c/common/src/codingstandards/c/OutOfBounds.qll
+++ b/c/common/src/codingstandards/c/OutOfBounds.qll
@@ -5,13 +5,13 @@
*/
import cpp
-import codingstandards.c.Pointers
+import codingstandards.cpp.Pointers
import codingstandards.c.Variable
import codingstandards.cpp.Allocations
import codingstandards.cpp.Overflow
import codingstandards.cpp.PossiblyUnsafeStringOperation
import codingstandards.cpp.SimpleRangeAnalysisCustomizations
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
module OOB {
diff --git a/c/common/src/codingstandards/c/Signal.qll b/c/common/src/codingstandards/c/Signal.qll
index 35286be4d9..95b27e2898 100644
--- a/c/common/src/codingstandards/c/Signal.qll
+++ b/c/common/src/codingstandards/c/Signal.qll
@@ -1,5 +1,5 @@
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* A signal corresponding to a computational exception
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..f39f3cb1c4 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.40.0-dev
license: MIT
dependencies:
codeql/common-cpp-coding-standards: '*'
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 1.4.2
diff --git a/c/common/test/codeql-pack.lock.yml b/c/common/test/codeql-pack.lock.yml
index 514e6963d0..910a6e060e 100644
--- a/c/common/test/codeql-pack.lock.yml
+++ b/c/common/test/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/c/common/test/qlpack.yml b/c/common/test/qlpack.yml
index c83d53ae3f..d417a17df2 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.40.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/c/misra/test/rules/RULE-20-12/MacroParameterUsedAsHashOperand.expected b/c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.expected
similarity index 58%
rename from c/misra/test/rules/RULE-20-12/MacroParameterUsedAsHashOperand.expected
rename to c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.expected
index be347218b3..d5f6f296d9 100644
--- a/c/misra/test/rules/RULE-20-12/MacroParameterUsedAsHashOperand.expected
+++ b/c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.expected
@@ -1,2 +1,2 @@
-| test.c:4:1:4:41 | #define BAD_MACRO_WITH_ARG(x) (x) + wow ## x | Macro BAD_MACRO_WITH_ARG contains use of parameter x used in multiple contexts. |
-| test.c:5:1:5:48 | #define BAD_MACRO_WITH_ARG_TWO(x,y) (x) + wow ## x | Macro BAD_MACRO_WITH_ARG_TWO contains use of parameter x used in multiple contexts. |
+| test.c:5:1:5:41 | #define BAD_MACRO_WITH_ARG(x) (x) + wow ## x | Macro BAD_MACRO_WITH_ARG contains use of parameter x used in multiple contexts. |
+| test.c:6:1:6:48 | #define BAD_MACRO_WITH_ARG_TWO(x,y) (x) + wow ## x | Macro BAD_MACRO_WITH_ARG_TWO contains use of parameter x used in multiple contexts. |
diff --git a/c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.ql b/c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.ql
new file mode 100644
index 0000000000..5aa514e86d
--- /dev/null
+++ b/c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.amixedusemacroargumentsubjecttoexpansion.AMixedUseMacroArgumentSubjectToExpansion
+
+class TestFileQuery extends AMixedUseMacroArgumentSubjectToExpansionSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/test.c b/c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/test.c
new file mode 100644
index 0000000000..7eb5e204c7
--- /dev/null
+++ b/c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/test.c
@@ -0,0 +1,26 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#define GOOD_MACRO_WITH_ARG(X) ((X)*X##_scale) // COMPLIANT
+#define MACRO 1
+#define BAD_MACRO_WITH_ARG(x) (x) + wow##x // NON_COMPLIANT
+#define BAD_MACRO_WITH_ARG_TWO(x, y) (x) + wow##x // NON_COMPLIANT
+#define MACROONE(x) #x // COMPLIANT
+#define MACROTWO(x) x *x // COMPLIANT
+#define MACROTHREE(x) "##\"\"'" + (x) // COMPLIANT
+#define FOO(x) #x MACROONE(x) // COMPLIANT - no further arg expansion
+
+void f() {
+
+ int x;
+ int x_scale;
+ int y;
+ int wowMACRO = 0;
+
+ y = GOOD_MACRO_WITH_ARG(x);
+ wowMACRO = BAD_MACRO_WITH_ARG(MACRO);
+ wowMACRO = BAD_MACRO_WITH_ARG_TWO(MACRO, 1);
+ char s[] = MACROONE(MACRO);
+ y = MACROTWO(MACRO);
+ MACROTHREE(MACRO);
+ FOO(x);
+}
\ No newline at end of file
diff --git a/c/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.expected b/c/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.expected
new file mode 100644
index 0000000000..489a990582
--- /dev/null
+++ b/c/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.expected
@@ -0,0 +1,4 @@
+| test.c:8:14:8:17 | call to atof | Call to banned function atof. |
+| test.c:9:12:9:15 | call to atoi | Call to banned function atoi. |
+| test.c:10:13:10:16 | call to atol | Call to banned function atol. |
+| test.c:11:18:11:22 | call to atoll | Call to banned function atoll. |
diff --git a/c/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.ql b/c/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.ql
new file mode 100644
index 0000000000..6da5fe6097
--- /dev/null
+++ b/c/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.atofatoiatolandatollused.AtofAtoiAtolAndAtollUsed
+
+class TestFileQuery extends AtofAtoiAtolAndAtollUsedSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/atofatoiatolandatollused/test.c b/c/common/test/rules/atofatoiatolandatollused/test.c
new file mode 100644
index 0000000000..f8140af79a
--- /dev/null
+++ b/c/common/test/rules/atofatoiatolandatollused/test.c
@@ -0,0 +1,13 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#include
+#include
+void f2();
+void f1() {
+ char l1[5] = "abcd";
+ float l2 = atof(l1); // NON_COMLIANT
+ int l3 = atoi(l1); // NON_COMPLIANT
+ long l4 = atol(l1); // NON_COMPLIANT
+ long long l5 = atoll(l1); // NON_COMPLIANT
+ f2(); // COMPLIANT
+}
diff --git a/c/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.expected b/c/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.expected
new file mode 100644
index 0000000000..f04b1b6ce9
--- /dev/null
+++ b/c/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.expected
@@ -0,0 +1,4 @@
+| test.c:8:7:8:8 | x1 | Bit-field 'x1' is declared on type 'int'. |
+| test.c:12:15:12:16 | x5 | Bit-field 'x5' is declared on type 'signed long'. |
+| test.c:14:15:14:16 | x6 | Bit-field 'x6' is declared on type 'signed char'. |
+| test.c:16:14:16:15 | x7 | Bit-field 'x7' is declared on type 'Color'. |
diff --git a/c/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.ql b/c/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.ql
new file mode 100644
index 0000000000..a3e1ecc76c
--- /dev/null
+++ b/c/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.bitfieldshallhaveanappropriatetype.BitFieldShallHaveAnAppropriateType
+
+class TestFileQuery extends BitFieldShallHaveAnAppropriateTypeSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/bitfieldshallhaveanappropriatetype/test.c b/c/common/test/rules/bitfieldshallhaveanappropriatetype/test.c
new file mode 100644
index 0000000000..c418e0e4fc
--- /dev/null
+++ b/c/common/test/rules/bitfieldshallhaveanappropriatetype/test.c
@@ -0,0 +1,17 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+typedef unsigned int UINT16;
+
+enum Color { R, G, B };
+
+struct SampleStruct {
+ int x1 : 2; // NON_COMPLIANT - not explicitly signed or unsigned
+ unsigned int x2 : 2; // COMPLIANT - explicitly unsigned
+ signed int x3 : 2; // COMPLIANT - explicitly signed
+ UINT16 x4 : 2; // COMPLIANT - type alias resolves to a compliant type
+ signed long x5 : 2; // NON_COMPLIANT - cannot declare bit field for long, even
+ // if it's signed
+ signed char x6 : 2; // NON_COMPLIANT - cannot declare bit field for char, even
+ // if it's signed
+ enum Color x7 : 3; // NON_COMPLIANT - cannot declare bit field for enum
+} sample_struct;
diff --git a/c/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected b/c/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
index 94e63062c5..d7dfc6c13f 100644
--- a/c/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
+++ b/c/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
@@ -1,20 +1,20 @@
problems
-| test.c:8:8:8:12 | c_str | test.c:15:16:15:21 | call to getenv | test.c:8:8:8:12 | c_str | The object returned by the function getenv should not be modified. |
-| test.c:64:5:64:9 | conv4 | test.c:61:11:61:20 | call to localeconv | test.c:64:5:64:9 | conv4 | The object returned by the function localeconv should not be modified. |
-| test.c:73:5:73:8 | conv | test.c:69:25:69:34 | call to localeconv | test.c:73:5:73:8 | conv | The object returned by the function localeconv should not be modified. |
+| test.c:11:8:11:12 | c_str | test.c:18:16:18:21 | call to getenv | test.c:11:8:11:12 | c_str | The object returned by the function getenv should not be modified. |
+| 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:5:18:5:22 | c_str | test.c:8:8:8:12 | c_str |
-| test.c:15:16:15:21 | call to getenv | test.c:21:9:21:12 | env1 |
-| test.c:21:9:21:12 | env1 | test.c:5:18:5:22 | c_str |
-| test.c:61:11:61:20 | call to localeconv | test.c:64:5:64:9 | conv4 |
-| test.c:69:25:69:34 | call to localeconv | test.c:73:5:73: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:5:18:5:22 | c_str | semmle.label | c_str |
-| test.c:8:8:8:12 | c_str | semmle.label | c_str |
-| test.c:15:16:15:21 | call to getenv | semmle.label | call to getenv |
-| test.c:21:9:21:12 | env1 | semmle.label | env1 |
-| test.c:61:11:61:20 | call to localeconv | semmle.label | call to localeconv |
-| test.c:64:5:64:9 | conv4 | semmle.label | conv4 |
-| test.c:69:25:69:34 | call to localeconv | semmle.label | call to localeconv |
-| test.c:73:5:73:8 | conv | semmle.label | conv |
+| test.c:8:18:8:22 | c_str | semmle.label | c_str |
+| test.c:11:8:11:12 | c_str | semmle.label | c_str |
+| test.c:18:16:18:21 | call to getenv | semmle.label | call to getenv |
+| test.c:24:9:24:12 | env1 | semmle.label | env1 |
+| test.c:64:11:64:20 | call to localeconv | semmle.label | call to localeconv |
+| test.c:67:5:67:9 | conv4 | semmle.label | conv4 |
+| test.c:72:25:72:34 | call to localeconv | semmle.label | call to localeconv |
+| test.c:76:5:76:8 | conv | semmle.label | conv |
subpaths
diff --git a/c/common/test/rules/constlikereturnvalue/test.c b/c/common/test/rules/constlikereturnvalue/test.c
index cd7c101898..e28c05961f 100644
--- a/c/common/test/rules/constlikereturnvalue/test.c
+++ b/c/common/test/rules/constlikereturnvalue/test.c
@@ -1,4 +1,7 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
#include
+#include
#include
#include
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..75866b8503 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 | Config |
+| 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 | Config |
+| 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..bda6c7ad05 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 | Config |
+| 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 | Config |
+| 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 | Config |
+| 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/functionlikemacrosdefined/FunctionLikeMacrosDefined.expected b/c/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.expected
new file mode 100644
index 0000000000..c9a9eb0d48
--- /dev/null
+++ b/c/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.expected
@@ -0,0 +1,2 @@
+| test.c:8:1:8:25 | #define MACRO4(x) (x + 1) | Macro used instead of a function. |
+| test.c:13:1:13:48 | #define MACRO9() printf_custom("output = %d", 7) | Macro used instead of a function. |
diff --git a/c/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.ql b/c/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.ql
new file mode 100644
index 0000000000..29088c4458
--- /dev/null
+++ b/c/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.functionlikemacrosdefined.FunctionLikeMacrosDefined
+
+class TestFileQuery extends FunctionLikeMacrosDefinedSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/functionlikemacrosdefined/test.c b/c/common/test/rules/functionlikemacrosdefined/test.c
new file mode 100644
index 0000000000..ee36549b8d
--- /dev/null
+++ b/c/common/test/rules/functionlikemacrosdefined/test.c
@@ -0,0 +1,42 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#include
+
+#define MACRO(OP, L, R) ((L)OP(R)) // COMPLIANT
+#define MACRO2(L, R) (L + R) // COMPLIANT
+#define MACRO3(L, R) (L " " R " " L) // COMPLIANT
+#define MACRO4(x) (x + 1) // NON_COMPLIANT
+#define MACRO5(L, LR) (LR + 1) // COMPLIANT
+#define MACRO6(x) printf_custom("output = %d", test##x) // COMPLIANT
+#define MACRO7(x) #x // COMPLIANT
+#define MACRO8(x) "NOP" // COMPLIANT
+#define MACRO9() printf_custom("output = %d", 7) // NON_COMPLIANT
+#define MACRO10(x) // COMPLIANT
+#define MY_ASSERT(X) assert(X) // NON_COMPLIANT[FALSE_NEGATIVE]
+
+char a1[MACRO2(1, 1) + 6];
+extern int printf_custom(char *, int);
+int test1;
+
+void f() {
+ int i = MACRO(+, 1, 1);
+ int i2 = MACRO2(7, 10);
+
+ static int i3 = MACRO2(1, 1);
+
+ char *i4 = MACRO3("prefix", "suffix");
+
+ int i5 = MACRO4(1);
+
+ int i6 = MACRO4(MACRO2(1, 1));
+
+ int i7 = MACRO5(1, 1);
+
+ MACRO6(1);
+
+ char *i10 = MACRO7("prefix");
+
+ asm(MACRO8(1));
+
+ MY_ASSERT(1);
+}
\ No newline at end of file
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/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.expected b/c/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.expected
new file mode 100644
index 0000000000..7fd94b47f3
--- /dev/null
+++ b/c/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.expected
@@ -0,0 +1,3 @@
+| test.c:4:3:4:10 | goto ... | The goto statement and its $@ are not declared or enclosed in the same block. | test.c:6:3:6:5 | label ...: | label |
+| test.c:42:3:42:10 | goto ... | The goto statement and its $@ are not declared or enclosed in the same block. | test.c:46:3:46:5 | label ...: | label |
+| test.c:57:5:57:12 | goto ... | The goto statement and its $@ are not declared or enclosed in the same block. | test.c:60:3:60:5 | label ...: | label |
diff --git a/c/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.ql b/c/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.ql
new file mode 100644
index 0000000000..f553135683
--- /dev/null
+++ b/c/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.gotoreferencealabelinsurroundingblock.GotoReferenceALabelInSurroundingBlock
+
+class TestFileQuery extends GotoReferenceALabelInSurroundingBlockSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-15-3/test.c b/c/common/test/rules/gotoreferencealabelinsurroundingblock/test.c
similarity index 88%
rename from c/misra/test/rules/RULE-15-3/test.c
rename to c/common/test/rules/gotoreferencealabelinsurroundingblock/test.c
index 739affcfc1..083e0fe57b 100644
--- a/c/misra/test/rules/RULE-15-3/test.c
+++ b/c/common/test/rules/gotoreferencealabelinsurroundingblock/test.c
@@ -1,3 +1,5 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
void f1() {
goto L1;
for (int i = 0; i < 100; i++) {
diff --git a/c/common/test/rules/gotostatementcondition/GotoStatementCondition.expected b/c/common/test/rules/gotostatementcondition/GotoStatementCondition.expected
index e522289c7b..c42642c343 100644
--- a/c/common/test/rules/gotostatementcondition/GotoStatementCondition.expected
+++ b/c/common/test/rules/gotostatementcondition/GotoStatementCondition.expected
@@ -1,3 +1,4 @@
-| test.c:5:3:5:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.c:5:3:5:10 | goto ... | L1 | test.c:2:1:2:3 | label ...: | label ...: |
-| test.c:14:3:14:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.c:14:3:14:10 | goto ... | L2 | test.c:12:1:12:3 | label ...: | label ...: |
-| test.c:16:3:16:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.c:16:3:16:10 | goto ... | L1 | test.c:11:1:11:3 | label ...: | label ...: |
+| test.c:9:3:9:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.c:9:3:9:10 | goto ... | l1 | test.c:5:1:5:3 | label ...: | label ...: |
+| test.c:21:3:21:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.c:21:3:21:10 | goto ... | l2 | test.c:17:1:17:3 | label ...: | label ...: |
+| test.c:23:3:23:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.c:23:3:23:10 | goto ... | l1 | test.c:16:1:16:3 | label ...: | label ...: |
+| test.c:28:3:28:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.c:28:3:28:10 | goto ... | l1 | test.c:27:1:27:3 | label ...: | label ...: |
diff --git a/c/common/test/rules/gotostatementcondition/test.c b/c/common/test/rules/gotostatementcondition/test.c
index 2c189cd433..48426261fe 100644
--- a/c/common/test/rules/gotostatementcondition/test.c
+++ b/c/common/test/rules/gotostatementcondition/test.c
@@ -1,17 +1,29 @@
-void f1() {
-L1:;
- goto L2; // COMPLIANT
- ;
- goto L1; // NON_COMPLIANT
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+void f1(int p1) {
-L2:;
+l1:
+ if (p1) {
+ goto l2; // COMPLIANT
+ }
+ goto l1; // NON_COMPLIANT
+
+l2:;
}
-void f2() {
-L1:;
-L2:
- goto L3; // COMPLIANT
- goto L2; // NON_COMPLIANT
-L3:
- goto L1; // NON_COMPLIANT
+void f2(int p1) {
+
+l1:;
+l2:
+ if (p1) {
+ goto l3; // COMPLIANT
+ }
+ goto l2; // NON_COMPLIANT
+l3:
+ goto l1; // NON_COMPLIANT
}
+
+void f3() {
+l1:
+ goto l1; // NON_COMPLIANT
+}
\ No newline at end of file
diff --git a/c/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.expected b/c/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.expected
new file mode 100644
index 0000000000..15dc49ee37
--- /dev/null
+++ b/c/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.expected
@@ -0,0 +1 @@
+| test.c:6:3:6:14 | goto ... | Use of goto. |
diff --git a/c/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.ql b/c/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.ql
new file mode 100644
index 0000000000..1a117d5ddd
--- /dev/null
+++ b/c/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.gotostatementshouldnotbeused.GotoStatementShouldNotBeUsed
+
+class TestFileQuery extends GotoStatementShouldNotBeUsedSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/gotostatementshouldnotbeused/test.c b/c/common/test/rules/gotostatementshouldnotbeused/test.c
new file mode 100644
index 0000000000..4ecc1789c7
--- /dev/null
+++ b/c/common/test/rules/gotostatementshouldnotbeused/test.c
@@ -0,0 +1,11 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+void test_goto() {
+ int x = 1;
+
+ goto label1; // NON_COMPLIANT
+
+label1:
+
+ x = 2;
+}
\ No newline at end of file
diff --git a/c/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.expected b/c/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.expected
index c52544450f..9270a5ac15 100644
--- a/c/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.expected
+++ b/c/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.expected
@@ -1,6 +1,6 @@
-| test.c:19:14:19:19 | tmpvar | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:11:12:11:17 | call to getenv | call to getenv | test.c:15:13:15:18 | call to getenv | call to getenv |
-| test.c:132:14:132:17 | temp | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:128:12:128:17 | call to getenv | call to getenv | test.c:129:11:129:16 | call to getenv | call to getenv |
-| test.c:132:20:132:22 | tmp | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:129:11:129:16 | call to getenv | call to getenv | test.c:128:12:128:17 | call to getenv | call to getenv |
-| test.c:163:14:163:26 | tmpvar_global | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:155:19:155:24 | call to getenv | call to getenv | test.c:159:20:159:25 | call to getenv | call to getenv |
-| test.c:186:18:186:18 | r | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:183:7:183:15 | call to setlocale | call to setlocale | test.c:185:8:185:17 | call to localeconv | call to localeconv |
-| test.c:206:10:206:15 | tmpvar | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:200:12:200:17 | call to getenv | call to getenv | test.c:204:3:204:8 | call to f11fun | call to f11fun |
+| test.c:21:14:21:19 | tmpvar | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:13:12:13:17 | call to getenv | call to getenv | test.c:17:13:17:18 | call to getenv | call to getenv |
+| test.c:134:14:134:17 | temp | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:130:12:130:17 | call to getenv | call to getenv | test.c:131:11:131:16 | call to getenv | call to getenv |
+| test.c:134:20:134:22 | tmp | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:131:11:131:16 | call to getenv | call to getenv | test.c:130:12:130:17 | call to getenv | call to getenv |
+| test.c:165:14:165:26 | tmpvar_global | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:157:19:157:24 | call to getenv | call to getenv | test.c:161:20:161:25 | call to getenv | call to getenv |
+| test.c:188:18:188:18 | r | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:185:7:185:15 | call to setlocale | call to setlocale | test.c:187:8:187:17 | call to localeconv | call to localeconv |
+| test.c:208:10:208:15 | tmpvar | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.c:202:12:202:17 | call to getenv | call to getenv | test.c:206:3:206:8 | call to f11fun | call to f11fun |
diff --git a/c/common/test/rules/invalidatedenvstringpointers/test.c b/c/common/test/rules/invalidatedenvstringpointers/test.c
index 59c9593d21..183a4891c1 100644
--- a/c/common/test/rules/invalidatedenvstringpointers/test.c
+++ b/c/common/test/rules/invalidatedenvstringpointers/test.c
@@ -1,3 +1,5 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
#include
#include
#include
diff --git a/c/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.expected b/c/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.expected
index 556a3fe4a8..628a4f99d6 100644
--- a/c/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.expected
+++ b/c/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.expected
@@ -1,2 +1,2 @@
-| test.c:13:19:13:24 | call to getenv | The value of variable $@ might become invalid after a subsequent call to function `getenv`. | test.c:10:7:10:19 | tmpvar_global | tmpvar_global |
-| test.c:16:20:16:25 | call to getenv | The value of variable $@ might become invalid after a subsequent call to function `getenv`. | test.c:7:9:7:20 | tmpvar_field | tmpvar_field |
+| test.c:15:19:15:24 | call to getenv | The value of variable $@ might become invalid after a subsequent call to function `getenv`. | test.c:12:7:12:19 | tmpvar_global | tmpvar_global |
+| test.c:18:20:18:25 | call to getenv | The value of variable $@ might become invalid after a subsequent call to function `getenv`. | test.c:9:9:9:20 | tmpvar_field | tmpvar_field |
diff --git a/c/common/test/rules/invalidatedenvstringpointerswarn/test.c b/c/common/test/rules/invalidatedenvstringpointerswarn/test.c
index 2b678df6ac..6d4cec1d8d 100644
--- a/c/common/test/rules/invalidatedenvstringpointerswarn/test.c
+++ b/c/common/test/rules/invalidatedenvstringpointerswarn/test.c
@@ -1,3 +1,5 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
#include
#include
#include
diff --git a/c/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.expected b/c/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.expected
new file mode 100644
index 0000000000..a381fdb7e8
--- /dev/null
+++ b/c/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.expected
@@ -0,0 +1,16 @@
+| test.c:5:10:5:11 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.c:6:10:6:12 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.c:9:10:9:12 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.c:10:10:10:12 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.c:15:11:15:12 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.c:16:11:16:13 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.c:19:11:19:13 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.c:20:11:20:13 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.c:25:10:25:14 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.c:26:10:26:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.c:29:10:29:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.c:30:10:30:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.c:35:11:35:14 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.c:36:11:36:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.c:39:11:39:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.c:40:11:40:15 | 1 | Lowercase 'l' used as a literal suffix. |
diff --git a/c/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.ql b/c/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.ql
new file mode 100644
index 0000000000..ab353ca8a9
--- /dev/null
+++ b/c/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.lowercaselstartsinliteralsuffix.LowercaseLStartsInLiteralSuffix
+
+class TestFileQuery extends LowercaseLStartsInLiteralSuffixSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-7-3/test.c b/c/common/test/rules/lowercaselstartsinliteralsuffix/test.c
similarity index 86%
rename from c/misra/test/rules/RULE-7-3/test.c
rename to c/common/test/rules/lowercaselstartsinliteralsuffix/test.c
index 5e1c448926..549e90bd7d 100644
--- a/c/misra/test/rules/RULE-7-3/test.c
+++ b/c/common/test/rules/lowercaselstartsinliteralsuffix/test.c
@@ -1,4 +1,6 @@
-
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+// int x = false; // COMPLIANT - reported as C++ FP in #319
int a1 = 0L; // COMPLIANT
int a2 = 0l; // NON_COMPLIANT
int a3 = 0ll; // NON_COMPLIANT
diff --git a/c/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.expected b/c/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.expected
new file mode 100644
index 0000000000..715bbe781d
--- /dev/null
+++ b/c/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.expected
@@ -0,0 +1 @@
+| test.c:27:1:27:29 | #define MACROTHIRTEEN(X) #X ## X | Macro definition uses an # operator followed by a ## operator. |
diff --git a/c/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.ql b/c/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.ql
new file mode 100644
index 0000000000..f753b75463
--- /dev/null
+++ b/c/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.macroparameterfollowinghash.MacroParameterFollowingHash
+
+class TestFileQuery extends MacroParameterFollowingHashSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/macroparameterfollowinghash/test.c b/c/common/test/rules/macroparameterfollowinghash/test.c
new file mode 100644
index 0000000000..d998ce8106
--- /dev/null
+++ b/c/common/test/rules/macroparameterfollowinghash/test.c
@@ -0,0 +1,29 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#define MACROONE 1 // COMPLIANT
+
+#define MACROTWO '#\'-#' + '#' // COMPLIANT
+
+#define MACROTHREE "##" // COMPLIANT
+
+#define MACROFOUR "##" + "#" // COMPLIANT
+
+#define MACROFIVE(X) #X // COMPLIANT
+
+#define MACROSIX(X, Y) X##Y // COMPLIANT
+
+#define MACROSEVEN "##'" #"#" // COMPLIANT
+
+#define MACROEIGHT '##' #"#" // COMPLIANT
+
+#define MACRONINE "##\"\"" + "#" // COMPLIANT
+
+#define MACROTEN "##\"\"'" + "#" // COMPLIANT
+
+#define MACROELEVEN(X) X #X #X // COMPLIANT
+
+#define MACROTWELVE(X) X##X##X // COMPLIANT
+
+#define MACROTHIRTEEN(X) #X##X // NON_COMPLIANT
+
+#define MACROFOURTEEN '#\'-#' + 1 #1 #1 + '#' // COMPLIANT
\ No newline at end of file
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/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.expected b/c/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.expected
new file mode 100644
index 0000000000..7a6b7c33a5
--- /dev/null
+++ b/c/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.expected
@@ -0,0 +1,5 @@
+| test.c:6:7:6:8 | x1 | A named bit-field with signed integral type should have at least 2 bits of storage. |
+| test.c:9:14:9:15 | x2 | A named bit-field with signed integral type should have at least 2 bits of storage. |
+| test.c:11:7:11:8 | x3 | A named bit-field with signed integral type should have at least 2 bits of storage. |
+| test.c:13:7:13:8 | x4 | A named bit-field with signed integral type should have at least 2 bits of storage. |
+| test.c:22:14:22:14 | x | A named bit-field with signed integral type should have at least 2 bits of storage. |
diff --git a/c/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.ql b/c/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.ql
new file mode 100644
index 0000000000..a82fa7905a
--- /dev/null
+++ b/c/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.namedbitfieldswithsignedintegertype.NamedBitFieldsWithSignedIntegerType
+
+class TestFileQuery extends NamedBitFieldsWithSignedIntegerTypeSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/namedbitfieldswithsignedintegertype/test.c b/c/common/test/rules/namedbitfieldswithsignedintegertype/test.c
new file mode 100644
index 0000000000..8fae6812fe
--- /dev/null
+++ b/c/common/test/rules/namedbitfieldswithsignedintegertype/test.c
@@ -0,0 +1,28 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#include
+
+struct SampleStruct {
+ int x1 : 1; // NON_COMPLIANT: very likely be signed, but if it's not, the
+ // query will automatically handle it since we use signed(), not
+ // isExplicitlySigned().
+ signed int x2 : 1; // NON_COMPLIANT: single-bit named field with a signed type
+ signed char
+ x3 : 1; // NON_COMPLIANT: single-bit named field with a signed type
+ signed short
+ x4 : 1; // NON_COMPLIANT: single-bit named field with a signed type
+ unsigned int
+ x5 : 1; // COMPLIANT: single-bit named field but with an unsigned type
+ signed int x6 : 2; // COMPLIANT: named field with a signed type but declared
+ // to carry more than 1 bit
+ signed char : 1; // COMPLIANT: single-bit bit-field but unnamed
+} sample_struct;
+
+struct S {
+ signed int x : 1; // NON-COMPLIANT
+ signed int y : 5; // COMPLIANT
+ signed int z : 7; // COMPLIANT
+ signed int : 0; // COMPLIANT
+ signed int : 1; // COMPLIANT
+ signed int : 2; // COMPLIANT
+};
\ No newline at end of file
diff --git a/c/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.expected b/c/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.expected
new file mode 100644
index 0000000000..26401472ac
--- /dev/null
+++ b/c/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.expected
@@ -0,0 +1,21 @@
+| test.c:37:18:37:24 | \u001aG | Invalid hexadecimal escape in string literal at '\\x1AG"'. |
+| test.c:40:18:40:23 | \u00029 | Invalid octal escape in string literal at '\\029"'. |
+| test.c:43:18:43:24 | \n7 | Invalid octal escape in string literal at '\\0127"'. |
+| test.c:44:18:44:24 | \r7 | Invalid octal escape in string literal at '\\0157"'. |
+| test.c:46:19:46:29 | \n\n9 | Invalid octal escape in string literal at '\\0129"'. |
+| test.c:47:19:47:28 | \n\u00019 | Invalid octal escape in string literal at '\\019"'. |
+| test.c:50:19:50:31 | \nAAA\u000f | Invalid octal escape in string literal at '\\012AAA\\017"'. |
+| test.c:53:19:53:39 | Some Data \n\u000fA | Invalid octal escape in string literal at '\\017A"'. |
+| test.c:54:19:55:21 | Some Data \n\u000fA5 | Invalid octal escape in string literal at '\\017A"\n "5"'. |
+| test.c:56:19:58:25 | Some Data \n\u000fA\n1 | Invalid octal escape in string literal at '\\0121"'. |
+| test.c:62:19:63:26 | \u0011G\u00012 | Invalid octal escape in string literal at '\\0012"'. |
+| test.c:64:19:65:25 | \u0011GG\u0001 | Invalid hexadecimal escape in string literal at '\\x11G"\n "G\\001"'. |
+| test.c:66:19:67:26 | \u0011GG\u00013 | Invalid hexadecimal escape in string literal at '\\x11G"\n "G\\0013"'. |
+| test.c:66:19:67:26 | \u0011GG\u00013 | Invalid octal escape in string literal at '\\0013"'. |
+| test.c:73:18:73:42 | Some Data \n\u000fA5 | Invalid octal escape in string literal at '\\017A" "5"'. |
+| test.c:74:18:74:49 | Some Data \n\u000fA\n1 | Invalid octal escape in string literal at '\\0121"'. |
+| test.c:76:18:76:32 | \u0011G\u00012 | Invalid octal escape in string literal at '\\0012"'. |
+| test.c:77:18:77:32 | \u0011GG\u0001 | Invalid hexadecimal escape in string literal at '\\x11G" "G\\001"'. |
+| test.c:78:18:78:33 | \u0011GG\u00013 | Invalid hexadecimal escape in string literal at '\\x11G" "G\\0013"'. |
+| test.c:78:18:78:33 | \u0011GG\u00013 | Invalid octal escape in string literal at '\\0013"'. |
+| test.c:81:11:81:16 | 10 | Invalid hexadecimal escape in string literal at '\\x0a''. |
diff --git a/c/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.ql b/c/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.ql
new file mode 100644
index 0000000000..c1aae3c31b
--- /dev/null
+++ b/c/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.nonterminatedescapesequences.NonTerminatedEscapeSequences
+
+class TestFileQuery extends NonTerminatedEscapeSequencesSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/nonterminatedescapesequences/test.c b/c/common/test/rules/nonterminatedescapesequences/test.c
new file mode 100644
index 0000000000..67c6e3d5a3
--- /dev/null
+++ b/c/common/test/rules/nonterminatedescapesequences/test.c
@@ -0,0 +1,81 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#include
+
+struct SampleStruct {
+ int x1 : 1; // NON_COMPLIANT: very likely be signed, but if it's not, the
+ // query will automatically handle it since we use signed(), not
+ // isExplicitlySigned().
+ signed int x2 : 1; // NON_COMPLIANT: single-bit named field with a signed type
+ signed char
+ x3 : 1; // NON_COMPLIANT: single-bit named field with a signed type
+ signed short
+ x4 : 1; // NON_COMPLIANT: single-bit named field with a signed type
+ unsigned int
+ x5 : 1; // COMPLIANT: single-bit named field but with an unsigned type
+ signed int x6 : 2; // COMPLIANT: named field with a signed type but declared
+ // to carry more than 1 bit
+ signed char : 1; // COMPLIANT: single-bit bit-field but unnamed
+} sample_struct;
+
+struct S {
+ signed int x : 1; // NON-COMPLIANT
+ signed int y : 5; // COMPLIANT
+ signed int z : 7; // COMPLIANT
+ signed int : 0; // COMPLIANT
+ signed int : 1; // COMPLIANT
+ signed int : 2; // COMPLIANT
+};
+const char *a1 = "\x11"
+ "G"; // COMPLIANT
+
+const char *a2 = "\x1"
+ "G"; // COMPLIANT
+
+const char *a3 = "\x1A"; // COMPLIANT
+
+const char *a4 = "\x1AG"; // NON_COMPLIANT
+
+const char *a5 = "\021"; // COMPLIANT
+const char *a6 = "\029"; // NON_COMPLIANT
+const char *a7 = "\0"
+ "0"; // COMPLIANT
+const char *a8 = "\0127"; // NON_COMPLIANT
+const char *a9 = "\0157"; // NON_COMPLIANT
+
+const char *a10 = "\012\0129"; // NON_COMPLIANT (1x)
+const char *a11 = "\012\019"; // NON_COMPLIANT
+const char *a12 = "\012\017"; // COMPLIANT
+
+const char *a13 = "\012AAA\017"; // NON_COMPLIANT (1x)
+
+const char *a14 = "Some Data \012\017"; // COMPLIANT
+const char *a15 = "Some Data \012\017A"; // NON_COMPLIANT (1x)
+const char *a16 = "Some Data \012\017A"
+ "5"; // NON_COMPLIANT (1x)
+const char *a17 = "Some Data \012\017"
+ "A"
+ "\0121"; // NON_COMPLIANT (1x)
+
+const char *a18 = "\x11"
+ "G\001"; // COMPLIANT
+const char *a19 = "\x11"
+ "G\0012"; // NON_COMPLIANT (1x)
+const char *a20 = "\x11G"
+ "G\001"; // NON_COMPLIANT (1x)
+const char *a21 = "\x11G"
+ "G\0013"; // NON_COMPLIANT (2x)
+
+// clang-format off
+const char *b1 = "\x11" "G"; // COMPLIANT
+const char *b2 = "\x1" "G"; // COMPLIANT
+const char *b3 = "\0" "0"; // COMPLIANT
+const char *b4 = "Some Data \012\017A" "5"; // NON_COMPLIANT (1x)
+const char *b5 = "Some Data \012\017" "A" "\0121"; // NON_COMPLIANT (1x)
+const char *b6 = "\x11" "G\001"; // COMPLIANT
+const char *b7 = "\x11" "G\0012"; // NON_COMPLIANT (1x)
+const char *b8 = "\x11G" "G\001"; // NON_COMPLIANT (1x)
+const char *b9 = "\x11G" "G\0013"; // NON_COMPLIANT (2x)
+
+char c1 = '\023'; // COMPLIANT
+char c2 = '\x0a'; // COMPLIANT
diff --git a/c/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.expected b/c/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.expected
new file mode 100644
index 0000000000..65e57e3575
--- /dev/null
+++ b/c/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.expected
@@ -0,0 +1 @@
+| test.c:5:19:5:20 | c4 | Nonunique value of enum constant compared to $@ | test.c:5:23:5:24 | c5 | c5 |
diff --git a/c/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.ql b/c/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.ql
new file mode 100644
index 0000000000..97ba6f516e
--- /dev/null
+++ b/c/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.nonuniqueenumerationconstant.NonUniqueEnumerationConstant
+
+class TestFileQuery extends NonUniqueEnumerationConstantSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-8-12/test.c b/c/common/test/rules/nonuniqueenumerationconstant/test.c
similarity index 62%
rename from c/misra/test/rules/RULE-8-12/test.c
rename to c/common/test/rules/nonuniqueenumerationconstant/test.c
index 349bb7867c..0712cb59e4 100644
--- a/c/misra/test/rules/RULE-8-12/test.c
+++ b/c/common/test/rules/nonuniqueenumerationconstant/test.c
@@ -1,3 +1,5 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
enum e { c = 3 }; // COMPLIANT
enum e1 { c1 = 3, c2 }; // COMPLIANT
enum e3 { c3 = 3, c4, c5 = 4 }; // NON_COMPLIANT
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/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.expected b/c/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.expected
new file mode 100644
index 0000000000..c0a8359320
--- /dev/null
+++ b/c/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.expected
@@ -0,0 +1,3 @@
+| test.c:9:7:9:12 | ... = ... | Use of an assignment operator's result. |
+| test.c:13:11:13:16 | ... = ... | Use of an assignment operator's result. |
+| test.c:15:8:15:13 | ... = ... | Use of an assignment operator's result. |
diff --git a/c/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql b/c/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
new file mode 100644
index 0000000000..286e4424a4
--- /dev/null
+++ b/c/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.resultofanassignmentoperatorshouldnotbeused.ResultOfAnAssignmentOperatorShouldNotBeUsed
+
+class TestFileQuery extends ResultOfAnAssignmentOperatorShouldNotBeUsedSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/resultofanassignmentoperatorshouldnotbeused/test.c b/c/common/test/rules/resultofanassignmentoperatorshouldnotbeused/test.c
new file mode 100644
index 0000000000..db0a45384e
--- /dev/null
+++ b/c/common/test/rules/resultofanassignmentoperatorshouldnotbeused/test.c
@@ -0,0 +1,16 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+void test() {
+ int l1, l2;
+ int l3[1];
+
+ l1 = l2; // COMPLIANT
+
+ if (l1 = 1) // NON_COMPLIANT
+ {
+ }
+
+ l1 = l3[l2 = 0]; // NON_COMPLIANT
+
+ l1 = l2 = 0; // NON_COMPLIANT
+}
diff --git a/c/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.expected b/c/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.expected
new file mode 100644
index 0000000000..33ec8d6995
--- /dev/null
+++ b/c/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.expected
@@ -0,0 +1,4 @@
+| test.c:7:3:7:9 | ... + ... | Operation + of type unsigned int may wrap. |
+| test.c:8:3:8:10 | ... += ... | Operation += of type unsigned int may wrap. |
+| test.c:61:3:61:9 | ... - ... | Operation - of type unsigned int may wrap. |
+| test.c:62:3:62:10 | ... -= ... | Operation -= of type unsigned int may wrap. |
diff --git a/c/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.ql b/c/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.ql
new file mode 100644
index 0000000000..b88e7637c1
--- /dev/null
+++ b/c/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.unsignedoperationwithconstantoperandswraps.UnsignedOperationWithConstantOperandsWraps
+
+class TestFileQuery extends UnsignedOperationWithConstantOperandsWrapsSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/unsignedoperationwithconstantoperandswraps/test.c b/c/common/test/rules/unsignedoperationwithconstantoperandswraps/test.c
new file mode 100644
index 0000000000..214b18a44f
--- /dev/null
+++ b/c/common/test/rules/unsignedoperationwithconstantoperandswraps/test.c
@@ -0,0 +1,83 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+
+#include
+
+void test_add_simple(unsigned int i1, unsigned int i2) {
+ i1 + i2; // NON_COMPLIANT - not bounds checked
+ i1 += i2; // NON_COMPLIANT - not bounds checked
+}
+
+void test_add_precheck(unsigned int i1, unsigned int i2) {
+ if (UINT_MAX - i1 < i2) {
+ // handle error
+ } else {
+ i1 + i2; // COMPLIANT - bounds checked
+ i1 += i2; // COMPLIANT - bounds checked
+ }
+}
+
+void test_add_precheck_2(unsigned int i1, unsigned int i2) {
+ if (i1 + i2 < i1) {
+ // handle error
+ } else {
+ i1 + i2; // COMPLIANT - bounds checked
+ i1 += i2; // COMPLIANT - bounds checked
+ }
+}
+
+void test_add_postcheck(unsigned int i1, unsigned int i2) {
+ unsigned int i3 = i1 + i2; // COMPLIANT - checked for overflow afterwards
+ if (i3 < i1) {
+ // handle error
+ }
+ i1 += i2; // COMPLIANT - checked for overflow afterwards
+ if (i1 < i2) {
+ // handle error
+ }
+}
+
+void test_ex2(unsigned int i1, unsigned int i2) {
+ unsigned int ci1 = 2;
+ unsigned int ci2 = 3;
+ ci1 + ci2; // COMPLIANT, compile time constants
+ i1 + 0; // COMPLIANT
+ i1 += 0; // COMPLIANT
+ i1 - 0; // COMPLIANT
+ i1 -= 0; // COMPLIANT
+ UINT_MAX - i1; // COMPLIANT - cannot be smaller than 0
+ i1 * 1; // COMPLIANT
+ i1 *= 1; // COMPLIANT
+ if (0 <= i1 && i1 < 32) {
+ UINT_MAX >> i1; // COMPLIANT
+ }
+}
+
+void test_ex3(unsigned int i1, unsigned int i2) {
+ i1 << i2; // COMPLIANT - by EX3
+}
+
+void test_sub_simple(unsigned int i1, unsigned int i2) {
+ i1 - i2; // NON_COMPLIANT - not bounds checked
+ i1 -= i2; // NON_COMPLIANT - not bounds checked
+}
+
+void test_sub_precheck(unsigned int i1, unsigned int i2) {
+ if (i1 < i2) {
+ // handle error
+ } else {
+ i1 - i2; // COMPLIANT - bounds checked
+ i1 -= i2; // COMPLIANT - bounds checked
+ }
+}
+
+void test_sub_postcheck(unsigned int i1, unsigned int i2) {
+ unsigned int i3 = i1 - i2; // COMPLIANT - checked for wrap afterwards
+ if (i3 > i1) {
+ // handle error
+ }
+ i1 -= i2; // COMPLIANT - checked for wrap afterwards
+ if (i1 > i2) {
+ // handle error
+ }
+}
\ No newline at end of file
diff --git a/c/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.expected b/c/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.expected
new file mode 100644
index 0000000000..bbd4264069
--- /dev/null
+++ b/c/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.expected
@@ -0,0 +1,2 @@
+| test.c:5:3:5:5 | 10 | Non zero octal literal 012. |
+| test.c:6:3:6:5 | 44 | Non zero octal literal 054. |
diff --git a/c/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.ql b/c/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.ql
new file mode 100644
index 0000000000..0404a7bc0c
--- /dev/null
+++ b/c/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.useofnonzerooctalliteral.UseOfNonZeroOctalLiteral
+
+class TestFileQuery extends UseOfNonZeroOctalLiteralSharedQuery, TestQuery { }
diff --git a/c/common/test/rules/useofnonzerooctalliteral/test.c b/c/common/test/rules/useofnonzerooctalliteral/test.c
new file mode 100644
index 0000000000..11b439b02e
--- /dev/null
+++ b/c/common/test/rules/useofnonzerooctalliteral/test.c
@@ -0,0 +1,7 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+void test_non_zero_octal() {
+ 0; // COMPLIANT - octal literal zero permitted
+ 012; // NON_COMPLIANT
+ 054; // NON_COMPLIANT
+}
\ No newline at end of file
diff --git a/c/misra/src/codeql-pack.lock.yml b/c/misra/src/codeql-pack.lock.yml
index 514e6963d0..910a6e060e 100644
--- a/c/misra/src/codeql-pack.lock.yml
+++ b/c/misra/src/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
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..9aceed1a49 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.40.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: 1.4.2
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 e53294fba5..582715e34f 100644
--- a/c/misra/src/rules/DIR-4-9/FunctionOverFunctionLikeMacro.ql
+++ b/c/misra/src/rules/DIR-4-9/FunctionOverFunctionLikeMacro.ql
@@ -10,27 +10,16 @@
* external/misra/audit
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.IrreplaceableFunctionLikeMacro
+import codingstandards.cpp.rules.functionlikemacrosdefined.FunctionLikeMacrosDefined
-predicate partOfConstantExpr(MacroInvocation i) {
- exists(Expr e |
- e.isConstant() and
- not i.getExpr() = e and
- i.getExpr().getParent+() = e
- )
+class FunctionOverFunctionLikeMacroQuery extends FunctionLikeMacrosDefinedSharedQuery {
+ FunctionOverFunctionLikeMacroQuery() {
+ this = Preprocessor6Package::functionOverFunctionLikeMacroQuery()
+ }
}
-
-from FunctionLikeMacro m
-where
- not isExcluded(m, Preprocessor6Package::functionOverFunctionLikeMacroQuery()) and
- not m instanceof IrreplaceableFunctionLikeMacro and
- //macros can have empty body
- not m.getBody().length() = 0 and
- //function call not allowed in a constant expression (where constant expr is parent)
- forall(MacroInvocation i | i = m.getAnInvocation() | not partOfConstantExpr(i))
-select m, "Macro used instead of a function."
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 c1ac4d4b40..90b0315e88 100644
--- a/c/misra/src/rules/RULE-13-2/UnsequencedSideEffects.ql
+++ b/c/misra/src/rules/RULE-13-2/UnsequencedSideEffects.ql
@@ -8,14 +8,14 @@
* @problem.severity error
* @tags external/misra/id/rule-13-2
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Expr
-import codingstandards.c.SideEffects
import codingstandards.c.Ordering
+import codingstandards.c.SideEffects
class VariableEffectOrAccess extends Expr {
VariableEffectOrAccess() {
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 6938f8e627..c840947b1f 100644
--- a/c/misra/src/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
+++ b/c/misra/src/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
@@ -9,14 +9,17 @@
* @tags external/misra/id/rule-13-4
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.rules.resultofanassignmentoperatorshouldnotbeused.ResultOfAnAssignmentOperatorShouldNotBeUsed
-from AssignExpr e
-where
- not isExcluded(e, SideEffects1Package::resultOfAnAssignmentOperatorShouldNotBeUsedQuery()) and
- not exists(ExprStmt s | s.getExpr() = e)
-select e, "Use of an assignment operator's result."
+class ResultOfAnAssignmentOperatorShouldNotBeUsedQuery extends ResultOfAnAssignmentOperatorShouldNotBeUsedSharedQuery
+{
+ ResultOfAnAssignmentOperatorShouldNotBeUsedQuery() {
+ this = SideEffects1Package::resultOfAnAssignmentOperatorShouldNotBeUsedQuery()
+ }
+}
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 ddc85c305c..84c7dbd408 100644
--- a/c/misra/src/rules/RULE-15-1/GotoStatementUsed.ql
+++ b/c/misra/src/rules/RULE-15-1/GotoStatementUsed.ql
@@ -8,14 +8,14 @@
* @tags external/misra/id/rule-15-1
* correctness
* security
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.rules.gotostatementshouldnotbeused.GotoStatementShouldNotBeUsed
-from Stmt s
-where
- not isExcluded(s, Statements6Package::gotoStatementUsedQuery()) and
- (s instanceof GotoStmt or s instanceof ComputedGotoStmt)
-select s, "Use of goto."
+class GotoStatementUsedQuery extends GotoStatementShouldNotBeUsedSharedQuery {
+ GotoStatementUsedQuery() { this = Statements6Package::gotoStatementUsedQuery() }
+}
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 aeb356b501..a88f3170de 100644
--- a/c/misra/src/rules/RULE-15-3/GotoLabelBlockCondition.ql
+++ b/c/misra/src/rules/RULE-15-3/GotoLabelBlockCondition.ql
@@ -9,54 +9,14 @@
* @tags external/misra/id/rule-15-3
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.rules.gotoreferencealabelinsurroundingblock.GotoReferenceALabelInSurroundingBlock
-predicate isPartOfSwitch(Stmt goto) {
- exists(SwitchStmt switch | switch.getStmt() = goto.getParent())
+class GotoLabelBlockConditionQuery extends GotoReferenceALabelInSurroundingBlockSharedQuery {
+ GotoLabelBlockConditionQuery() { this = Statements2Package::gotoLabelBlockConditionQuery() }
}
-
-SwitchCase getSwitchCase(Stmt stmt) {
- exists(int index, SwitchStmt switch |
- getStmtInSwitch(switch, stmt, index) and getStmtInSwitch(switch, result, index - 1)
- )
- or
- exists(int index, SwitchStmt switch, Stmt other |
- getStmtInSwitch(switch, stmt, index) and
- getStmtInSwitch(switch, other, index - 1) and
- not other instanceof SwitchCase and
- result = getSwitchCase(other)
- )
-}
-
-predicate getStmtInSwitch(SwitchStmt switch, Stmt s, int index) {
- switch.getStmt().(BlockStmt).getStmt(index) = s
-}
-
-int statementDepth(Stmt statement) {
- statement.getParent() = statement.getEnclosingFunction().getBlock() and result = 1
- or
- statementDepth(statement.getParent()) + 1 = result
-}
-
-from GotoStmt goto, Stmt target, int gotoDepth, int targetDepth
-where
- not isExcluded(goto, Statements2Package::gotoLabelBlockConditionQuery()) and
- goto.getTarget() = target and
- gotoDepth = statementDepth(goto) and
- targetDepth = statementDepth(target) and
- targetDepth >= gotoDepth and
- (
- targetDepth = gotoDepth
- implies
- (
- not isPartOfSwitch(goto) and not goto.getParent() = target.getParent()
- or
- isPartOfSwitch(goto) and not getSwitchCase(goto) = getSwitchCase(target)
- )
- )
-select goto, "The $@ statement and its $@ are not declared or enclosed in the same block.", goto,
- "goto", target, "label"
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 c596cb2970..9cc5bf9dda 100644
--- a/c/misra/src/rules/RULE-15-6/LoopCompoundCondition.ql
+++ b/c/misra/src/rules/RULE-15-6/LoopCompoundCondition.ql
@@ -1,6 +1,6 @@
/**
* @id c/misra/loop-compound-condition
- * @name RULE-15-6: the statement forming the body of a loop shall be a compound statement
+ * @name RULE-15-6: The statement forming the body of a loop shall be a compound statement
* @description if the body of a loop is not enclosed in braces, then this can lead to incorrect
* execution, and is hard for developers to maintain.
* @kind problem
@@ -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 0c97b3ea5a..f84c142414 100644
--- a/c/misra/src/rules/RULE-15-6/SelectionCompoundCondition.ql
+++ b/c/misra/src/rules/RULE-15-6/SelectionCompoundCondition.ql
@@ -1,6 +1,6 @@
/**
* @id c/misra/selection-compound-condition
- * @name RULE-15-6: the statement forming the body of a loop shall be a compound statement
+ * @name RULE-15-6: The statement forming the body of a slection statement shall be a compound statement
* @description if the body of a selection statement is not enclosed in braces, then this can lead
* to incorrect execution, and is hard for developers to maintain.
* @kind problem
@@ -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..9673b39eb2 100644
--- a/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql
+++ b/c/misra/src/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.ql
@@ -8,12 +8,13 @@
* @problem.severity error
* @tags external/misra/id/rule-17-5
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/advisory
*/
import cpp
import codingstandards.c.misra
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* Models a function parameter of type array with specified size
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..5f4a28d642 100644
--- a/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql
+++ b/c/misra/src/rules/RULE-17-7/ValueReturnedByAFunctionNotUsed.ql
@@ -8,12 +8,13 @@
* @problem.severity error
* @tags external/misra/id/rule-17-7
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
from Call c
where
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-10/PointersToVariablyModifiedArrayTypesUsed.ql b/c/misra/src/rules/RULE-18-10/PointersToVariablyModifiedArrayTypesUsed.ql
new file mode 100644
index 0000000000..3a99ebd842
--- /dev/null
+++ b/c/misra/src/rules/RULE-18-10/PointersToVariablyModifiedArrayTypesUsed.ql
@@ -0,0 +1,51 @@
+/**
+ * @id c/misra/pointers-to-variably-modified-array-types-used
+ * @name RULE-18-10: Pointers to variably-modified array types shall not be used
+ * @description Pointers to variably-modified array types shall not be used, as these pointer types
+ * are frequently incompatible with other fixed or variably sized arrays, resulting in
+ * undefined behavior.
+ * @kind problem
+ * @precision high
+ * @problem.severity error
+ * @tags external/misra/id/rule-18-10
+ * external/misra/c/2012/amendment4
+ * correctness
+ * security
+ * external/misra/obligation/mandatory
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.VariablyModifiedTypes
+
+from VmtDeclarationEntry v, string declstr, string adjuststr, string relationstr
+where
+ not isExcluded(v, InvalidMemory3Package::pointersToVariablyModifiedArrayTypesUsedQuery()) and
+ // Capture only pointers to VLA types, not raw VLA types.
+ not v.getVlaType() = v.getType() and
+ (
+ if v instanceof ParameterDeclarationEntry
+ then declstr = "Parameter "
+ else
+ if v instanceof VariableDeclarationEntry
+ then declstr = "Variable "
+ else declstr = "Declaration "
+ ) and
+ (
+ if
+ v instanceof ParameterDeclarationEntry and
+ v.getType() instanceof ParameterAdjustedVariablyModifiedType
+ then adjuststr = "adjusted to"
+ else adjuststr = "declared with"
+ ) and
+ (
+ if v.getType().(PointerType).getBaseType() instanceof CandidateVlaType
+ then relationstr = "pointer to"
+ else relationstr = "with inner"
+ ) and
+ // Remove results that appear to be unreliable, potentially from a macro.
+ not v.appearsDuplicated()
+select v,
+ declstr + v.getName() + " is " + adjuststr + " variably-modified type, " + relationstr +
+ " variable length array of non constant size $@ and element type '" +
+ v.getVlaType().getVariableBaseType() + "'", v.getSizeExpr(), v.getSizeExpr().toString()
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..cf19c02eca 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
*/
@@ -15,33 +16,53 @@ import cpp
import codingstandards.c.misra
/**
- * A variable length array (VLA)
- * ie an array where the size
- * is not an integer constant expression
+ * Typedefs may be declared as VLAs, eg, `typedef int vla[x];`. This query finds types that refer to
+ * such typedef types, for instance `vla foo;` or adding a dimension via `vla bar[10];`.
+ *
+ * Consts and other specifiers may be added, but `vla *ptr;` is not a VLA any more, and is excluded.
*/
-class VariableLengthArray extends VariableDeclarationEntry {
- VariableLengthArray() {
- //VLAs will not have: static/extern specifiers (compilation error)
- not this.hasSpecifier("static") and
- not this.hasSpecifier("extern") and
- //VLAs are not allowed to be initialized
- not this.getDeclaration().hasInitializer() and
- exists(ArrayType a |
- //a.hasArraySize() does not catch multidimensional VLAs like a[1][]
- a.toString().matches("%[]%") and
- this.getUnspecifiedType() = a and
- //variable length array is one declared in block or function prototype
- (
- this.getDeclaration().getParentScope() instanceof Function or
- this.getDeclaration().getParentScope() instanceof BlockStmt
- )
+class VlaTypedefType extends Type {
+ VlaDeclStmt vlaDecl;
+ ArrayType arrayType;
+
+ VlaTypedefType() {
+ // Holds for direct references to the typedef type:
+ this = vlaDecl.getType() and
+ vlaDecl.getType() instanceof TypedefType and
+ arrayType = vlaDecl.getType().stripTopLevelSpecifiers()
+ or
+ // Handle arrays of VLA typedefs, and carefully handle specified VLA typedef types, as
+ // `stripTopLevelSpecifiers` resolves past the VLA typedef type.
+ exists(DerivedType dt, VlaTypedefType vlaType |
+ (dt instanceof ArrayType or dt instanceof SpecifiedType) and
+ this = dt and
+ vlaType = dt.getBaseType() and
+ vlaDecl = vlaType.getVlaDeclStmt() and
+ arrayType = vlaType.getArrayType()
)
}
+
+ VlaDeclStmt getVlaDeclStmt() { result = vlaDecl }
+
+ ArrayType getArrayType() { result = arrayType }
}
-from VariableLengthArray v
+from Variable v, Expr size, ArrayType arrayType, VlaDeclStmt vlaDecl, string typeStr
where
not isExcluded(v, Declarations7Package::variableLengthArrayTypesUsedQuery()) and
- //an exception, argv in : int main(int argc, char *argv[])
- not v.getDeclaration().getParentScope().(Function).hasName("main")
-select v, "Variable length array declared."
+ size = vlaDecl.getVlaDimensionStmt(0).getDimensionExpr() and
+ (
+ // Holds is if v is a variable declaration:
+ v = vlaDecl.getVariable() and
+ arrayType = v.getType().stripTopLevelSpecifiers()
+ or
+ // Holds is if v is a typedef declaration:
+ exists(VlaTypedefType typedef |
+ v.getType() = typedef and
+ arrayType = typedef.getArrayType() and
+ vlaDecl = typedef.getVlaDeclStmt()
+ )
+ ) and
+ typeStr = arrayType.getBaseType().toString()
+select v, "Variable length array of element type '" + typeStr + "' with non-constant size $@.",
+ size, size.toString()
diff --git a/c/misra/src/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.ql b/c/misra/src/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.ql
new file mode 100644
index 0000000000..5317966f3b
--- /dev/null
+++ b/c/misra/src/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.ql
@@ -0,0 +1,70 @@
+/**
+ * @id c/misra/array-to-pointer-conversion-of-temporary-object
+ * @name RULE-18-9: An object with temporary lifetime shall not undergo array to pointer conversion
+ * @description Modifying or accessing elements of an array with temporary lifetime that has been
+ * converted to a pointer will result in undefined behavior.
+ * @kind problem
+ * @precision high
+ * @problem.severity error
+ * @tags external/misra/id/rule-18-9
+ * external/misra/c/2012/amendment3
+ * correctness
+ * security
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.lifetimes.CLifetimes
+
+/**
+ * Holds if the value of an expression is used or stored.
+ *
+ * For instance, `(x)` does not use any values, but `x + y` uses `x` and `y`.
+ *
+ * A pointer-to-array conversion does not need to be flagged if the result of
+ * that conversion is not used or stored.
+ */
+predicate isUsedOrStored(Expr e) {
+ e = any(Operation o).getAnOperand()
+ or
+ e = any(ConditionalExpr c).getCondition()
+ or
+ e = any(Call c).getAnArgument()
+ or
+ e = any(VariableDeclarationEntry d).getDeclaration().getInitializer().getExpr()
+ or
+ e = any(ClassAggregateLiteral l).getAFieldExpr(_)
+}
+
+/**
+ * Find expressions that defer their value directly to an inner expression
+ * value.
+ *
+ * When an array is on the rhs of a comma expr, or in the then/else branch of a
+ * ternary expr, and the result us used as a pointer, then the ArrayToPointer
+ * conversion is marked inside comma expr/ternary expr, on the operands. These
+ * conversions are only non-compliant if they flow into an operation or store.
+ *
+ * Full flow analysis with localFlowStep should not be necessary, and may cast a
+ * wider net than needed for some queries, potentially resulting in false
+ * positives.
+ */
+Expr temporaryObjectFlowStep(Expr e) {
+ e = result.(CommaExpr).getRightOperand()
+ or
+ e = result.(ConditionalExpr).getThen()
+ or
+ e = result.(ConditionalExpr).getElse()
+}
+
+from
+ TemporaryLifetimeArrayAccess fa, TemporaryLifetimeExpr temporary,
+ ArrayToPointerConversion conversion
+where
+ not isExcluded(conversion, InvalidMemory3Package::arrayToPointerConversionOfTemporaryObjectQuery()) and
+ fa.getTemporary() = temporary and
+ conversion.getExpr() = fa and
+ isUsedOrStored(temporaryObjectFlowStep*(conversion.getExpr()))
+select conversion, "Array to pointer conversion of array $@ from temporary object $@.",
+ fa.getTarget(), fa.getTarget().getName(), temporary, temporary.toString()
diff --git a/c/misra/src/rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.ql b/c/misra/src/rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.ql
new file mode 100644
index 0000000000..f8a341b9bd
--- /dev/null
+++ b/c/misra/src/rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.ql
@@ -0,0 +1,59 @@
+/**
+ * @id c/misra/modifiable-l-value-subscripted-with-temporary-lifetime
+ * @name RULE-18-9: Usage of the subscript operator on an object with temporary lifetime shall not return a modifiable value
+ * @description Modifying elements of an array with temporary lifetime will result in undefined
+ * behavior.
+ * @kind problem
+ * @precision high
+ * @problem.severity error
+ * @tags external/misra/id/rule-18-9
+ * external/misra/c/2012/amendment3
+ * correctness
+ * security
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import codingstandards.cpp.lifetimes.CLifetimes
+
+class TemporaryLifetimeArrayExpr extends ArrayExpr {
+ TemporaryLifetimeArrayAccess member;
+ Type elementType;
+
+ TemporaryLifetimeArrayExpr() {
+ member = getArrayBase() and
+ elementType = member.getType().(ArrayType).getBaseType()
+ or
+ exists(TemporaryLifetimeArrayExpr inner |
+ inner = getArrayBase() and
+ member = inner.getMember() and
+ elementType = inner.getElementType().(ArrayType).getBaseType()
+ )
+ }
+
+ TemporaryLifetimeArrayAccess getMember() { result = member }
+
+ Type getElementType() { result = elementType }
+}
+
+predicate usedAsModifiableLvalue(Expr expr) {
+ exists(Assignment parent | parent.getLValue() = expr)
+ or
+ exists(CrementOperation parent | parent.getOperand() = expr)
+ or
+ exists(AddressOfExpr parent | parent.getOperand() = expr)
+ or
+ exists(FieldAccess parent | parent.getQualifier() = expr and usedAsModifiableLvalue(parent))
+}
+
+from TemporaryLifetimeArrayExpr expr, TemporaryLifetimeArrayAccess member
+where
+ not isExcluded(expr,
+ InvalidMemory3Package::modifiableLValueSubscriptedWithTemporaryLifetimeQuery()) and
+ member = expr.getMember() and
+ not expr.isUnevaluated() and
+ usedAsModifiableLvalue(expr)
+select expr,
+ "Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ ",
+ member, member.getTarget().getName(), member.getTemporary(), member.getTemporary().toString()
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..78974ec1fb 100644
--- a/c/misra/src/rules/RULE-19-1/ObjectCopiedToAnOverlappingObject.ql
+++ b/c/misra/src/rules/RULE-19-1/ObjectCopiedToAnOverlappingObject.ql
@@ -7,13 +7,14 @@
* @problem.severity error
* @tags external/misra/id/rule-19-1
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
import cpp
import codingstandards.c.misra
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* Offset in bytes of a field access
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 6ea7aa0a13..fc87186d3e 100644
--- a/c/misra/src/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.ql
+++ b/c/misra/src/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.ql
@@ -8,19 +8,16 @@
* @problem.severity warning
* @tags external/misra/id/rule-20-11
* correctness
+ * 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.rules.macroparameterfollowinghash.MacroParameterFollowingHash
-from Macro m
-where
- not isExcluded(m, Preprocessor2Package::moreThanOneHashOperatorInMacroDefinitionQuery()) and
- exists(StringizingOperator one, TokenPastingOperator two |
- one.getMacro() = m and
- two.getMacro() = m and
- one.getOffset() < two.getOffset()
- )
-select m, "Macro definition uses an # operator followed by a ## operator."
+class MoreThanOneHashOperatorInMacroDefinitionQuery extends MacroParameterFollowingHashSharedQuery {
+ MoreThanOneHashOperatorInMacroDefinitionQuery() {
+ this = Preprocessor2Package::moreThanOneHashOperatorInMacroDefinitionQuery()
+ }
+}
diff --git a/c/misra/src/rules/RULE-20-12/MacroParameterUsedAsHashOperand.ql b/c/misra/src/rules/RULE-20-12/MacroParameterUsedAsHashOperand.ql
index 6a66afb74b..da66f66fb2 100644
--- a/c/misra/src/rules/RULE-20-12/MacroParameterUsedAsHashOperand.ql
+++ b/c/misra/src/rules/RULE-20-12/MacroParameterUsedAsHashOperand.ql
@@ -10,27 +10,17 @@
* @tags external/misra/id/rule-20-12
* 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.rules.amixedusemacroargumentsubjecttoexpansion.AMixedUseMacroArgumentSubjectToExpansion
-from FunctionLikeMacro m, MacroInvocation mi, int i, string expanded, string param
-where
- not isExcluded(mi, Preprocessor2Package::macroParameterUsedAsHashOperandQuery()) and
- mi = m.getAnInvocation() and
- param = m.getParameter(i) and
- (
- exists(TokenPastingOperator op | op.getMacro() = m and op.getOperand() = param)
- or
- exists(StringizingOperator op | op.getMacro() = m and op.getOperand() = param)
- ) and
- // An expansion that is equal to "" means the expansion is not used and is optimized away by EDG. This happens when the expanded argument is an operand to `#` or `##`.
- // This check ensure there is an expansion that is used.
- expanded = mi.getExpandedArgument(i) and
- not expanded = "" and
- not mi.getUnexpandedArgument(i) = mi.getExpandedArgument(i)
-select m,
- "Macro " + m.getName() + " contains use of parameter " + param + " used in multiple contexts."
+class MacroParameterUsedAsHashOperandQuery extends AMixedUseMacroArgumentSubjectToExpansionSharedQuery
+{
+ MacroParameterUsedAsHashOperandQuery() {
+ this = Preprocessor2Package::macroParameterUsedAsHashOperandQuery()
+ }
+}
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..b487f5b9b5 100644
--- a/c/misra/src/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.ql
+++ b/c/misra/src/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.ql
@@ -9,13 +9,14 @@
* @tags external/misra/id/rule-21-14
* maintainability
* correctness
+ * 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.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import NullTerminatedStringToMemcmpFlow::PathGraph
// Data flow from a StringLiteral or from an array of characters, to a memcmp call
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 f834201cbd..ce781403b1 100644
--- a/c/misra/src/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.ql
+++ b/c/misra/src/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.ql
@@ -8,18 +8,16 @@
* @problem.severity error
* @tags external/misra/id/rule-21-7
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.rules.atofatoiatolandatollused.AtofAtoiAtolAndAtollUsed
-private string atoi() { result = ["atof", "atoi", "atol", "atoll"] }
-
-from FunctionCall fc, Function f
-where
- not isExcluded(fc, BannedPackage::atofAtoiAtolAndAtollOfStdlibhUsedQuery()) and
- f = fc.getTarget() and
- f.getName() = atoi() and
- f.getFile().getBaseName() = "stdlib.h"
-select fc, "Call to banned function " + f.getName() + "."
+class AtofAtoiAtolAndAtollOfStdlibhUsedQuery extends AtofAtoiAtolAndAtollUsedSharedQuery {
+ AtofAtoiAtolAndAtollOfStdlibhUsedQuery() {
+ this = BannedPackage::atofAtoiAtolAndAtollOfStdlibhUsedQuery()
+ }
+}
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..642813bbab 100644
--- a/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql
+++ b/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql
@@ -8,13 +8,14 @@
* @problem.severity error
* @tags external/misra/id/rule-22-3
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
import codingstandards.cpp.standardlibrary.FileAccess
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.controlflow.SubBasicBlocks
diff --git a/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql b/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql
index 6dc3b3ee71..2439d4ca47 100644
--- a/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql
+++ b/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql
@@ -7,13 +7,14 @@
* @problem.severity error
* @tags external/misra/id/rule-22-4
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/mandatory
*/
import cpp
import codingstandards.c.misra
import codingstandards.cpp.standardlibrary.FileAccess
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
module FileDFConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
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 a7fdf080a7..0f04a7362b 100644
--- a/c/misra/src/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.ql
+++ b/c/misra/src/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.ql
@@ -10,39 +10,17 @@
* maintainability
* readability
* correctness
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.rules.nonterminatedescapesequences.NonTerminatedEscapeSequences
-bindingset[s]
-predicate isOctalEscape(string s) {
- s.charAt(0) = "\\" and
- exists(int i | i = [0 .. 7] | i.toString() = s.charAt(1))
+class OctalAndHexadecimalEscapeSequencesNotTerminatedQuery extends NonTerminatedEscapeSequencesSharedQuery
+{
+ OctalAndHexadecimalEscapeSequencesNotTerminatedQuery() {
+ this = SyntaxPackage::octalAndHexadecimalEscapeSequencesNotTerminatedQuery()
+ }
}
-
-bindingset[s]
-predicate isHexEscape(string s) { s.indexOf("\\x") = 0 }
-
-from Literal l, string escapeKind, string s
-where
- not isExcluded(l, SyntaxPackage::octalAndHexadecimalEscapeSequencesNotTerminatedQuery()) and
- exists(int idx, string sl |
- sl = l.getValueText() and
- idx = sl.indexOf("\\") and
- s = sl.substring(idx, sl.length()) and
- // Note: Octal representations must be 1-3 digits. There is no limitation on a
- // Hex literal as long as the characters are valid. This query does not consider
- // if the hex literal being constructed will overflow.
- (
- isHexEscape(s) and
- not s.regexpMatch("^((\\\\x[0-9A-F]+(?=[\"'\\\\])))[\\s\\S]*") and
- escapeKind = "hexadecimal"
- or
- isOctalEscape(s) and
- not s.regexpMatch("^(((\\\\[0-7]{1,3})(?=[\"'\\\\])))[\\s\\S]*") and
- escapeKind = "octal"
- )
- )
-select l, "Invalid " + escapeKind + " escape in string literal at '" + s + "'."
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 fce1d9ad1a..078c2c48b7 100644
--- a/c/misra/src/rules/RULE-6-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.ql
+++ b/c/misra/src/rules/RULE-6-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.ql
@@ -7,38 +7,17 @@
* @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
*/
import cpp
import codingstandards.c.misra
-import codingstandards.cpp.Compiler
+import codingstandards.cpp.rules.bitfieldshallhaveanappropriatetype.BitFieldShallHaveAnAppropriateType
-Type getSupportedBitFieldType(Compiler compiler) {
- compiler instanceof UnsupportedCompiler and
- (
- result instanceof IntType and
- (
- result.(IntegralType).isExplicitlySigned() or
- result.(IntegralType).isExplicitlyUnsigned()
- )
- or
- result instanceof BoolType
- )
- or
- (compiler instanceof Gcc or compiler instanceof Clang) and
- (
- result instanceof IntegralOrEnumType
- or
- result instanceof BoolType
- )
+class BitFieldsShallOnlyBeDeclaredWithAnAppropriateTypeQuery extends BitFieldShallHaveAnAppropriateTypeSharedQuery
+{
+ BitFieldsShallOnlyBeDeclaredWithAnAppropriateTypeQuery() {
+ this = BitfieldTypesPackage::bitFieldsShallOnlyBeDeclaredWithAnAppropriateTypeQuery()
+ }
}
-
-from BitField bitField
-where
- not isExcluded(bitField,
- BitfieldTypesPackage::bitFieldsShallOnlyBeDeclaredWithAnAppropriateTypeQuery()) and
- /* A violation would neither be an appropriate primitive type nor an appropriate typedef. */
- not getSupportedBitFieldType(getCompiler(bitField.getFile())) =
- bitField.getType().resolveTypedefs()
-select bitField, "Bit-field '" + bitField + "' is declared on type '" + bitField.getType() + "'."
diff --git a/c/misra/src/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql b/c/misra/src/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql
index d4be3d6dd2..142a0b542d 100644
--- a/c/misra/src/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql
+++ b/c/misra/src/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql
@@ -7,28 +7,17 @@
* @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
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.rules.namedbitfieldswithsignedintegertype.NamedBitFieldsWithSignedIntegerType
-/*
- * Check if the DECLARED bit-fields is a single bit, because Rule 6.2 also intends to catch confusion on the programmers' part. Consider:
- *
- * struct S {
- * int32_t x: 1;
- * }
- *
- * In this case, field x is essentially of 32 bits, but is declared as 1 bit and its type int32_t is signed. Therefore, it indicates confusion by the programmer, which is exactly what this rule intends to find.
- */
-
-from BitField bitField
-where
- not isExcluded(bitField, BitfieldTypesPackage::singleBitNamedBitFieldsOfASignedTypeQuery()) and
- bitField.getDeclaredNumBits() = 1 and // Single-bit,
- not bitField.isAnonymous() and // named,
- bitField.getType().(IntegralType).isSigned() // but its type is signed.
-select bitField,
- "Single-bit bit-field named " + bitField.toString() + " has a signed type " + bitField.getType() +
- "."
+class SingleBitNamedBitFieldsOfASignedTypeQuery extends NamedBitFieldsWithSignedIntegerTypeSharedQuery
+{
+ SingleBitNamedBitFieldsOfASignedTypeQuery() {
+ this = BitfieldTypesPackage::singleBitNamedBitFieldsOfASignedTypeQuery()
+ }
+}
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 4fc257578b..0b38b26eea 100644
--- a/c/misra/src/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.ql
+++ b/c/misra/src/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.ql
@@ -9,12 +9,13 @@
* @tags external/misra/id/rule-7-3
* maintainability
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
-import codingstandards.c.Literals
+import codingstandards.cpp.Literals
from IntegerLiteral l
where
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 0772da9b05..6ebabc3810 100644
--- a/c/misra/src/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.ql
+++ b/c/misra/src/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.ql
@@ -9,30 +9,17 @@
* @tags external/misra/id/rule-8-12
* correctness
* readability
+ * external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
+import codingstandards.cpp.rules.nonuniqueenumerationconstant.NonUniqueEnumerationConstant
-/**
- * An `EnumConstant` that has an implicitly specified value:
- * `enum e { explicit = 1, implicit }`
- */
-class ImplicitlySpecifiedEnumConstant extends EnumConstant {
- ImplicitlySpecifiedEnumConstant() {
- //implicitly specified have an initializer with location: `file://:0:0:0:0`
- not this.getInitializer().getLocation().getFile() = this.getFile()
+class ValueImplicitEnumerationConstantNotUniqueQuery extends NonUniqueEnumerationConstantSharedQuery
+{
+ ValueImplicitEnumerationConstantNotUniqueQuery() {
+ this = Declarations7Package::valueImplicitEnumerationConstantNotUniqueQuery()
}
}
-
-from EnumConstant exp, ImplicitlySpecifiedEnumConstant imp
-where
- not isExcluded(exp, Declarations7Package::valueImplicitEnumerationConstantNotUniqueQuery()) and
- not isExcluded(imp, Declarations7Package::valueImplicitEnumerationConstantNotUniqueQuery()) and
- not exp = imp and
- imp.getValue() = exp.getValue() and
- imp.getDeclaringEnum() = exp.getDeclaringEnum() and
- //can technically be the same declared enum across multiple headers but those are not relevant to this rule
- imp.getFile() = exp.getFile()
-select imp, "Nonunique value of enum constant compared to $@", exp, exp.getName()
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-15/RedeclarationOfObjectWithUnmatchedAlignment.ql b/c/misra/src/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.ql
new file mode 100644
index 0000000000..dc82f63d10
--- /dev/null
+++ b/c/misra/src/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.ql
@@ -0,0 +1,36 @@
+/**
+ * @id c/misra/redeclaration-of-object-with-unmatched-alignment
+ * @name RULE-8-15: Alignment should match between all declarations of an object
+ * @description All declarations of an object with an explicit alignment specification shall specify
+ * the same alignment.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-8-15
+ * external/misra/c/2012/amendment3
+ * readability
+ * maintainability
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+import semmle.code.cpp.valuenumbering.HashCons
+
+predicate lexicallyEqual(AttributeArgument a, AttributeArgument b) {
+ hashCons(a.getValueConstant()) = hashCons(b.getValueConstant()) or
+ a.getValueType() = b.getValueType()
+}
+
+from Attribute alignment, Attribute mismatched, string variable
+where
+ not isExcluded(alignment, AlignmentPackage::redeclarationOfObjectWithUnmatchedAlignmentQuery()) and
+ alignment.hasName("_Alignas") and
+ mismatched.hasName("_Alignas") and
+ exists(Variable v |
+ v.getAnAttribute() = alignment and v.getAnAttribute() = mismatched and v.getName() = variable
+ ) and
+ not lexicallyEqual(alignment.getArgument(0), mismatched.getArgument(0))
+select alignment,
+ "Variable " + variable + " declared with lexically different _Alignof() values '$@' and '$@'.",
+ alignment, alignment.getArgument(0).toString(), mismatched, mismatched.getArgument(0).toString()
diff --git a/c/misra/src/rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.ql b/c/misra/src/rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.ql
new file mode 100644
index 0000000000..df9f3f2d1c
--- /dev/null
+++ b/c/misra/src/rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.ql
@@ -0,0 +1,96 @@
+/**
+ * @id c/misra/redeclaration-of-object-without-alignment
+ * @name RULE-8-15: Alignment should match between all declarations of an object
+ * @description An object declared with an explicit alignment shall be explicitly aligned in all
+ * declarations.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-8-15
+ * external/misra/c/2012/amendment3
+ * readability
+ * maintainability
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.c.misra
+
+/**
+ * Performance optimization; start query by joining attributes to declarations
+ * rather than locations.
+ *
+ * Including the entry location also speeds up search.
+ */
+newtype TAttributeDeclLocation =
+ TAttributeDeclLocationInfo(Attribute attribute, DeclarationEntry entry, Location entryLocation) {
+ entry.getDeclaration().(Variable).getAnAttribute() = attribute and
+ entryLocation = entry.getLocation()
+ }
+
+/**
+ * Get a DeclarationEntry along with its explicitly declared Attributes.
+ *
+ * DeclarationEntry does not have a method for getting Attributes by default,
+ * because an attribute declared on any DeclarationEntry affects all others,
+ * and attributes really belong to the declared variable rather than the
+ * declaration itself.
+ *
+ * In order to support this rule, we find for each attribute
+ * - A declaration entry which
+ * - corresponds to a variable associated with this attribute
+ * - is in the same file as this attribute
+ * - has identifier location after the attribute declaration
+ * - has no other declaration entry between this one and the attribute.
+ *
+ * This should give us a highly reliable means of finding which attributes are
+ * associated with which `DeclarationEntry`s.
+ *
+ * One note of caution: the location of the associated `Variable` must be
+ * treated with caution, as calls to `getLocation()` on a redeclared `Variable`
+ * can return multiple results. This class must act on `DeclarationEntry`s to
+ * deliver reliable results.
+ */
+class DeclarationEntryAttribute extends Attribute {
+ DeclarationEntry declarationEntry;
+ Location location;
+ Location declLocation;
+ File file;
+ TAttributeDeclLocation locInfo;
+
+ DeclarationEntryAttribute() {
+ locInfo = TAttributeDeclLocationInfo(this, declarationEntry, declLocation) and
+ file = getFile() and
+ location = getLocation() and
+ declLocation = declarationEntry.getLocation() and
+ declarationEntry.getDeclaration().(Variable).getAnAttribute() = this and
+ declarationEntry.getFile() = file and
+ location.isBefore(declLocation, _) and
+ not exists(TAttributeDeclLocation blocInfo, DeclarationEntry betterFit, Location blocation |
+ blocInfo = TAttributeDeclLocationInfo(this, betterFit, blocation) and
+ not betterFit = declarationEntry and
+ blocation = betterFit.getLocation() and
+ betterFit.getFile() = file and
+ betterFit.getDeclaration() = declarationEntry.getDeclaration() and
+ blocation.isBefore(declLocation, _) and
+ location.isBefore(blocation, _)
+ )
+ }
+
+ DeclarationEntry getDeclarationEntry() { result = declarationEntry }
+}
+
+from DeclarationEntry unaligned, DeclarationEntry aligned, DeclarationEntryAttribute attribute
+where
+ not isExcluded(unaligned, AlignmentPackage::redeclarationOfObjectWithoutAlignmentQuery()) and
+ attribute.hasName("_Alignas") and
+ attribute.getDeclarationEntry() = aligned and
+ aligned.getDeclaration() = unaligned.getDeclaration() and
+ not exists(DeclarationEntryAttribute matchingAlignment |
+ matchingAlignment.hasName("_Alignas") and
+ matchingAlignment.getDeclarationEntry() = unaligned
+ )
+select unaligned,
+ "Variable " + unaligned.getName() +
+ " declared without explicit alignment to match $@ with alignment $@.", aligned,
+ "other definition", attribute, attribute.toString()
diff --git a/c/misra/src/rules/RULE-8-16/AlignmentWithSizeZero.ql b/c/misra/src/rules/RULE-8-16/AlignmentWithSizeZero.ql
new file mode 100644
index 0000000000..4a0cd9d50b
--- /dev/null
+++ b/c/misra/src/rules/RULE-8-16/AlignmentWithSizeZero.ql
@@ -0,0 +1,24 @@
+/**
+ * @id c/misra/alignment-with-size-zero
+ * @name RULE-8-16: The alignment specification of zero should not appear in an object declaration
+ * @description A declaration shall not have an alignment of size zero.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-8-16
+ * external/misra/c/2012/amendment3
+ * readability
+ * maintainability
+ * external/misra/obligation/advisory
+ */
+
+import cpp
+import codingstandards.c.misra
+
+from Attribute a, Variable v
+where
+ not isExcluded(a, AlignmentPackage::alignmentWithSizeZeroQuery()) and
+ a.hasName("_Alignas") and
+ a.getArgument(0).getValueInt() = 0 and
+ v.getAnAttribute() = a
+select a.getArgument(0), "Invalid alignof() size set to zero for variable $@.", v, v.getName()
diff --git a/c/misra/src/rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.ql b/c/misra/src/rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.ql
new file mode 100644
index 0000000000..f4e0d93d92
--- /dev/null
+++ b/c/misra/src/rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.ql
@@ -0,0 +1,38 @@
+/**
+ * @id c/misra/more-than-one-alignment-specifier-on-declaration
+ * @name RULE-8-17: At most one explicit alignment specifier should appear in an object declaration
+ * @description While C permits the usage of multiple alignment specifiers, doing so reduces
+ * readability and may obscure the intent of the declaration.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-8-17
+ * external/misra/c/2012/amendment3
+ * readability
+ * external/misra/obligation/advisory
+ */
+
+import cpp
+import codingstandards.c.misra
+
+from Variable v, Attribute first, Attribute last
+where
+ not isExcluded(v, AlignmentPackage::moreThanOneAlignmentSpecifierOnDeclarationQuery()) and
+ first = v.getAnAttribute() and
+ last = v.getAnAttribute() and
+ not first = last and
+ first.hasName("_Alignas") and
+ last.hasName("_Alignas") and
+ // Handle double reporting: the first Attribute should really be first, and the last Attribute
+ // should really be last. This implies the first is before the last. This approach also ensures
+ // a single result for variables that have more than two alignment specifiers.
+ not exists(Attribute beforeFirst |
+ beforeFirst.getLocation().isBefore(first.getLocation(), _) and
+ v.getAnAttribute() = beforeFirst
+ ) and
+ not exists(Attribute afterLast |
+ last.getLocation().isBefore(afterLast.getLocation(), _) and
+ v.getAnAttribute() = afterLast
+ )
+select v, "Variable " + v.getName() + " contains more than one alignment specifier, $@ and $@",
+ first, first.toString(), last, last.toString()
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..910a6e060e 100644
--- a/c/misra/test/codeql-pack.lock.yml
+++ b/c/misra/test/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/c/misra/test/qlpack.yml b/c/misra/test/qlpack.yml
index efe05e7d75..d53bc95f28 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.40.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/c/misra/test/rules/DIR-4-2/UsageOfAssemblyLanguageShouldBeDocumented.testref b/c/misra/test/rules/DIR-4-2/UsageOfAssemblyLanguageShouldBeDocumented.testref
index ea9ce384ea..3b0dc2fe5a 100644
--- a/c/misra/test/rules/DIR-4-2/UsageOfAssemblyLanguageShouldBeDocumented.testref
+++ b/c/misra/test/rules/DIR-4-2/UsageOfAssemblyLanguageShouldBeDocumented.testref
@@ -1 +1 @@
-cpp/common/test/rules/usageofassemblernotdocumented/UsageOfAssemblerNotDocumented.ql
\ No newline at end of file
+c/common/test/rules/usageofassemblernotdocumented/UsageOfAssemblerNotDocumented.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/DIR-4-4/SectionsOfCodeShallNotBeCommentedOut.testref b/c/misra/test/rules/DIR-4-4/SectionsOfCodeShallNotBeCommentedOut.testref
index 303a38a19b..4460b5ed53 100644
--- a/c/misra/test/rules/DIR-4-4/SectionsOfCodeShallNotBeCommentedOut.testref
+++ b/c/misra/test/rules/DIR-4-4/SectionsOfCodeShallNotBeCommentedOut.testref
@@ -1 +1 @@
-cpp/common/test/rules/sectionsofcodeshallnotbecommentedout/SectionsOfCodeShallNotBeCommentedOut.ql
\ No newline at end of file
+c/common/test/rules/sectionsofcodeshallnotbecommentedout/SectionsOfCodeShallNotBeCommentedOut.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/DIR-4-5/IdentifiersInTheSameNameSpaceUnambiguous.testref b/c/misra/test/rules/DIR-4-5/IdentifiersInTheSameNameSpaceUnambiguous.testref
index dffdbb26b8..2dc788dd11 100644
--- a/c/misra/test/rules/DIR-4-5/IdentifiersInTheSameNameSpaceUnambiguous.testref
+++ b/c/misra/test/rules/DIR-4-5/IdentifiersInTheSameNameSpaceUnambiguous.testref
@@ -1 +1 @@
-cpp/common/test/rules/differentidentifiersnottypographicallyunambiguous/DifferentIdentifiersNotTypographicallyUnambiguous.ql
\ No newline at end of file
+c/common/test/rules/differentidentifiersnottypographicallyunambiguous/DifferentIdentifiersNotTypographicallyUnambiguous.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/DIR-4-9/FunctionOverFunctionLikeMacro.testref b/c/misra/test/rules/DIR-4-9/FunctionOverFunctionLikeMacro.testref
new file mode 100644
index 0000000000..fb033c44e4
--- /dev/null
+++ b/c/misra/test/rules/DIR-4-9/FunctionOverFunctionLikeMacro.testref
@@ -0,0 +1 @@
+c/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.ql
\ No newline at end of file
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..fb8d44ea19
--- /dev/null
+++ b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected
@@ -0,0 +1,10 @@
+edges
+| test.c:39:16:39:20 | *call to fopen | test.c:39:16:39:20 | *call to fopen | provenance | |
+| 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: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-13-2/UnsequencedSideEffects.expected b/c/misra/test/rules/RULE-13-2/UnsequencedSideEffects.expected
index 17b89c2f01..75bd8169ba 100644
--- a/c/misra/test/rules/RULE-13-2/UnsequencedSideEffects.expected
+++ b/c/misra/test/rules/RULE-13-2/UnsequencedSideEffects.expected
@@ -3,4 +3,4 @@
| test.c:17:3:17:21 | ... = ... | The expression contains unsequenced $@ to $@ and $@ to $@. | test.c:17:8:17:9 | l1 | side effect | test.c:17:8:17:9 | l1 | l1 | test.c:17:13:17:14 | l1 | side effect | test.c:17:13:17:14 | l1 | l1 |
| test.c:19:3:19:5 | call to foo | The expression contains unsequenced $@ to $@ and $@ to $@. | test.c:19:7:19:8 | l1 | side effect | test.c:19:7:19:8 | l1 | l1 | test.c:19:11:19:12 | l2 | side effect | test.c:19:11:19:12 | l2 | l2 |
| test.c:25:3:25:5 | call to foo | The expression contains unsequenced $@ to $@ and $@ to $@. | test.c:25:7:25:10 | ... ++ | side effect | test.c:25:7:25:8 | l8 | l8 | test.c:25:13:25:14 | l8 | read | test.c:25:13:25:14 | l8 | l8 |
-| test.c:35:5:35:13 | ... = ... | The expression contains unsequenced $@ to $@ and $@ to $@. | test.c:35:10:35:12 | ... ++ | side effect | test.c:35:10:35:10 | i | i | test.c:35:10:35:12 | ... ++ | side effect | test.c:35:10:35:10 | i | i |
+| test.c:35:5:35:13 | ... = ... | The expression contains unsequenced $@ to $@ and $@ to $@. | test.c:35:10:35:12 | ... ++ | side effect | test.c:35:10:35:10 | i | i | test.c:35:10:35:12 | ... ++ | side effect | test.c:35:10:35:10 | i | i |
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.expected b/c/misra/test/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.expected
deleted file mode 100644
index 57f90043e1..0000000000
--- a/c/misra/test/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-| test.c:7:7:7:12 | ... = ... | Use of an assignment operator's result. |
-| test.c:11:11:11:16 | ... = ... | Use of an assignment operator's result. |
-| test.c:13:8:13:13 | ... = ... | Use of an assignment operator's result. |
diff --git a/c/misra/test/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.qlref b/c/misra/test/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.qlref
deleted file mode 100644
index 16d027d915..0000000000
--- a/c/misra/test/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.testref b/c/misra/test/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.testref
new file mode 100644
index 0000000000..41e225624c
--- /dev/null
+++ b/c/misra/test/rules/RULE-13-4/ResultOfAnAssignmentOperatorShouldNotBeUsed.testref
@@ -0,0 +1 @@
+c/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-15-1/GotoStatementUsed.expected b/c/misra/test/rules/RULE-15-1/GotoStatementUsed.expected
deleted file mode 100644
index 7e06759159..0000000000
--- a/c/misra/test/rules/RULE-15-1/GotoStatementUsed.expected
+++ /dev/null
@@ -1 +0,0 @@
-| test.c:4:3:4:14 | goto ... | Use of goto. |
diff --git a/c/misra/test/rules/RULE-15-1/GotoStatementUsed.qlref b/c/misra/test/rules/RULE-15-1/GotoStatementUsed.qlref
deleted file mode 100644
index 338455d28f..0000000000
--- a/c/misra/test/rules/RULE-15-1/GotoStatementUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-15-1/GotoStatementUsed.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-15-1/GotoStatementUsed.testref b/c/misra/test/rules/RULE-15-1/GotoStatementUsed.testref
new file mode 100644
index 0000000000..1834c6e140
--- /dev/null
+++ b/c/misra/test/rules/RULE-15-1/GotoStatementUsed.testref
@@ -0,0 +1 @@
+c/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-15-1/test.c b/c/misra/test/rules/RULE-15-1/test.c
deleted file mode 100644
index d13f01961c..0000000000
--- a/c/misra/test/rules/RULE-15-1/test.c
+++ /dev/null
@@ -1,9 +0,0 @@
-void test_goto() {
- int x = 1;
-
- goto label1; // NON_COMPLIANT
-
-label1:
-
- x = 2;
-}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-15-3/GotoLabelBlockCondition.expected b/c/misra/test/rules/RULE-15-3/GotoLabelBlockCondition.expected
deleted file mode 100644
index 730403cbd7..0000000000
--- a/c/misra/test/rules/RULE-15-3/GotoLabelBlockCondition.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-| test.c:2:3:2:10 | goto ... | The $@ statement and its $@ are not declared or enclosed in the same block. | test.c:2:3:2:10 | goto ... | goto | test.c:4:3:4:5 | label ...: | label |
-| test.c:40:3:40:10 | goto ... | The $@ statement and its $@ are not declared or enclosed in the same block. | test.c:40:3:40:10 | goto ... | goto | test.c:44:3:44:5 | label ...: | label |
-| test.c:55:5:55:12 | goto ... | The $@ statement and its $@ are not declared or enclosed in the same block. | test.c:55:5:55:12 | goto ... | goto | test.c:58:3:58:5 | label ...: | label |
diff --git a/c/misra/test/rules/RULE-15-3/GotoLabelBlockCondition.qlref b/c/misra/test/rules/RULE-15-3/GotoLabelBlockCondition.qlref
deleted file mode 100644
index 5f430f0790..0000000000
--- a/c/misra/test/rules/RULE-15-3/GotoLabelBlockCondition.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-15-3/GotoLabelBlockCondition.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-15-3/GotoLabelBlockCondition.testref b/c/misra/test/rules/RULE-15-3/GotoLabelBlockCondition.testref
new file mode 100644
index 0000000000..cf558d9350
--- /dev/null
+++ b/c/misra/test/rules/RULE-15-3/GotoLabelBlockCondition.testref
@@ -0,0 +1 @@
+c/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.ql
\ 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-5/ArrayFunctionArgumentNumberOfElements.expected b/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected
index 913f6f1c34..174c6aa40f 100644
--- a/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected
+++ b/c/misra/test/rules/RULE-17-5/ArrayFunctionArgumentNumberOfElements.expected
@@ -1,3 +1,9 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ArrayFunctionArgumentNumberOfElements.ql:48,36-44)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ArrayFunctionArgumentNumberOfElements.ql:49,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ArrayFunctionArgumentNumberOfElements.ql:51,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ArrayFunctionArgumentNumberOfElements.ql:56,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ArrayFunctionArgumentNumberOfElements.ql:72,28-36)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ArrayFunctionArgumentNumberOfElements.ql:72,51-59)
| test.c:18:6:18:6 | 0 | The function argument does not have a sufficient number or elements declared in the $@. | test.c:1:13:1:14 | ar | parameter |
| test.c:19:6:19:7 | ar | The function argument does not have a sufficient number or elements declared in the $@. | test.c:1:13:1:14 | ar | parameter |
| test.c:21:6:21:9 | ar2p | The function argument does not have a sufficient number or elements declared in the $@. | test.c:1:13:1:14 | ar | parameter |
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-18-10/PointersToVariablyModifiedArrayTypesUsed.expected b/c/misra/test/rules/RULE-18-10/PointersToVariablyModifiedArrayTypesUsed.expected
new file mode 100644
index 0000000000..76b3da5eb0
--- /dev/null
+++ b/c/misra/test/rules/RULE-18-10/PointersToVariablyModifiedArrayTypesUsed.expected
@@ -0,0 +1,17 @@
+| test.c:17:11:17:12 | definition of p5 | Parameter p5 is declared with variably-modified type, pointer to variable length array of non constant size $@ and element type 'int' | test.c:17:15:17:16 | p0 | p0 |
+| test.c:18:11:18:12 | definition of p6 | Parameter p6 is declared with variably-modified type, with inner variable length array of non constant size $@ and element type 'int' | test.c:18:18:18:19 | p0 | p0 |
+| test.c:19:11:19:12 | definition of p7 | Parameter p7 is declared with variably-modified type, pointer to variable length array of non constant size $@ and element type 'int[2]' | test.c:19:15:19:16 | p0 | p0 |
+| test.c:20:11:20:12 | definition of p8 | Parameter p8 is declared with variably-modified type, pointer to variable length array of non constant size $@ and element type 'int[]' | test.c:20:15:20:16 | p0 | p0 |
+| test.c:20:11:20:12 | definition of p8 | Parameter p8 is declared with variably-modified type, pointer to variable length array of non constant size $@ and element type 'int[]' | test.c:20:19:20:20 | p0 | p0 |
+| test.c:24:12:24:13 | definition of p9 | Parameter p9 is declared with variably-modified type, pointer to variable length array of non constant size $@ and element type 'int *' | test.c:24:16:24:17 | p0 | p0 |
+| test.c:25:13:25:15 | definition of p10 | Parameter p10 is declared with variably-modified type, with inner variable length array of non constant size $@ and element type 'int *' | test.c:25:18:25:19 | p0 | p0 |
+| test.c:28:12:28:14 | definition of p11 | Parameter p11 is adjusted to variably-modified type, with inner variable length array of non constant size $@ and element type 'int' | test.c:28:21:28:22 | p0 | p0 |
+| test.c:32:17:32:19 | definition of p13 | Parameter p13 is declared with variably-modified type, pointer to variable length array of non constant size $@ and element type 'const int' | test.c:32:22:32:23 | p0 | p0 |
+| test.c:33:17:33:19 | definition of p14 | Parameter p14 is declared with variably-modified type, with inner variable length array of non constant size $@ and element type 'int' | test.c:33:22:33:23 | p0 | p0 |
+| test.c:40:12:40:14 | definition of p17 | Parameter p17 is declared with variably-modified type, with inner variable length array of non constant size $@ and element type 'int' | test.c:40:24:40:25 | p0 | p0 |
+| test.c:41:14:41:16 | definition of p18 | Parameter p18 is declared with variably-modified type, with inner variable length array of non constant size $@ and element type 'int' | test.c:41:27:41:28 | p0 | p0 |
+| test.c:68:9:68:11 | definition of p27 | Parameter p27 is adjusted to variably-modified type, with inner variable length array of non constant size $@ and element type 'int' | test.c:68:13:68:14 | p0 | p0 |
+| test.c:68:9:68:11 | definition of p27 | Parameter p27 is adjusted to variably-modified type, with inner variable length array of non constant size $@ and element type 'int' | test.c:68:17:68:18 | p0 | p0 |
+| test.c:74:8:74:9 | definition of l3 | Variable l3 is declared with variably-modified type, pointer to variable length array of non constant size $@ and element type 'int' | test.c:74:12:74:13 | p0 | p0 |
+| test.c:79:15:79:16 | definition of l4 | Variable l4 is declared with variably-modified type, pointer to variable length array of non constant size $@ and element type 'int' | test.c:79:19:79:20 | p0 | p0 |
+| test.c:84:16:84:18 | declaration of td3 | Declaration td3 is declared with variably-modified type, with inner variable length array of non constant size $@ and element type 'int' | test.c:84:21:84:22 | p0 | p0 |
diff --git a/c/misra/test/rules/RULE-18-10/PointersToVariablyModifiedArrayTypesUsed.qlref b/c/misra/test/rules/RULE-18-10/PointersToVariablyModifiedArrayTypesUsed.qlref
new file mode 100644
index 0000000000..1a60cfacca
--- /dev/null
+++ b/c/misra/test/rules/RULE-18-10/PointersToVariablyModifiedArrayTypesUsed.qlref
@@ -0,0 +1 @@
+rules/RULE-18-10/PointersToVariablyModifiedArrayTypesUsed.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-18-10/test.c b/c/misra/test/rules/RULE-18-10/test.c
new file mode 100644
index 0000000000..645943733d
--- /dev/null
+++ b/c/misra/test/rules/RULE-18-10/test.c
@@ -0,0 +1,106 @@
+#define CONSTANT 1
+
+int g1[3]; // COMPLIANT
+int (*g2)[3]; // COMPLIANT
+int (*g3)[CONSTANT]; // COMPLIANT
+
+void f1(
+ int p0,
+
+ // Basic fixed length array types:
+ int p1[3], // COMPLIANT
+ int (*p2)[3], // COMPLIANT
+ int (*p3)[2][3], // COMPLIANT
+ int (*p4)[CONSTANT], // COMPLIANT
+
+ // Basic pointers to VMTs:
+ int (*p5)[p0], // NON-COMPLIANT
+ int (*p6)[2][p0], // NON-COMPLIANT
+ int (*p7)[p0][2], // NON-COMPLIANT
+ int (*p8)[p0][p0], // NON-COMPLIANT
+
+ // Types referring to pointers to VMTs:
+ // - pointer to pointer to VMT
+ int(*(*p9)[p0]), // NON-COMPLIANT
+ int(*(**p10)[p0]), // NON-COMPLIANT
+
+ // - array of pointers to VMT
+ int (*(p11[3]))[p0], // NON-COMPLIANT
+
+ // - const VMTs, const array-to-pointer adjustment
+ const int p12[p0], // COMPLIANT
+ const int (*p13)[p0], // NON-COMPLIANT
+ int (*const p14)[p0], // NON-COMPLIANT
+
+ // - function types with argument that is a pointer to a VMT
+ int p15(int (*inner)[p0]), // NON-COMPLIANT[FALSE_NEGATIVE]
+ int (*p16)(int (*inner)[p0]), // NON-COMPLIANT[FALSE_NEGATIVE]
+
+ // - function types that returns a pointer to a VMT
+ int (*(p17(void)))[p0], // NON-COMPLIANT
+ int (*((*p18)(void)))[p0], // NON-COMPLIANT
+
+ // - structs cannot contain a VMT as a member.
+ struct {
+ int g1[3]; // COMPLIANT
+ int(*g2)[3]; // COMPLIANT
+ int(*g3)[CONSTANT]; // COMPLIANT
+ // Pointer to VMT (`int (*g4)[p0]`) is not allowed.
+ } p19,
+
+ // - unions cannot contain a VMT as a member.
+ union {
+ int g1[3]; // COMPLIANT
+ int(*g2)[3]; // COMPLIANT
+ int(*g3)[CONSTANT]; // COMPLIANT
+ // Pointer to VMT (`int (*g4)[p0]`) is not allowed.
+ } p20,
+
+ // Unknown array length types:
+ int p21[], // COMPLIANT
+ int p22[][], // COMPLIANT
+ int (*p23)[], // COMPLIANT
+ int (*p24)[2][], // COMPLIANT
+ int (*p25)[][2], // COMPLIANT
+
+ // VLA types that are rewritten as pointers:
+ int p26[p0], // COMPLIANT
+ int p27[p0][p0] // NON-COMPLIANT
+) {
+ // Local variables may contain pointers to VMTs:
+ int l0[p0]; // COMPLIANT
+ int(*l1)[]; // COMPLIANT
+ int(*l2)[3]; // COMPLIANT
+ int(*l3)[p0]; // NON-COMPLIANT
+
+ int l6[10] = p23;
+
+ // A pointer to a VMT may be declared `static`.
+ static int(*l4)[p0]; // NON-COMPLIANT
+
+ // Block scope typedefs may refer to VMTs
+ typedef int(*td1)[3]; // COMPLIANT
+ typedef int(*td2)[]; // COMPLIANT
+ typedef int(*td3)[p0]; // NON-COMPLIANT
+
+ td3 l5; // NON-COMPLIANT
+}
+
+// Function prototypes may contain VMTs using '*' syntax:
+void f2(int (*p1)[3], // COMPLIANT
+ int (*p2)[*], // NON-COMPLIANT[FALSE_NEGATIVE]
+ int (*p3)[2][*], // NON-COMPLIANT[FALSE_NEGATIVE]
+ int (*p4)[*][2], // NON-COMPLIANT[FALSE_NEGATIVE]
+ int (*p5)[*][*] // NON-COMPLIANT[FALSE_NEGATIVE]
+);
+
+#define CONFUSING_MACRO() \
+ int x; \
+ int(*vla)[x]; \
+ int(*not_vla)[];
+
+void f3() {
+ // We cannot report `vla` in this macro without a false positive for
+ // `not_vla`.
+ CONFUSING_MACRO() // COMPLIANT
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-18-8/VariableLengthArrayTypesUsed.expected b/c/misra/test/rules/RULE-18-8/VariableLengthArrayTypesUsed.expected
index e9721ce642..af73daccfd 100644
--- a/c/misra/test/rules/RULE-18-8/VariableLengthArrayTypesUsed.expected
+++ b/c/misra/test/rules/RULE-18-8/VariableLengthArrayTypesUsed.expected
@@ -1,5 +1,8 @@
-| test.c:3:19:3:20 | definition of pa | Variable length array declared. |
-| test.c:6:7:6:8 | definition of a1 | Variable length array declared. |
-| test.c:7:7:7:8 | definition of a2 | Variable length array declared. |
-| test.c:8:7:8:8 | definition of a3 | Variable length array declared. |
-| test.c:14:20:14:21 | definition of pa | Variable length array declared. |
+| test.c:6:7:6:8 | a1 | Variable length array of element type 'int' with non-constant size $@. | test.c:6:10:6:14 | ... + ... | ... + ... |
+| test.c:7:7:7:8 | a2 | Variable length array of element type 'int' with non-constant size $@. | test.c:7:10:7:10 | n | n |
+| test.c:8:7:8:8 | a3 | Variable length array of element type 'int[]' with non-constant size $@. | test.c:8:13:8:13 | n | n |
+| test.c:12:7:12:8 | a7 | Variable length array of element type 'int[1]' with non-constant size $@. | test.c:12:10:12:10 | n | n |
+| test.c:20:14:20:15 | t1 | Variable length array of element type 'int' with non-constant size $@. | test.c:18:26:18:26 | n | n |
+| test.c:21:14:21:15 | t2 | Variable length array of element type 'int' with non-constant size $@. | test.c:18:26:18:26 | n | n |
+| test.c:22:14:22:15 | t3 | Variable length array of element type 'int' with non-constant size $@. | test.c:18:26:18:26 | n | n |
+| test.c:22:14:22:15 | t3 | Variable length array of element type 'vlaTypedef' with non-constant size $@. | test.c:22:17:22:17 | x | x |
diff --git a/c/misra/test/rules/RULE-18-8/test.c b/c/misra/test/rules/RULE-18-8/test.c
index 3a0a040f6d..e6e038049c 100644
--- a/c/misra/test/rules/RULE-18-8/test.c
+++ b/c/misra/test/rules/RULE-18-8/test.c
@@ -1,7 +1,7 @@
#define TEST 1
-void f(int n, int pa[1][n]) { // NON_COMPLIANT
- int a[1]; // COMPLIANT
+void f(int n) {
+ int a[1]; // COMPLIANT
int x = 1;
int a1[1 + x]; // NON_COMPLIANT - not integer constant expr
int a2[n]; // NON_COMPLIANT
@@ -9,7 +9,33 @@ void f(int n, int pa[1][n]) { // NON_COMPLIANT
int a4[] = {1}; // COMPLIANT - not a VLA
int a5[TEST]; // COMPLIANT
int a6[1 + 1]; // COMPLIANT
+ int a7[n][1]; // NON_COMPLIANT
+ int(*a8)[n]; // COMPLIANT - pointer to VLA, see RULE-18-10
+
+ extern int e1[]; // COMPLIANT
+
+ // A typedef is not a VLA.
+ typedef int vlaTypedef[n]; // COMPLIANT
+ // The declarations using the typedef may or may not be VLAs.
+ vlaTypedef t1; // NON_COMPLIANT
+ vlaTypedef t2[1]; // NON_COMPLIANT
+ vlaTypedef t3[x]; // NON_COMPLIANT
+ vlaTypedef *t4; // COMPLIANT
}
-void f1(int n, int pa[n]) { // NON_COMPLIANT
-}
\ No newline at end of file
+void f1(int n,
+ // Parameter array types are adjusted to pointers
+ int p1[n], // COMPLIANT
+ // Pointers to variably-modified types are not VLAs.
+ int p2[n][n],
+ int p3[], // array of unknown length is converted to pointer
+ int p4[][] // array of unknown length are not VLAs.
+) {}
+
+struct s {
+ // Structs must have at least one non-flexible array member.
+ int foo;
+
+ // Flexible array members are not VLAs.
+ int flexibleArrayMember[]; // COMPLIANT
+};
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.expected b/c/misra/test/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.expected
new file mode 100644
index 0000000000..688dde4650
--- /dev/null
+++ b/c/misra/test/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.expected
@@ -0,0 +1,30 @@
+| test.c:45:3:45:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:45:3:45:8 | call to get_s1 | call to get_s1 |
+| test.c:46:3:46:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:46:3:46:8 | call to get_s1 | call to get_s1 |
+| test.c:47:7:47:24 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:47:7:47:12 | call to get_s1 | call to get_s1 |
+| test.c:48:4:48:21 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:48:4:48:9 | call to get_s1 | call to get_s1 |
+| test.c:49:4:49:21 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:49:4:49:9 | call to get_s1 | call to get_s1 |
+| test.c:50:3:50:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:50:3:50:8 | call to get_s1 | call to get_s1 |
+| test.c:51:3:51:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:51:3:51:8 | call to get_s1 | call to get_s1 |
+| test.c:52:3:52:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:52:3:52:8 | call to get_s1 | call to get_s1 |
+| test.c:53:3:53:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:53:3:53:8 | call to get_s1 | call to get_s1 |
+| test.c:54:3:54:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:54:3:54:8 | call to get_s1 | call to get_s1 |
+| test.c:55:8:55:25 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:55:8:55:13 | call to get_s1 | call to get_s1 |
+| test.c:56:3:56:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:56:3:56:8 | call to get_s1 | call to get_s1 |
+| test.c:57:8:57:25 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:57:8:57:13 | call to get_s1 | call to get_s1 |
+| test.c:58:3:58:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:58:3:58:8 | call to get_s1 | call to get_s1 |
+| test.c:59:3:59:20 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:59:3:59:8 | call to get_s1 | call to get_s1 |
+| test.c:60:15:60:32 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:60:15:60:20 | call to get_s1 | call to get_s1 |
+| test.c:61:16:61:33 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:61:16:61:21 | call to get_s1 | call to get_s1 |
+| test.c:62:23:62:40 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:62:23:62:28 | call to get_s1 | call to get_s1 |
+| test.c:63:7:63:24 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:63:7:63:12 | call to get_s1 | call to get_s1 |
+| test.c:64:16:64:33 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:64:16:64:21 | call to get_s1 | call to get_s1 |
+| test.c:65:15:65:32 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:65:15:65:20 | call to get_s1 | call to get_s1 |
+| test.c:66:16:66:33 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:66:16:66:21 | call to get_s1 | call to get_s1 |
+| test.c:67:23:67:40 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:67:23:67:28 | call to get_s1 | call to get_s1 |
+| test.c:89:3:89:30 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:89:12:89:20 | member_s1 | member_s1 |
+| test.c:90:3:90:36 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:90:3:90:26 | access to array | access to array |
+| test.c:91:15:91:42 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:91:24:91:32 | member_s1 | member_s1 |
+| test.c:92:15:92:48 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:92:15:92:38 | access to array | access to array |
+| test.c:111:15:111:33 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:111:16:111:22 | ... = ... | ... = ... |
+| test.c:113:15:113:37 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:113:16:113:26 | ... ? ... : ... | ... ? ... : ... |
+| test.c:114:15:114:31 | array to pointer conversion | Array to pointer conversion of array $@ from temporary object $@. | test.c:3:13:3:21 | const_arr | const_arr | test.c:114:16:114:20 | ... , ... | ... , ... |
diff --git a/c/misra/test/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.qlref b/c/misra/test/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.qlref
new file mode 100644
index 0000000000..d2db40e77c
--- /dev/null
+++ b/c/misra/test/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.qlref
@@ -0,0 +1 @@
+rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.expected b/c/misra/test/rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.expected
new file mode 100644
index 0000000000..ae140dcd59
--- /dev/null
+++ b/c/misra/test/rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.expected
@@ -0,0 +1,15 @@
+| test.c:80:3:80:17 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:80:12:80:14 | arr | arr | test.c:80:3:80:8 | call to get_s1 | call to get_s1 |
+| test.c:81:3:81:17 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:81:12:81:14 | arr | arr | test.c:81:3:81:8 | call to get_s1 | call to get_s1 |
+| test.c:82:3:82:17 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:82:12:82:14 | arr | arr | test.c:82:3:82:8 | call to get_s1 | call to get_s1 |
+| test.c:83:3:83:17 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:83:12:83:14 | arr | arr | test.c:83:3:83:8 | call to get_s1 | call to get_s1 |
+| test.c:84:5:84:19 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:84:14:84:16 | arr | arr | test.c:84:5:84:10 | call to get_s1 | call to get_s1 |
+| test.c:93:3:93:27 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:93:22:93:24 | arr | arr | test.c:93:12:93:20 | member_s1 | member_s1 |
+| test.c:94:3:94:27 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:94:22:94:24 | arr | arr | test.c:94:3:94:20 | access to array | access to array |
+| test.c:137:3:137:23 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:137:12:137:20 | arr_union | arr_union | test.c:137:3:137:8 | call to get_s3 | call to get_s3 |
+| test.c:138:3:138:24 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:138:12:138:21 | arr_struct | arr_struct | test.c:138:3:138:8 | call to get_s3 | call to get_s3 |
+| test.c:139:3:139:24 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:139:12:139:21 | arr_struct | arr_struct | test.c:139:3:139:8 | call to get_s3 | call to get_s3 |
+| test.c:140:3:140:24 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:140:12:140:21 | arr_struct | arr_struct | test.c:140:3:140:8 | call to get_s3 | call to get_s3 |
+| test.c:141:3:141:24 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:141:12:141:21 | arr_struct | arr_struct | test.c:141:3:141:8 | call to get_s3 | call to get_s3 |
+| test.c:142:4:142:25 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:142:13:142:22 | arr_struct | arr_struct | test.c:142:4:142:9 | call to get_s3 | call to get_s3 |
+| test.c:146:3:146:22 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:146:12:146:16 | arr2d | arr2d | test.c:146:3:146:8 | call to get_s3 | call to get_s3 |
+| test.c:147:4:147:20 | access to array | Modifiable lvalue produced by subscripting array member $@ of temporary lifetime object $@ | test.c:147:13:147:17 | arr2d | arr2d | test.c:147:4:147:9 | call to get_s3 | call to get_s3 |
diff --git a/c/misra/test/rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.qlref b/c/misra/test/rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.qlref
new file mode 100644
index 0000000000..c1fb0bd2d4
--- /dev/null
+++ b/c/misra/test/rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.qlref
@@ -0,0 +1 @@
+rules/RULE-18-9/ModifiableLValueSubscriptedWithTemporaryLifetime.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-18-9/test.c b/c/misra/test/rules/RULE-18-9/test.c
new file mode 100644
index 0000000000..f2fb44fdc9
--- /dev/null
+++ b/c/misra/test/rules/RULE-18-9/test.c
@@ -0,0 +1,151 @@
+struct s1 {
+ int m1;
+ const int const_arr[10];
+ int arr[10];
+};
+
+struct s1 get_s1();
+
+struct s2 {
+ struct s1 member_s1;
+ struct s1 const const_s1_arr[10];
+ struct s1 *s1ptr;
+ struct s1 s1_arr[10];
+};
+
+struct s2 get_s2();
+struct s2 *get_s2_ptr();
+
+void use_int(int x) {}
+void use_int_ptr(int *x) {}
+
+void f(void) {
+ struct s1 l1;
+
+ // Auto lifetime, allowed:
+ l1.const_arr + 1; // COMPLIANT
+ l1.const_arr - 1; // COMPLIANT
+ &l1.const_arr; // COMPLIANT
+ use_int_ptr(l1.const_arr); // COMPLIANT
+ l1.arr[0] = 1; // COMPLIANT
+
+ // Extern lifetime, allowed:
+ extern struct s1 g1;
+ g1.const_arr + 1; // COMPLIANT
+ g1.const_arr - 1; // COMPLIANT
+ &g1.const_arr; // COMPLIANT
+ use_int_ptr(g1.const_arr); // COMPLIANT
+ g1.arr[0] = 1; // COMPLIANT
+
+ // Temporary lifetime, no conversion:
+ get_s1().const_arr; // COMPLIANT - not used as a value.
+ get_s1().m1 + 1; // COMPLIANT - not an array.
+
+ // Temporary lifetime, array to pointer conversions:
+ get_s1().const_arr + 1; // NON-COMPLIANT
+ get_s1().const_arr - 1; // NON-COMPLIANT
+ 1 + get_s1().const_arr; // NON-COMPLIANT
+ *get_s1().const_arr; // NON-COMPLIANT
+ !get_s1().const_arr; // NON-COMPLIANT
+ get_s1().const_arr < 1; // NON-COMPLIANT
+ get_s1().const_arr <= 1; // NON-COMPLIANT
+ get_s1().const_arr > 1; // NON-COMPLIANT
+ get_s1().const_arr >= 1; // NON-COMPLIANT
+ get_s1().const_arr == 1; // NON-COMPLIANT
+ 1 == get_s1().const_arr; // NON-COMPLIANT
+ get_s1().const_arr && 1; // NON-COMPLIANT
+ 1 && get_s1().const_arr; // NON-COMPLIANT
+ get_s1().const_arr || 1; // NON-COMPLIANT
+ get_s1().const_arr ? 1 : 1; // NON-COMPLIANT
+ use_int_ptr(get_s1().const_arr); // NON-COMPLIANT
+ use_int_ptr((get_s1().const_arr)); // NON-COMPLIANT
+ use_int_ptr((void *)get_s1().const_arr); // NON-COMPLIANT
+ (1, get_s1().const_arr) + 1; // NON-COMPLIANT
+ int *local = get_s1().const_arr; // NON-COMPLIANT
+ (struct s1){get_s1().const_arr}; // NON-COMPLIANT
+ (struct s2){{get_s1().const_arr}}; // NON-COMPLIANT
+ struct s1 local2 = {get_s1().const_arr}; // NON-COMPLIANT
+
+ // Results are not 'used' as a value.
+ (void *)get_s1().const_arr; // COMPLIANT
+ sizeof(get_s1().const_arr); // COMPLIANT
+ get_s1().const_arr, 1; // COMPLIANT
+ 1, get_s1().const_arr; // COMPLIANT
+ (get_s1().const_arr); // COMPLIANT
+
+ get_s1().const_arr[0]; // COMPLIANT - subscripted value not modifiable
+ get_s1().arr[0]; // COMPLIANT - subscripted value not used as modifiable
+ use_int(get_s1().const_arr[0]); // COMPLIANT
+ use_int(get_s1().arr[0]); // COMPLIANT
+ get_s1().arr[0] = 1; // NON-COMPLIANT
+ get_s1().arr[0] -= 1; // NON-COMPLIANT
+ get_s1().arr[0]--; // NON-COMPLIANT
+ get_s1().arr[0]++; // NON-COMPLIANT
+ &(get_s1().arr[0]); // NON-COMPLIANT
+
+ struct s2 l2;
+
+ // Deeper accesses:
+ get_s2().member_s1.const_arr + 1; // NON-COMPLIANT
+ get_s2().const_s1_arr[0].const_arr + 1; // NON-COMPLIANT
+ use_int_ptr(get_s2().member_s1.const_arr); // NON-COMPLIANT
+ use_int_ptr(get_s2().const_s1_arr[0].const_arr); // NON-COMPLIANT
+ get_s2().member_s1.arr[0] = 1; // NON-COMPLIANT
+ get_s2().s1_arr[0].arr[0] = 1; // NON-COMPLIANT
+ get_s2().member_s1.const_arr[0]; // COMPLIANT
+ get_s2().const_s1_arr[0].const_arr[0]; // COMPLIANT
+ get_s2().s1_arr[0].const_arr[0]; // COMPLIANT
+ get_s2().s1ptr->const_arr[0]; // COMPLIANT
+ use_int(get_s2().member_s1.const_arr[0]); // COMPLIANT
+ use_int(get_s2().const_s1_arr[0].const_arr[0]); // COMPLIANT
+ use_int(get_s2().s1ptr->const_arr[0]); // COMPLIANT
+
+ // Pointer members of a struct don't have temporary lifetime.
+ get_s2().s1ptr->const_arr + 1; // COMPLIANT
+ use_int_ptr(get_s2().s1ptr->const_arr); // COMPLIANT
+ get_s2().s1ptr->arr[0] = 1; // COMPLIANT
+ get_s2_ptr()->member_s1.const_arr + 1; // COMPLIANT
+ get_s2_ptr()->member_s1.arr[0] = 1; // COMPLIANT
+
+ // Other types of non-lvalue types
+ use_int_ptr((l1 = l1).const_arr); // NON-COMPLIANT
+ use_int_ptr(((struct s1)l1).const_arr); // NON-COMPLIANT[FALSE_NEGATIVE]
+ use_int_ptr((1 ? l1 : l1).const_arr); // NON-COMPLIANT
+ use_int_ptr((0, l1).const_arr); // NON-COMPLIANT
+ use_int_ptr((l2.s1ptr++)->const_arr); // COMPLIANT
+ use_int_ptr((--l2.s1ptr)->const_arr); // COMPLIANT
+}
+
+// Additional modifiable lvalue tests
+struct s3 {
+ struct s4 {
+ struct s5 {
+ struct s6 {
+ int x;
+ } m1;
+ } m1;
+ } arr_struct[1];
+
+ union u1 {
+ int x;
+ } arr_union[1];
+
+ int arr2d[1][1];
+} get_s3();
+
+void f2(void) {
+ get_s3().arr_union[0].x = 1; // NON_COMPLIANT
+ get_s3().arr_struct[0] = (struct s4){0}; // NON_COMPLIANT
+ get_s3().arr_struct[0].m1 = (struct s5){0}; // NON_COMPLIANT
+ get_s3().arr_struct[0].m1.m1 = (struct s6){0}; // NON_COMPLIANT
+ get_s3().arr_struct[0].m1.m1.x = 1; // NON_COMPLIANT
+ &get_s3().arr_struct[0].m1.m1.x; // NON_COMPLIANT
+ get_s3().arr_struct[0].m1.m1.x + 1; // COMPLIANT
+
+ get_s3().arr2d[1][1] + 1; // COMPLIANT
+ get_s3().arr2d[1][1] = 1; // NON_COMPLIANT
+ &get_s3().arr2d[1]; // NON_COMPLIANT
+ // The following cases are missing an ArrayToPointerConversion
+ use_int_ptr(get_s3().arr2d[1]); // NON_COMPLIANT[FALSE NEGATIVE]
+ get_s3().arr2d[1] + 1; // NON_COMPLIANT[FALSE NEGATIVE]
+}
\ 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-20-11/MoreThanOneHashOperatorInMacroDefinition.expected b/c/misra/test/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.expected
deleted file mode 100644
index 406010428c..0000000000
--- a/c/misra/test/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.expected
+++ /dev/null
@@ -1 +0,0 @@
-| test.c:25:1:25:29 | #define MACROTHIRTEEN(X) #X ## X | Macro definition uses an # operator followed by a ## operator. |
diff --git a/c/misra/test/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.qlref b/c/misra/test/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.qlref
deleted file mode 100644
index 35ef457cac..0000000000
--- a/c/misra/test/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.testref b/c/misra/test/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.testref
new file mode 100644
index 0000000000..be7ebf2815
--- /dev/null
+++ b/c/misra/test/rules/RULE-20-11/MoreThanOneHashOperatorInMacroDefinition.testref
@@ -0,0 +1 @@
+c/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-20-12/MacroParameterUsedAsHashOperand.qlref b/c/misra/test/rules/RULE-20-12/MacroParameterUsedAsHashOperand.qlref
deleted file mode 100644
index a2edc3acc4..0000000000
--- a/c/misra/test/rules/RULE-20-12/MacroParameterUsedAsHashOperand.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-20-12/MacroParameterUsedAsHashOperand.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-20-12/MacroParameterUsedAsHashOperand.testref b/c/misra/test/rules/RULE-20-12/MacroParameterUsedAsHashOperand.testref
new file mode 100644
index 0000000000..d1cc5971c7
--- /dev/null
+++ b/c/misra/test/rules/RULE-20-12/MacroParameterUsedAsHashOperand.testref
@@ -0,0 +1 @@
+c/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.ql
\ 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..5ae49919a9 100644
--- a/c/misra/test/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.expected
+++ b/c/misra/test/rules/RULE-21-14/MemcmpUsedToCompareNullTerminatedStrings.expected
@@ -1,10 +1,14 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (MemcmpUsedToCompareNullTerminatedStrings.ql:23,54-62)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (MemcmpUsedToCompareNullTerminatedStrings.ql:24,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (MemcmpUsedToCompareNullTerminatedStrings.ql:50,20-28)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (MemcmpUsedToCompareNullTerminatedStrings.ql:58,43-56)
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-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.expected b/c/misra/test/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.expected
deleted file mode 100644
index 29a0c6fac1..0000000000
--- a/c/misra/test/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-| test.c:6:14:6:17 | call to atof | Call to banned function atof. |
-| test.c:7:12:7:15 | call to atoi | Call to banned function atoi. |
-| test.c:8:13:8:16 | call to atol | Call to banned function atol. |
-| test.c:9:18:9:22 | call to atoll | Call to banned function atoll. |
diff --git a/c/misra/test/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.qlref b/c/misra/test/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.qlref
deleted file mode 100644
index 52e70db92b..0000000000
--- a/c/misra/test/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.testref b/c/misra/test/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.testref
new file mode 100644
index 0000000000..fccafa2049
--- /dev/null
+++ b/c/misra/test/rules/RULE-21-7/AtofAtoiAtolAndAtollOfStdlibhUsed.testref
@@ -0,0 +1 @@
+c/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.expected b/c/misra/test/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.expected
index 6111072ba8..0365f4980d 100644
--- a/c/misra/test/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.expected
+++ b/c/misra/test/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.expected
@@ -1,3 +1,4 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (FileOpenForReadAndWriteOnDifferentStreams.ql:39,9-17)
| test.c:6:14:6:18 | call to fopen | The same file was already opened $@. Files should not be read and written at the same time using different streams. | test.c:5:14:5:18 | call to fopen | here |
| test.c:17:14:17:18 | call to fopen | The same file was already opened $@. Files should not be read and written at the same time using different streams. | test.c:16:14:16:18 | call to fopen | here |
| test.c:33:14:33:18 | call to fopen | The same file was already opened $@. Files should not be read and written at the same time using different streams. | test.c:32:14:32:18 | call to fopen | here |
diff --git a/c/misra/test/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.expected b/c/misra/test/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.expected
index 0bfce133c5..dbf08e3d3d 100644
--- a/c/misra/test/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.expected
+++ b/c/misra/test/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.expected
@@ -1,2 +1,8 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:19,32-40)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:20,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:25,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:31,21-29)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:33,6-14)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:36,28-36)
| test.c:10:3:10:9 | call to fprintf | Attempt to write to a $@ opened as read-only. | test.c:9:14:9:18 | call to fopen | stream |
| test.c:15:3:15:9 | call to fprintf | Attempt to write to a $@ opened as read-only. | test.c:18:14:18:18 | call to fopen | stream |
diff --git a/c/misra/test/rules/RULE-22-7/EofShallBeComparedWithUnmodifiedReturnValues.expected b/c/misra/test/rules/RULE-22-7/EofShallBeComparedWithUnmodifiedReturnValues.expected
index 709d8b002c..83a10a46fb 100644
--- a/c/misra/test/rules/RULE-22-7/EofShallBeComparedWithUnmodifiedReturnValues.expected
+++ b/c/misra/test/rules/RULE-22-7/EofShallBeComparedWithUnmodifiedReturnValues.expected
@@ -1,2 +1,10 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (EofShallBeComparedWithUnmodifiedReturnValues.ql:23,28-36)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (EofShallBeComparedWithUnmodifiedReturnValues.ql:24,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (EofShallBeComparedWithUnmodifiedReturnValues.ql:28,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (EofShallBeComparedWithUnmodifiedReturnValues.ql:37,23-31)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (EofShallBeComparedWithUnmodifiedReturnValues.ql:42,17-25)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (EofShallBeComparedWithUnmodifiedReturnValues.ql:51,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (EofShallBeComparedWithUnmodifiedReturnValues.ql:59,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (EofShallBeComparedWithUnmodifiedReturnValues.ql:59,46-54)
| test.c:6:7:6:20 | ... != ... | The check is not reliable as the type of the return value of $@ is converted. | test.c:5:14:5:20 | call to getchar | call to getchar |
| test.c:13:7:13:15 | ... != ... | The check is not reliable as the type of the return value of $@ is converted. | test.c:12:14:12:20 | call to getchar | call to getchar |
diff --git a/c/misra/test/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.expected b/c/misra/test/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.expected
deleted file mode 100644
index 39d5aa5d85..0000000000
--- a/c/misra/test/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.expected
+++ /dev/null
@@ -1,21 +0,0 @@
-| test.c:9:18:9:24 | \u001aG | Invalid hexadecimal escape in string literal at '\\x1AG"'. |
-| test.c:12:18:12:23 | \u00029 | Invalid octal escape in string literal at '\\029"'. |
-| test.c:15:18:15:24 | \n7 | Invalid octal escape in string literal at '\\0127"'. |
-| test.c:16:18:16:24 | \r7 | Invalid octal escape in string literal at '\\0157"'. |
-| test.c:18:19:18:29 | \n\n9 | Invalid octal escape in string literal at '\\0129"'. |
-| test.c:19:19:19:28 | \n\u00019 | Invalid octal escape in string literal at '\\019"'. |
-| test.c:22:19:22:31 | \nAAA\u000f | Invalid octal escape in string literal at '\\012AAA\\017"'. |
-| test.c:25:19:25:39 | Some Data \n\u000fA | Invalid octal escape in string literal at '\\017A"'. |
-| test.c:26:19:27:21 | Some Data \n\u000fA5 | Invalid octal escape in string literal at '\\017A"\n "5"'. |
-| test.c:28:19:30:25 | Some Data \n\u000fA\n1 | Invalid octal escape in string literal at '\\0121"'. |
-| test.c:34:19:35:26 | \u0011G\u00012 | Invalid octal escape in string literal at '\\0012"'. |
-| test.c:36:19:37:25 | \u0011GG\u0001 | Invalid hexadecimal escape in string literal at '\\x11G"\n "G\\001"'. |
-| test.c:38:19:39:26 | \u0011GG\u00013 | Invalid hexadecimal escape in string literal at '\\x11G"\n "G\\0013"'. |
-| test.c:38:19:39:26 | \u0011GG\u00013 | Invalid octal escape in string literal at '\\0013"'. |
-| test.c:45:18:45:42 | Some Data \n\u000fA5 | Invalid octal escape in string literal at '\\017A" "5"'. |
-| test.c:46:18:46:49 | Some Data \n\u000fA\n1 | Invalid octal escape in string literal at '\\0121"'. |
-| test.c:48:18:48:32 | \u0011G\u00012 | Invalid octal escape in string literal at '\\0012"'. |
-| test.c:49:18:49:32 | \u0011GG\u0001 | Invalid hexadecimal escape in string literal at '\\x11G" "G\\001"'. |
-| test.c:50:18:50:33 | \u0011GG\u00013 | Invalid hexadecimal escape in string literal at '\\x11G" "G\\0013"'. |
-| test.c:50:18:50:33 | \u0011GG\u00013 | Invalid octal escape in string literal at '\\0013"'. |
-| test.c:53:11:53:16 | 10 | Invalid hexadecimal escape in string literal at '\\x0a''. |
diff --git a/c/misra/test/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.qlref b/c/misra/test/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.qlref
deleted file mode 100644
index fbdd187532..0000000000
--- a/c/misra/test/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.testref b/c/misra/test/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.testref
new file mode 100644
index 0000000000..f8b5396a9c
--- /dev/null
+++ b/c/misra/test/rules/RULE-4-1/OctalAndHexadecimalEscapeSequencesNotTerminated.testref
@@ -0,0 +1 @@
+c/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.ql
\ No newline at end of file
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-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.testref b/c/misra/test/rules/RULE-6-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.testref
new file mode 100644
index 0000000000..9d02a25700
--- /dev/null
+++ b/c/misra/test/rules/RULE-6-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.testref
@@ -0,0 +1 @@
+c/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.expected b/c/misra/test/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.expected
deleted file mode 100644
index df7677961a..0000000000
--- a/c/misra/test/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-| test.c:4:7:4:8 | x1 | Single-bit bit-field named x1 has a signed type int. |
-| test.c:7:14:7:15 | x2 | Single-bit bit-field named x2 has a signed type signed int. |
-| test.c:9:7:9:8 | x3 | Single-bit bit-field named x3 has a signed type signed char. |
-| test.c:11:7:11:8 | x4 | Single-bit bit-field named x4 has a signed type signed short. |
diff --git a/c/misra/test/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.qlref b/c/misra/test/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.qlref
deleted file mode 100644
index 50c34f70a7..0000000000
--- a/c/misra/test/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.testref b/c/misra/test/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.testref
new file mode 100644
index 0000000000..edc2f5a16d
--- /dev/null
+++ b/c/misra/test/rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.testref
@@ -0,0 +1 @@
+c/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.ql
\ 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-1/OctalConstantsUsed.expected b/c/misra/test/rules/RULE-7-1/OctalConstantsUsed.expected
deleted file mode 100644
index deecdf994c..0000000000
--- a/c/misra/test/rules/RULE-7-1/OctalConstantsUsed.expected
+++ /dev/null
@@ -1,2 +0,0 @@
-| test.c:7:3:7:5 | 10 | Use of banned $@ constant. | test.c:7:3:7:5 | 10 | octal |
-| test.c:8:3:8:5 | 44 | Use of banned $@ constant. | test.c:8:3:8:5 | 44 | octal |
diff --git a/c/misra/test/rules/RULE-7-1/OctalConstantsUsed.qlref b/c/misra/test/rules/RULE-7-1/OctalConstantsUsed.qlref
deleted file mode 100644
index 7d66675dad..0000000000
--- a/c/misra/test/rules/RULE-7-1/OctalConstantsUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-7-1/OctalConstantsUsed.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-1/test.c b/c/misra/test/rules/RULE-7-1/test.c
deleted file mode 100644
index fb0f2e0d36..0000000000
--- a/c/misra/test/rules/RULE-7-1/test.c
+++ /dev/null
@@ -1,10 +0,0 @@
-void test_non_zero_octal() {
- '\0'; // COMPLIANT - octal zero escape sequence permitted
- '\012'; // COMPLIANT
- '\054'; // COMPLIANT
- '\0149'; // COMPLIANT
- 0; // COMPLIANT - octal literal zero permitted
- 012; // NON_COMPLIANT
- 054; // NON_COMPLIANT
- "\0"; // COMPLIANT - octal zero escape sequence permitted
-}
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-3/LowercaseCharacterLUsedInLiteralSuffix.expected b/c/misra/test/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.expected
deleted file mode 100644
index 279fd7e621..0000000000
--- a/c/misra/test/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.expected
+++ /dev/null
@@ -1,16 +0,0 @@
-| test.c:3:10:3:11 | 0 | Lowercase 'l' used as a literal suffix. |
-| test.c:4:10:4:12 | 0 | Lowercase 'l' used as a literal suffix. |
-| test.c:7:10:7:12 | 0 | Lowercase 'l' used as a literal suffix. |
-| test.c:8:10:8:12 | 0 | Lowercase 'l' used as a literal suffix. |
-| test.c:13:11:13:12 | 0 | Lowercase 'l' used as a literal suffix. |
-| test.c:14:11:14:13 | 0 | Lowercase 'l' used as a literal suffix. |
-| test.c:17:11:17:13 | 0 | Lowercase 'l' used as a literal suffix. |
-| test.c:18:11:18:13 | 0 | Lowercase 'l' used as a literal suffix. |
-| test.c:23:10:23:14 | 1 | Lowercase 'l' used as a literal suffix. |
-| test.c:24:10:24:15 | 1 | Lowercase 'l' used as a literal suffix. |
-| test.c:27:10:27:15 | 1 | Lowercase 'l' used as a literal suffix. |
-| test.c:28:10:28:15 | 1 | Lowercase 'l' used as a literal suffix. |
-| test.c:33:11:33:14 | 1 | Lowercase 'l' used as a literal suffix. |
-| test.c:34:11:34:15 | 1 | Lowercase 'l' used as a literal suffix. |
-| test.c:37:11:37:15 | 1 | Lowercase 'l' used as a literal suffix. |
-| test.c:38:11:38:15 | 1 | Lowercase 'l' used as a literal suffix. |
diff --git a/c/misra/test/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.qlref b/c/misra/test/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.qlref
deleted file mode 100644
index 464efc3b2f..0000000000
--- a/c/misra/test/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.testref b/c/misra/test/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.testref
new file mode 100644
index 0000000000..1fc7164d80
--- /dev/null
+++ b/c/misra/test/rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.testref
@@ -0,0 +1 @@
+c/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-3/cpp/LowercaseCharacterLUsedInLiteralSuffix.qlref b/c/misra/test/rules/RULE-7-3/cpp/LowercaseCharacterLUsedInLiteralSuffix.qlref
deleted file mode 100644
index 464efc3b2f..0000000000
--- a/c/misra/test/rules/RULE-7-3/cpp/LowercaseCharacterLUsedInLiteralSuffix.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-7-3/LowercaseCharacterLUsedInLiteralSuffix.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-3/cpp/options b/c/misra/test/rules/RULE-7-3/cpp/options
deleted file mode 100644
index 8dbed822c6..0000000000
--- a/c/misra/test/rules/RULE-7-3/cpp/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options:--clang -std=c++14 --edg --diag_error=implicit_func_decl -nostdinc -I../../../../../cpp/common/test/includes/standard-library
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-7-3/cpp/test.cpp b/c/misra/test/rules/RULE-7-3/cpp/test.cpp
deleted file mode 100644
index ba3ca4f14e..0000000000
--- a/c/misra/test/rules/RULE-7-3/cpp/test.cpp
+++ /dev/null
@@ -1 +0,0 @@
-int x = false; // COMPLIANT - reported as FP in #319
\ 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-12/ValueImplicitEnumerationConstantNotUnique.expected b/c/misra/test/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.expected
deleted file mode 100644
index 55abb72b57..0000000000
--- a/c/misra/test/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.expected
+++ /dev/null
@@ -1 +0,0 @@
-| test.c:3:19:3:20 | c4 | Nonunique value of enum constant compared to $@ | test.c:3:23:3:24 | c5 | c5 |
diff --git a/c/misra/test/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.qlref b/c/misra/test/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.qlref
deleted file mode 100644
index e43c765d37..0000000000
--- a/c/misra/test/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.testref b/c/misra/test/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.testref
new file mode 100644
index 0000000000..7db7d79d72
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-12/ValueImplicitEnumerationConstantNotUnique.testref
@@ -0,0 +1 @@
+c/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.ql
\ 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-15/RedeclarationOfObjectWithUnmatchedAlignment.expected b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.expected
new file mode 100644
index 0000000000..3479ef1e35
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.expected
@@ -0,0 +1,8 @@
+| test.c:18:8:18:15 | alignas(...) | Variable g6 declared with lexically different _Alignof() values '$@' and '$@'. | test.c:18:8:18:15 | alignas(...) | int | test.c:19:8:19:15 | alignas(...) | 4 |
+| test.c:19:8:19:15 | alignas(...) | Variable g6 declared with lexically different _Alignof() values '$@' and '$@'. | test.c:19:8:19:15 | alignas(...) | 4 | test.c:18:8:18:15 | alignas(...) | int |
+| test.c:22:8:22:15 | alignas(...) | Variable g7 declared with lexically different _Alignof() values '$@' and '$@'. | test.c:22:8:22:15 | alignas(...) | ... * ... | test.c:23:8:23:15 | alignas(...) | 32 |
+| test.c:23:8:23:15 | alignas(...) | Variable g7 declared with lexically different _Alignof() values '$@' and '$@'. | test.c:23:8:23:15 | alignas(...) | 32 | test.c:22:8:22:15 | alignas(...) | ... * ... |
+| test.c:28:8:28:15 | alignas(...) | Variable g9 declared with lexically different _Alignof() values '$@' and '$@'. | test.c:28:8:28:15 | alignas(...) | ... * ... | test.c:29:8:29:15 | alignas(...) | ... * ... |
+| test.c:29:8:29:15 | alignas(...) | Variable g9 declared with lexically different _Alignof() values '$@' and '$@'. | test.c:29:8:29:15 | alignas(...) | ... * ... | test.c:28:8:28:15 | alignas(...) | ... * ... |
+| test.c:34:8:34:15 | alignas(...) | Variable g11 declared with lexically different _Alignof() values '$@' and '$@'. | test.c:34:8:34:15 | alignas(...) | signed int | test.c:35:8:35:15 | alignas(...) | unsigned int |
+| test.c:35:8:35:15 | alignas(...) | Variable g11 declared with lexically different _Alignof() values '$@' and '$@'. | test.c:35:8:35:15 | alignas(...) | unsigned int | test.c:34:8:34:15 | alignas(...) | signed int |
diff --git a/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.expected.gcc b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.expected.gcc
new file mode 100644
index 0000000000..f1054946a7
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.expected.gcc
@@ -0,0 +1,10 @@
+| test.c:11:8:11:15 | alignas(...) | Variable g4 declared with lexically different _Alignof() values '$@' and '$@' | test.c:11:8:11:15 | alignas(...) | 16 | test.c:12:8:12:15 | alignas(...) | 32 |
+| test.c:12:8:12:15 | alignas(...) | Variable g4 declared with lexically different _Alignof() values '$@' and '$@' | test.c:12:8:12:15 | alignas(...) | 32 | test.c:11:8:11:15 | alignas(...) | 16 |
+| test.c:18:8:18:15 | alignas(...) | Variable g6 declared with lexically different _Alignof() values '$@' and '$@' | test.c:18:8:18:15 | alignas(...) | int | test.c:19:8:19:15 | alignas(...) | 4 |
+| test.c:19:8:19:15 | alignas(...) | Variable g6 declared with lexically different _Alignof() values '$@' and '$@' | test.c:19:8:19:15 | alignas(...) | 4 | test.c:18:8:18:15 | alignas(...) | int |
+| test.c:22:8:22:15 | alignas(...) | Variable g7 declared with lexically different _Alignof() values '$@' and '$@' | test.c:22:8:22:15 | alignas(...) | ... * ... | test.c:23:8:23:15 | alignas(...) | 32 |
+| test.c:23:8:23:15 | alignas(...) | Variable g7 declared with lexically different _Alignof() values '$@' and '$@' | test.c:23:8:23:15 | alignas(...) | 32 | test.c:22:8:22:15 | alignas(...) | ... * ... |
+| test.c:28:8:28:15 | alignas(...) | Variable g9 declared with lexically different _Alignof() values '$@' and '$@' | test.c:28:8:28:15 | alignas(...) | ... * ... | test.c:29:8:29:15 | alignas(...) | ... * ... |
+| test.c:29:8:29:15 | alignas(...) | Variable g9 declared with lexically different _Alignof() values '$@' and '$@' | test.c:29:8:29:15 | alignas(...) | ... * ... | test.c:28:8:28:15 | alignas(...) | ... * ... |
+| test.c:34:8:34:15 | alignas(...) | Variable g11 declared with lexically different _Alignof() values '$@' and '$@' | test.c:34:8:34:15 | alignas(...) | signed int | test.c:35:8:35:15 | alignas(...) | unsigned int |
+| test.c:35:8:35:15 | alignas(...) | Variable g11 declared with lexically different _Alignof() values '$@' and '$@' | test.c:35:8:35:15 | alignas(...) | unsigned int | test.c:34:8:34:15 | alignas(...) | signed int |
diff --git a/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.qlref b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.qlref
new file mode 100644
index 0000000000..08648fd168
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.qlref
@@ -0,0 +1 @@
+rules/RULE-8-15/RedeclarationOfObjectWithUnmatchedAlignment.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.expected b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.expected
new file mode 100644
index 0000000000..69d2c8bb2d
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.expected
@@ -0,0 +1,2 @@
+| test.c:5:12:5:13 | declaration of g2 | Variable g2 declared without explicit alignment to match $@ with alignment $@. | test.c:4:25:4:26 | declaration of g2 | other definition | test.c:4:8:4:15 | alignas(...) | alignas(...) |
+| test.c:7:12:7:13 | declaration of g3 | Variable g3 declared without explicit alignment to match $@ with alignment $@. | test.c:8:25:8:26 | declaration of g3 | other definition | test.c:8:8:8:15 | alignas(...) | alignas(...) |
diff --git a/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.qlref b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.qlref
new file mode 100644
index 0000000000..f5f13e2125
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.qlref
@@ -0,0 +1 @@
+rules/RULE-8-15/RedeclarationOfObjectWithoutAlignment.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-15/test.c b/c/misra/test/rules/RULE-8-15/test.c
new file mode 100644
index 0000000000..f97a79d5b6
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-15/test.c
@@ -0,0 +1,35 @@
+extern _Alignas(16) int g1; // COMPLIANT
+extern _Alignas(16) int g1; // COMPLIANT
+
+extern _Alignas(16) int g2;
+extern int g2; // NON_COMPLIANT
+
+extern int g3; // NON_COMPLIANT
+extern _Alignas(16) int g3;
+
+// Does not compile on clang:
+// extern _Alignas(16) int g4; // COMPLIANT
+// extern _Alignas(32) int g4; // COMPLIANT
+
+extern int g5; // COMPLIANT
+extern int g5; // COMPLIANT
+
+// Spec says elements must be lexically identical after macro expansion
+extern _Alignas(int) int g6; // NON_COMPLIANT
+extern _Alignas(4) int g6; // NON_COMPLIANT
+
+#define THIRTY_TWO 32
+extern _Alignas(16 * 2) int g7; // NON_COMPLIANT
+extern _Alignas(32) int g7; // NON_COMPLIANT
+
+extern _Alignas(THIRTY_TWO) int g8; // COMPLIANT
+extern _Alignas(32) int g8; // COMPLIANT
+
+extern _Alignas(16 * 2) int g9; // NON_COMPLIANT
+extern _Alignas(2 * 16) int g9; // NON_COMPLIANT
+
+extern _Alignas(int) int g10; // COMPLIANT
+extern _Alignas(int) int g10; // COMPLIANT
+
+extern _Alignas(signed int) int g11; // NON_COMPLIANT
+extern _Alignas(unsigned int) int g11; // NON_COMPLIANT
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-15/test.c.gcc b/c/misra/test/rules/RULE-8-15/test.c.gcc
new file mode 100644
index 0000000000..d0f53bf89a
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-15/test.c.gcc
@@ -0,0 +1,35 @@
+extern _Alignas(16) int g1; // COMPLIANT
+extern _Alignas(16) int g1; // COMPLIANT
+
+extern _Alignas(16) int g2;
+extern int g2; // NON_COMPLIANT
+
+extern int g3; // NON_COMPLIANT
+extern _Alignas(16) int g3;
+
+// Does not compile on clang:
+extern _Alignas(16) int g4; // COMPLIANT
+extern _Alignas(32) int g4; // COMPLIANT
+
+extern int g5; // COMPLIANT
+extern int g5; // COMPLIANT
+
+// Spec says elements must be lexically identical after macro expansion
+extern _Alignas(int) int g6; // NON_COMPLIANT
+extern _Alignas(4) int g6; // NON_COMPLIANT
+
+#define THIRTY_TWO 32
+extern _Alignas(16 * 2) int g7; // NON_COMPLIANT
+extern _Alignas(32) int g7; // NON_COMPLIANT
+
+extern _Alignas(THIRTY_TWO) int g8; // COMPLIANT
+extern _Alignas(32) int g8; // COMPLIANT
+
+extern _Alignas(16 * 2) int g9; // NON_COMPLIANT
+extern _Alignas(2 * 16) int g9; // NON_COMPLIANT
+
+extern _Alignas(int) int g10; // COMPLIANT
+extern _Alignas(int) int g10; // COMPLIANT
+
+extern _Alignas(signed int) int g11; // NON_COMPLIANT
+extern _Alignas(unsigned int) int g11; // NON_COMPLIANT
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-16/AlignmentWithSizeZero.expected b/c/misra/test/rules/RULE-8-16/AlignmentWithSizeZero.expected
new file mode 100644
index 0000000000..4daa3475ed
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-16/AlignmentWithSizeZero.expected
@@ -0,0 +1,4 @@
+| test.c:2:10:2:10 | 0 | Invalid alignof() size set to zero for variable $@. | test.c:2:17:2:18 | g2 | g2 |
+| test.c:3:10:3:14 | ... - ... | Invalid alignof() size set to zero for variable $@. | test.c:3:21:3:22 | g3 | g3 |
+| test.c:8:12:8:12 | 0 | Invalid alignof() size set to zero for variable $@. | test.c:8:19:8:20 | m2 | m2 |
+| test.c:13:12:13:12 | 0 | Invalid alignof() size set to zero for variable $@. | test.c:13:19:13:20 | l2 | l2 |
diff --git a/c/misra/test/rules/RULE-8-16/AlignmentWithSizeZero.qlref b/c/misra/test/rules/RULE-8-16/AlignmentWithSizeZero.qlref
new file mode 100644
index 0000000000..c8e19d1fe5
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-16/AlignmentWithSizeZero.qlref
@@ -0,0 +1 @@
+rules/RULE-8-16/AlignmentWithSizeZero.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-16/test.c b/c/misra/test/rules/RULE-8-16/test.c
new file mode 100644
index 0000000000..3e96b7b8cc
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-16/test.c
@@ -0,0 +1,14 @@
+_Alignas(8) int g1; // COMPLIANT
+_Alignas(0) int g2; // NON-COMPLIANT
+_Alignas(8 - 8) int g3; // NON-COMPLIANT
+_Alignas(float) int g4; // COMPLIANT
+
+struct s {
+ _Alignas(64) int m1; // COMPLIANT
+ _Alignas(0) int m2; // NON_COMPLIANT
+};
+
+void f() {
+ _Alignas(8) int l1; // COMPLIANT
+ _Alignas(0) int l2; // NON-COMPLIANT
+}
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.expected b/c/misra/test/rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.expected
new file mode 100644
index 0000000000..24707ca457
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.expected
@@ -0,0 +1,6 @@
+| test.c:2:30:2:31 | g2 | Variable g2 contains more than one alignment specifier, $@ and $@ | test.c:2:1:2:8 | alignas(...) | alignas(...) | test.c:2:13:2:20 | alignas(...) | alignas(...) |
+| test.c:3:29:3:30 | g3 | Variable g3 contains more than one alignment specifier, $@ and $@ | test.c:3:1:3:8 | alignas(...) | alignas(...) | test.c:3:13:3:20 | alignas(...) | alignas(...) |
+| test.c:4:35:4:36 | g4 | Variable g4 contains more than one alignment specifier, $@ and $@ | test.c:4:1:4:8 | alignas(...) | alignas(...) | test.c:4:17:4:24 | alignas(...) | alignas(...) |
+| test.c:6:53:6:54 | g5 | Variable g5 contains more than one alignment specifier, $@ and $@ | test.c:5:1:5:8 | alignas(...) | alignas(...) | test.c:6:33:6:40 | alignas(...) | alignas(...) |
+| test.c:10:35:10:36 | m2 | Variable m2 contains more than one alignment specifier, $@ and $@ | test.c:10:3:10:10 | alignas(...) | alignas(...) | test.c:10:18:10:25 | alignas(...) | alignas(...) |
+| test.c:15:35:15:36 | l2 | Variable l2 contains more than one alignment specifier, $@ and $@ | test.c:15:3:15:10 | alignas(...) | alignas(...) | test.c:15:18:15:25 | alignas(...) | alignas(...) |
diff --git a/c/misra/test/rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.qlref b/c/misra/test/rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.qlref
new file mode 100644
index 0000000000..7ff11e8a61
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.qlref
@@ -0,0 +1 @@
+rules/RULE-8-17/MoreThanOneAlignmentSpecifierOnDeclaration.ql
\ No newline at end of file
diff --git a/c/misra/test/rules/RULE-8-17/test.c b/c/misra/test/rules/RULE-8-17/test.c
new file mode 100644
index 0000000000..e2f8b2b44f
--- /dev/null
+++ b/c/misra/test/rules/RULE-8-17/test.c
@@ -0,0 +1,16 @@
+_Alignas(8) int g1; // COMPLIANT
+_Alignas(8) _Alignas(16) int g2; // NON-COMPLIANT
+_Alignas(8) _Alignas(8) int g3; // NON-COMPLIANT
+_Alignas(float) _Alignas(int) int g4; // NON-COMPLIANT
+_Alignas(float) _Alignas(float) int g5; // NON-COMPLIANT
+_Alignas(float) _Alignas(float) _Alignas(float) int g5; // NON-COMPLIANT
+
+struct s {
+ _Alignas(64) int m1; // COMPLIANT
+ _Alignas(long) _Alignas(16) int m2; // NON_COMPLIANT
+};
+
+void f() {
+ _Alignas(8) int l1; // COMPLIANT
+ _Alignas(long) _Alignas(16) int l2; // NON_COMPLIANT
+}
\ 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-23-fix-fp-646-M0-1-10.md b/change_notes/2024-07-23-fix-fp-646-M0-1-10.md
new file mode 100644
index 0000000000..8854c7b59a
--- /dev/null
+++ b/change_notes/2024-07-23-fix-fp-646-M0-1-10.md
@@ -0,0 +1,2 @@
+- `M0-1-10` - `EncapsulatingFunctions.qll`:
+ - Fixes #646. Consider typedef'd `int` return types for `main()` function as MainFunction.
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-10-rule-18-8-vla-rule-changes-amendment4.md b/change_notes/2024-10-10-rule-18-8-vla-rule-changes-amendment4.md
new file mode 100644
index 0000000000..f465836052
--- /dev/null
+++ b/change_notes/2024-10-10-rule-18-8-vla-rule-changes-amendment4.md
@@ -0,0 +1,4 @@
+- `RULE-18-8` - `VariableLengthArrayTypesUsed.ql`:
+ - Implement changes declared in MISRA C 2012 Amendment 4. This rule now only bans the use of VLA objects. Rules restricting the use of VLA types -- specifically, pointers to VLA types -- are now implemented in `RULE-18-10`.
+- `EXP-35-C` - `DoNotModifyObjectsWithTemporaryLifetime.ql`
+ - Refactor component into a shared library, should not have any effect on rule results.
\ 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-fix-fp-m6-5-3.md b/change_notes/2024-10-22-fix-fp-m6-5-3.md
new file mode 100644
index 0000000000..0d8ca573d9
--- /dev/null
+++ b/change_notes/2024-10-22-fix-fp-m6-5-3.md
@@ -0,0 +1,2 @@
+- `M6-5-3` - `Loops.qll`:
+ - Fixes #755. Specifies that the access to the loop counter must be via non-const address.
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-23-cvalue-widening.md b/change_notes/2024-10-23-cvalue-widening.md
new file mode 100644
index 0000000000..1d7a0f876a
--- /dev/null
+++ b/change_notes/2024-10-23-cvalue-widening.md
@@ -0,0 +1,2 @@
+ - `M5-0-3`, `M5-0-7`, `M5-0-8`, `M5-0-9` - `CvalueExpressionConvertedToDifferentUnderlyingType.ql`, `ExplicitFloatingIntegralConversionOfACValueExpr.ql`, `ExplicitWideningConversionOfACValueExpr.ql`, `ExplicitSignedness.ql`:
+ - Reduce false positives from misidentifying an explicitly casted expression used as a function argument or return value as a `cvalue`.
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-10-30-fix-issue-629.md b/change_notes/2024-10-30-fix-issue-629.md
new file mode 100644
index 0000000000..1e7421f6f6
--- /dev/null
+++ b/change_notes/2024-10-30-fix-issue-629.md
@@ -0,0 +1,2 @@
+- `A7-1-7` - `IdentifierDeclarationAndInitializationNotOnSeparateLines.ql`
+ - Fixes #629. Adds brackets, excluding expressions statements in macros.
diff --git a/change_notes/2024-11-11-fix-fp-789.md b/change_notes/2024-11-11-fix-fp-789.md
new file mode 100644
index 0000000000..b06ebb9b11
--- /dev/null
+++ b/change_notes/2024-11-11-fix-fp-789.md
@@ -0,0 +1,3 @@
+- `A7-1-2` - `VariableMissingConstexpr.ql`:
+ - Do not report on member variables if the class has un-instantiated member function(s).
+ - Check a call's qualifier as well whether it can be compile time evaluated or not.
diff --git a/change_notes/2024-11-13-fix-fp-796.md b/change_notes/2024-11-13-fix-fp-796.md
new file mode 100644
index 0000000000..5fa32f57e8
--- /dev/null
+++ b/change_notes/2024-11-13-fix-fp-796.md
@@ -0,0 +1,2 @@
+ - `A13-3-1` - `FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql`:
+ - Reduce false positives by explicitly checking that the locations of overloaded functions are different.
diff --git a/change_notes/2024-12-05-upgrade-to-2.18.4.md b/change_notes/2024-12-05-upgrade-to-2.18.4.md
new file mode 100644
index 0000000000..6f3d4ba404
--- /dev/null
+++ b/change_notes/2024-12-05-upgrade-to-2.18.4.md
@@ -0,0 +1,3 @@
+- Updated the CodeQL version to `2.18.4`.
+- `A12-8-6` - `CopyAndMoveNotDeclaredProtected.ql`:
+ - Implicitly created copy and move constructors will no longer be flagged in tenplate instantiations when they are unused, or trivial (tracked at https://github.com/github/codeql-coding-standards/issues/811).
\ No newline at end of file
diff --git a/change_notes/2024-12-08-identifier-hiding.md b/change_notes/2024-12-08-identifier-hiding.md
new file mode 100644
index 0000000000..b769b16e57
--- /dev/null
+++ b/change_notes/2024-12-08-identifier-hiding.md
@@ -0,0 +1,7 @@
+ - `A2-10-1` - `IdentifierHiding.ql`:
+ - Improved evaluation performance.
+ - Addressed false negatives where nested loops used the same variable name.
+ - Exclude cases where a variable declared in a lambda expression shadowed a global or namespace variable that did not appear in the same translation unit.
+ - `RULE-5-3` - `IdentifierHidingC.ql`:
+ - Improved evaluation performance.
+ - Addressed false negatives where nested loops used the same variable name.
\ No newline at end of file
diff --git a/change_notes/2024-12-17-fix-fp-824-a15-4-4 b/change_notes/2024-12-17-fix-fp-824-a15-4-4
new file mode 100644
index 0000000000..89ccf49815
--- /dev/null
+++ b/change_notes/2024-12-17-fix-fp-824-a15-4-4
@@ -0,0 +1,2 @@
+ - `A15-4-4` - `MissingNoExcept.ql`:
+ - Reduce false positives by not reporting on functions that have a noexcept specification with a complex expression or call other such functions.
diff --git a/change_notes/2024-12-18-fix-fp-540-a3-9-1.md b/change_notes/2024-12-18-fix-fp-540-a3-9-1.md
new file mode 100644
index 0000000000..fbd09ca840
--- /dev/null
+++ b/change_notes/2024-12-18-fix-fp-540-a3-9-1.md
@@ -0,0 +1,2 @@
+ - `A3-9-1` - `VariableWidthIntegerTypesUsed.ql`:
+ - Reduce false positives by not considering variables from template instantiations.
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..910a6e060e 100644
--- a/cpp/autosar/src/codeql-pack.lock.yml
+++ b/cpp/autosar/src/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/cpp/autosar/src/qlpack.yml b/cpp/autosar/src/qlpack.yml
index 9c0bccbc08..f44ad54c74 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.40.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: 1.4.2
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/A12-1-1/ExplicitConstructorBaseClassInitialization.ql b/cpp/autosar/src/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.ql
index e1aeec46a0..66fe0345dc 100644
--- a/cpp/autosar/src/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.ql
+++ b/cpp/autosar/src/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.ql
@@ -16,29 +16,11 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.Constructor
+import codingstandards.cpp.rules.initializeallvirtualbaseclasses.InitializeAllVirtualBaseClasses
-from Constructor c, Class declaringType, Class baseClass, string type
-where
- not isExcluded(c, InitializationPackage::explicitConstructorBaseClassInitializationQuery()) and
- declaringType = c.getDeclaringType() and
- (
- declaringType.getABaseClass() = baseClass and type = ""
- or
- baseClass.(VirtualBaseClass).getAVirtuallyDerivedClass().getADerivedClass+() = declaringType and
- type = " virtual"
- ) and
- // There is not an initializer on the constructor for this particular base class
- not exists(ConstructorBaseClassInit init |
- c.getAnInitializer() = init and
- init.getInitializedClass() = baseClass and
- not init.isCompilerGenerated()
- ) and
- // Must be a defined constructor
- c.hasDefinition() and
- // Not a compiler-generated constructor
- not c.isCompilerGenerated() and
- // Not a defaulted constructor
- not c.isDefaulted()
-select c, "Constructor for $@ does not explicitly call constructor for" + type + " base class $@.",
- declaringType, declaringType.getSimpleName(), baseClass, baseClass.getSimpleName()
+class ExplicitConstructorBaseClassInitializationQuery extends InitializeAllVirtualBaseClassesSharedQuery
+{
+ ExplicitConstructorBaseClassInitializationQuery() {
+ this = InitializationPackage::explicitConstructorBaseClassInitializationQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.ql b/cpp/autosar/src/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.ql
index a2ce643784..9697176711 100644
--- a/cpp/autosar/src/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.ql
+++ b/cpp/autosar/src/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.ql
@@ -17,43 +17,11 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.Operator
+import codingstandards.cpp.rules.copyandmoveassignmentsshallhandleselfassignment.CopyAndMoveAssignmentsShallHandleSelfAssignment
-predicate isUserCopyOrUserMove(Operator o) {
- o instanceof UserCopyOperator or
- o instanceof UserMoveOperator
+class CopyAssignmentAndAMoveHandleSelfAssignmentQuery extends CopyAndMoveAssignmentsShallHandleSelfAssignmentSharedQuery
+{
+ CopyAssignmentAndAMoveHandleSelfAssignmentQuery() {
+ this = OperatorInvariantsPackage::copyAssignmentAndAMoveHandleSelfAssignmentQuery()
+ }
}
-
-predicate callsStdSwap(Function f) {
- exists(FunctionCall fc |
- fc.getTarget().hasGlobalOrStdName("swap") and
- fc.getEnclosingFunction() = f
- )
-}
-
-predicate callsNoExceptSwap(Operator o) {
- exists(Function f, FunctionCall fc |
- callsStdSwap(f) and
- fc.getEnclosingFunction() = o and
- fc.getTarget() = f
- )
-}
-
-predicate checksForSelfAssignment(Operator o) {
- exists(IfStmt i, ComparisonOperation c |
- i.getEnclosingFunction() = o and
- i.getCondition() = c and
- (
- c.getLeftOperand().toString() = "this" or
- c.getRightOperand().toString() = "this"
- )
- )
-}
-
-from Operator o
-where
- not isExcluded(o, OperatorInvariantsPackage::copyAssignmentAndAMoveHandleSelfAssignmentQuery()) and
- isUserCopyOrUserMove(o) and
- not callsNoExceptSwap(o) and
- not checksForSelfAssignment(o)
-select o, "User defined copy or user defined move does not handle self-assignment correctly."
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..4593065e01 100644
--- a/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.ql
+++ b/cpp/autosar/src/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.ql
@@ -14,12 +14,12 @@
*/
import cpp
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.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-2-1/AssignmentOperatorReturnThis.ql b/cpp/autosar/src/rules/A13-2-1/AssignmentOperatorReturnThis.ql
index ae0acc3bb5..4e6b7d6f0c 100644
--- a/cpp/autosar/src/rules/A13-2-1/AssignmentOperatorReturnThis.ql
+++ b/cpp/autosar/src/rules/A13-2-1/AssignmentOperatorReturnThis.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.Operator
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
predicate returnsThisPointer(UserAssignmentOperator o) {
exists(PointerDereferenceExpr p, ThisExpr t, ReturnStmt r |
diff --git a/cpp/autosar/src/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql b/cpp/autosar/src/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql
index 393c1222fd..1ae2bc87ab 100644
--- a/cpp/autosar/src/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql
+++ b/cpp/autosar/src/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql
@@ -14,6 +14,7 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.FunctionEquivalence
class Candidate extends TemplateFunction {
Candidate() {
@@ -29,28 +30,18 @@ where
OperatorsPackage::functionThatContainsForwardingReferenceAsItsArgumentOverloadedQuery()) and
not f.isDeleted() and
f = c.getAnOverload() and
+ // Ensure the functions are not equivalent to each other (refer #796).
+ not f = getAnEquivalentFunction(c) and
// 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/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.ql b/cpp/autosar/src/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.ql
index e53b532493..86218a47d6 100644
--- a/cpp/autosar/src/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.ql
+++ b/cpp/autosar/src/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.ql
@@ -16,8 +16,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.functiontemplatesexplicitlyspecialized.FunctionTemplatesExplicitlySpecialized
-from FunctionTemplateSpecialization f
-where not isExcluded(f, TemplatesPackage::explicitSpecializationsOfFunctionTemplatesUsedQuery())
-select f, "Specialization of function template from primary template located in $@.",
- f.getPrimaryTemplate(), f.getPrimaryTemplate().getFile().getBaseName()
+class ExplicitSpecializationsOfFunctionTemplatesUsedQuery extends FunctionTemplatesExplicitlySpecializedSharedQuery
+{
+ ExplicitSpecializationsOfFunctionTemplatesUsedQuery() {
+ this = TemplatesPackage::explicitSpecializationsOfFunctionTemplatesUsedQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/A15-1-2/PointerExceptionObject.ql b/cpp/autosar/src/rules/A15-1-2/PointerExceptionObject.ql
index 348e02609c..b2f101082f 100644
--- a/cpp/autosar/src/rules/A15-1-2/PointerExceptionObject.ql
+++ b/cpp/autosar/src/rules/A15-1-2/PointerExceptionObject.ql
@@ -15,10 +15,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.exceptionobjecthavepointertype.ExceptionObjectHavePointerType
-from Expr thrownExpr
-where
- not isExcluded(thrownExpr, Exceptions1Package::pointerExceptionObjectQuery()) and
- thrownExpr = any(ThrowExpr te).getExpr() and
- thrownExpr.getType().getUnspecifiedType() instanceof PointerType
-select thrownExpr, "Exception object with pointer type " + thrownExpr.getType() + " is thrown here."
+class PointerExceptionObjectQuery extends ExceptionObjectHavePointerTypeSharedQuery {
+ PointerExceptionObjectQuery() { this = Exceptions1Package::pointerExceptionObjectQuery() }
+}
diff --git a/cpp/autosar/src/rules/A15-1-3/ThrownExceptionsShouldBeUnique.ql b/cpp/autosar/src/rules/A15-1-3/ThrownExceptionsShouldBeUnique.ql
index 1459b79b43..97e9133a7a 100644
--- a/cpp/autosar/src/rules/A15-1-3/ThrownExceptionsShouldBeUnique.ql
+++ b/cpp/autosar/src/rules/A15-1-3/ThrownExceptionsShouldBeUnique.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.exceptions.ExceptionFlow
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.valuenumbering.HashCons
/** Find a value which defines the exception thrown by the `DirectThrowExpr`, if any. */
diff --git a/cpp/autosar/src/rules/A15-2-2/ConstructorErrorLeavesObjectInInvalidState.ql b/cpp/autosar/src/rules/A15-2-2/ConstructorErrorLeavesObjectInInvalidState.ql
index 9fcd8fa609..1b3a3cfed2 100644
--- a/cpp/autosar/src/rules/A15-2-2/ConstructorErrorLeavesObjectInInvalidState.ql
+++ b/cpp/autosar/src/rules/A15-2-2/ConstructorErrorLeavesObjectInInvalidState.ql
@@ -15,7 +15,7 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.autosar
import codingstandards.cpp.exceptions.ExceptionFlow
import codingstandards.cpp.exceptions.ExceptionSpecifications
diff --git a/cpp/autosar/src/rules/A15-4-2/NoExceptFunctionThrows.ql b/cpp/autosar/src/rules/A15-4-2/NoExceptFunctionThrows.ql
index 0c5bbb6011..169b5fc8f3 100644
--- a/cpp/autosar/src/rules/A15-4-2/NoExceptFunctionThrows.ql
+++ b/cpp/autosar/src/rules/A15-4-2/NoExceptFunctionThrows.ql
@@ -15,25 +15,8 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.exceptions.ExceptionFlow
-import ExceptionPathGraph
-import codingstandards.cpp.exceptions.ExceptionSpecifications
+import codingstandards.cpp.rules.noexceptfunctionshouldnotpropagatetothecaller.NoexceptFunctionShouldNotPropagateToTheCaller
-class NoExceptThrowingFunction extends ExceptionThrowingFunction {
- NoExceptThrowingFunction() {
- // Can exit with an exception
- exists(getAFunctionThrownType(_, _)) and
- // But is marked noexcept(true) or equivalent
- isNoExceptTrue(this)
- }
+class NoExceptFunctionThrowsQuery extends NoexceptFunctionShouldNotPropagateToTheCallerSharedQuery {
+ NoExceptFunctionThrowsQuery() { this = Exceptions1Package::noExceptFunctionThrowsQuery() }
}
-
-from
- NoExceptThrowingFunction f, ExceptionFlowNode exceptionSource, ExceptionFlowNode functionNode,
- ExceptionType exceptionType
-where
- not isExcluded(f, Exceptions1Package::noExceptFunctionThrowsQuery()) and
- f.hasExceptionFlow(exceptionSource, functionNode, exceptionType)
-select f, exceptionSource, functionNode,
- "Function " + f.getName() + " is declared noexcept(true) but can throw exceptions of type " +
- exceptionType.getExceptionName() + "."
diff --git a/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql b/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql
index 7701a8a1ea..33369e00a4 100644
--- a/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql
+++ b/cpp/autosar/src/rules/A15-4-4/MissingNoExcept.ql
@@ -19,6 +19,36 @@ import codingstandards.cpp.autosar
import codingstandards.cpp.exceptions.ExceptionSpecifications
import codingstandards.cpp.exceptions.ExceptionFlow
+// These functions have a noexcept specification that could not be resolved
+// to noexcept(true). So either, they are noexcept(false) functions which
+// means, they can throw an exception OR they have an expression which
+// could not be resolved to "true" or "false". Even in this case, lets
+// be more conservative and assume they may thrown an exception.
+class FunctionWithUnknownNoExcept extends Function {
+ FunctionWithUnknownNoExcept() {
+ // Exists a noexcept specification but not noexcept(true)
+ exists(this.getADeclarationEntry().getNoExceptExpr()) and
+ not isNoExceptTrue(this)
+ }
+}
+
+// This predicate checks if a function can call to other functions
+// that may have a noexcept specification which cannot be resolved to
+// noexcept(true).
+predicate mayCallThrowingFunctions(Function f) {
+ // Exists a call in this function
+ exists(Call fc |
+ fc.getEnclosingFunction() = f and
+ (
+ // Either this call is to a function with an unknown noexcept OR
+ fc.getTarget() instanceof FunctionWithUnknownNoExcept
+ or
+ // That function can further have calls to unknown noexcept functions.
+ mayCallThrowingFunctions(fc.getTarget())
+ )
+ )
+}
+
from Function f
where
not isExcluded(f, Exceptions1Package::missingNoExceptQuery()) and
@@ -28,6 +58,12 @@ where
not isNoExceptTrue(f) and
// Not explicitly marked noexcept(false)
not isNoExceptExplicitlyFalse(f) and
+ // Not having a noexcept specification that
+ // could not be computed as true or false above.
+ not exists(f.getADeclarationEntry().getNoExceptExpr()) and
+ // Not calling function(s) which have a noexcept specification that
+ // could not be computed as true.
+ not mayCallThrowingFunctions(f) and
// Not compiler generated
not f.isCompilerGenerated() and
// The function is defined in this database
diff --git a/cpp/autosar/src/rules/A18-1-2/VectorboolSpecializationUsed.ql b/cpp/autosar/src/rules/A18-1-2/VectorboolSpecializationUsed.ql
index 2d94fde98c..5bbe181927 100644
--- a/cpp/autosar/src/rules/A18-1-2/VectorboolSpecializationUsed.ql
+++ b/cpp/autosar/src/rules/A18-1-2/VectorboolSpecializationUsed.ql
@@ -17,23 +17,10 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.StdNamespace
+import codingstandards.cpp.rules.vectorshouldnotbespecializedwithbool.VectorShouldNotBeSpecializedWithBool
-predicate isVectorBool(ClassTemplateInstantiation c) {
- c.getNamespace() instanceof StdNS and
- c.getTemplateArgument(0) instanceof BoolType and
- c.getSimpleName() = "vector"
+class VectorboolSpecializationUsedQuery extends VectorShouldNotBeSpecializedWithBoolSharedQuery {
+ VectorboolSpecializationUsedQuery() {
+ this = BannedTypesPackage::vectorboolSpecializationUsedQuery()
+ }
}
-
-predicate isUsingVectorBool(ClassTemplateInstantiation c) {
- isVectorBool(c) or
- isUsingVectorBool(c.getTemplateArgument(_))
-}
-
-from Variable v, ClassTemplateInstantiation c
-where
- v.getUnderlyingType() = c and
- not v.isFromTemplateInstantiation(_) and
- isUsingVectorBool(c) and
- not isExcluded(v, BannedTypesPackage::vectorboolSpecializationUsedQuery())
-select v, "Use of std::vector specialization."
diff --git a/cpp/autosar/src/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.ql b/cpp/autosar/src/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.ql
index 842dc14390..353c985137 100644
--- a/cpp/autosar/src/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.ql
+++ b/cpp/autosar/src/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.SmartPointers
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import SingleObjectSmartPointerArrayConstructionFlow::PathGraph
class AutosarSmartPointerArraySpecialisation extends AutosarSmartPointer {
diff --git a/cpp/autosar/src/rules/A18-5-2/DoNotUseNonPlacementNew.ql b/cpp/autosar/src/rules/A18-5-2/DoNotUseNonPlacementNew.ql
index 082827f5bb..1320d6e486 100644
--- a/cpp/autosar/src/rules/A18-5-2/DoNotUseNonPlacementNew.ql
+++ b/cpp/autosar/src/rules/A18-5-2/DoNotUseNonPlacementNew.ql
@@ -15,7 +15,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
from NewOrNewArrayExpr na
where
diff --git a/cpp/autosar/src/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.ql b/cpp/autosar/src/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.ql
index 7819cfad4d..274b18301c 100644
--- a/cpp/autosar/src/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.ql
+++ b/cpp/autosar/src/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.ql
@@ -15,14 +15,11 @@
import cpp
import codingstandards.cpp.autosar
-import OperatorDelete
+import codingstandards.cpp.rules.globalsizedoperatordeletenotdefined.GlobalSizedOperatorDeleteNotDefined
-from OperatorDelete unsized_delete
-where
- not isExcluded(unsized_delete, DeclarationsPackage::globalSizedOperatorDeleteNotDefinedQuery()) and
- not unsized_delete.isSizeDelete() and
- not exists(OperatorDelete od | unsized_delete.isNoThrowDelete() = od.isNoThrowDelete() |
- od.isSizeDelete()
- )
-select unsized_delete,
- "Unsized function '" + unsized_delete.getName() + "' defined globally without sized version."
+class GlobalSizedOperatorDeleteNotDefinedQuery extends GlobalSizedOperatorDeleteNotDefinedSharedQuery
+{
+ GlobalSizedOperatorDeleteNotDefinedQuery() {
+ this = DeclarationsPackage::globalSizedOperatorDeleteNotDefinedQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.ql b/cpp/autosar/src/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.ql
index 2c96660704..2bd0ada800 100644
--- a/cpp/autosar/src/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.ql
+++ b/cpp/autosar/src/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.ql
@@ -15,14 +15,11 @@
import cpp
import codingstandards.cpp.autosar
-import OperatorDelete
+import codingstandards.cpp.rules.globalunsizedoperatordeletenotdefined.GlobalUnsizedOperatorDeleteNotDefined
-from OperatorDelete sized_delete
-where
- not isExcluded(sized_delete, DeclarationsPackage::globalUnsizedOperatorDeleteNotDefinedQuery()) and
- sized_delete.isSizeDelete() and
- not exists(OperatorDelete od | sized_delete.isNoThrowDelete() = od.isNoThrowDelete() |
- not od.isSizeDelete()
- )
-select sized_delete,
- "Sized function '" + sized_delete.getName() + "' defined globally without unsized version."
+class GlobalUnsizedOperatorDeleteNotDefinedQuery extends GlobalUnsizedOperatorDeleteNotDefinedSharedQuery
+{
+ GlobalUnsizedOperatorDeleteNotDefinedQuery() {
+ this = DeclarationsPackage::globalUnsizedOperatorDeleteNotDefinedQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/A18-5-8/UnnecessaryUseOfDynamicStorage.ql b/cpp/autosar/src/rules/A18-5-8/UnnecessaryUseOfDynamicStorage.ql
index 7b68030476..cf83f055bd 100644
--- a/cpp/autosar/src/rules/A18-5-8/UnnecessaryUseOfDynamicStorage.ql
+++ b/cpp/autosar/src/rules/A18-5-8/UnnecessaryUseOfDynamicStorage.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import codingstandards.cpp.standardlibrary.Utility
/*
diff --git a/cpp/autosar/src/rules/A18-9-2/ForwardingValuesToOtherFunctions.ql b/cpp/autosar/src/rules/A18-9-2/ForwardingValuesToOtherFunctions.ql
index b0dd714209..72de362ebc 100644
--- a/cpp/autosar/src/rules/A18-9-2/ForwardingValuesToOtherFunctions.ql
+++ b/cpp/autosar/src/rules/A18-9-2/ForwardingValuesToOtherFunctions.ql
@@ -14,20 +14,12 @@
*/
import cpp
-import codingstandards.cpp.standardlibrary.Utility
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.forwardingreferencesandforwardnotusedtogether.ForwardingReferencesAndForwardNotUsedTogether
-from FunctionCall c, Parameter a, string message
-where
- not isExcluded(c, MoveForwardPackage::forwardingValuesToOtherFunctionsQuery()) and
- a.getAnAccess() = c.getAnArgument() and
- (
- c instanceof StdMoveCall and
- a instanceof ForwardParameter and
- message = "Function `std::forward` should be used for forwarding the forward reference $@."
- or
- c instanceof StdForwardCall and
- a instanceof ConsumeParameter and
- message = "Function `std::move` should be used for forwarding rvalue reference $@."
- )
-select c, message, a, a.getName()
+class ForwardingValuesToOtherFunctionsQuery extends ForwardingReferencesAndForwardNotUsedTogetherSharedQuery
+{
+ ForwardingValuesToOtherFunctionsQuery() {
+ this = MoveForwardPackage::forwardingValuesToOtherFunctionsQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/A18-9-4/ArgumentToForwardSubsequentlyUsed.ql b/cpp/autosar/src/rules/A18-9-4/ArgumentToForwardSubsequentlyUsed.ql
index d87366c624..a3acf916ec 100644
--- a/cpp/autosar/src/rules/A18-9-4/ArgumentToForwardSubsequentlyUsed.ql
+++ b/cpp/autosar/src/rules/A18-9-4/ArgumentToForwardSubsequentlyUsed.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.standardlibrary.Utility
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
from StdForwardCall f, Access a
where
diff --git a/cpp/autosar/src/rules/A2-13-1/EscapeSequenceOutsideISO.ql b/cpp/autosar/src/rules/A2-13-1/EscapeSequenceOutsideISO.ql
index d8382f51c8..0f1d9a3271 100644
--- a/cpp/autosar/src/rules/A2-13-1/EscapeSequenceOutsideISO.ql
+++ b/cpp/autosar/src/rules/A2-13-1/EscapeSequenceOutsideISO.ql
@@ -16,11 +16,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.backslashcharactermisuse.BackslashCharacterMisuse
-from StringLiteral l, string es
-where
- not isExcluded(l, LiteralsPackage::escapeSequenceOutsideISOQuery()) and
- es = l.getANonStandardEscapeSequence(_, _) and
- // Exclude universal-character-names, which begin with \u or \U
- not es.toLowerCase().matches("\\u")
-select l, "This literal contains the non-standard escape sequence " + es + "."
+class EscapeSequenceOutsideISOQuery extends BackslashCharacterMisuseSharedQuery {
+ EscapeSequenceOutsideISOQuery() { this = LiteralsPackage::escapeSequenceOutsideISOQuery() }
+}
diff --git a/cpp/autosar/src/rules/A2-7-1/SingleLineCommentEndsWithSlash.ql b/cpp/autosar/src/rules/A2-7-1/SingleLineCommentEndsWithSlash.ql
index adbb1dccea..cd7d7c42cd 100644
--- a/cpp/autosar/src/rules/A2-7-1/SingleLineCommentEndsWithSlash.ql
+++ b/cpp/autosar/src/rules/A2-7-1/SingleLineCommentEndsWithSlash.ql
@@ -17,9 +17,10 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.linesplicingusedincomments.LineSplicingUsedInComments
-from CppStyleComment c
-where
- not isExcluded(c, CommentsPackage::singleLineCommentEndsWithSlashQuery()) and
- exists(c.getContents().regexpFind("\\\n", _, _))
-select c, "C++ comment includes \\ as the last character of a line"
+class SingleLineCommentEndsWithSlashQuery extends LineSplicingUsedInCommentsSharedQuery {
+ SingleLineCommentEndsWithSlashQuery() {
+ this = CommentsPackage::singleLineCommentEndsWithSlashQuery()
+ }
+}
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/A20-8-4/SharedPointerUsedWithNoOwnershipSharing.ql b/cpp/autosar/src/rules/A20-8-4/SharedPointerUsedWithNoOwnershipSharing.ql
index c7ff6f6bf2..0294bfe2e6 100644
--- a/cpp/autosar/src/rules/A20-8-4/SharedPointerUsedWithNoOwnershipSharing.ql
+++ b/cpp/autosar/src/rules/A20-8-4/SharedPointerUsedWithNoOwnershipSharing.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.SmartPointers
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/*
* Finds `std::shared_ptr` local variables which are not copy or move initialized, and are not used in
diff --git a/cpp/autosar/src/rules/A27-0-4/CStyleStringsUsed.ql b/cpp/autosar/src/rules/A27-0-4/CStyleStringsUsed.ql
index b698ecf351..b24a4a96cf 100644
--- a/cpp/autosar/src/rules/A27-0-4/CStyleStringsUsed.ql
+++ b/cpp/autosar/src/rules/A27-0-4/CStyleStringsUsed.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
class InstanceOfCStyleString extends Expr {
InstanceOfCStyleString() {
diff --git a/cpp/autosar/src/rules/A3-9-1/VariableWidthIntegerTypesUsed.ql b/cpp/autosar/src/rules/A3-9-1/VariableWidthIntegerTypesUsed.ql
index 84a38b0f6a..fa19ad998f 100644
--- a/cpp/autosar/src/rules/A3-9-1/VariableWidthIntegerTypesUsed.ql
+++ b/cpp/autosar/src/rules/A3-9-1/VariableWidthIntegerTypesUsed.ql
@@ -32,6 +32,10 @@ where
typeStrippedOfSpecifiers instanceof SignedCharType
) and
not v instanceof ExcludedVariable and
+ // Dont consider template instantiations because instantiations with
+ // Fixed Width Types are recorded after stripping their typedef'd type,
+ // thereby, causing false positives (#540).
+ not v.isFromTemplateInstantiation(_) and
//post-increment/post-decrement operators are required by the standard to have a dummy int parameter
not v.(Parameter).getFunction() instanceof PostIncrementOperator and
not v.(Parameter).getFunction() instanceof PostDecrementOperator
diff --git a/cpp/autosar/src/rules/A4-10-1/NullPointerConstantNotNullptr.ql b/cpp/autosar/src/rules/A4-10-1/NullPointerConstantNotNullptr.ql
index e77c8265d5..ce3c6f8461 100644
--- a/cpp/autosar/src/rules/A4-10-1/NullPointerConstantNotNullptr.ql
+++ b/cpp/autosar/src/rules/A4-10-1/NullPointerConstantNotNullptr.ql
@@ -16,17 +16,11 @@
import cpp
import codingstandards.cpp.autosar
-import semmle.code.cpp.commons.NULL
+import codingstandards.cpp.rules.nullptrnottheonlyformofthenullpointerconstant.NullptrNotTheOnlyFormOfTheNullPointerConstant
-from Literal l
-where
- not isExcluded(l, LiteralsPackage::nullPointerConstantNotNullptrQuery()) and
- // Not the type of the nullptr literal
- not l.getType() instanceof NullPointerType and
- // Converted to a pointer type
- l.getConversion().getType().getUnspecifiedType() instanceof PointerType and
- // Value of zero
- l.getValue() = "0" and
- // Not the StringLiteral "0"
- not l instanceof StringLiteral
-select l, l.getValueText() + " is used as the null-pointer-constant but is not nullptr."
+class NullPointerConstantNotNullptrQuery extends NullptrNotTheOnlyFormOfTheNullPointerConstantSharedQuery
+{
+ NullPointerConstantNotNullptrQuery() {
+ this = LiteralsPackage::nullPointerConstantNotNullptrQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.ql b/cpp/autosar/src/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.ql
index 34b6660778..ac2375f6aa 100644
--- a/cpp/autosar/src/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.ql
+++ b/cpp/autosar/src/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.ql
@@ -17,7 +17,7 @@
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.Type
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import NonFinalClassToPointerArithmeticExprFlow::PathGraph
class ArrayAccessOrPointerArith extends Expr {
diff --git a/cpp/autosar/src/rules/A5-1-7/LambdaPassedToDecltype.ql b/cpp/autosar/src/rules/A5-1-7/LambdaPassedToDecltype.ql
index afbd809664..971d3b9259 100644
--- a/cpp/autosar/src/rules/A5-1-7/LambdaPassedToDecltype.ql
+++ b/cpp/autosar/src/rules/A5-1-7/LambdaPassedToDecltype.ql
@@ -15,7 +15,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
module LambdaExpressionToInitializerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof LambdaExpression }
diff --git a/cpp/autosar/src/rules/A5-1-7/LambdaPassedToTypeid.ql b/cpp/autosar/src/rules/A5-1-7/LambdaPassedToTypeid.ql
index 08dbecc755..56952dace9 100644
--- a/cpp/autosar/src/rules/A5-1-7/LambdaPassedToTypeid.ql
+++ b/cpp/autosar/src/rules/A5-1-7/LambdaPassedToTypeid.ql
@@ -14,7 +14,7 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.autosar
import LambdaExpressionToTypeidFlow::PathGraph
diff --git a/cpp/autosar/src/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.ql b/cpp/autosar/src/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.ql
index 2289dc4e79..825347754d 100644
--- a/cpp/autosar/src/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.ql
+++ b/cpp/autosar/src/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.ql
@@ -16,19 +16,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.potentiallyvirtualpointeronlycomparestonullptr.PotentiallyVirtualPointerOnlyComparesToNullptr
-from
- EqualityOperation equalityComparison, MemberFunction virtualFunction,
- FunctionAccess accessOperand, Expr otherOperand
-where
- not isExcluded(equalityComparison,
- PointersPackage::pointerToMemberVirtualFunctionWithNullPointerConstantQuery()) and
- virtualFunction.isVirtual() and
- equalityComparison.getAnOperand() = accessOperand and
- accessOperand.getTarget() = virtualFunction and
- otherOperand = equalityComparison.getAnOperand() and
- not otherOperand = accessOperand and
- not otherOperand.getType() instanceof NullPointerType
-select equalityComparison,
- "A pointer to member virtual function $@ is tested for equality with non-null-pointer-constant $@. ",
- virtualFunction, virtualFunction.getName(), otherOperand, otherOperand.toString()
+class PointerToMemberVirtualFunctionWithNullPointerConstantQuery extends PotentiallyVirtualPointerOnlyComparesToNullptrSharedQuery
+{
+ PointerToMemberVirtualFunctionWithNullPointerConstantQuery() {
+ this = PointersPackage::pointerToMemberVirtualFunctionWithNullPointerConstantQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/A5-2-4/ReinterpretCastUsed.ql b/cpp/autosar/src/rules/A5-2-4/ReinterpretCastUsed.ql
index 92cf12d8a0..bf5805698d 100644
--- a/cpp/autosar/src/rules/A5-2-4/ReinterpretCastUsed.ql
+++ b/cpp/autosar/src/rules/A5-2-4/ReinterpretCastUsed.ql
@@ -16,7 +16,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.reinterpretcastused.ReinterpretCastUsed
-from ReinterpretCast rc
-where not isExcluded(rc, BannedSyntaxPackage::reinterpretCastUsedQuery())
-select rc, "Use of reinterpret_cast."
+class ReinterpretCastUsedQuery extends ReinterpretCastUsedSharedQuery {
+ ReinterpretCastUsedQuery() { this = BannedSyntaxPackage::reinterpretCastUsedQuery() }
+}
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/A6-6-1/GotoStatementUsed.ql b/cpp/autosar/src/rules/A6-6-1/GotoStatementUsed.ql
index 5e1c10e4c7..03b891e6db 100644
--- a/cpp/autosar/src/rules/A6-6-1/GotoStatementUsed.ql
+++ b/cpp/autosar/src/rules/A6-6-1/GotoStatementUsed.ql
@@ -16,9 +16,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.gotostatementshouldnotbeused.GotoStatementShouldNotBeUsed
-from Stmt s
-where
- not isExcluded(s, BannedSyntaxPackage::gotoStatementUsedQuery()) and
- (s instanceof GotoStmt or s instanceof ComputedGotoStmt)
-select s, "Use of goto."
+class GotoStatementUsedQuery extends GotoStatementShouldNotBeUsedSharedQuery {
+ GotoStatementUsedQuery() { this = BannedSyntaxPackage::gotoStatementUsedQuery() }
+}
diff --git a/cpp/autosar/src/rules/A7-1-2/VariableMissingConstexpr.ql b/cpp/autosar/src/rules/A7-1-2/VariableMissingConstexpr.ql
index f0adab07d4..a07dbd43f7 100644
--- a/cpp/autosar/src/rules/A7-1-2/VariableMissingConstexpr.ql
+++ b/cpp/autosar/src/rules/A7-1-2/VariableMissingConstexpr.ql
@@ -35,13 +35,25 @@ predicate isTypeZeroInitializable(Type t) {
t.getUnderlyingType() instanceof ArrayType
}
-from Variable v
+from Variable v, string msg
where
not isExcluded(v, ConstPackage::variableMissingConstexprQuery()) and
v.hasDefinition() and
not v.isConstexpr() and
not v instanceof Parameter and
not v.isAffectedByMacro() and
+ (
+ not v instanceof MemberVariable
+ or
+ // In case member functions are left un-instantiated, it is possible
+ // the member variable could be modified in them.
+ // Hence, don't raise an alert in case this member variable's class
+ // has a member function that doesn't have a definition.
+ not exists(MemberFunction mf |
+ mf.getDeclaringType() = v.getDeclaringType() and
+ mf.isFromUninstantiatedTemplate(_)
+ )
+ ) and
isLiteralType(v.getType()) and
// Unfortunately, `isConstant` is not sufficient here because it doesn't include calls to
// constexpr constructors, and does not take into account zero initialization
@@ -66,5 +78,6 @@ where
// Exclude variables in uninstantiated templates, as they may be incomplete
not v.isFromUninstantiatedTemplate(_) and
// Exclude compiler generated variables, which are not user controllable
- not v.isCompilerGenerated()
-select v, "Variable '" + v.getName() + "' could be marked 'constexpr'."
+ not v.isCompilerGenerated() and
+ if v instanceof MemberVariable and not v.isStatic() then msg = " and static." else msg = "."
+select v, "Variable '" + v.getName() + "' could be marked 'constexpr'" + msg
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-1-7/IdentifierDeclarationAndInitializationNotOnSeparateLines.ql b/cpp/autosar/src/rules/A7-1-7/IdentifierDeclarationAndInitializationNotOnSeparateLines.ql
index 8c10a0f80c..89aca8048e 100644
--- a/cpp/autosar/src/rules/A7-1-7/IdentifierDeclarationAndInitializationNotOnSeparateLines.ql
+++ b/cpp/autosar/src/rules/A7-1-7/IdentifierDeclarationAndInitializationNotOnSeparateLines.ql
@@ -19,26 +19,28 @@ import codingstandards.cpp.autosar
class UniqueLineStmt extends Locatable {
UniqueLineStmt() {
not isAffectedByMacro() and
- exists(Declaration d |
- this = d.getADeclarationEntry() and
- not d instanceof Parameter and
- not d instanceof TemplateParameter and
- // TODO - Needs to be enhanced to solve issues with
- // templated inner classes.
- not d instanceof Function and
- not d.isFromTemplateInstantiation(_) and
- not d.(Variable).isCompilerGenerated() and
- not exists(RangeBasedForStmt f | f.getADeclaration() = d) and
- not exists(DeclStmt declStmt, ForStmt f |
- f.getInitialization() = declStmt and
- declStmt.getADeclaration() = d
- ) and
- not exists(LambdaCapture lc | lc.getField().getADeclarationEntry() = this)
+ (
+ exists(Declaration d |
+ this = d.getADeclarationEntry() and
+ not d instanceof Parameter and
+ not d instanceof TemplateParameter and
+ // TODO - Needs to be enhanced to solve issues with
+ // templated inner classes.
+ not d instanceof Function and
+ not d.isFromTemplateInstantiation(_) and
+ not d.(Variable).isCompilerGenerated() and
+ not exists(RangeBasedForStmt f | f.getADeclaration() = d) and
+ not exists(DeclStmt declStmt, ForStmt f |
+ f.getInitialization() = declStmt and
+ declStmt.getADeclaration() = d
+ ) and
+ not exists(LambdaCapture lc | lc.getField().getADeclarationEntry() = this)
+ )
+ or
+ this instanceof ExprStmt and
+ not exists(ForStmt f | f.getInitialization().getAChild*() = this) and
+ not exists(LambdaExpression l | l.getLambdaFunction().getBlock().getAChild*() = this)
)
- or
- this instanceof ExprStmt and
- not exists(ForStmt f | f.getInitialization().getAChild*() = this) and
- not exists(LambdaExpression l | l.getLambdaFunction().getBlock().getAChild*() = this)
}
}
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/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.ql b/cpp/autosar/src/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.ql
index cf5273f45d..42924945cd 100644
--- a/cpp/autosar/src/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.ql
+++ b/cpp/autosar/src/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.ql
@@ -17,9 +17,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.enumerationnotdefinedwithanexplicitunderlyingtype.EnumerationNotDefinedWithAnExplicitUnderlyingType
-from Enum e
-where
- not isExcluded(e, DeclarationsPackage::enumerationUnderlyingBaseTypeNotExplicitlyDefinedQuery()) and
- not e.hasExplicitUnderlyingType()
-select e, "Base type of enumeration is not explicitly specified."
+class EnumerationUnderlyingBaseTypeNotExplicitlyDefinedQuery extends EnumerationNotDefinedWithAnExplicitUnderlyingTypeSharedQuery
+{
+ EnumerationUnderlyingBaseTypeNotExplicitlyDefinedQuery() {
+ this = DeclarationsPackage::enumerationUnderlyingBaseTypeNotExplicitlyDefinedQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.ql b/cpp/autosar/src/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.ql
index ac6e1b6ff9..75cb2016b5 100644
--- a/cpp/autosar/src/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.ql
+++ b/cpp/autosar/src/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.ql
@@ -16,56 +16,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.definitionnotconsideredforunqualifiedlookup.DefinitionNotConsideredForUnqualifiedLookup
-/**
- * Holds if `functionDecl` is a possible intended target of the `usingDecl`.
- */
-pragma[noinline]
-predicate isPossibleIntendedTarget(
- FunctionDeclarationEntry functionDecl, UsingDeclarationEntry usingDecl
-) {
- // Extracted to improve the join order. With this approach, we first compute a set of using
- // declarations and a set of possible intended targets
- functionDecl.getDeclaration().isTopLevel() and
- functionDecl.getDeclaration().getQualifiedName() = usingDecl.getDeclaration().getQualifiedName() and
- functionDecl.getDeclaration().getNamespace().getParentNamespace*() = usingDecl.getParentScope()
+class DefinitionNotConsideredForUnqualifiedLookupQuery extends DefinitionNotConsideredForUnqualifiedLookupSharedQuery
+{
+ DefinitionNotConsideredForUnqualifiedLookupQuery() {
+ this = ScopePackage::definitionNotConsideredForUnqualifiedLookupQuery()
+ }
}
-
-/**
- * Holds if `functionDecl` is a possible intended target of the `usingDecl`, and they exist at the
- * given locations.
- */
-pragma[noinline]
-predicate isPossibleIntendedTargetLocation(
- FunctionDeclarationEntry functionDecl, UsingDeclarationEntry usingDecl, File usingsFile,
- File unavailableFile, int usingsStartLine, int unavailableStartLine
-) {
- // Extracted to improve the join order. With this approach, we take the set of possible intended
- // targets computed in isPossibleIntendedTargets, and compute the files and start lines.
- // This helps avoid the join order preferred by the optimiser if this is all written directly in
- // the from-where-select, where it will eagerly join:
- //
- // usingDeclarationEntries -> enclosing files -> all other elements in those files
- //
- // which is expensive when there are a lot of files with using declarations
- isPossibleIntendedTarget(functionDecl, usingDecl) and
- usingsFile = usingDecl.getFile() and
- unavailableFile = functionDecl.getFile() and
- usingsStartLine = usingDecl.getLocation().getStartLine() and
- unavailableStartLine = functionDecl.getLocation().getStartLine()
-}
-
-from FunctionDeclarationEntry unavailableDecl, UsingDeclarationEntry usingDecl
-where
- not isExcluded(unavailableDecl, ScopePackage::definitionNotConsideredForUnqualifiedLookupQuery()) and
- exists(File usingsFile, File unavailableFile, int usingsStartLine, int unavailableStartLine |
- isPossibleIntendedTargetLocation(unavailableDecl, usingDecl, usingsFile, unavailableFile,
- usingsStartLine, unavailableStartLine) and
- // An approximation of order where we want the using to preceed the new declaration.
- usingsFile = unavailableFile and
- usingsStartLine < unavailableStartLine
- )
-select unavailableDecl,
- "Definition for '" + unavailableDecl.getName() +
- "' is not available for unqualified lookup because it is declared after $@", usingDecl,
- "using-declaration"
diff --git a/cpp/autosar/src/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.ql b/cpp/autosar/src/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.ql
index fa1859c229..fd9602f218 100644
--- a/cpp/autosar/src/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.ql
+++ b/cpp/autosar/src/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.ql
@@ -15,45 +15,11 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.Class
+import codingstandards.cpp.rules.hiddeninheritednonoverridablememberfunction.HiddenInheritedNonOverridableMemberFunction
-/**
- * Holds if the class has a non-virtual member function with the given name.
- */
-pragma[noinline, nomagic]
-predicate hasNonVirtualMemberFunction(Class clazz, MemberFunction mf, string name) {
- mf.getDeclaringType() = clazz and
- mf.getName() = name and
- not mf.isVirtual() and
- // Exclude private member functions, which cannot be inherited.
- not mf.isPrivate()
+class HiddenInheritedNonOverridableMemberFunctionQuery extends HiddenInheritedNonOverridableMemberFunctionSharedQuery
+{
+ HiddenInheritedNonOverridableMemberFunctionQuery() {
+ this = ScopePackage::hiddenInheritedNonOverridableMemberFunctionQuery()
+ }
}
-
-/**
- * Holds if the member function is in a class with the given base class, and has the given name.
- */
-pragma[noinline, nomagic]
-predicate hasDeclarationBaseClass(MemberFunction mf, Class baseClass, string functionName) {
- baseClass = mf.getDeclaringType().getABaseClass() and
- functionName = mf.getName()
-}
-
-from MemberFunction overridingDecl, MemberFunction hiddenDecl, Class baseClass, string name
-where
- not isExcluded(overridingDecl, ScopePackage::hiddenInheritedNonOverridableMemberFunctionQuery()) and
- // Check if we are overriding a non-virtual inherited member function
- hasNonVirtualMemberFunction(baseClass, hiddenDecl, name) and
- hasDeclarationBaseClass(overridingDecl, baseClass, name) and
- // Where the hidden member function isn't explicitly brought in scope through a using declaration.
- not exists(UsingDeclarationEntry ude |
- ude.getDeclaration() = hiddenDecl and
- ude.getEnclosingElement() = overridingDecl.getDeclaringType()
- ) and
- // Exclude compiler generated member functions which include things like copy constructor that hide base class
- // copy constructors.
- not overridingDecl.isCompilerGenerated() and
- // Exclude special member functions, which cannot be inherited.
- not overridingDecl instanceof SpecialMemberFunction
-select overridingDecl,
- "Declaration for member '" + name + "' hides non-overridable inherited member function $@",
- hiddenDecl, hiddenDecl.getName()
diff --git a/cpp/autosar/src/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.ql b/cpp/autosar/src/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.ql
index 437c8798f9..aa9105f9de 100644
--- a/cpp/autosar/src/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.ql
+++ b/cpp/autosar/src/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.ql
@@ -15,42 +15,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.hiddeninheritedoverridablememberfunction.HiddenInheritedOverridableMemberFunction
-from FunctionDeclarationEntry overridingDecl, FunctionDeclarationEntry hiddenDecl
-where
- not isExcluded(overridingDecl, ScopePackage::hiddenInheritedOverridableMemberFunctionQuery()) and
- // Check if we are overriding a virtual inherited member function
- hiddenDecl.getDeclaration().isVirtual() and
- // Exclude private member functions, which cannot be inherited.
- not hiddenDecl.getDeclaration().(MemberFunction).isPrivate() and
- // The overriding declaration hides the hidden declaration if:
- (
- // 1. the overriding declaration overrides a function in a base class that is an overload of the hidden declaration
- // and the hidden declaration isn't overriden in the same class.
- exists(FunctionDeclarationEntry overridenDecl |
- overridingDecl.getDeclaration().(MemberFunction).overrides(overridenDecl.getDeclaration()) and
- overridenDecl.getDeclaration().getAnOverload() = hiddenDecl.getDeclaration() and
- not exists(MemberFunction overridingFunc |
- hiddenDecl.getDeclaration().(MemberFunction).getAnOverridingFunction() = overridingFunc and
- overridingFunc.getDeclaringType() = overridingDecl.getDeclaration().getDeclaringType()
- )
- ) and
- // and the hidden declaration isn't explicitly brought in scope through a using declaration.
- not exists(UsingDeclarationEntry ude |
- ude.getDeclaration() = hiddenDecl.getDeclaration() and
- ude.getEnclosingElement() = overridingDecl.getDeclaration().getDeclaringType()
- )
- or
- // 2. if the overriding declaration doesn't override a base member function but has the same name
- // as the hidden declaration
- not overridingDecl.getDeclaration().(MemberFunction).overrides(_) and
- overridingDecl.getName() = hiddenDecl.getName() and
- overridingDecl.getDeclaration().getDeclaringType().getABaseClass() =
- hiddenDecl.getDeclaration().getDeclaringType()
- ) and
- // Limit the results to the declarations and not the definitions, if any.
- (overridingDecl.getDeclaration().hasDefinition() implies not overridingDecl.isDefinition()) and
- (hiddenDecl.getDeclaration().hasDefinition() implies not hiddenDecl.isDefinition())
-select overridingDecl,
- "Declaration for member '" + overridingDecl.getName() +
- "' hides overridable inherited member function $@", hiddenDecl, hiddenDecl.getName()
+class HiddenInheritedOverridableMemberFunctionQuery extends HiddenInheritedOverridableMemberFunctionSharedQuery
+{
+ HiddenInheritedOverridableMemberFunctionQuery() {
+ this = ScopePackage::hiddenInheritedOverridableMemberFunctionQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/A7-4-1/AsmDeclarationUsed.ql b/cpp/autosar/src/rules/A7-4-1/AsmDeclarationUsed.ql
index d94811ff18..44489151da 100644
--- a/cpp/autosar/src/rules/A7-4-1/AsmDeclarationUsed.ql
+++ b/cpp/autosar/src/rules/A7-4-1/AsmDeclarationUsed.ql
@@ -15,7 +15,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.asmdeclarationused.AsmDeclarationUsed
-from AsmStmt a
-where not isExcluded(a, BannedSyntaxPackage::asmDeclarationUsedQuery())
-select a, "Use of asm declaration"
+class AsmDeclarationUsedQuery extends AsmDeclarationUsedSharedQuery {
+ AsmDeclarationUsedQuery() { this = BannedSyntaxPackage::asmDeclarationUsedQuery() }
+}
diff --git a/cpp/autosar/src/rules/A7-5-1/InvalidFunctionReturnType.ql b/cpp/autosar/src/rules/A7-5-1/InvalidFunctionReturnType.ql
index 6994ab028f..c36bda6cdd 100644
--- a/cpp/autosar/src/rules/A7-5-1/InvalidFunctionReturnType.ql
+++ b/cpp/autosar/src/rules/A7-5-1/InvalidFunctionReturnType.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
from Parameter p, ReturnStmt ret
where
diff --git a/cpp/autosar/src/rules/A7-5-2/RecursiveFunctions.ql b/cpp/autosar/src/rules/A7-5-2/RecursiveFunctions.ql
index 13883624b3..6b305d9ca9 100644
--- a/cpp/autosar/src/rules/A7-5-2/RecursiveFunctions.ql
+++ b/cpp/autosar/src/rules/A7-5-2/RecursiveFunctions.ql
@@ -16,21 +16,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.functionscallthemselveseitherdirectlyorindirectly.FunctionsCallThemselvesEitherDirectlyOrIndirectly
-class RecursiveCall extends FunctionCall {
- RecursiveCall() {
- this.getTarget().calls*(this.getEnclosingFunction()) and
- not this.getTarget().hasSpecifier("is_constexpr")
- }
+class RecursiveFunctionsQuery extends FunctionsCallThemselvesEitherDirectlyOrIndirectlySharedQuery {
+ RecursiveFunctionsQuery() { this = FunctionsPackage::recursiveFunctionsQuery() }
}
-
-from RecursiveCall call, string msg, FunctionCall fc
-where
- not isExcluded(fc, FunctionsPackage::recursiveFunctionsQuery()) and
- fc.getTarget() = call.getTarget() and
- if fc.getTarget() = fc.getEnclosingFunction()
- then msg = "This call directly invokes its containing function $@."
- else
- msg =
- "The function " + fc.getEnclosingFunction() + " is indirectly recursive via this call to $@."
-select fc, msg, fc.getTarget(), fc.getTarget().getName()
diff --git a/cpp/autosar/src/rules/A8-4-11/SmartPointerAsParameterWithoutLifetimeSemantics.ql b/cpp/autosar/src/rules/A8-4-11/SmartPointerAsParameterWithoutLifetimeSemantics.ql
index 811d98eccb..0bf42ce4ca 100644
--- a/cpp/autosar/src/rules/A8-4-11/SmartPointerAsParameterWithoutLifetimeSemantics.ql
+++ b/cpp/autosar/src/rules/A8-4-11/SmartPointerAsParameterWithoutLifetimeSemantics.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.SmartPointers
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.standardlibrary.Utility
Expr lifetimeAffectingSmartPointerExpr(Function f) {
diff --git a/cpp/autosar/src/rules/A8-4-12/UniquePtrPassedToFunctionWithImproperSemantics.ql b/cpp/autosar/src/rules/A8-4-12/UniquePtrPassedToFunctionWithImproperSemantics.ql
index 5dec96ed81..3cd310b59b 100644
--- a/cpp/autosar/src/rules/A8-4-12/UniquePtrPassedToFunctionWithImproperSemantics.ql
+++ b/cpp/autosar/src/rules/A8-4-12/UniquePtrPassedToFunctionWithImproperSemantics.ql
@@ -18,7 +18,7 @@ import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.SmartPointers
import codingstandards.cpp.standardlibrary.Utility
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
Expr underlyingObjectAffectingUniquePointerExpr(Function f) {
result =
diff --git a/cpp/autosar/src/rules/A8-4-4/FunctionReturnMultipleValueCondition.ql b/cpp/autosar/src/rules/A8-4-4/FunctionReturnMultipleValueCondition.ql
index fa38b1d3f6..ff0040f26f 100644
--- a/cpp/autosar/src/rules/A8-4-4/FunctionReturnMultipleValueCondition.ql
+++ b/cpp/autosar/src/rules/A8-4-4/FunctionReturnMultipleValueCondition.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
abstract class OutputValue extends Element {
abstract string getOutputName();
diff --git a/cpp/autosar/src/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.ql b/cpp/autosar/src/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.ql
index 2a44ca650e..180cbf7224 100644
--- a/cpp/autosar/src/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.ql
+++ b/cpp/autosar/src/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.ql
@@ -17,50 +17,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.initializerlistconstructoristheonlyconstructor.InitializerListConstructorIsTheOnlyConstructor
-class StdInitializerList extends Class {
- StdInitializerList() { hasQualifiedName("std", "initializer_list") }
-}
-
-/**
- * An _initializer-list constructor_ according to `[dcl.init.list]`.
- *
- * A `Constructor` where the first parameter refers to `std::initializer_list`, and any remaining
- * parameters have default arguments.
- */
-class InitializerListConstructor extends Constructor {
- InitializerListConstructor() {
- // The first parameter is a `std::intializer_list` parameter
- exists(Type firstParamType | firstParamType = getParameter(0).getType() |
- // Either directly `std::initializer_list`
- firstParamType instanceof StdInitializerList
- or
- //A reference to `std::initializer_list`
- firstParamType.(ReferenceType).getBaseType().getUnspecifiedType() instanceof
- StdInitializerList
- ) and
- // All parameters other than the fi
- forall(Parameter other | other = getParameter([1 .. (getNumberOfParameters() - 1)]) |
- exists(other.getInitializer())
- )
+class ConfusingUseOfInitializerListConstructorsQuery extends InitializerListConstructorIsTheOnlyConstructorSharedQuery
+{
+ ConfusingUseOfInitializerListConstructorsQuery() {
+ this = InitializationPackage::confusingUseOfInitializerListConstructorsQuery()
}
}
-
-from Constructor c, InitializerListConstructor stdInitializerConstructor, string paramList
-where
- not isExcluded(c, InitializationPackage::confusingUseOfInitializerListConstructorsQuery()) and
- // Not an initializer-list constructor
- not c instanceof InitializerListConstructor and
- // Constructor is not a special member function constructor
- not c instanceof CopyConstructor and
- not c instanceof MoveConstructor and
- not c.getNumberOfParameters() = 0 and // default constructor
- // And there is an initalizer-list constructor
- stdInitializerConstructor = c.getDeclaringType().getAConstructor() and
- // Determine the parameter type list of the constructor
- paramList =
- concat(string parameter | parameter = c.getAParameter().getType().getName() | parameter, ",")
-select c,
- "The constructor " + c.getQualifiedName() + "(" + paramList +
- ") may be ignored in favour of $@ when using braced initialization.", stdInitializerConstructor,
- "the constructor accepting std::initializer_list"
diff --git a/cpp/autosar/src/rules/A9-3-1/ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.ql b/cpp/autosar/src/rules/A9-3-1/ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.ql
index f40faad3dd..478f8dcdf0 100644
--- a/cpp/autosar/src/rules/A9-3-1/ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.ql
+++ b/cpp/autosar/src/rules/A9-3-1/ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.ql
@@ -15,7 +15,7 @@
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.CommonTypes as CommonTypes
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
class AccessAwareMemberFunction extends MemberFunction {
Class c;
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/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.ql b/cpp/autosar/src/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.ql
index 6b6cead0ea..c16e5461f0 100644
--- a/cpp/autosar/src/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.ql
+++ b/cpp/autosar/src/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.ql
@@ -14,24 +14,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.virtualandnonvirtualclassinthehierarchy.VirtualAndNonVirtualClassInTheHierarchy
-from Class c1, Class c2, Class c3, Class base, ClassDerivation cd1, ClassDerivation cd2
-where
- not isExcluded(c3,
- InheritancePackage::accessibleBaseClassBothVirtualAndNonVirtualInHierarchyQuery()) and
- // for each pair of classes, get all of their derivations
- cd1 = c1.getADerivation() and
- cd2 = c2.getADerivation() and
- // where they share the same base class
- base = cd1.getBaseClass() and
- base = cd2.getBaseClass() and
- // but one is virtual, and one is not, and the derivations are in different classes
- cd1.isVirtual() and
- not cd2.isVirtual() and
- // and there is some 'other class' that derives from both of these classes
- c3.derivesFrom*(c1) and
- c3.derivesFrom*(c2) and
- // and the base class is accessible from the 'other class'
- c3.getAMemberFunction().getEnclosingAccessHolder().canAccessClass(base, c3)
-select c3, "Class inherits base class $@, which is derived virtual by $@ and non-virtual by $@.",
- base, base.getName(), cd1, cd1.getDerivedClass().toString(), c2, cd2.getDerivedClass().toString()
+class AccessibleBaseClassBothVirtualAndNonVirtualInHierarchyQuery extends VirtualAndNonVirtualClassInTheHierarchySharedQuery
+{
+ AccessibleBaseClassBothVirtualAndNonVirtualInHierarchyQuery() {
+ this = InheritancePackage::accessibleBaseClassBothVirtualAndNonVirtualInHierarchyQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.ql b/cpp/autosar/src/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.ql
index 35f41c179a..4b6c037aba 100644
--- a/cpp/autosar/src/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.ql
+++ b/cpp/autosar/src/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.ql
@@ -14,79 +14,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.objectsdynamictypeusedfromconstructorordestructor.ObjectsDynamicTypeUsedFromConstructorOrDestructor
-predicate thisCall(FunctionCall c) {
- c.getQualifier() instanceof ThisExpr or
- c.getQualifier().(PointerDereferenceExpr).getChild(0) instanceof ThisExpr
-}
-
-predicate virtualThisCall(FunctionCall c, Function overridingFunction) {
- c.isVirtual() and
- thisCall(c) and
- overridingFunction = c.getTarget().(VirtualFunction).getAnOverridingFunction()
-}
-
-class DynamicTypeExpr extends Expr {
- DynamicTypeExpr() {
- this instanceof TypeidOperator and
- this.getEnclosingFunction().getDeclaringType().isPolymorphic()
- or
- this instanceof DynamicCast
- or
- virtualThisCall(this.(FunctionCall), _)
+class DynamicTypeOfThisUsedFromConstructorOrDestructorQuery extends ObjectsDynamicTypeUsedFromConstructorOrDestructorSharedQuery
+{
+ DynamicTypeOfThisUsedFromConstructorOrDestructorQuery() {
+ this = InheritancePackage::dynamicTypeOfThisUsedFromConstructorOrDestructorQuery()
}
}
-
-/*
- * Catch most cases: go into functions in the same class, but only catch direct
- * references to "this".
- */
-
-predicate nonVirtualMemberFunction(MemberFunction mf, Class c) {
- mf = c.getAMemberFunction() and
- not mf instanceof Constructor and
- not mf instanceof Destructor and
- not mf.isVirtual()
-}
-
-predicate callFromNonVirtual(MemberFunction source, Class c, MemberFunction targ) {
- exists(FunctionCall fc |
- fc.getEnclosingFunction() = source and fc.getTarget() = targ and thisCall(fc)
- ) and
- targ = c.getAMemberFunction() and
- nonVirtualMemberFunction(source, c)
-}
-
-predicate indirectlyInvokesDynamicTypeExpr(MemberFunction caller, DynamicTypeExpr target) {
- target =
- any(DynamicTypeExpr expr |
- expr.getEnclosingFunction() = caller and
- nonVirtualMemberFunction(caller, caller.getDeclaringType())
- )
- or
- exists(MemberFunction mid |
- indirectlyInvokesDynamicTypeExpr(mid, target) and
- callFromNonVirtual(caller, caller.getDeclaringType(), mid)
- )
-}
-
-from DynamicTypeExpr expr, FunctionCall call, MemberFunction mf, string explanation
-where
- not isExcluded(expr, InheritancePackage::dynamicTypeOfThisUsedFromConstructorOrDestructorQuery()) and
- (
- mf instanceof Constructor or
- mf instanceof Destructor
- ) and
- (
- mf = expr.getEnclosingFunction() and
- explanation = "$@ uses the dynamic type of its own object."
- or
- mf != expr.getEnclosingFunction() and
- mf = call.getEnclosingFunction() and
- thisCall(call) and
- indirectlyInvokesDynamicTypeExpr(call.getTarget(), expr) and
- explanation =
- "$@ calls " + call.getTarget().getQualifiedName() +
- ", which uses the dynamic type of its own object."
- )
-select expr, explanation, mf, mf.getQualifiedName()
diff --git a/cpp/autosar/src/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.ql b/cpp/autosar/src/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.ql
index 2736d39290..486a428474 100644
--- a/cpp/autosar/src/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.ql
+++ b/cpp/autosar/src/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.ql
@@ -16,27 +16,11 @@
import cpp
import codingstandards.cpp.autosar
-import NameInDependentBase
+import codingstandards.cpp.rules.namenotreferredusingaqualifiedidorthis.NameNotReferredUsingAQualifiedIdOrThis
-from
- TemplateClass c, NameQualifiableElement fn, string targetName, Element actualTarget,
- Element dependentTypeMemberWithSameName
-where
- not isExcluded(fn, TemplatesPackage::nameNotReferredUsingAQualifiedIdOrThisQuery()) and
- not isCustomExcluded(fn) and
- missingNameQualifier(fn) and
- (
- fn = getConfusingFunctionAccess(c, targetName, actualTarget, dependentTypeMemberWithSameName)
- or
- fn = getConfusingFunctionCall(c, targetName, actualTarget, dependentTypeMemberWithSameName) and
- not exists(Expr e | e = fn.(FunctionCall).getQualifier())
- or
- fn =
- getConfusingMemberVariableAccess(c, targetName, actualTarget, dependentTypeMemberWithSameName) and
- not exists(Expr e | e = fn.(VariableAccess).getQualifier())
- ) and
- not fn.isAffectedByMacro()
-select fn,
- "Use of unqualified identifier " + targetName +
- " targets $@ but a member with the name also exists $@.", actualTarget, targetName,
- dependentTypeMemberWithSameName, "in the dependent base class"
+class NameNotReferredUsingAQualifiedIdOrThisQuery extends NameNotReferredUsingAQualifiedIdOrThisSharedQuery
+{
+ NameNotReferredUsingAQualifiedIdOrThisQuery() {
+ this = TemplatesPackage::nameNotReferredUsingAQualifiedIdOrThisQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.ql b/cpp/autosar/src/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.ql
index 401edf3b61..ea56b841ed 100644
--- a/cpp/autosar/src/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.ql
+++ b/cpp/autosar/src/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.ql
@@ -16,27 +16,11 @@
import cpp
import codingstandards.cpp.autosar
-import NameInDependentBase
+import codingstandards.cpp.rules.namenotreferredusingaqualifiedidorthisaudit.NameNotReferredUsingAQualifiedIdOrThisAudit
-from
- TemplateClass c, NameQualifiableElement fn, string targetName, Element actualTarget,
- Element dependentTypeMemberWithSameName
-where
- not isExcluded(fn, TemplatesPackage::nameNotReferredUsingAQualifiedIdOrThisAuditQuery()) and
- not isCustomExcluded(fn) and
- missingNameQualifier(fn) and
- (
- fn = getConfusingFunctionAccess(c, targetName, actualTarget, dependentTypeMemberWithSameName)
- or
- fn = getConfusingFunctionCall(c, targetName, actualTarget, dependentTypeMemberWithSameName) and
- not exists(Expr e | e = fn.(FunctionCall).getQualifier())
- or
- not fn.(VariableAccess).getTarget() instanceof Parameter and
- fn =
- getConfusingMemberVariableAccess(c, targetName, actualTarget, dependentTypeMemberWithSameName) and
- not exists(Expr e | e = fn.(VariableAccess).getQualifier())
- )
-select fn,
- "Use of unqualified identifier " + targetName +
- " targets $@ but a member with the name also exists $@.", actualTarget, targetName,
- dependentTypeMemberWithSameName, "in the dependent base class"
+class NameNotReferredUsingAQualifiedIdOrThisAuditQuery extends NameNotReferredUsingAQualifiedIdOrThisAuditSharedQuery
+{
+ NameNotReferredUsingAQualifiedIdOrThisAuditQuery() {
+ this = TemplatesPackage::nameNotReferredUsingAQualifiedIdOrThisAuditQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M15-1-3/EmptyThrowOutsideCatch.ql b/cpp/autosar/src/rules/M15-1-3/EmptyThrowOutsideCatch.ql
index 7e263d66bb..9f99e7c356 100644
--- a/cpp/autosar/src/rules/M15-1-3/EmptyThrowOutsideCatch.ql
+++ b/cpp/autosar/src/rules/M15-1-3/EmptyThrowOutsideCatch.ql
@@ -15,9 +15,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.emptythrowonlywithinacatchhandler.EmptyThrowOnlyWithinACatchHandler
-from ReThrowExpr re
-where
- not isExcluded(re, Exceptions1Package::emptyThrowOutsideCatchQuery()) and
- not re.getEnclosingElement+() instanceof CatchBlock
-select re, "Rethrow outside catch block"
+class EmptyThrowOutsideCatchQuery extends EmptyThrowOnlyWithinACatchHandlerSharedQuery {
+ EmptyThrowOutsideCatchQuery() { this = Exceptions1Package::emptyThrowOutsideCatchQuery() }
+}
diff --git a/cpp/autosar/src/rules/M18-2-1/MacroOffsetofUsed.ql b/cpp/autosar/src/rules/M18-2-1/MacroOffsetofUsed.ql
index a572497418..cd347be44d 100644
--- a/cpp/autosar/src/rules/M18-2-1/MacroOffsetofUsed.ql
+++ b/cpp/autosar/src/rules/M18-2-1/MacroOffsetofUsed.ql
@@ -15,9 +15,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.macrooffsetofused.MacroOffsetofUsed
-from MacroInvocation mi
-where
- not isExcluded(mi, BannedFunctionsPackage::macroOffsetofUsedQuery()) and
- mi.getMacroName() = "offsetof"
-select mi, "Use of banned macro " + mi.getMacroName() + "."
+class MacroOffsetofUsedQuery extends MacroOffsetofUsedSharedQuery {
+ MacroOffsetofUsedQuery() { this = BannedFunctionsPackage::macroOffsetofUsedQuery() }
+}
diff --git a/cpp/autosar/src/rules/M18-7-1/CsignalFunctionsUsed.ql b/cpp/autosar/src/rules/M18-7-1/CsignalFunctionsUsed.ql
index ff264baffc..4df4715848 100644
--- a/cpp/autosar/src/rules/M18-7-1/CsignalFunctionsUsed.ql
+++ b/cpp/autosar/src/rules/M18-7-1/CsignalFunctionsUsed.ql
@@ -16,10 +16,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.csignalfunctionsused.CsignalFunctionsUsed
-from FunctionCall fc, Function f
-where
- not isExcluded(fc, BannedLibrariesPackage::csignalFunctionsUsedQuery()) and
- f = fc.getTarget() and
- f.hasGlobalOrStdName(["signal", "raise"])
-select fc, "Use of function '" + f.getQualifiedName() + "'."
+class CsignalFunctionsUsedQuery extends CsignalFunctionsUsedSharedQuery {
+ CsignalFunctionsUsedQuery() { this = BannedLibrariesPackage::csignalFunctionsUsedQuery() }
+}
diff --git a/cpp/autosar/src/rules/M18-7-1/CsignalTypesUsed.ql b/cpp/autosar/src/rules/M18-7-1/CsignalTypesUsed.ql
index c91d56c572..89e9ca169a 100644
--- a/cpp/autosar/src/rules/M18-7-1/CsignalTypesUsed.ql
+++ b/cpp/autosar/src/rules/M18-7-1/CsignalTypesUsed.ql
@@ -16,10 +16,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.csignaltypesused.CsignalTypesUsed
-from TypeMention tm, UserType ut
-where
- not isExcluded(tm, BannedLibrariesPackage::csignalTypesUsedQuery()) and
- ut = tm.getMentionedType() and
- ut.hasGlobalOrStdName("sig_atomic_t")
-select tm, "Use of type '" + ut.getQualifiedName() + "'."
+class CsignalTypesUsedQuery extends CsignalTypesUsedSharedQuery {
+ CsignalTypesUsedQuery() { this = BannedLibrariesPackage::csignalTypesUsedQuery() }
+}
diff --git a/cpp/autosar/src/rules/M2-13-2/UseOfNonZeroOctalLiteral.ql b/cpp/autosar/src/rules/M2-13-2/UseOfNonZeroOctalLiteral.ql
index 2bd35e2484..b689edab6b 100644
--- a/cpp/autosar/src/rules/M2-13-2/UseOfNonZeroOctalLiteral.ql
+++ b/cpp/autosar/src/rules/M2-13-2/UseOfNonZeroOctalLiteral.ql
@@ -16,10 +16,8 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.Cpp14Literal
+import codingstandards.cpp.rules.useofnonzerooctalliteral.UseOfNonZeroOctalLiteral
-from Cpp14Literal::OctalLiteral octalLiteral
-where
- not isExcluded(octalLiteral, LiteralsPackage::useOfNonZeroOctalLiteralQuery()) and
- not octalLiteral.getValue() = "0"
-select octalLiteral, "Non zero octal literal " + octalLiteral.getValueText() + "."
+class UseOfNonZeroOctalLiteralQuery extends UseOfNonZeroOctalLiteralSharedQuery {
+ UseOfNonZeroOctalLiteralQuery() { this = LiteralsPackage::useOfNonZeroOctalLiteralQuery() }
+}
diff --git a/cpp/autosar/src/rules/M2-13-3/MissingUSuffix.ql b/cpp/autosar/src/rules/M2-13-3/MissingUSuffix.ql
index 25cae1e03f..5bfa338864 100644
--- a/cpp/autosar/src/rules/M2-13-3/MissingUSuffix.ql
+++ b/cpp/autosar/src/rules/M2-13-3/MissingUSuffix.ql
@@ -18,18 +18,8 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.Cpp14Literal
+import codingstandards.cpp.rules.unsignedintegerliteralsnotappropriatelysuffixed.UnsignedIntegerLiteralsNotAppropriatelySuffixed
-from Cpp14Literal::NumericLiteral nl, string literalKind
-where
- not isExcluded(nl, LiteralsPackage::missingUSuffixQuery()) and
- (
- nl instanceof Cpp14Literal::OctalLiteral and literalKind = "Octal"
- or
- nl instanceof Cpp14Literal::HexLiteral and literalKind = "Hex"
- ) and
- // This either directly has an unsigned integer type, or it is converted to an unsigned integer type
- nl.getType().getUnspecifiedType().(IntegralType).isUnsigned() and
- // The literal already has a `u` or `U` suffix.
- not nl.getValueText().regexpMatch(".*[lL]*[uU][lL]*")
-select nl, literalKind + " literal is an unsigned integer but does not include a 'U' suffix."
+class MissingUSuffixQuery extends UnsignedIntegerLiteralsNotAppropriatelySuffixedSharedQuery {
+ MissingUSuffixQuery() { this = LiteralsPackage::missingUSuffixQuery() }
+}
diff --git a/cpp/autosar/src/rules/M2-7-1/SlashStarUsedWithinACStyleComment.ql b/cpp/autosar/src/rules/M2-7-1/SlashStarUsedWithinACStyleComment.ql
index 768acb0532..356a361cb1 100644
--- a/cpp/autosar/src/rules/M2-7-1/SlashStarUsedWithinACStyleComment.ql
+++ b/cpp/autosar/src/rules/M2-7-1/SlashStarUsedWithinACStyleComment.ql
@@ -16,9 +16,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.charactersequenceusedwithinacstylecomment.CharacterSequenceUsedWithinACStyleComment
-from CStyleComment c
-where
- not isExcluded(c, CommentsPackage::slashStarUsedWithinACStyleCommentQuery()) and
- exists(c.getContents().regexpFind("./\\*", _, _))
-select c, "C-style /* comment includes nested /*."
+class SlashStarUsedWithinACStyleCommentQuery extends CharacterSequenceUsedWithinACStyleCommentSharedQuery
+{
+ SlashStarUsedWithinACStyleCommentQuery() {
+ this = CommentsPackage::slashStarUsedWithinACStyleCommentQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M27-0-1/CstdioFunctionsUsed.ql b/cpp/autosar/src/rules/M27-0-1/CstdioFunctionsUsed.ql
index 55254581a6..5656fc2edf 100644
--- a/cpp/autosar/src/rules/M27-0-1/CstdioFunctionsUsed.ql
+++ b/cpp/autosar/src/rules/M27-0-1/CstdioFunctionsUsed.ql
@@ -17,26 +17,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.cstdiofunctionsused.CstdioFunctionsUsed
-from FunctionCall fc, Function f
-where
- not isExcluded(fc, BannedLibrariesPackage::cstdioFunctionsUsedQuery()) and
- f = fc.getTarget() and
- f.hasGlobalOrStdName([
- "remove", "rename", "tmpfile", "tmpnam",
- // File access
- "fclose", "fflush", "fopen", "freopen", "setbuf", "setvbuf",
- // Formatted input/output
- "fprintf", "fscanf", "printf", "scanf", "snprintf", "sprintf", "sscanf", "vfprintf",
- "vfscanf", "vprintf", "vscanf", "vsnprintf", "vsprintf", "vsscanf",
- // Character input/output
- "fgetc", "fgets", "fputc", "fputs", "getc", "getchar", "gets", "putc", "putchar", "puts",
- "ungetc",
- // Direct input/output
- "fread", "fwrite",
- // File positioning
- "fgetpos", "fseek", "fsetpos", "ftell", "rewind",
- // Error handling
- "clearerr", "feof", "ferror", "perror"
- ])
-select fc, "Use of function '" + f.getQualifiedName() + "'."
+class CstdioFunctionsUsedQuery extends CstdioFunctionsUsedSharedQuery {
+ CstdioFunctionsUsedQuery() { this = BannedLibrariesPackage::cstdioFunctionsUsedQuery() }
+}
diff --git a/cpp/autosar/src/rules/M27-0-1/CstdioMacrosUsed.ql b/cpp/autosar/src/rules/M27-0-1/CstdioMacrosUsed.ql
index ccf633488e..311baeb195 100644
--- a/cpp/autosar/src/rules/M27-0-1/CstdioMacrosUsed.ql
+++ b/cpp/autosar/src/rules/M27-0-1/CstdioMacrosUsed.ql
@@ -17,12 +17,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.cstdiomacrosused.CstdioMacrosUsed
-from MacroInvocation mi
-where
- not isExcluded(mi, BannedLibrariesPackage::cstdioMacrosUsedQuery()) and
- mi.getMacroName() in [
- "BUFSIZ", "EOF", "FILENAME_MAX", "FOPEN_MAX", "L_tmpnam", "TMP_MAX", "_IOFBF", "IOLBF",
- "_IONBF", "SEEK_CUR", "SEEK_END", "SEEK_SET"
- ]
-select mi, "Use of macro '" + mi.getMacroName() + "'."
+class CstdioMacrosUsedQuery extends CstdioMacrosUsedSharedQuery {
+ CstdioMacrosUsedQuery() { this = BannedLibrariesPackage::cstdioMacrosUsedQuery() }
+}
diff --git a/cpp/autosar/src/rules/M27-0-1/CstdioTypesUsed.ql b/cpp/autosar/src/rules/M27-0-1/CstdioTypesUsed.ql
index 6fc2adaffb..3a1f647c22 100644
--- a/cpp/autosar/src/rules/M27-0-1/CstdioTypesUsed.ql
+++ b/cpp/autosar/src/rules/M27-0-1/CstdioTypesUsed.ql
@@ -17,10 +17,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.cstdiotypesused.CstdioTypesUsed
-from TypeMention tm, UserType ut
-where
- not isExcluded(tm, BannedLibrariesPackage::cstdioTypesUsedQuery()) and
- ut = tm.getMentionedType() and
- ut.hasGlobalOrStdName(["FILE", "fpos_t"])
-select tm, "Use of type '" + ut.getQualifiedName() + "'."
+class CstdioTypesUsedQuery extends CstdioTypesUsedSharedQuery {
+ CstdioTypesUsedQuery() { this = BannedLibrariesPackage::cstdioTypesUsedQuery() }
+}
diff --git a/cpp/autosar/src/rules/M3-9-3/UnderlyingBitRepresentationsOfFloatingPointValuesUsed.ql b/cpp/autosar/src/rules/M3-9-3/UnderlyingBitRepresentationsOfFloatingPointValuesUsed.ql
index f7e6664269..279ad08f3c 100644
--- a/cpp/autosar/src/rules/M3-9-3/UnderlyingBitRepresentationsOfFloatingPointValuesUsed.ql
+++ b/cpp/autosar/src/rules/M3-9-3/UnderlyingBitRepresentationsOfFloatingPointValuesUsed.ql
@@ -14,7 +14,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
predicate pointeeIsModified(PointerDereferenceExpr e, Expr m) {
exists(Assignment a | a.getLValue() = e and m = a)
diff --git a/cpp/autosar/src/rules/M5-0-17/PointerSubtractionOnDifferentArrays.ql b/cpp/autosar/src/rules/M5-0-17/PointerSubtractionOnDifferentArrays.ql
index ec432cea42..d6d4f6130a 100644
--- a/cpp/autosar/src/rules/M5-0-17/PointerSubtractionOnDifferentArrays.ql
+++ b/cpp/autosar/src/rules/M5-0-17/PointerSubtractionOnDifferentArrays.ql
@@ -15,7 +15,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import ArrayToPointerDiffOperandFlow::PathGraph
module ArrayToPointerDiffOperandConfig implements DataFlow::ConfigSig {
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-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.ql b/cpp/autosar/src/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.ql
index 4207b4d56c..943fc026e8 100644
--- a/cpp/autosar/src/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.ql
+++ b/cpp/autosar/src/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.ql
@@ -15,33 +15,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.arraypassedasfunctionargumentdecaytoapointer.ArrayPassedAsFunctionArgumentDecayToAPointer
-predicate arrayToPointerDecay(Access ae, Parameter p) {
- (
- p.getType() instanceof PointerType and
- // exclude parameters of void* because then it assumed the caller can pass in dimensions through other means.
- // examples are uses in `memset` or `memcpy`
- not p.getType() instanceof VoidPointerType
- or
- p.getType() instanceof ArrayType
- ) and
- ae.getType() instanceof ArrayType and
- // exclude char[] arrays because we assume that we can determine its dimension by looking for a NULL byte.
- not ae.getType().(ArrayType).getBaseType() instanceof CharType
+class IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointerQuery extends ArrayPassedAsFunctionArgumentDecayToAPointerSharedQuery
+{
+ IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointerQuery() {
+ this = PointersPackage::identifierWithArrayTypePassedAsFunctionArgumentDecayToAPointerQuery()
+ }
}
-
-from
- FunctionCall fc, Function f, Parameter decayedArray, Variable array, VariableAccess arrayAccess,
- int i
-where
- not isExcluded(fc,
- PointersPackage::identifierWithArrayTypePassedAsFunctionArgumentDecayToAPointerQuery()) and
- arrayAccess = array.getAnAccess() and
- f = fc.getTarget() and
- arrayAccess = fc.getArgument(i) and
- decayedArray = f.getParameter(i) and
- arrayToPointerDecay(arrayAccess, decayedArray) and
- not arrayAccess.isAffectedByMacro()
-select fc.getArgument(i),
- "The array $@ decays to the pointer $@ when passed as an argument to the function $@.", array,
- array.getName(), decayedArray, decayedArray.getName(), f, f.getName()
diff --git a/cpp/autosar/src/rules/M5-2-2/PointerToAVirtualBaseClassCastToAPointer.ql b/cpp/autosar/src/rules/M5-2-2/PointerToAVirtualBaseClassCastToAPointer.ql
index 8f20bf808e..d24c4d35df 100644
--- a/cpp/autosar/src/rules/M5-2-2/PointerToAVirtualBaseClassCastToAPointer.ql
+++ b/cpp/autosar/src/rules/M5-2-2/PointerToAVirtualBaseClassCastToAPointer.ql
@@ -15,7 +15,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
from Cast cast, VirtualBaseClass castFrom, Class castTo
where
diff --git a/cpp/autosar/src/rules/M5-2-6/CastNotConvertPointerToFunction.ql b/cpp/autosar/src/rules/M5-2-6/CastNotConvertPointerToFunction.ql
index b6a51dc0ab..5a8df45ab1 100644
--- a/cpp/autosar/src/rules/M5-2-6/CastNotConvertPointerToFunction.ql
+++ b/cpp/autosar/src/rules/M5-2-6/CastNotConvertPointerToFunction.ql
@@ -15,11 +15,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.castsbetweenapointertofunctionandanyothertype.CastsBetweenAPointerToFunctionAndAnyOtherType
-from Cast c
-where
- not isExcluded(c, PointersPackage::castNotConvertPointerToFunctionQuery()) and
- not c.isImplicit() and
- not c.isAffectedByMacro() and
- c.getExpr().getType() instanceof FunctionPointerType
-select c, "Cast converting a pointer to function."
+class CastNotConvertPointerToFunctionQuery extends CastsBetweenAPointerToFunctionAndAnyOtherTypeSharedQuery
+{
+ CastNotConvertPointerToFunctionQuery() {
+ this = PointersPackage::castNotConvertPointerToFunctionQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.ql b/cpp/autosar/src/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.ql
index 0367f0aebe..7017d5e7de 100644
--- a/cpp/autosar/src/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.ql
+++ b/cpp/autosar/src/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.ql
@@ -14,13 +14,12 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.builtinunaryoperatorappliedtounsignedexpression.BuiltInUnaryOperatorAppliedToUnsignedExpression
-from UnaryMinusExpr e, IntegralType t
-where
- not isExcluded(e,
- OperatorsPackage::unaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsignedQuery()) and
- t = e.getOperand().getExplicitlyConverted().getType().getUnderlyingType() and
- t.isUnsigned() and
- not e.isAffectedByMacro()
-select e.getOperand(),
- "The unary minus operator shall not be applied to an expression whose underlying type is unsigned."
+class UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsignedQuery extends BuiltInUnaryOperatorAppliedToUnsignedExpressionSharedQuery
+{
+ UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsignedQuery() {
+ this =
+ OperatorsPackage::unaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsignedQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M5-3-3/UnaryOperatorOverloaded.ql b/cpp/autosar/src/rules/M5-3-3/UnaryOperatorOverloaded.ql
index 7e9511cf7e..94f0bc6062 100644
--- a/cpp/autosar/src/rules/M5-3-3/UnaryOperatorOverloaded.ql
+++ b/cpp/autosar/src/rules/M5-3-3/UnaryOperatorOverloaded.ql
@@ -13,8 +13,8 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.Operator
+import codingstandards.cpp.rules.addressofoperatoroverloaded.AddressOfOperatorOverloaded
-from UnaryAddressOfOperator o
-where not isExcluded(o, OperatorsPackage::unaryOperatorOverloadedQuery())
-select o, "The unary & operator overloaded."
+class UnaryOperatorOverloadedQuery extends AddressOfOperatorOverloadedSharedQuery {
+ UnaryOperatorOverloadedQuery() { this = OperatorsPackage::unaryOperatorOverloadedQuery() }
+}
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/src/rules/M6-3-1/LoopCompoundCondition.ql b/cpp/autosar/src/rules/M6-3-1/LoopCompoundCondition.ql
index 1c6c0b980e..b3566a1e27 100644
--- a/cpp/autosar/src/rules/M6-3-1/LoopCompoundCondition.ql
+++ b/cpp/autosar/src/rules/M6-3-1/LoopCompoundCondition.ql
@@ -16,9 +16,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.loopcompoundcondition.LoopCompoundCondition
-from Loop loop
-where
- not isExcluded(loop, ConditionalsPackage::loopCompoundConditionQuery()) and
- not loop.getStmt() instanceof BlockStmt
-select loop, "Loop body not enclosed within braces."
+class LoopCompoundConditionQuery extends LoopCompoundConditionSharedQuery {
+ LoopCompoundConditionQuery() { this = ConditionalsPackage::loopCompoundConditionQuery() }
+}
diff --git a/cpp/autosar/src/rules/M6-3-1/SwitchCompoundCondition.ql b/cpp/autosar/src/rules/M6-3-1/SwitchCompoundCondition.ql
index ee83f44ccf..f550a456dc 100644
--- a/cpp/autosar/src/rules/M6-3-1/SwitchCompoundCondition.ql
+++ b/cpp/autosar/src/rules/M6-3-1/SwitchCompoundCondition.ql
@@ -16,36 +16,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.switchcompoundcondition.SwitchCompoundCondition
-/**
- * Class to differentiate between extractor generated blockstmt and actual blockstmt. The extractor
- * will generate an artificial blockstmt when there is a single case and statement, e.g.
- * ```
- * switch(x)
- * case 1:
- * f();
- * ```
- * This is because our AST model considers the `case` to be a statement in its own right, so the
- * extractor needs an aritifical block to hold both the case and the statement.
- */
-class ArtificialBlock extends BlockStmt {
- ArtificialBlock() {
- exists(Location block, Location firstStatement |
- block = getLocation() and firstStatement = getStmt(0).getLocation()
- |
- // We can identify artificial blocks as those where the start of the statement is at the same
- // location as the start of the first statement in the block i.e. there was no opening brace.
- block.getStartLine() = firstStatement.getStartLine() and
- block.getStartColumn() = firstStatement.getStartColumn()
- )
- }
+class SwitchCompoundConditionQuery extends SwitchCompoundConditionSharedQuery {
+ SwitchCompoundConditionQuery() { this = ConditionalsPackage::switchCompoundConditionQuery() }
}
-
-from SwitchStmt switch
-where
- not isExcluded(switch, ConditionalsPackage::switchCompoundConditionQuery()) and
- (
- switch.getStmt() instanceof ArtificialBlock or
- not switch.getStmt() instanceof BlockStmt
- )
-select switch, "Switch body not enclosed within braces."
diff --git a/cpp/autosar/src/rules/M7-3-1/GlobalNamespaceMembershipViolation.ql b/cpp/autosar/src/rules/M7-3-1/GlobalNamespaceMembershipViolation.ql
index cb714a65f2..e359880027 100644
--- a/cpp/autosar/src/rules/M7-3-1/GlobalNamespaceMembershipViolation.ql
+++ b/cpp/autosar/src/rules/M7-3-1/GlobalNamespaceMembershipViolation.ql
@@ -16,13 +16,10 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.globalnamespacedeclarations.GlobalNamespaceDeclarations
-from DeclarationEntry de
-where
- not isExcluded(de, ScopePackage::globalNamespaceMembershipViolationQuery()) and
- de.getDeclaration().getNamespace() instanceof GlobalNamespace and
- de.getDeclaration().isTopLevel() and
- not exists(Function f | f = de.getDeclaration() | f.hasGlobalName("main") or f.hasCLinkage())
-select de,
- "Declaration " + de.getName() +
- " is in the global namespace and is not a main, a namespace, or an extern \"C\" declaration."
+class GlobalNamespaceMembershipViolationQuery extends GlobalNamespaceDeclarationsSharedQuery {
+ GlobalNamespaceMembershipViolationQuery() {
+ this = ScopePackage::globalNamespaceMembershipViolationQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.ql b/cpp/autosar/src/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.ql
index 9d86bd3637..25a01c66f8 100644
--- a/cpp/autosar/src/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.ql
+++ b/cpp/autosar/src/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.ql
@@ -15,11 +15,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.nonglobalfunctionmain.NonGlobalFunctionMain
-from Function f
-where
- not isExcluded(f,
- NamingPackage::identifierMainUsedForAFunctionOtherThanTheGlobalFunctionMainQuery()) and
- f.hasName("main") and
- not f.hasGlobalName("main")
-select f, "Identifier main used for a function other than the global function main."
+class IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMainQuery extends NonGlobalFunctionMainSharedQuery
+{
+ IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMainQuery() {
+ this = NamingPackage::identifierMainUsedForAFunctionOtherThanTheGlobalFunctionMainQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M7-5-1/FunctionReturnAutomaticVarCondition.ql b/cpp/autosar/src/rules/M7-5-1/FunctionReturnAutomaticVarCondition.ql
index e35858f40b..cb5aa9d105 100644
--- a/cpp/autosar/src/rules/M7-5-1/FunctionReturnAutomaticVarCondition.ql
+++ b/cpp/autosar/src/rules/M7-5-1/FunctionReturnAutomaticVarCondition.ql
@@ -16,19 +16,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.returnreferenceorpointertoautomaticlocalvariable.ReturnReferenceOrPointerToAutomaticLocalVariable
-from ReturnStmt rs, StackVariable auto, Function f, VariableAccess va, string returnType
-where
- f = rs.getEnclosingFunction() and
- (
- f.getType() instanceof ReferenceType and va = rs.getExpr() and returnType = "reference"
- or
- f.getType() instanceof PointerType and
- va = rs.getExpr().(AddressOfExpr).getOperand() and
- returnType = "pointer"
- ) and
- auto = va.getTarget() and
- not auto.isStatic() and
- not f.isCompilerGenerated() and
- not auto.getType() instanceof ReferenceType
-select rs, "The $@ returns a " + returnType + "to an $@ variable", f, f.getName(), auto, "automatic"
+class FunctionReturnAutomaticVarConditionQuery extends ReturnReferenceOrPointerToAutomaticLocalVariableSharedQuery
+{
+ FunctionReturnAutomaticVarConditionQuery() {
+ this = FunctionsPackage::functionReturnAutomaticVarConditionQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.ql b/cpp/autosar/src/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.ql
index 8d16fccd94..c152821ab2 100644
--- a/cpp/autosar/src/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.ql
+++ b/cpp/autosar/src/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.ql
@@ -16,57 +16,10 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.multipleglobalormemberdeclarators.MultipleGlobalOrMemberDeclarators
-/*
- * Unfortunately, we do not have an equivalent of `DeclStmt` for non-local declarations, so we
- * cannot determine whether a declaration was declared with another declaration.
- *
- * However, we can use location trickery to figure out if the declaration occurs close enough to
- * another declaration that it _must_ have been declared within the same declaration sequence.
- *
- * We do this by requiring that the end location of a previous declaration is within a certain
- * number of characters of the start location of the current declaration.
- */
-
-/**
- * A `Declaration` which is not in a local scope, and is written directly by the user.
- *
- * These act as "candidates" for declarations that could plausibly occur in a declaration sequence
- * with other candidates.
- */
-class NonLocalUserDeclaration extends Declaration {
- NonLocalUserDeclaration() {
- not this instanceof StackVariable and
- not this instanceof TemplateParameter and
- not this instanceof EnumConstant and
- not this instanceof TypedefType and
- not any(LambdaCapture lc).getField() = this and
- not this.(Function).isCompilerGenerated() and
- not this.(Variable).isCompilerGenerated() and
- not this.(Parameter).getFunction().isCompilerGenerated() and
- not this.isInMacroExpansion() and
- not exists(Struct s, TypedefType t |
- s.isAnonymous() and
- t.getBaseType() = s and
- this = s.getAMemberVariable()
- )
+class MultipleGlobalOrMemberDeclaratorsQuery extends MultipleGlobalOrMemberDeclaratorsSharedQuery {
+ MultipleGlobalOrMemberDeclaratorsQuery() {
+ this = InitializationPackage::multipleGlobalOrMemberDeclaratorsQuery()
}
}
-
-/**
- * Holds if `d1` is followed directly by `d2`.
- */
-predicate isFollowingDeclaration(NonLocalUserDeclaration d1, NonLocalUserDeclaration d2) {
- exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
- d1.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
- d2.getLocation().hasLocationInfo(filepath, startline, endcolumn + [2 .. 3], endline, _)
- ) and
- not d1.(UserType).stripType() = d2.(Variable).getType().stripType()
-}
-
-from NonLocalUserDeclaration d1
-where
- not isExcluded(d1, InitializationPackage::multipleGlobalOrMemberDeclaratorsQuery()) and
- isFollowingDeclaration(d1, _) and
- not isFollowingDeclaration(_, d1)
-select d1, "Multiple declarations after " + d1.getName() + " in this declaration sequence."
diff --git a/cpp/autosar/src/rules/M8-0-1/MultipleLocalDeclarators.ql b/cpp/autosar/src/rules/M8-0-1/MultipleLocalDeclarators.ql
index 7545315b7e..6198ab7a5a 100644
--- a/cpp/autosar/src/rules/M8-0-1/MultipleLocalDeclarators.ql
+++ b/cpp/autosar/src/rules/M8-0-1/MultipleLocalDeclarators.ql
@@ -16,11 +16,8 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.multiplelocaldeclarators.MultipleLocalDeclarators
-from DeclStmt ds
-where
- not isExcluded(ds, InitializationPackage::multipleLocalDeclaratorsQuery()) and
- count(Declaration d | d = ds.getADeclaration()) > 1 and
- // Not a compiler generated `DeclStmt`, such as in the range-based for loop
- not ds.isCompilerGenerated()
-select ds, "Declaration list contains more than one declaration."
+class MultipleLocalDeclaratorsQuery extends MultipleLocalDeclaratorsSharedQuery {
+ MultipleLocalDeclaratorsQuery() { this = InitializationPackage::multipleLocalDeclaratorsQuery() }
+}
diff --git a/cpp/autosar/src/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.ql b/cpp/autosar/src/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.ql
index 9d2b2d2006..a0ef5143e9 100644
--- a/cpp/autosar/src/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.ql
+++ b/cpp/autosar/src/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.ql
@@ -16,29 +16,11 @@
import cpp
import codingstandards.cpp.autosar
+import codingstandards.cpp.rules.overridingshallspecifydifferentdefaultarguments.OverridingShallSpecifyDifferentDefaultArguments
-from VirtualFunction f1, VirtualFunction f2
-where
- not isExcluded(f1,
- VirtualFunctionsPackage::virtualFunctionParametersUseTheSameDefaultArgumentsQuery()) and
- not isExcluded(f2,
- VirtualFunctionsPackage::virtualFunctionParametersUseTheSameDefaultArgumentsQuery()) and
- f2 = f1.getAnOverridingFunction() and
- exists(Parameter p1, Parameter p2 |
- p1 = f1.getAParameter() and
- p2 = f2.getParameter(p1.getIndex())
- |
- if p1.hasInitializer()
- then
- // if there is no initializer
- not p2.hasInitializer()
- or
- // if there is one and it doesn't match
- not p1.getInitializer().getExpr().getValueText() =
- p2.getInitializer().getExpr().getValueText()
- else
- // if p1 doesn't have an initializer p2 shouldn't either
- p2.hasInitializer()
- )
-select f2, "$@ does not have the same default parameters as $@", f2, "overriding function", f1,
- "overridden function"
+class VirtualFunctionParametersUseTheSameDefaultArgumentsQuery extends OverridingShallSpecifyDifferentDefaultArgumentsSharedQuery
+{
+ VirtualFunctionParametersUseTheSameDefaultArgumentsQuery() {
+ this = VirtualFunctionsPackage::virtualFunctionParametersUseTheSameDefaultArgumentsQuery()
+ }
+}
diff --git a/cpp/autosar/src/rules/M9-3-1/ConstMemberFunctionReturnsNonConstPointer.ql b/cpp/autosar/src/rules/M9-3-1/ConstMemberFunctionReturnsNonConstPointer.ql
index 98207a62a3..559b41527c 100644
--- a/cpp/autosar/src/rules/M9-3-1/ConstMemberFunctionReturnsNonConstPointer.ql
+++ b/cpp/autosar/src/rules/M9-3-1/ConstMemberFunctionReturnsNonConstPointer.ql
@@ -18,7 +18,7 @@
import cpp
import codingstandards.cpp.autosar
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
class ReferenceTypeWithNonConstBaseType extends ReferenceType {
ReferenceTypeWithNonConstBaseType() { not this.getBaseType().isConst() }
diff --git a/cpp/autosar/src/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.ql b/cpp/autosar/src/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.ql
index 7748f26ec1..96e434633e 100644
--- a/cpp/autosar/src/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.ql
+++ b/cpp/autosar/src/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.ql
@@ -22,4 +22,4 @@ where
bf.getType().getUnderlyingType().(IntegralType).isSigned() and
bf.getNumBits() < 2 and
bf.getName() != "(unnamed bitfield)"
-select bf, "A named bit-field with signed integral type should have at least 2 bits of storage "
+select bf, "A named bit-field with signed integral type should have at least 2 bits of storage."
diff --git a/cpp/autosar/test/codeql-pack.lock.yml b/cpp/autosar/test/codeql-pack.lock.yml
index 514e6963d0..910a6e060e 100644
--- a/cpp/autosar/test/codeql-pack.lock.yml
+++ b/cpp/autosar/test/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/cpp/autosar/test/qlpack.yml b/cpp/autosar/test/qlpack.yml
index 6743c3b3ee..178d8cc314 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.40.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/c/misra/test/rules/RULE-7-3/cpp/LowercaseCharacterLUsedInLiteralSuffix.expected b/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.clang
similarity index 100%
rename from c/misra/test/rules/RULE-7-3/cpp/LowercaseCharacterLUsedInLiteralSuffix.expected
rename to cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.clang
diff --git a/cpp/autosar/test/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.expected b/cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.gcc
similarity index 100%
rename from cpp/autosar/test/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.expected
rename to cpp/autosar/test/rules/A1-1-2.2/CompilerWarningLevelNotInCompliance.expected.gcc
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/A12-0-1/MissingSpecialMemberFunction.expected b/cpp/autosar/test/rules/A12-0-1/MissingSpecialMemberFunction.expected
index 9e1cd591c6..ced97cced2 100644
--- a/cpp/autosar/test/rules/A12-0-1/MissingSpecialMemberFunction.expected
+++ b/cpp/autosar/test/rules/A12-0-1/MissingSpecialMemberFunction.expected
@@ -1,2 +1,8 @@
| test.cpp:12:7:12:8 | C3 | Class $@ has provided at least one user-defined special member function but is missing definitions for all five special member functions. | test.cpp:12:7:12:8 | C3 | C3 |
| test.cpp:28:7:28:8 | C5 | Class $@ has provided at least one user-defined special member function but is missing definitions for all five special member functions. | test.cpp:28:7:28:8 | C5 | C5 |
+| test.cpp:51:7:51:9 | C10 | Class $@ has provided at least one user-defined special member function but is missing definitions for all five special member functions. | test.cpp:51:7:51:9 | C10 | C10 |
+| test.cpp:55:7:55:9 | C11 | Class $@ has provided at least one user-defined special member function but is missing definitions for all five special member functions. | test.cpp:55:7:55:9 | C11 | C11 |
+| test.cpp:59:7:59:9 | C12 | Class $@ has provided at least one user-defined special member function but is missing definitions for all five special member functions. | test.cpp:59:7:59:9 | C12 | C12 |
+| test.cpp:63:7:63:9 | C13 | Class $@ has provided at least one user-defined special member function but is missing definitions for all five special member functions. | test.cpp:63:7:63:9 | C13 | C13 |
+| test.cpp:67:7:67:9 | C14 | Class $@ has provided at least one user-defined special member function but is missing definitions for all five special member functions. | test.cpp:67:7:67:9 | C14 | C14 |
+| test.cpp:71:7:71:9 | C15 | Class $@ has provided at least one user-defined special member function but is missing definitions for all five special member functions. | test.cpp:71:7:71:9 | C15 | C15 |
diff --git a/cpp/autosar/test/rules/A12-0-1/test.cpp b/cpp/autosar/test/rules/A12-0-1/test.cpp
index 71652633b4..9a38204641 100644
--- a/cpp/autosar/test/rules/A12-0-1/test.cpp
+++ b/cpp/autosar/test/rules/A12-0-1/test.cpp
@@ -46,4 +46,63 @@ struct C7::C8 { // COMPLIANT
struct C9 { // COMPLIANT
C9() {}
C9(int x) {}
+};
+
+class C10 {
+ ~C10() = default; // NON_COMPLIANT
+};
+
+class C11 {
+ ~C11() = delete; // NON_COMPLIANT
+};
+
+class C12 {
+ C12(C12 const &); // NON_COMPLIANT
+};
+
+class C13 {
+ C13(C13 const &) = default; // NON_COMPLIANT
+};
+
+class C14 {
+ C14(C14 const &) = delete; // NON_COMPLIANT
+};
+
+class C15 {
+ C15 &operator=(C15 const &); // NON_COMPLIANT
+};
+
+template class C16 { // COMPLIANT
+ C16() = default;
+};
+
+template class C17 { // COMPLIANT
+ C17() = default;
+ C17(C17 const &) = default;
+ C17(C17 &&) = default;
+ virtual ~C17() = default;
+ C17 &operator=(C17 const &) = default;
+ C17 &operator=(C17 &&) = default;
+};
+
+template class C18 { // COMPLIANT
+ C18() = default;
+ C18(C18 const &) = delete;
+ C18(C18 &&) = delete;
+ virtual ~C18() = default;
+ C18 &operator=(C18 const &) = delete;
+ C18 &operator=(C18 &&) = delete;
+};
+
+template class C19 { // COMPLIANT
+public:
+ explicit C19(T i) : i(i) {}
+ C19(C19 const &) = delete;
+ C19(C19 &&) = delete;
+ virtual ~C19() = default;
+ C19 &operator=(C19 const &) = delete;
+ C19 &operator=(C19 &&) = delete;
+
+private:
+ T i;
};
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.qlref b/cpp/autosar/test/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.qlref
deleted file mode 100644
index 9d356add77..0000000000
--- a/cpp/autosar/test/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A12-1-1/ExplicitConstructorBaseClassInitialization.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.testref b/cpp/autosar/test/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.testref
new file mode 100644
index 0000000000..ac8c5e1a83
--- /dev/null
+++ b/cpp/autosar/test/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.qlref b/cpp/autosar/test/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.qlref
deleted file mode 100644
index 686462e15f..0000000000
--- a/cpp/autosar/test/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.testref b/cpp/autosar/test/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.testref
new file mode 100644
index 0000000000..65fc614121
--- /dev/null
+++ b/cpp/autosar/test/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/copyandmoveassignmentsshallhandleselfassignment/CopyAndMoveAssignmentsShallHandleSelfAssignment.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A12-8-6/CopyAndMoveNotDeclaredProtected.expected b/cpp/autosar/test/rules/A12-8-6/CopyAndMoveNotDeclaredProtected.expected
index 9f85da12d6..74ed472a52 100644
--- a/cpp/autosar/test/rules/A12-8-6/CopyAndMoveNotDeclaredProtected.expected
+++ b/cpp/autosar/test/rules/A12-8-6/CopyAndMoveNotDeclaredProtected.expected
@@ -20,7 +20,3 @@
| test.cpp:109:3:109:12 | declaration of BaseClass8 | Move constructor for base class 'BaseClass8' is not declared protected. |
| test.cpp:110:15:110:23 | declaration of operator= | Copy assignment operator for base class 'BaseClass8' is not declared protected. |
| test.cpp:111:15:111:23 | declaration of operator= | Move assignment operator for base class 'BaseClass8' is not declared protected. |
-| test.cpp:124:26:124:26 | declaration of BaseClass9 | Implicit copy constructor for base class 'BaseClass9' is not declared deleted. |
-| test.cpp:124:26:124:26 | declaration of BaseClass9 | Implicit move constructor for base class 'BaseClass9' is not declared deleted. |
-| test.cpp:124:26:124:26 | declaration of operator= | Implicit copy assignment operator for base class 'BaseClass9' is not declared deleted. |
-| test.cpp:124:26:124:26 | declaration of operator= | Implicit move assignment operator for base class 'BaseClass9' is not declared deleted. |
diff --git a/cpp/autosar/test/rules/A12-8-6/test.cpp b/cpp/autosar/test/rules/A12-8-6/test.cpp
index 6a31ca60ae..d197fc18fb 100644
--- a/cpp/autosar/test/rules/A12-8-6/test.cpp
+++ b/cpp/autosar/test/rules/A12-8-6/test.cpp
@@ -12,8 +12,8 @@ class DerivedClass1 // COMPLIANT - not a base class itself
// Base class with compiler generated move/copy is not compliant, because they
// are public by default
-class BaseClass2 {}; // NON_COMPLIANT - compiler generated move and assignment
- // are in contravention
+class BaseClass2 {}; // NON_COMPLIANT[FALSE_NEGATIVE] - compiler generated move
+ // and assignment are in contravention
class DerivedClass2 // COMPLIANT - not a base class itself
: public BaseClass2 {};
@@ -87,7 +87,7 @@ template class BaseClass7 {
BaseClass7 &operator=(BaseClass7 const &) = default; // NON_COMPLIANT
BaseClass7 &operator=(BaseClass7 &&) = default; // NON_COMPLIANT
int operator=(int i); // COMPLIANT - not an assignment operator
-}; // COMPLIANT
+};
template
class DerivedClass7 // COMPLIANT - not a base class itself
@@ -121,7 +121,7 @@ class DerivedClass9 // COMPLIANT - not a base class itself
T t;
};
-template class BaseClass9 { // NON_COMPLIANT
+template class BaseClass9 { // NON_COMPLIANT[FALSE_NEGATIVE]
public:
BaseClass9() {}
diff --git a/cpp/autosar/test/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.expected b/cpp/autosar/test/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.expected
index 53dc884023..5d1d6022b5 100644
--- a/cpp/autosar/test/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.expected
+++ b/cpp/autosar/test/rules/A13-1-3/UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.expected
@@ -1 +1,4 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.ql:27,33-41)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.ql:28,5-13)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (UserDefinedLiteralsOperatorsShallOnlyPerformConversionOfPassedParameters.ql:27,7-20)
| test.cpp:47:8:47:23 | operator ""_uds5 | User defined literal operator returns $@, which is not converted from a passed parameter | test.cpp:48:10:48:12 | 0.0 | expression |
diff --git a/cpp/autosar/test/rules/A13-2-1/AssignmentOperatorReturnThis.expected b/cpp/autosar/test/rules/A13-2-1/AssignmentOperatorReturnThis.expected
index e9929173b0..9c0d50ca86 100644
--- a/cpp/autosar/test/rules/A13-2-1/AssignmentOperatorReturnThis.expected
+++ b/cpp/autosar/test/rules/A13-2-1/AssignmentOperatorReturnThis.expected
@@ -1,3 +1,4 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (AssignmentOperatorReturnThis.ql:25,5-13)
| test.cpp:10:12:10:20 | operator= | User-defined assignment operator $@ does not return *this | test.cpp:10:12:10:20 | operator= | user defined assignment operator |
| test.cpp:17:11:17:19 | operator= | User-defined assignment operator $@ does not return *this | test.cpp:17:11:17:19 | operator= | user defined assignment operator |
| test.cpp:24:12:24:20 | operator= | User-defined assignment operator $@ does not return *this | test.cpp:24:12:24:20 | operator= | user defined assignment operator |
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/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.qlref b/cpp/autosar/test/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.qlref
deleted file mode 100644
index b2f19b3af3..0000000000
--- a/cpp/autosar/test/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.testref b/cpp/autosar/test/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.testref
new file mode 100644
index 0000000000..6a284e2cbb
--- /dev/null
+++ b/cpp/autosar/test/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/functiontemplatesexplicitlyspecialized/FunctionTemplatesExplicitlySpecialized.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A15-1-2/PointerExceptionObject.qlref b/cpp/autosar/test/rules/A15-1-2/PointerExceptionObject.qlref
deleted file mode 100644
index 68c8e7af9a..0000000000
--- a/cpp/autosar/test/rules/A15-1-2/PointerExceptionObject.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A15-1-2/PointerExceptionObject.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A15-1-2/PointerExceptionObject.testref b/cpp/autosar/test/rules/A15-1-2/PointerExceptionObject.testref
new file mode 100644
index 0000000000..24d4229225
--- /dev/null
+++ b/cpp/autosar/test/rules/A15-1-2/PointerExceptionObject.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/exceptionobjecthavepointertype/ExceptionObjectHavePointerType.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A15-1-3/ThrownExceptionsShouldBeUnique.expected b/cpp/autosar/test/rules/A15-1-3/ThrownExceptionsShouldBeUnique.expected
index b085736659..5db0f83985 100644
--- a/cpp/autosar/test/rules/A15-1-3/ThrownExceptionsShouldBeUnique.expected
+++ b/cpp/autosar/test/rules/A15-1-3/ThrownExceptionsShouldBeUnique.expected
@@ -1,3 +1,4 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThrownExceptionsShouldBeUnique.ql:24,3-11)
| test.cpp:6:5:6:26 | throw ... | The $@ thrown here is a possible duplicate of the $@ thrown $@. | test.cpp:6:5:6:26 | call to exception | std::exception exception | test.cpp:14:5:14:26 | call to exception | exception | test.cpp:14:5:14:26 | throw ... | here |
| test.cpp:8:5:8:53 | throw ... | The $@ thrown here is a possible duplicate of the $@ thrown $@. | test.cpp:8:5:8:53 | call to runtime_error | std::runtime_error exception | test.cpp:16:5:16:53 | call to runtime_error | exception | test.cpp:16:5:16:53 | throw ... | here |
| test.cpp:14:5:14:26 | throw ... | The $@ thrown here is a possible duplicate of the $@ thrown $@. | test.cpp:14:5:14:26 | call to exception | std::exception exception | test.cpp:6:5:6:26 | call to exception | exception | test.cpp:6:5:6:26 | throw ... | here |
diff --git a/cpp/autosar/test/rules/A15-2-2/ConstructorErrorLeavesObjectInInvalidState.expected b/cpp/autosar/test/rules/A15-2-2/ConstructorErrorLeavesObjectInInvalidState.expected
index 941771dada..529a7ccf99 100644
--- a/cpp/autosar/test/rules/A15-2-2/ConstructorErrorLeavesObjectInInvalidState.expected
+++ b/cpp/autosar/test/rules/A15-2-2/ConstructorErrorLeavesObjectInInvalidState.expected
@@ -1,3 +1,12 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstructorErrorLeavesObjectInInvalidState.ql:47,12-20)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstructorErrorLeavesObjectInInvalidState.ql:48,30-38)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstructorErrorLeavesObjectInInvalidState.ql:48,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstructorErrorLeavesObjectInInvalidState.ql:74,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstructorErrorLeavesObjectInInvalidState.ql:74,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstructorErrorLeavesObjectInInvalidState.ql:75,7-15)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstructorErrorLeavesObjectInInvalidState.ql:130,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstructorErrorLeavesObjectInInvalidState.ql:130,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstructorErrorLeavesObjectInInvalidState.ql:130,54-62)
edges
| test.cpp:12:16:12:27 | new [bad_alloc] | test.cpp:14:33:16:5 | { ... } [bad_alloc] |
| test.cpp:13:7:13:28 | throw ... [exception] | test.cpp:14:33:16:5 | { ... } [exception] |
diff --git a/cpp/autosar/test/rules/A15-4-2/NoExceptFunctionThrows.qlref b/cpp/autosar/test/rules/A15-4-2/NoExceptFunctionThrows.qlref
deleted file mode 100644
index 80fbc7365c..0000000000
--- a/cpp/autosar/test/rules/A15-4-2/NoExceptFunctionThrows.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A15-4-2/NoExceptFunctionThrows.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A15-4-2/NoExceptFunctionThrows.testref b/cpp/autosar/test/rules/A15-4-2/NoExceptFunctionThrows.testref
new file mode 100644
index 0000000000..76dc55827f
--- /dev/null
+++ b/cpp/autosar/test/rules/A15-4-2/NoExceptFunctionThrows.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A18-1-1/test.cpp b/cpp/autosar/test/rules/A18-1-1/test.cpp
index 90596780d9..0e9bffa3d7 100644
--- a/cpp/autosar/test/rules/A18-1-1/test.cpp
+++ b/cpp/autosar/test/rules/A18-1-1/test.cpp
@@ -11,6 +11,6 @@ int test_c_arrays() {
int x[100]; // NON_COMPLIANT
constexpr int a[]{0, 1, 2}; // NON_COMPLIANT
- __func__; // COMPLAINT
+ __func__; // COMPLIANT
return 0;
-}
\ No newline at end of file
+}
diff --git a/cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.qlref b/cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.qlref
deleted file mode 100644
index 9f78cda4c6..0000000000
--- a/cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A18-1-2/VectorboolSpecializationUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.testref b/cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.testref
new file mode 100644
index 0000000000..a934690acb
--- /dev/null
+++ b/cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.ql
\ 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..bd46224da6 100644
--- a/cpp/autosar/test/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.expected
+++ b/cpp/autosar/test/rules/A18-1-4/PointerToAnElementOfAnArrayPassedToASmartPointer.expected
@@ -1,10 +1,18 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerToAnElementOfAnArrayPassedToASmartPointer.ql:26,67-75)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerToAnElementOfAnArrayPassedToASmartPointer.ql:27,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerToAnElementOfAnArrayPassedToASmartPointer.ql:39,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerToAnElementOfAnArrayPassedToASmartPointer.ql:50,34-42)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerToAnElementOfAnArrayPassedToASmartPointer.ql:50,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerToAnElementOfAnArrayPassedToASmartPointer.ql:58,25-33)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (PointerToAnElementOfAnArrayPassedToASmartPointer.ql:70,3-16)
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:12:27:12:28 | v2 | test.cpp:12:30:12:36 | call to release | provenance | Config |
+| 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/A18-5-4/GlobalSizedOperatorDeleteNotDefined.qlref b/cpp/autosar/test/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.qlref
deleted file mode 100644
index 1f1e8258e4..0000000000
--- a/cpp/autosar/test/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.testref b/cpp/autosar/test/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.testref
new file mode 100644
index 0000000000..4d1e21d4cb
--- /dev/null
+++ b/cpp/autosar/test/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/globalsizedoperatordeletenotdefined/GlobalSizedOperatorDeleteNotDefined.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.qlref b/cpp/autosar/test/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.qlref
deleted file mode 100644
index 04cc5622dd..0000000000
--- a/cpp/autosar/test/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.testref b/cpp/autosar/test/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.testref
new file mode 100644
index 0000000000..f2fcc2eded
--- /dev/null
+++ b/cpp/autosar/test/rules/A18-5-4/GlobalUnsizedOperatorDeleteNotDefined.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/globalunsizedoperatordeletenotdefined/GlobalUnsizedOperatorDeleteNotDefined.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A18-5-8/UnnecessaryUseOfDynamicStorage.expected b/cpp/autosar/test/rules/A18-5-8/UnnecessaryUseOfDynamicStorage.expected
index d9dd02c054..68cab835fa 100644
--- a/cpp/autosar/test/rules/A18-5-8/UnnecessaryUseOfDynamicStorage.expected
+++ b/cpp/autosar/test/rules/A18-5-8/UnnecessaryUseOfDynamicStorage.expected
@@ -1,3 +1,8 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UnnecessaryUseOfDynamicStorage.ql:55,34-42)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UnnecessaryUseOfDynamicStorage.ql:58,33-41)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UnnecessaryUseOfDynamicStorage.ql:60,26-34)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (UnnecessaryUseOfDynamicStorage.ql:74,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (UnnecessaryUseOfDynamicStorage.ql:79,41-54)
| test.cpp:17:17:17:29 | new | StructA object of size 8 bytes does not appear to outlive the function, but is created on the heap instead of the stack. |
| test.cpp:21:17:21:32 | new[] | StructA[] object of size 800 bytes does not appear to outlive the function, but is created on the heap instead of the stack. |
| test.cpp:35:20:35:44 | call to make_shared | StructA object of size 8 bytes does not appear to outlive the function, but is created on the heap instead of the stack. |
diff --git a/cpp/autosar/test/rules/A18-9-2/ForwardingValuesToOtherFunctions.qlref b/cpp/autosar/test/rules/A18-9-2/ForwardingValuesToOtherFunctions.qlref
deleted file mode 100644
index 05bcab607a..0000000000
--- a/cpp/autosar/test/rules/A18-9-2/ForwardingValuesToOtherFunctions.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A18-9-2/ForwardingValuesToOtherFunctions.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A18-9-2/ForwardingValuesToOtherFunctions.testref b/cpp/autosar/test/rules/A18-9-2/ForwardingValuesToOtherFunctions.testref
new file mode 100644
index 0000000000..d56acb8415
--- /dev/null
+++ b/cpp/autosar/test/rules/A18-9-2/ForwardingValuesToOtherFunctions.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/forwardingreferencesandforwardnotusedtogether/ForwardingReferencesAndForwardNotUsedTogether.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A18-9-4/ArgumentToForwardSubsequentlyUsed.expected b/cpp/autosar/test/rules/A18-9-4/ArgumentToForwardSubsequentlyUsed.expected
index 1c72dd7bf3..9e1cf41d3d 100644
--- a/cpp/autosar/test/rules/A18-9-4/ArgumentToForwardSubsequentlyUsed.expected
+++ b/cpp/autosar/test/rules/A18-9-4/ArgumentToForwardSubsequentlyUsed.expected
@@ -1 +1,4 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ArgumentToForwardSubsequentlyUsed.ql:22,10-18)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ArgumentToForwardSubsequentlyUsed.ql:24,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ArgumentToForwardSubsequentlyUsed.ql:24,30-38)
| test.cpp:8:5:8:6 | t2 | The argument $@ of `std::forward` may be indeterminate when accessed at this location. | test.cpp:7:45:7:46 | t2 | t2 |
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-13-1/EscapeSequenceOutsideISO.qlref b/cpp/autosar/test/rules/A2-13-1/EscapeSequenceOutsideISO.qlref
deleted file mode 100644
index ce6347c955..0000000000
--- a/cpp/autosar/test/rules/A2-13-1/EscapeSequenceOutsideISO.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A2-13-1/EscapeSequenceOutsideISO.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A2-13-1/EscapeSequenceOutsideISO.testref b/cpp/autosar/test/rules/A2-13-1/EscapeSequenceOutsideISO.testref
new file mode 100644
index 0000000000..924122e38e
--- /dev/null
+++ b/cpp/autosar/test/rules/A2-13-1/EscapeSequenceOutsideISO.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/backslashcharactermisuse/BackslashCharacterMisuse.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A2-7-1/SingleLineCommentEndsWithSlash.qlref b/cpp/autosar/test/rules/A2-7-1/SingleLineCommentEndsWithSlash.qlref
deleted file mode 100644
index 876f24be61..0000000000
--- a/cpp/autosar/test/rules/A2-7-1/SingleLineCommentEndsWithSlash.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A2-7-1/SingleLineCommentEndsWithSlash.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A2-7-1/SingleLineCommentEndsWithSlash.testref b/cpp/autosar/test/rules/A2-7-1/SingleLineCommentEndsWithSlash.testref
new file mode 100644
index 0000000000..7874a476a0
--- /dev/null
+++ b/cpp/autosar/test/rules/A2-7-1/SingleLineCommentEndsWithSlash.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/linesplicingusedincomments/LineSplicingUsedInComments.ql
\ 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/A20-8-4/SharedPointerUsedWithNoOwnershipSharing.expected b/cpp/autosar/test/rules/A20-8-4/SharedPointerUsedWithNoOwnershipSharing.expected
index f15f142b3b..5b770a1925 100644
--- a/cpp/autosar/test/rules/A20-8-4/SharedPointerUsedWithNoOwnershipSharing.expected
+++ b/cpp/autosar/test/rules/A20-8-4/SharedPointerUsedWithNoOwnershipSharing.expected
@@ -1,3 +1,4 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (SharedPointerUsedWithNoOwnershipSharing.ql:47,7-15)
| test.cpp:14:24:14:26 | sp3 | The ownership of shared_ptr $@ is not shared within or passed out of the local scope of function $@. | test.cpp:14:24:14:26 | sp3 | sp3 | test.cpp:11:22:11:23 | f1 | f1 |
| test.cpp:16:24:16:26 | sp5 | The ownership of shared_ptr $@ is not shared within or passed out of the local scope of function $@. | test.cpp:16:24:16:26 | sp5 | sp5 | test.cpp:11:22:11:23 | f1 | f1 |
| test.cpp:17:24:17:26 | sp6 | The ownership of shared_ptr $@ is not shared within or passed out of the local scope of function $@. | test.cpp:17:24:17:26 | sp6 | sp6 | test.cpp:11:22:11:23 | f1 | f1 |
diff --git a/cpp/autosar/test/rules/A27-0-4/CStyleStringsUsed.expected b/cpp/autosar/test/rules/A27-0-4/CStyleStringsUsed.expected
index 6184aad74e..555cb412b8 100644
--- a/cpp/autosar/test/rules/A27-0-4/CStyleStringsUsed.expected
+++ b/cpp/autosar/test/rules/A27-0-4/CStyleStringsUsed.expected
@@ -1,3 +1,6 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CStyleStringsUsed.ql:39,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CStyleStringsUsed.ql:39,23-31)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (CStyleStringsUsed.ql:39,47-55)
| test.cpp:7:20:7:27 | CodeQL | Usage of C-style string in $@. | test.cpp:7:20:7:27 | CodeQL | expression |
| test.cpp:7:20:7:27 | CodeQL | Usage of C-style string in $@. | test.cpp:16:16:16:17 | a1 | expression |
| test.cpp:8:22:8:26 | call to c_str | Usage of C-style string in $@. | test.cpp:8:22:8:26 | call to c_str | expression |
diff --git a/cpp/autosar/test/rules/A3-9-1/test.cpp b/cpp/autosar/test/rules/A3-9-1/test.cpp
index 882738eea1..7ffb87ca39 100644
--- a/cpp/autosar/test/rules/A3-9-1/test.cpp
+++ b/cpp/autosar/test/rules/A3-9-1/test.cpp
@@ -75,4 +75,15 @@ void test_variable_width_type_qualified_variables() {
struct test_fix_fp_614 {
test_fix_fp_614 operator++(int); // COMPLIANT
test_fix_fp_614 operator--(int); // COMPLIANT
-};
\ No newline at end of file
+};
+
+// COMPLIANT - instantiated with Fixed Width Types.
+template constexpr void test_fix_fp_540(MyType value) {
+ value++;
+}
+
+int call_test_fix_fp_540() {
+ test_fix_fp_540(19);
+ test_fix_fp_540(20);
+ return 0;
+}
diff --git a/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.qlref b/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.qlref
deleted file mode 100644
index d836b834b3..0000000000
--- a/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A4-10-1/NullPointerConstantNotNullptr.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.testref b/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.testref
new file mode 100644
index 0000000000..aeb655a341
--- /dev/null
+++ b/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.ql
\ 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..e2b51e5fb9 100644
--- a/cpp/autosar/test/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.expected
+++ b/cpp/autosar/test/rules/A5-0-4/PointerArithmeticUsedWithPointersToNonFinalClasses.expected
@@ -1,15 +1,19 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerArithmeticUsedWithPointersToNonFinalClasses.ql:45,62-70)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerArithmeticUsedWithPointersToNonFinalClasses.ql:46,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerArithmeticUsedWithPointersToNonFinalClasses.ql:55,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (PointerArithmeticUsedWithPointersToNonFinalClasses.ql:61,3-11)
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/LambdaPassedToDecltype.expected b/cpp/autosar/test/rules/A5-1-7/LambdaPassedToDecltype.expected
index 8f6447a96b..56896d69fd 100644
--- a/cpp/autosar/test/rules/A5-1-7/LambdaPassedToDecltype.expected
+++ b/cpp/autosar/test/rules/A5-1-7/LambdaPassedToDecltype.expected
@@ -1 +1,7 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToDecltype.ql:20,55-63)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToDecltype.ql:21,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToDecltype.ql:23,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToDecltype.ql:28,44-52)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToDecltype.ql:39,47-55)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToDecltype.ql:40,9-17)
| test.cpp:14:23:14:24 | decltype(...) | Lambda $@ passed as operand to decltype. | test.cpp:5:13:5:30 | [...](...){...} | expression |
diff --git a/cpp/autosar/test/rules/A5-1-7/LambdaPassedToTypeid.expected b/cpp/autosar/test/rules/A5-1-7/LambdaPassedToTypeid.expected
index 4b19073ded..8f86a87616 100644
--- a/cpp/autosar/test/rules/A5-1-7/LambdaPassedToTypeid.expected
+++ b/cpp/autosar/test/rules/A5-1-7/LambdaPassedToTypeid.expected
@@ -1,6 +1,10 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToTypeid.ql:21,50-58)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToTypeid.ql:22,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToTypeid.ql:24,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (LambdaPassedToTypeid.ql:27,39-47)
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-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.qlref b/cpp/autosar/test/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.qlref
deleted file mode 100644
index 5f588b44ab..0000000000
--- a/cpp/autosar/test/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.testref b/cpp/autosar/test/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.testref
new file mode 100644
index 0000000000..ca8eab9681
--- /dev/null
+++ b/cpp/autosar/test/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A5-10-1/PotentiallyVirtualPointerOnlyComparesToNullptr.testref b/cpp/autosar/test/rules/A5-10-1/PotentiallyVirtualPointerOnlyComparesToNullptr.testref
new file mode 100644
index 0000000000..ca8eab9681
--- /dev/null
+++ b/cpp/autosar/test/rules/A5-10-1/PotentiallyVirtualPointerOnlyComparesToNullptr.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A5-2-4/ReinterpretCastUsed.qlref b/cpp/autosar/test/rules/A5-2-4/ReinterpretCastUsed.qlref
deleted file mode 100644
index 3cfb0444cc..0000000000
--- a/cpp/autosar/test/rules/A5-2-4/ReinterpretCastUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A5-2-4/ReinterpretCastUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A5-2-4/ReinterpretCastUsed.testref b/cpp/autosar/test/rules/A5-2-4/ReinterpretCastUsed.testref
new file mode 100644
index 0000000000..81f18c2d9c
--- /dev/null
+++ b/cpp/autosar/test/rules/A5-2-4/ReinterpretCastUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/reinterpretcastused/ReinterpretCastUsed.ql
\ No newline at end of file
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/A6-6-1/GotoStatementUsed.expected b/cpp/autosar/test/rules/A6-6-1/GotoStatementUsed.expected
deleted file mode 100644
index 9f4343cf1c..0000000000
--- a/cpp/autosar/test/rules/A6-6-1/GotoStatementUsed.expected
+++ /dev/null
@@ -1 +0,0 @@
-| test.cpp:4:3:4:14 | goto ... | Use of goto. |
diff --git a/cpp/autosar/test/rules/A6-6-1/GotoStatementUsed.qlref b/cpp/autosar/test/rules/A6-6-1/GotoStatementUsed.qlref
deleted file mode 100644
index d3516aa03b..0000000000
--- a/cpp/autosar/test/rules/A6-6-1/GotoStatementUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A6-6-1/GotoStatementUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A6-6-1/GotoStatementUsed.testref b/cpp/autosar/test/rules/A6-6-1/GotoStatementUsed.testref
new file mode 100644
index 0000000000..44d306f80c
--- /dev/null
+++ b/cpp/autosar/test/rules/A6-6-1/GotoStatementUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A6-6-1/test.cpp b/cpp/autosar/test/rules/A6-6-1/test.cpp
deleted file mode 100644
index d13f01961c..0000000000
--- a/cpp/autosar/test/rules/A6-6-1/test.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-void test_goto() {
- int x = 1;
-
- goto label1; // NON_COMPLIANT
-
-label1:
-
- x = 2;
-}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-1-2/VariableMissingConstexpr.expected b/cpp/autosar/test/rules/A7-1-2/VariableMissingConstexpr.expected
index f86faf1a7b..31c26a11ff 100644
--- a/cpp/autosar/test/rules/A7-1-2/VariableMissingConstexpr.expected
+++ b/cpp/autosar/test/rules/A7-1-2/VariableMissingConstexpr.expected
@@ -7,9 +7,9 @@
| test.cpp:41:14:41:15 | l2 | Variable 'l2' could be marked 'constexpr'. |
| test.cpp:44:16:44:17 | lc | Variable 'lc' could be marked 'constexpr'. |
| test.cpp:45:17:45:19 | lc2 | Variable 'lc2' could be marked 'constexpr'. |
-| test.cpp:55:7:55:8 | m2 | Variable 'm2' could be marked 'constexpr'. |
-| test.cpp:130:7:130:8 | m1 | Variable 'm1' could be marked 'constexpr'. |
-| test.cpp:141:7:141:8 | m1 | Variable 'm1' could be marked 'constexpr'. |
+| test.cpp:55:7:55:8 | m2 | Variable 'm2' could be marked 'constexpr' and static. |
+| test.cpp:130:7:130:8 | m1 | Variable 'm1' could be marked 'constexpr' and static. |
+| test.cpp:141:7:141:8 | m1 | Variable 'm1' could be marked 'constexpr' and static. |
| test.cpp:221:7:221:8 | l1 | Variable 'l1' could be marked 'constexpr'. |
| test.cpp:235:7:235:8 | l6 | Variable 'l6' could be marked 'constexpr'. |
| test.cpp:237:7:237:8 | l8 | Variable 'l8' could be marked 'constexpr'. |
diff --git a/cpp/autosar/test/rules/A7-1-2/test.cpp b/cpp/autosar/test/rules/A7-1-2/test.cpp
index 8395f60ff3..664a9cb8e7 100644
--- a/cpp/autosar/test/rules/A7-1-2/test.cpp
+++ b/cpp/autosar/test/rules/A7-1-2/test.cpp
@@ -127,7 +127,7 @@ class MissingConstexprClass {
MissingConstexprClass(int i) = delete; // NON_COMPLIANT
MissingConstexprClass(int i, LiteralClass lc) {} // NON_COMPLIANT
private:
- int m1 = 0;
+ int m1 = 0; // NON_COMPLIANT
};
class VirtualBaseClass {};
@@ -138,7 +138,7 @@ class DerivedClass : public virtual VirtualBaseClass {
DerivedClass(int i) = delete; // COMPLIANT
DerivedClass(int i, LiteralClass lc) {} // COMPLIANT
private:
- int m1 = 0;
+ int m1 = 0; // NON_COMPLIANT
};
class NotAllMembersInitializedClass {
@@ -274,4 +274,4 @@ template T *init() {
return t;
}
-void test_template_instantiation() { int *t = init(); }
\ No newline at end of file
+void test_template_instantiation() { int *t = init(); }
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-1-7/test.cpp b/cpp/autosar/test/rules/A7-1-7/test.cpp
index 7c5a6263cf..80f6542b11 100644
--- a/cpp/autosar/test/rules/A7-1-7/test.cpp
+++ b/cpp/autosar/test/rules/A7-1-7/test.cpp
@@ -152,4 +152,14 @@ void example_function() { f1(); } // COMPLIANT
// clang-format off
typedef struct x { int y; } z; //COMPLIANT - for struct typedef and struct var //NON_COMPLIANT - for struct all on one line
-// clang-format on
\ No newline at end of file
+// clang-format on
+
+#define foo(x, y) \
+ x++; \
+ y++;
+
+void test_foo() {
+ int a = 1;
+ int b = 1;
+ foo(a, b); // COMPLIANT
+}
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/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.qlref b/cpp/autosar/test/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.qlref
deleted file mode 100644
index 1ed510a506..0000000000
--- a/cpp/autosar/test/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.testref b/cpp/autosar/test/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.testref
new file mode 100644
index 0000000000..d7a73fd488
--- /dev/null
+++ b/cpp/autosar/test/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/enumerationnotdefinedwithanexplicitunderlyingtype/EnumerationNotDefinedWithAnExplicitUnderlyingType.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.qlref b/cpp/autosar/test/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.qlref
deleted file mode 100644
index 0fe94e847c..0000000000
--- a/cpp/autosar/test/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.testref b/cpp/autosar/test/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.testref
new file mode 100644
index 0000000000..7a5ae74d2e
--- /dev/null
+++ b/cpp/autosar/test/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/definitionnotconsideredforunqualifiedlookup/DefinitionNotConsideredForUnqualifiedLookup.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.qlref b/cpp/autosar/test/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.qlref
deleted file mode 100644
index d94c3c0b0a..0000000000
--- a/cpp/autosar/test/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.testref b/cpp/autosar/test/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.testref
new file mode 100644
index 0000000000..2fb9608ee8
--- /dev/null
+++ b/cpp/autosar/test/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/hiddeninheritednonoverridablememberfunction/HiddenInheritedNonOverridableMemberFunction.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.qlref b/cpp/autosar/test/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.qlref
deleted file mode 100644
index 57d16c4e90..0000000000
--- a/cpp/autosar/test/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A7-3-1/HiddenInheritedOverridableMemberFunction.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.testref b/cpp/autosar/test/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.testref
new file mode 100644
index 0000000000..e768ced8d3
--- /dev/null
+++ b/cpp/autosar/test/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/hiddeninheritedoverridablememberfunction/HiddenInheritedOverridableMemberFunction.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-4-1/AsmDeclarationUsed.qlref b/cpp/autosar/test/rules/A7-4-1/AsmDeclarationUsed.qlref
deleted file mode 100644
index 286e62bd18..0000000000
--- a/cpp/autosar/test/rules/A7-4-1/AsmDeclarationUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A7-4-1/AsmDeclarationUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-4-1/AsmDeclarationUsed.testref b/cpp/autosar/test/rules/A7-4-1/AsmDeclarationUsed.testref
new file mode 100644
index 0000000000..f643f6a9c7
--- /dev/null
+++ b/cpp/autosar/test/rules/A7-4-1/AsmDeclarationUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/asmdeclarationused/AsmDeclarationUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-5-1/InvalidFunctionReturnType.expected b/cpp/autosar/test/rules/A7-5-1/InvalidFunctionReturnType.expected
index b6d9490803..3287ba88d1 100644
--- a/cpp/autosar/test/rules/A7-5-1/InvalidFunctionReturnType.expected
+++ b/cpp/autosar/test/rules/A7-5-1/InvalidFunctionReturnType.expected
@@ -1,2 +1,5 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (InvalidFunctionReturnType.ql:27,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (InvalidFunctionReturnType.ql:27,23-31)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (InvalidFunctionReturnType.ql:27,51-59)
| test.cpp:5:3:5:11 | return ... | Function test_refconst_return returns a reference or a pointer to $@ that is passed by reference to const. | test.cpp:4:44:4:44 | x | parameter |
| test.cpp:8:3:8:14 | return ... | Function test_ptrconst_return returns a reference or a pointer to $@ that is passed by reference to const. | test.cpp:7:44:7:44 | x | parameter |
diff --git a/cpp/autosar/test/rules/A7-5-2/RecursiveFunctions.qlref b/cpp/autosar/test/rules/A7-5-2/RecursiveFunctions.qlref
deleted file mode 100644
index 10fccea7f7..0000000000
--- a/cpp/autosar/test/rules/A7-5-2/RecursiveFunctions.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A7-5-2/RecursiveFunctions.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-5-2/RecursiveFunctions.testref b/cpp/autosar/test/rules/A7-5-2/RecursiveFunctions.testref
new file mode 100644
index 0000000000..f459a29bf1
--- /dev/null
+++ b/cpp/autosar/test/rules/A7-5-2/RecursiveFunctions.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A8-4-11/SmartPointerAsParameterWithoutLifetimeSemantics.expected b/cpp/autosar/test/rules/A8-4-11/SmartPointerAsParameterWithoutLifetimeSemantics.expected
index b751d81835..2ce56fdce9 100644
--- a/cpp/autosar/test/rules/A8-4-11/SmartPointerAsParameterWithoutLifetimeSemantics.expected
+++ b/cpp/autosar/test/rules/A8-4-11/SmartPointerAsParameterWithoutLifetimeSemantics.expected
@@ -1,3 +1,5 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (SmartPointerAsParameterWithoutLifetimeSemantics.ql:47,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (SmartPointerAsParameterWithoutLifetimeSemantics.ql:56,5-13)
| test.cpp:7:41:7:43 | up1 | Function $@ takes smart pointer parameter 'up1' but does not implement any lifetime-affecting operations. | test.cpp:7:6:7:18 | smart_ptr_get | smart_ptr_get |
| test.cpp:16:53:16:55 | sp1 | Function $@ takes smart pointer parameter 'sp1' but does not implement any lifetime-affecting operations. | test.cpp:16:6:16:29 | smart_ptr_ref_assign_ref | smart_ptr_ref_assign_ref |
| test.cpp:28:55:28:57 | sp1 | Function $@ takes smart pointer parameter 'sp1' but does not implement any lifetime-affecting operations. | test.cpp:28:6:28:31 | smart_ptr_ref_noncompliant | smart_ptr_ref_noncompliant |
diff --git a/cpp/autosar/test/rules/A8-4-12/UniquePtrPassedToFunctionWithImproperSemantics.expected b/cpp/autosar/test/rules/A8-4-12/UniquePtrPassedToFunctionWithImproperSemantics.expected
index a01b93335d..0a8ead4af8 100644
--- a/cpp/autosar/test/rules/A8-4-12/UniquePtrPassedToFunctionWithImproperSemantics.expected
+++ b/cpp/autosar/test/rules/A8-4-12/UniquePtrPassedToFunctionWithImproperSemantics.expected
@@ -1,3 +1,5 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UniquePtrPassedToFunctionWithImproperSemantics.ql:41,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UniquePtrPassedToFunctionWithImproperSemantics.ql:51,5-13)
| test.cpp:13:55:13:56 | v1 | Parameter of type std::unique_ptr passed as lvalue reference but not used to modify underlying object. |
| test.cpp:17:47:17:48 | v1 | Parameter of type std::unique_ptr passed as lvalue reference but not used to modify underlying object. |
| test.cpp:22:27:22:28 | v1 | Parameter of type std::unique_ptr passed as lvalue reference but not used to modify underlying object. |
diff --git a/cpp/autosar/test/rules/A8-4-9/InOutParametersDeclaredAsTNotModified.expected b/cpp/autosar/test/rules/A8-4-9/InOutParametersDeclaredAsTNotModified.expected
index e3cfa71bb7..bafa98112f 100644
--- a/cpp/autosar/test/rules/A8-4-9/InOutParametersDeclaredAsTNotModified.expected
+++ b/cpp/autosar/test/rules/A8-4-9/InOutParametersDeclaredAsTNotModified.expected
@@ -1,3 +1,5 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (InOutParametersDeclaredAsTNotModified.ql:49,7-15)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (InOutParametersDeclaredAsTNotModified.ql:63,7-15)
| test.cpp:4:13:4:13 | i | In-out parameter i that is not written to. |
| test.cpp:7:22:7:24 | str | In-out parameter str that is not read from. |
| test.cpp:18:14:18:14 | i | In-out parameter i that is not read from. |
diff --git a/cpp/autosar/test/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.qlref b/cpp/autosar/test/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.qlref
deleted file mode 100644
index eb351d9e36..0000000000
--- a/cpp/autosar/test/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/A8-5-4/ConfusingUseOfInitializerListConstructors.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.testref b/cpp/autosar/test/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.testref
new file mode 100644
index 0000000000..49b73d06a9
--- /dev/null
+++ b/cpp/autosar/test/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/initializerlistconstructoristheonlyconstructor/InitializerListConstructorIsTheOnlyConstructor.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A9-3-1/ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.expected b/cpp/autosar/test/rules/A9-3-1/ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.expected
index 04c1f35a45..70892c12c8 100644
--- a/cpp/autosar/test/rules/A9-3-1/ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.expected
+++ b/cpp/autosar/test/rules/A9-3-1/ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.expected
@@ -1,3 +1,6 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.ql:73,3-11)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.ql:73,23-31)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ReturnsNonConstRawPointersOrReferencesToPrivateOrProtectedData.ql:73,46-54)
| test.cpp:20:8:20:12 | getB2 | Member function A::getB2 $@ a non-const raw pointer or reference to a private or protected $@. | test.cpp:20:25:20:25 | b | returns | test.cpp:54:7:54:7 | b | field |
| test.cpp:22:8:22:12 | getB3 | Member function A::getB3 $@ a non-const raw pointer or reference to a private or protected $@. | test.cpp:22:25:22:26 | & ... | returns | test.cpp:54:7:54:7 | b | field |
| test.cpp:24:8:24:13 | getB33 | Member function A::getB33 $@ a non-const raw pointer or reference to a private or protected $@. | test.cpp:26:12:26:13 | bb | returns | test.cpp:54:7:54:7 | b | field |
diff --git a/cpp/autosar/test/rules/M0-1-10.1/UnusedFunction.expected b/cpp/autosar/test/rules/M0-1-10.1/UnusedFunction.expected
new file mode 100644
index 0000000000..3f58065520
--- /dev/null
+++ b/cpp/autosar/test/rules/M0-1-10.1/UnusedFunction.expected
@@ -0,0 +1 @@
+| test.cpp:23:14:23:26 | uncalled_func | Function uncalled_func is never called. |
diff --git a/cpp/autosar/test/rules/M0-1-10.1/UnusedFunction.qlref b/cpp/autosar/test/rules/M0-1-10.1/UnusedFunction.qlref
new file mode 100644
index 0000000000..519660f289
--- /dev/null
+++ b/cpp/autosar/test/rules/M0-1-10.1/UnusedFunction.qlref
@@ -0,0 +1 @@
+rules/M0-1-10/UnusedFunction.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M0-1-10.1/test.cpp b/cpp/autosar/test/rules/M0-1-10.1/test.cpp
new file mode 100644
index 0000000000..5b9c68a827
--- /dev/null
+++ b/cpp/autosar/test/rules/M0-1-10.1/test.cpp
@@ -0,0 +1,39 @@
+#include
+
+namespace mains {
+static std::int32_t var;
+
+// @brief namespace_func
+static void
+namespace_func(void) noexcept { // COMPLIANT: Called from "main" below.
+ mains::var = -1;
+ return;
+}
+} // namespace mains
+
+std::int32_t func2() // COMPLIANT: Called from func1
+{
+ return mains::var + 20;
+}
+
+std::int32_t func1() { // COMPLIANT: Called from main
+ return mains::var + func2(); // func2 called here.
+}
+
+std::int32_t uncalled_func() // NON_COMPLIANT: Not called.
+{
+ return mains::var + func1(); // func1 called here.
+}
+
+// @brief main
+// @return exit code
+std::int32_t main(void) {
+ std::int32_t ret{0};
+ try {
+ ret = func1(); // func1 called here.
+ mains::var += ret;
+ } catch (...) {
+ mains::namespace_func(); // namespace_func called here.
+ }
+ return ret;
+}
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/autosar/test/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.qlref b/cpp/autosar/test/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.qlref
deleted file mode 100644
index 208baa8d08..0000000000
--- a/cpp/autosar/test/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.testref b/cpp/autosar/test/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.testref
new file mode 100644
index 0000000000..fe57c50fe3
--- /dev/null
+++ b/cpp/autosar/test/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/virtualandnonvirtualclassinthehierarchy/VirtualAndNonVirtualClassInTheHierarchy.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.qlref b/cpp/autosar/test/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.qlref
deleted file mode 100644
index 4235959d77..0000000000
--- a/cpp/autosar/test/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.testref b/cpp/autosar/test/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.testref
new file mode 100644
index 0000000000..596f74b010
--- /dev/null
+++ b/cpp/autosar/test/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/objectsdynamictypeusedfromconstructorordestructor/ObjectsDynamicTypeUsedFromConstructorOrDestructor.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.qlref b/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.qlref
deleted file mode 100644
index f0e2ebd711..0000000000
--- a/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.testref b/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.testref
new file mode 100644
index 0000000000..ad5590bc1f
--- /dev/null
+++ b/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/namenotreferredusingaqualifiedidorthis/NameNotReferredUsingAQualifiedIdOrThis.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.qlref b/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.qlref
deleted file mode 100644
index 442eb62675..0000000000
--- a/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.testref b/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.testref
new file mode 100644
index 0000000000..f7ff9100a6
--- /dev/null
+++ b/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/namenotreferredusingaqualifiedidorthisaudit/NameNotReferredUsingAQualifiedIdOrThisAudit.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M15-1-3/EmptyThrowOutsideCatch.qlref b/cpp/autosar/test/rules/M15-1-3/EmptyThrowOutsideCatch.qlref
deleted file mode 100644
index 3643376e59..0000000000
--- a/cpp/autosar/test/rules/M15-1-3/EmptyThrowOutsideCatch.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M15-1-3/EmptyThrowOutsideCatch.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M15-1-3/EmptyThrowOutsideCatch.testref b/cpp/autosar/test/rules/M15-1-3/EmptyThrowOutsideCatch.testref
new file mode 100644
index 0000000000..f3c961d8f1
--- /dev/null
+++ b/cpp/autosar/test/rules/M15-1-3/EmptyThrowOutsideCatch.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/emptythrowonlywithinacatchhandler/EmptyThrowOnlyWithinACatchHandler.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.expected.gcc b/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.expected.gcc
deleted file mode 100644
index f09fafd410..0000000000
--- a/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.expected.gcc
+++ /dev/null
@@ -1 +0,0 @@
-| test.cpp:9:32:9:51 | offsetof(__typ,__id) | Use of banned macro offsetof. |
diff --git a/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.qlref b/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.qlref
deleted file mode 100644
index a69e18549f..0000000000
--- a/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M18-2-1/MacroOffsetofUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.testref b/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.testref
new file mode 100644
index 0000000000..022fef6071
--- /dev/null
+++ b/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M18-7-1/CsignalFunctionsUsed.qlref b/cpp/autosar/test/rules/M18-7-1/CsignalFunctionsUsed.qlref
deleted file mode 100644
index 445ccd5bd4..0000000000
--- a/cpp/autosar/test/rules/M18-7-1/CsignalFunctionsUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M18-7-1/CsignalFunctionsUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M18-7-1/CsignalFunctionsUsed.testref b/cpp/autosar/test/rules/M18-7-1/CsignalFunctionsUsed.testref
new file mode 100644
index 0000000000..a09406a932
--- /dev/null
+++ b/cpp/autosar/test/rules/M18-7-1/CsignalFunctionsUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/csignalfunctionsused/CsignalFunctionsUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M18-7-1/CsignalTypesUsed.qlref b/cpp/autosar/test/rules/M18-7-1/CsignalTypesUsed.qlref
deleted file mode 100644
index 34c83d741a..0000000000
--- a/cpp/autosar/test/rules/M18-7-1/CsignalTypesUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M18-7-1/CsignalTypesUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M18-7-1/CsignalTypesUsed.testref b/cpp/autosar/test/rules/M18-7-1/CsignalTypesUsed.testref
new file mode 100644
index 0000000000..3d398d799b
--- /dev/null
+++ b/cpp/autosar/test/rules/M18-7-1/CsignalTypesUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/csignaltypesused/CsignalTypesUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalEscape.expected b/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalEscape.expected
index 17a0016fec..41ebcf7629 100644
--- a/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalEscape.expected
+++ b/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalEscape.expected
@@ -1,6 +1,6 @@
| test.cpp:3:3:3:8 | 10 | This literal contains the non-zero octal escape code \\012. |
| test.cpp:4:3:4:8 | 44 | This literal contains the non-zero octal escape code \\054. |
| test.cpp:5:3:5:9 | 3129 | This literal contains the non-zero octal escape code \\014. |
-| test.cpp:10:3:10:8 | \n | This literal contains the non-zero octal escape code \\012. |
-| test.cpp:11:3:11:8 | , | This literal contains the non-zero octal escape code \\054. |
-| test.cpp:12:3:12:9 | \u000c9 | This literal contains the non-zero octal escape code \\014. |
+| test.cpp:7:3:7:8 | \n | This literal contains the non-zero octal escape code \\012. |
+| test.cpp:8:3:8:8 | , | This literal contains the non-zero octal escape code \\054. |
+| test.cpp:9:3:9:9 | \u000c9 | This literal contains the non-zero octal escape code \\014. |
diff --git a/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalLiteral.expected b/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalLiteral.expected
deleted file mode 100644
index 8109c107a5..0000000000
--- a/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalLiteral.expected
+++ /dev/null
@@ -1,2 +0,0 @@
-| test.cpp:7:3:7:5 | 10 | Non zero octal literal 012. |
-| test.cpp:8:3:8:5 | 44 | Non zero octal literal 054. |
diff --git a/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalLiteral.qlref b/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalLiteral.qlref
deleted file mode 100644
index 67900e54f7..0000000000
--- a/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalLiteral.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M2-13-2/UseOfNonZeroOctalLiteral.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalLiteral.testref b/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalLiteral.testref
new file mode 100644
index 0000000000..97c466a866
--- /dev/null
+++ b/cpp/autosar/test/rules/M2-13-2/UseOfNonZeroOctalLiteral.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M2-13-2/test.cpp b/cpp/autosar/test/rules/M2-13-2/test.cpp
index a89809d68c..3c7fba30dd 100644
--- a/cpp/autosar/test/rules/M2-13-2/test.cpp
+++ b/cpp/autosar/test/rules/M2-13-2/test.cpp
@@ -3,9 +3,6 @@ void test_non_zero_octal() {
'\012'; // NON_COMPLIANT
'\054'; // NON_COMPLIANT
'\0149'; // NON_COMPLIANT
- 0; // COMPLIANT - octal literal zero permitted
- 012; // NON_COMPLIANT
- 054; // NON_COMPLIANT
"\0"; // COMPLIANT - octal zero escape sequence permitted
"\012"; // NON_COMPLIANT
"\054"; // NON_COMPLIANT
diff --git a/cpp/autosar/test/rules/M2-13-3/MissingUSuffix.expected b/cpp/autosar/test/rules/M2-13-3/MissingUSuffix.expected
deleted file mode 100644
index 56dce901dd..0000000000
--- a/cpp/autosar/test/rules/M2-13-3/MissingUSuffix.expected
+++ /dev/null
@@ -1 +0,0 @@
-| test.cpp:3:3:3:12 | 4294967295 | Hex literal is an unsigned integer but does not include a 'U' suffix. |
diff --git a/cpp/autosar/test/rules/M2-13-3/MissingUSuffix.qlref b/cpp/autosar/test/rules/M2-13-3/MissingUSuffix.qlref
deleted file mode 100644
index ffb71066d5..0000000000
--- a/cpp/autosar/test/rules/M2-13-3/MissingUSuffix.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M2-13-3/MissingUSuffix.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M2-13-3/MissingUSuffix.testref b/cpp/autosar/test/rules/M2-13-3/MissingUSuffix.testref
new file mode 100644
index 0000000000..9133a84ce4
--- /dev/null
+++ b/cpp/autosar/test/rules/M2-13-3/MissingUSuffix.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M2-13-3/test.cpp b/cpp/autosar/test/rules/M2-13-3/test.cpp
deleted file mode 100644
index e5b3abfa47..0000000000
--- a/cpp/autosar/test/rules/M2-13-3/test.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-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
-}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M2-7-1/SlashStarUsedWithinACStyleComment.qlref b/cpp/autosar/test/rules/M2-7-1/SlashStarUsedWithinACStyleComment.qlref
deleted file mode 100644
index 3f146ebeaf..0000000000
--- a/cpp/autosar/test/rules/M2-7-1/SlashStarUsedWithinACStyleComment.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M2-7-1/SlashStarUsedWithinACStyleComment.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M2-7-1/SlashStarUsedWithinACStyleComment.testref b/cpp/autosar/test/rules/M2-7-1/SlashStarUsedWithinACStyleComment.testref
new file mode 100644
index 0000000000..971b1953f7
--- /dev/null
+++ b/cpp/autosar/test/rules/M2-7-1/SlashStarUsedWithinACStyleComment.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/charactersequenceusedwithinacstylecomment/CharacterSequenceUsedWithinACStyleComment.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M27-0-1/CstdioFunctionsUsed.qlref b/cpp/autosar/test/rules/M27-0-1/CstdioFunctionsUsed.qlref
deleted file mode 100644
index 7d97c146c9..0000000000
--- a/cpp/autosar/test/rules/M27-0-1/CstdioFunctionsUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M27-0-1/CstdioFunctionsUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M27-0-1/CstdioFunctionsUsed.testref b/cpp/autosar/test/rules/M27-0-1/CstdioFunctionsUsed.testref
new file mode 100644
index 0000000000..5f8b3d8a9a
--- /dev/null
+++ b/cpp/autosar/test/rules/M27-0-1/CstdioFunctionsUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/cstdiofunctionsused/CstdioFunctionsUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M27-0-1/CstdioMacrosUsed.qlref b/cpp/autosar/test/rules/M27-0-1/CstdioMacrosUsed.qlref
deleted file mode 100644
index 20bf876eba..0000000000
--- a/cpp/autosar/test/rules/M27-0-1/CstdioMacrosUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M27-0-1/CstdioMacrosUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M27-0-1/CstdioMacrosUsed.testref b/cpp/autosar/test/rules/M27-0-1/CstdioMacrosUsed.testref
new file mode 100644
index 0000000000..a1ba376c3b
--- /dev/null
+++ b/cpp/autosar/test/rules/M27-0-1/CstdioMacrosUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/cstdiomacrosused/CstdioMacrosUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M27-0-1/CstdioTypesUsed.qlref b/cpp/autosar/test/rules/M27-0-1/CstdioTypesUsed.qlref
deleted file mode 100644
index 10beab7eaa..0000000000
--- a/cpp/autosar/test/rules/M27-0-1/CstdioTypesUsed.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M27-0-1/CstdioTypesUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M27-0-1/CstdioTypesUsed.testref b/cpp/autosar/test/rules/M27-0-1/CstdioTypesUsed.testref
new file mode 100644
index 0000000000..4c08a75cfe
--- /dev/null
+++ b/cpp/autosar/test/rules/M27-0-1/CstdioTypesUsed.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/cstdiotypesused/CstdioTypesUsed.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M3-9-3/UnderlyingBitRepresentationsOfFloatingPointValuesUsed.expected b/cpp/autosar/test/rules/M3-9-3/UnderlyingBitRepresentationsOfFloatingPointValuesUsed.expected
index 9aec2314da..d0fe6416ca 100644
--- a/cpp/autosar/test/rules/M3-9-3/UnderlyingBitRepresentationsOfFloatingPointValuesUsed.expected
+++ b/cpp/autosar/test/rules/M3-9-3/UnderlyingBitRepresentationsOfFloatingPointValuesUsed.expected
@@ -1,2 +1,5 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UnderlyingBitRepresentationsOfFloatingPointValuesUsed.ql:27,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UnderlyingBitRepresentationsOfFloatingPointValuesUsed.ql:36,10-18)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UnderlyingBitRepresentationsOfFloatingPointValuesUsed.ql:37,5-13)
| test.cpp:5:3:5:20 | ... &= ... | Modification of bit-representation of float originated at $@ | test.cpp:4:24:4:60 | reinterpret_cast... | cast |
| test.cpp:12:3:12:14 | ... &= ... | Modification of bit-representation of float originated at $@ | test.cpp:11:18:11:30 | (uint8_t *)... | cast |
diff --git a/cpp/autosar/test/rules/M5-0-3/CvalueExpressionConvertedToDifferentUnderlyingType.expected b/cpp/autosar/test/rules/M5-0-3/CvalueExpressionConvertedToDifferentUnderlyingType.expected
index 5782ac9849..8ce6a225dc 100644
--- a/cpp/autosar/test/rules/M5-0-3/CvalueExpressionConvertedToDifferentUnderlyingType.expected
+++ b/cpp/autosar/test/rules/M5-0-3/CvalueExpressionConvertedToDifferentUnderlyingType.expected
@@ -1,3 +1,7 @@
-| test.cpp:11:8:11:14 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:11:8:11:14 | ... + ... | expression |
-| test.cpp:11:8:11:14 | ... + ... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:11:8:11:14 | ... + ... | expression |
-| test.cpp:13:8:13:13 | ... + ... | Implicit conversion converts cvalue $@ from signed short to signed int. | test.cpp:13:8:13:13 | ... + ... | expression |
+| test.cpp:12:8:12:14 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:12:8:12:14 | ... + ... | expression |
+| test.cpp:12:8:12:14 | ... + ... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:12:8:12:14 | ... + ... | expression |
+| test.cpp:14:8:14:13 | ... + ... | Implicit conversion converts cvalue $@ from signed short to signed int. | test.cpp:14:8:14:13 | ... + ... | expression |
+| test.cpp:23:13:23:19 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:23:13:23:19 | ... + ... | expression |
+| test.cpp:25:13:25:45 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:25:13:25:45 | static_cast... | expression |
+| test.cpp:31:12:31:18 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:31:12:31:18 | ... + ... | expression |
+| test.cpp:33:12:33:44 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:33:12:33:44 | static_cast... | expression |
diff --git a/cpp/autosar/test/rules/M5-0-3/test.cpp b/cpp/autosar/test/rules/M5-0-3/test.cpp
index cb74512979..7275204519 100644
--- a/cpp/autosar/test/rules/M5-0-3/test.cpp
+++ b/cpp/autosar/test/rules/M5-0-3/test.cpp
@@ -1,4 +1,5 @@
#include
+
void f1() {
using std::int16_t;
using std::int32_t;
@@ -13,4 +14,24 @@ void f1() {
l3 = l2 + 1; // NON_COMPLIANT
l3 = static_cast(l2) + 1; // COMPLIANT
l3 = l2 + 0x01ffff; // COMPLIANT
+}
+
+void int16_arg(std::int16_t t);
+
+void test_func_call() {
+ std::int8_t l1;
+ int16_arg(l1 + l1); // NON_COMPLIANT
+ int16_arg(static_cast(l1 + l1)); // COMPLIANT
+ int16_arg(static_cast(l1 + l1)); // NON_COMPLIANT
+}
+
+std::int16_t test_return(int test) {
+ std::int8_t l1;
+ if (test > 0) {
+ return l1 + l1; // NON_COMPLIANT
+ } else if (test < 0) {
+ return static_cast(l1 + l1); // NON_COMPLIANT
+ } else {
+ return static_cast(l1 + l1); // COMPLIANT
+ }
}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-0-7/test.cpp b/cpp/autosar/test/rules/M5-0-7/test.cpp
index 36a2259028..ecbddd6750 100644
--- a/cpp/autosar/test/rules/M5-0-7/test.cpp
+++ b/cpp/autosar/test/rules/M5-0-7/test.cpp
@@ -18,4 +18,13 @@ void f1() {
s16a = static_cast(f32a / f32b); // NON_COMPLIANT
s16a = static_cast(f32a); // COMPLIANT
s16a = static_cast(f32a) / f32b; // COMPLIANT
+}
+
+void int_arg(std::int32_t i);
+
+std::int16_t test_args() {
+ float f32a;
+ float f32b;
+ int_arg(static_cast(f32a)); // COMPLIANT - f32a is not a cvalue
+ return static_cast(f32a); // COMPLIANT - f32a is not a cvalue
}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-0-8/test.cpp b/cpp/autosar/test/rules/M5-0-8/test.cpp
index 198bebed9f..ab785c661a 100644
--- a/cpp/autosar/test/rules/M5-0-8/test.cpp
+++ b/cpp/autosar/test/rules/M5-0-8/test.cpp
@@ -22,4 +22,22 @@ void f() {
f64 = static_cast(1.0f + 1.0f); // NON_COMPLIANT
f32 = static_cast(1.0f + 1); // COMPLIANT
f64 = static_cast(1.0 + 1); // COMPLIANT; no suffix defines a double
+}
+
+#include
+
+void function_args() {
+ std::vector v{0};
+
+ std::uint32_t u32{0};
+ v.at(static_cast(u32)); // COMPLIANT - cast is not a cvalue
+ std::size_t st =
+ static_cast(u32); // COMPLIANT - cast is not a cvalue
+ v.at(st);
+}
+
+std::size_t return_args() {
+ std::uint32_t u32{0};
+
+ return static_cast(u32); // COMPLIANT
}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-0-9/ExplicitSignednessConversionOfCValue.expected b/cpp/autosar/test/rules/M5-0-9/ExplicitSignednessConversionOfCValue.expected
index b2619503b3..b7fc97f99c 100644
--- a/cpp/autosar/test/rules/M5-0-9/ExplicitSignednessConversionOfCValue.expected
+++ b/cpp/autosar/test/rules/M5-0-9/ExplicitSignednessConversionOfCValue.expected
@@ -1,3 +1,3 @@
-| test.cpp:16:8:16:35 | static_cast... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:16:28:16:34 | ... + ... | cvalue |
-| test.cpp:18:8:18:40 | static_cast... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:18:28:18:39 | ... + ... | cvalue |
-| test.cpp:20:8:20:35 | static_cast... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:20:28:20:34 | ... * ... | cvalue |
+| test.cpp:20:8:20:35 | static_cast... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:20:28:20:34 | ... + ... | cvalue |
+| test.cpp:22:8:22:40 | static_cast... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:22:28:22:39 | ... + ... | cvalue |
+| test.cpp:24:8:24:35 | static_cast... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:24:28:24:34 | ... * ... | cvalue |
diff --git a/cpp/autosar/test/rules/M5-0-9/test.cpp b/cpp/autosar/test/rules/M5-0-9/test.cpp
index b46dbc390f..7b050d24de 100644
--- a/cpp/autosar/test/rules/M5-0-9/test.cpp
+++ b/cpp/autosar/test/rules/M5-0-9/test.cpp
@@ -1,4 +1,8 @@
#include
+
+void signed_arg(std::uint32_t s);
+void unsigned_arg(std::uint32_t u);
+
void f() {
using std::int16_t;
using std::int32_t;
@@ -22,4 +26,7 @@ void f() {
i16 = static_cast(i16 / i8); // NON_COMPLIANT
i8 = static_cast(u8) + static_cast(u8); // COMPLIANT
+
+ unsigned(static_cast(i32)); // COMPLIANT - i32 is not a cvalue
+ signed(static_cast(u32)); // COMPLIANT - u32 is not a cvalue
}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.qlref b/cpp/autosar/test/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.qlref
deleted file mode 100644
index 3a513b4cbe..0000000000
--- a/cpp/autosar/test/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.testref b/cpp/autosar/test/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.testref
new file mode 100644
index 0000000000..06f2ec8fbb
--- /dev/null
+++ b/cpp/autosar/test/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/arraypassedasfunctionargumentdecaytoapointer/ArrayPassedAsFunctionArgumentDecayToAPointer.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-2-6/CastNotConvertPointerToFunction.expected b/cpp/autosar/test/rules/M5-2-6/CastNotConvertPointerToFunction.expected
deleted file mode 100644
index 63c33f26d7..0000000000
--- a/cpp/autosar/test/rules/M5-2-6/CastNotConvertPointerToFunction.expected
+++ /dev/null
@@ -1,2 +0,0 @@
-| test.cpp:2:3:2:34 | reinterpret_cast<..(*)(..)>... | Cast converting a pointer to function. |
-| test.cpp:3:3:3:30 | reinterpret_cast... | Cast converting a pointer to function. |
diff --git a/cpp/autosar/test/rules/M5-2-6/CastNotConvertPointerToFunction.qlref b/cpp/autosar/test/rules/M5-2-6/CastNotConvertPointerToFunction.qlref
deleted file mode 100644
index 7f4d4c1161..0000000000
--- a/cpp/autosar/test/rules/M5-2-6/CastNotConvertPointerToFunction.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M5-2-6/CastNotConvertPointerToFunction.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-2-6/CastNotConvertPointerToFunction.testref b/cpp/autosar/test/rules/M5-2-6/CastNotConvertPointerToFunction.testref
new file mode 100644
index 0000000000..e7bde2ea08
--- /dev/null
+++ b/cpp/autosar/test/rules/M5-2-6/CastNotConvertPointerToFunction.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.qlref b/cpp/autosar/test/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.qlref
deleted file mode 100644
index 37d8a72ce5..0000000000
--- a/cpp/autosar/test/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.testref b/cpp/autosar/test/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.testref
new file mode 100644
index 0000000000..bd12c39fbd
--- /dev/null
+++ b/cpp/autosar/test/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/builtinunaryoperatorappliedtounsignedexpression/BuiltInUnaryOperatorAppliedToUnsignedExpression.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-3-3/UnaryOperatorOverloaded.qlref b/cpp/autosar/test/rules/M5-3-3/UnaryOperatorOverloaded.qlref
deleted file mode 100644
index 9e6cb1d0f8..0000000000
--- a/cpp/autosar/test/rules/M5-3-3/UnaryOperatorOverloaded.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M5-3-3/UnaryOperatorOverloaded.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M5-3-3/UnaryOperatorOverloaded.testref b/cpp/autosar/test/rules/M5-3-3/UnaryOperatorOverloaded.testref
new file mode 100644
index 0000000000..1f2a126671
--- /dev/null
+++ b/cpp/autosar/test/rules/M5-3-3/UnaryOperatorOverloaded.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/addressofoperatoroverloaded/AddressOfOperatorOverloaded.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M6-3-1/LoopCompoundCondition.qlref b/cpp/autosar/test/rules/M6-3-1/LoopCompoundCondition.qlref
deleted file mode 100644
index 4ee6239a13..0000000000
--- a/cpp/autosar/test/rules/M6-3-1/LoopCompoundCondition.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M6-3-1/LoopCompoundCondition.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M6-3-1/LoopCompoundCondition.testref b/cpp/autosar/test/rules/M6-3-1/LoopCompoundCondition.testref
new file mode 100644
index 0000000000..84dc7caf76
--- /dev/null
+++ b/cpp/autosar/test/rules/M6-3-1/LoopCompoundCondition.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/loopcompoundcondition/LoopCompoundCondition.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M6-3-1/SwitchCompoundCondition.qlref b/cpp/autosar/test/rules/M6-3-1/SwitchCompoundCondition.qlref
deleted file mode 100644
index eff312aa30..0000000000
--- a/cpp/autosar/test/rules/M6-3-1/SwitchCompoundCondition.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M6-3-1/SwitchCompoundCondition.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M6-3-1/SwitchCompoundCondition.testref b/cpp/autosar/test/rules/M6-3-1/SwitchCompoundCondition.testref
new file mode 100644
index 0000000000..f02b02ba85
--- /dev/null
+++ b/cpp/autosar/test/rules/M6-3-1/SwitchCompoundCondition.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/switchcompoundcondition/SwitchCompoundCondition.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M6-5-3/LoopCounterModifiedWithinStatement.expected b/cpp/autosar/test/rules/M6-5-3/LoopCounterModifiedWithinStatement.expected
index a6988586f0..4643298e3a 100644
--- a/cpp/autosar/test/rules/M6-5-3/LoopCounterModifiedWithinStatement.expected
+++ b/cpp/autosar/test/rules/M6-5-3/LoopCounterModifiedWithinStatement.expected
@@ -2,3 +2,4 @@
| test.cpp:25:35:25:35 | x | Loop counters should not be modified within a statement in a for loop. |
| test.cpp:36:5:36:5 | x | Loop counters should not be modified within a statement in a for loop. |
| test.cpp:43:9:43:9 | i | Loop counters should not be modified within a statement in a for loop. |
+| test.cpp:93:15:93:15 | i | Loop counters should not be modified within a statement in a for loop. |
diff --git a/cpp/autosar/test/rules/M6-5-3/test.cpp b/cpp/autosar/test/rules/M6-5-3/test.cpp
index a534e6ba8e..a41ba8a22d 100644
--- a/cpp/autosar/test/rules/M6-5-3/test.cpp
+++ b/cpp/autosar/test/rules/M6-5-3/test.cpp
@@ -43,3 +43,54 @@ void test_loop_counter_mod_in_side_effect() {
inc(i); // NON_COMPLIANT - modifies `i`
}
}
+
+void test_loop_counter_reference_mod_in_condition() {
+ auto loop = [](int &i) {
+ for (; (i++ < 10); i++) { // NON_COMPLIANT
+ }
+ };
+ int i = 0;
+ loop(i);
+}
+
+void test_loop_counter_reference_mod() {
+ auto loop = [](int &i) {
+ for (; i < 10; i++) { // COMPLIANT
+ }
+ };
+ int i = 0;
+ loop(i);
+}
+
+void test_loop_const_reference() {
+ auto loop = []([[maybe_unused]] int const &i) {
+ for (int i = 0; i < 10; i++) { // COMPLIANT
+ }
+ };
+ int i = 0;
+ loop(i);
+}
+
+void test_loop_counter_reference_mod_in_statement() {
+ auto loop = [](int &i) {
+ for (; (i < 10); i++) {
+ i++; // NON_COMPLIANT
+ }
+ };
+ int i = 0;
+ loop(i);
+}
+
+int const_reference(int const &i) { return i; }
+
+int reference(int &i) { return i; }
+
+int copy(int i) { return i; }
+
+void test_pass_argument_by() {
+ for (int i = 0; i < 10; i++) {
+ const_reference(i); // COMPLIANT
+ reference(i); // NON_COMPLIANT
+ copy(i); // COMPLIANT
+ }
+}
diff --git a/cpp/autosar/test/rules/M7-3-1/GlobalNamespaceMembershipViolation.qlref b/cpp/autosar/test/rules/M7-3-1/GlobalNamespaceMembershipViolation.qlref
deleted file mode 100644
index f2ec336eec..0000000000
--- a/cpp/autosar/test/rules/M7-3-1/GlobalNamespaceMembershipViolation.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M7-3-1/GlobalNamespaceMembershipViolation.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M7-3-1/GlobalNamespaceMembershipViolation.testref b/cpp/autosar/test/rules/M7-3-1/GlobalNamespaceMembershipViolation.testref
new file mode 100644
index 0000000000..8f71738005
--- /dev/null
+++ b/cpp/autosar/test/rules/M7-3-1/GlobalNamespaceMembershipViolation.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/globalnamespacedeclarations/GlobalNamespaceDeclarations.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.qlref b/cpp/autosar/test/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.qlref
deleted file mode 100644
index 36bc86bb79..0000000000
--- a/cpp/autosar/test/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.testref b/cpp/autosar/test/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.testref
new file mode 100644
index 0000000000..e149f3a33b
--- /dev/null
+++ b/cpp/autosar/test/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/nonglobalfunctionmain/NonGlobalFunctionMain.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M7-5-1/FunctionReturnAutomaticVarCondition.qlref b/cpp/autosar/test/rules/M7-5-1/FunctionReturnAutomaticVarCondition.qlref
deleted file mode 100644
index 4cb410e095..0000000000
--- a/cpp/autosar/test/rules/M7-5-1/FunctionReturnAutomaticVarCondition.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M7-5-1/FunctionReturnAutomaticVarCondition.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M7-5-1/FunctionReturnAutomaticVarCondition.testref b/cpp/autosar/test/rules/M7-5-1/FunctionReturnAutomaticVarCondition.testref
new file mode 100644
index 0000000000..45dbffde00
--- /dev/null
+++ b/cpp/autosar/test/rules/M7-5-1/FunctionReturnAutomaticVarCondition.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/returnreferenceorpointertoautomaticlocalvariable/ReturnReferenceOrPointerToAutomaticLocalVariable.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.qlref b/cpp/autosar/test/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.qlref
deleted file mode 100644
index 2703512673..0000000000
--- a/cpp/autosar/test/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M8-0-1/MultipleGlobalOrMemberDeclarators.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.testref b/cpp/autosar/test/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.testref
new file mode 100644
index 0000000000..434cb47456
--- /dev/null
+++ b/cpp/autosar/test/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/multipleglobalormemberdeclarators/MultipleGlobalOrMemberDeclarators.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M8-0-1/MultipleLocalDeclarators.qlref b/cpp/autosar/test/rules/M8-0-1/MultipleLocalDeclarators.qlref
deleted file mode 100644
index 2375201bf3..0000000000
--- a/cpp/autosar/test/rules/M8-0-1/MultipleLocalDeclarators.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M8-0-1/MultipleLocalDeclarators.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M8-0-1/MultipleLocalDeclarators.testref b/cpp/autosar/test/rules/M8-0-1/MultipleLocalDeclarators.testref
new file mode 100644
index 0000000000..be7c9ac352
--- /dev/null
+++ b/cpp/autosar/test/rules/M8-0-1/MultipleLocalDeclarators.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/multiplelocaldeclarators/MultipleLocalDeclarators.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.expected b/cpp/autosar/test/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.expected
deleted file mode 100644
index b5cdd76a2b..0000000000
--- a/cpp/autosar/test/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.expected
+++ /dev/null
@@ -1,2 +0,0 @@
-| test.cpp:16:8:16:8 | f | $@ does not have the same default parameters as $@ | test.cpp:16:8:16:8 | f | overriding function | test.cpp:4:16:4:16 | f | overridden function |
-| test.cpp:21:8:21:8 | f | $@ does not have the same default parameters as $@ | test.cpp:21:8:21:8 | f | overriding function | test.cpp:4:16:4:16 | f | overridden function |
diff --git a/cpp/autosar/test/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.qlref b/cpp/autosar/test/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.qlref
deleted file mode 100644
index ae0c1df157..0000000000
--- a/cpp/autosar/test/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.testref b/cpp/autosar/test/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.testref
new file mode 100644
index 0000000000..7e06403515
--- /dev/null
+++ b/cpp/autosar/test/rules/M8-3-1/VirtualFunctionParametersUseTheSameDefaultArguments.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M9-3-1/ConstMemberFunctionReturnsNonConstPointer.expected b/cpp/autosar/test/rules/M9-3-1/ConstMemberFunctionReturnsNonConstPointer.expected
index ee9652f505..af7e9efc36 100644
--- a/cpp/autosar/test/rules/M9-3-1/ConstMemberFunctionReturnsNonConstPointer.expected
+++ b/cpp/autosar/test/rules/M9-3-1/ConstMemberFunctionReturnsNonConstPointer.expected
@@ -1,3 +1,5 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstMemberFunctionReturnsNonConstPointer.ql:53,7-15)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (ConstMemberFunctionReturnsNonConstPointer.ql:55,7-15)
| test.cpp:8:8:8:11 | getA | Const member function returns a pointer to class data $@. | test.cpp:3:8:3:8 | a | a |
| test.cpp:9:8:9:11 | getB | Const member function returns a pointer to class data $@. | test.cpp:4:8:4:8 | b | b |
| test.cpp:11:6:11:12 | getThis | Const member function returns a pointer to class data $@. | test.cpp:11:36:11:39 | this | this |
diff --git a/cpp/autosar/test/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.expected b/cpp/autosar/test/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.expected
deleted file mode 100644
index 26b9aac563..0000000000
--- a/cpp/autosar/test/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.expected
+++ /dev/null
@@ -1 +0,0 @@
-| test.cpp:2:14:2:14 | x | A named bit-field with signed integral type should have at least 2 bits of storage |
diff --git a/cpp/autosar/test/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.qlref b/cpp/autosar/test/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.qlref
deleted file mode 100644
index cdb9677f5f..0000000000
--- a/cpp/autosar/test/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.qlref
+++ /dev/null
@@ -1 +0,0 @@
-rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.testref b/cpp/autosar/test/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.testref
new file mode 100644
index 0000000000..5dd7991a37
--- /dev/null
+++ b/cpp/autosar/test/rules/M9-6-4/NamedBitFieldsWithSignedIntegerTypeShallHaveALengthOfMoreThanOneBit.testref
@@ -0,0 +1 @@
+cpp/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.ql
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M9-6-4/test.cpp b/cpp/autosar/test/rules/M9-6-4/test.cpp
deleted file mode 100644
index d3939b71ee..0000000000
--- a/cpp/autosar/test/rules/M9-6-4/test.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-struct S {
- signed int x : 1; // NON-COMPLIANT
- signed int y : 5; // COMPLIANT
- signed int z : 7; // COMPLIANT
- signed int : 0; // COMPLIANT
- signed int : 1; // COMPLIANT
- signed int : 2; // COMPLIANT
-};
\ 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..910a6e060e 100644
--- a/cpp/cert/src/codeql-pack.lock.yml
+++ b/cpp/cert/src/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/cpp/cert/src/qlpack.yml b/cpp/cert/src/qlpack.yml
index 47c2c319c7..735dd9f5b4 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.40.0-dev
description: CERT C++ 2016
suites: codeql-suites
license: MIT
dependencies:
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 1.4.2
codeql/common-cpp-coding-standards: '*'
diff --git a/cpp/cert/src/rules/CTR52-CPP/GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql b/cpp/cert/src/rules/CTR52-CPP/GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql
index dc53b7a6d0..9f49b43786 100644
--- a/cpp/cert/src/rules/CTR52-CPP/GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql
+++ b/cpp/cert/src/rules/CTR52-CPP/GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql
@@ -16,7 +16,7 @@ import codingstandards.cpp.cert
import codingstandards.cpp.Iterators
import codingstandards.cpp.rules.containeraccesswithoutrangecheck.ContainerAccessWithoutRangeCheck as ContainerAccessWithoutRangeCheck
import semmle.code.cpp.controlflow.Guards
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/**
diff --git a/cpp/cert/src/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.ql b/cpp/cert/src/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.ql
index a7756b6a6a..0f5c50164c 100644
--- a/cpp/cert/src/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.ql
+++ b/cpp/cert/src/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.cpp.cert
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import NonFinalClassToPointerArithmeticExprFlow::PathGraph
class ArrayAccessOrPointerArith extends Expr {
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/DCL53-CPP/LocalConstructorInitializedObjectHidesIdentifier.ql b/cpp/cert/src/rules/DCL53-CPP/LocalConstructorInitializedObjectHidesIdentifier.ql
index 237ebbe985..f6fe18a3db 100644
--- a/cpp/cert/src/rules/DCL53-CPP/LocalConstructorInitializedObjectHidesIdentifier.ql
+++ b/cpp/cert/src/rules/DCL53-CPP/LocalConstructorInitializedObjectHidesIdentifier.ql
@@ -20,6 +20,6 @@ from UserVariable v, UserVariable hidden
where
not isExcluded(v, ScopePackage::localConstructorInitializedObjectHidesIdentifierQuery()) and
v.getInitializer().getExpr() instanceof ConstructorCall and
- hides(hidden, v)
+ hidesStrict(hidden, v)
select v, "The declaration declares variable " + v.getName() + " that hides $@", hidden,
hidden.getName()
diff --git a/cpp/cert/src/rules/DCL53-CPP/LocalFunctionDeclaration.ql b/cpp/cert/src/rules/DCL53-CPP/LocalFunctionDeclaration.ql
index 3f91530c84..368c0a05e4 100644
--- a/cpp/cert/src/rules/DCL53-CPP/LocalFunctionDeclaration.ql
+++ b/cpp/cert/src/rules/DCL53-CPP/LocalFunctionDeclaration.ql
@@ -13,7 +13,6 @@
import cpp
import codingstandards.cpp.cert
-import codingstandards.cpp.Scope
class LocalUserFunctionDeclarationEntry extends FunctionDeclarationEntry {
DeclStmt ds;
diff --git a/cpp/cert/src/rules/EXP50-CPP/DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql b/cpp/cert/src/rules/EXP50-CPP/DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql
index a385ee1ffc..7bfb298d3d 100644
--- a/cpp/cert/src/rules/EXP50-CPP/DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql
+++ b/cpp/cert/src/rules/EXP50-CPP/DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql
@@ -14,8 +14,8 @@
import cpp
import codingstandards.cpp.cert
import codingstandards.cpp.SideEffect
-import codingstandards.cpp.dataflow.DataFlow
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/** Holds if the function's return value is derived from the `AliasParamter` p. */
diff --git a/cpp/cert/src/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.ql b/cpp/cert/src/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.ql
index bdf6a7973e..e900d1b259 100644
--- a/cpp/cert/src/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.ql
+++ b/cpp/cert/src/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.cpp.cert
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import AllocationToDeleteFlow::PathGraph
module AllocationToDeleteConfig implements DataFlow::ConfigSig {
diff --git a/cpp/cert/src/rules/MEM52-CPP/DetectAndHandleMemoryAllocationErrors.ql b/cpp/cert/src/rules/MEM52-CPP/DetectAndHandleMemoryAllocationErrors.ql
index c25e1aa0ad..083aad1e3c 100644
--- a/cpp/cert/src/rules/MEM52-CPP/DetectAndHandleMemoryAllocationErrors.ql
+++ b/cpp/cert/src/rules/MEM52-CPP/DetectAndHandleMemoryAllocationErrors.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.cpp.cert
import semmle.code.cpp.controlflow.Guards
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.exceptions.ExceptionSpecifications
/**
diff --git a/cpp/cert/src/rules/MEM53-CPP/ManuallyManagedLifetime.qll b/cpp/cert/src/rules/MEM53-CPP/ManuallyManagedLifetime.qll
index 358a3583fc..4392b598f7 100644
--- a/cpp/cert/src/rules/MEM53-CPP/ManuallyManagedLifetime.qll
+++ b/cpp/cert/src/rules/MEM53-CPP/ManuallyManagedLifetime.qll
@@ -3,7 +3,7 @@ import codingstandards.cpp.Conversion
import codingstandards.cpp.TrivialType
import ManuallyManagedLifetime
import semmle.code.cpp.controlflow.Dominance
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
/**
* A taint-tracking configuration from allocation expressions to casts to a specific pointer type.
@@ -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/src/rules/MEM53-CPP/MissingConstructorCallForManuallyManagedObject.ql b/cpp/cert/src/rules/MEM53-CPP/MissingConstructorCallForManuallyManagedObject.ql
index 30c5280482..6e3121e46d 100644
--- a/cpp/cert/src/rules/MEM53-CPP/MissingConstructorCallForManuallyManagedObject.ql
+++ b/cpp/cert/src/rules/MEM53-CPP/MissingConstructorCallForManuallyManagedObject.ql
@@ -14,7 +14,7 @@ import cpp
import codingstandards.cpp.cert
import codingstandards.cpp.TrivialType
import ManuallyManagedLifetime
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import AllocToStaticCastFlow::PathGraph
/*
diff --git a/cpp/cert/src/rules/MEM53-CPP/MissingDestructorCallForManuallyManagedObject.ql b/cpp/cert/src/rules/MEM53-CPP/MissingDestructorCallForManuallyManagedObject.ql
index b498729d69..22e2ac336f 100644
--- a/cpp/cert/src/rules/MEM53-CPP/MissingDestructorCallForManuallyManagedObject.ql
+++ b/cpp/cert/src/rules/MEM53-CPP/MissingDestructorCallForManuallyManagedObject.ql
@@ -13,7 +13,7 @@
import cpp
import codingstandards.cpp.cert
import ManuallyManagedLifetime
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import FreeWithoutDestructorFlow::PathGraph
from FreeWithoutDestructorFlow::PathNode source, FreeWithoutDestructorFlow::PathNode sink
diff --git a/cpp/cert/src/rules/MSC51-CPP/BadlySeededRandomNumberGenerator.ql b/cpp/cert/src/rules/MSC51-CPP/BadlySeededRandomNumberGenerator.ql
index 52b14d9629..76f8500362 100644
--- a/cpp/cert/src/rules/MSC51-CPP/BadlySeededRandomNumberGenerator.ql
+++ b/cpp/cert/src/rules/MSC51-CPP/BadlySeededRandomNumberGenerator.ql
@@ -15,7 +15,7 @@
import cpp
import codingstandards.cpp.cert
import codingstandards.cpp.standardlibrary.Random
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
from RandomNumberEngineCreation createRandomNumberEngine, string seedSource
where
diff --git a/cpp/cert/test/codeql-pack.lock.yml b/cpp/cert/test/codeql-pack.lock.yml
index 514e6963d0..910a6e060e 100644
--- a/cpp/cert/test/codeql-pack.lock.yml
+++ b/cpp/cert/test/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/cpp/cert/test/qlpack.yml b/cpp/cert/test/qlpack.yml
index 7b8ed0858d..3a6d02e7d4 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.40.0-dev
extractor: cpp
license: MIT
dependencies:
diff --git a/cpp/cert/test/rules/CTR52-CPP/GuaranteeGenericCppLibraryFunctionsDoNotOverflow.expected b/cpp/cert/test/rules/CTR52-CPP/GuaranteeGenericCppLibraryFunctionsDoNotOverflow.expected
index 4e87d1436c..209d81ba8b 100644
--- a/cpp/cert/test/rules/CTR52-CPP/GuaranteeGenericCppLibraryFunctionsDoNotOverflow.expected
+++ b/cpp/cert/test/rules/CTR52-CPP/GuaranteeGenericCppLibraryFunctionsDoNotOverflow.expected
@@ -1,3 +1,12 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql:88,7-15)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql:88,27-35)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql:89,9-17)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql:93,9-17)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql:93,29-37)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql:94,11-19)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql:104,35-43)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql:105,11-19)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (GuaranteeGenericCppLibraryFunctionsDoNotOverflow.ql:104,9-22)
| test.cpp:8:42:8:46 | call to begin | Output iterator for $@ is not guaranteed to be large enough for the input iterator. | test.cpp:8:3:8:11 | call to copy | call to copy |
| test.cpp:17:42:17:46 | call to begin | Output iterator for $@ is not guaranteed to be large enough for the input iterator. | test.cpp:17:3:17:11 | call to copy | call to copy |
| test.cpp:55:42:55:46 | call to begin | Output iterator for $@ is not guaranteed to be large enough for the input iterator. | test.cpp:55:3:55:11 | call to copy | call to copy |
diff --git a/cpp/cert/test/rules/CTR53-CPP/UseValidIteratorRanges.expected b/cpp/cert/test/rules/CTR53-CPP/UseValidIteratorRanges.expected
index 61260a0579..b5c36727f5 100644
--- a/cpp/cert/test/rules/CTR53-CPP/UseValidIteratorRanges.expected
+++ b/cpp/cert/test/rules/CTR53-CPP/UseValidIteratorRanges.expected
@@ -1,3 +1,9 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UseValidIteratorRanges.ql:23,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UseValidIteratorRanges.ql:23,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UseValidIteratorRanges.ql:24,7-15)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UseValidIteratorRanges.ql:30,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UseValidIteratorRanges.ql:30,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (UseValidIteratorRanges.ql:31,7-15)
| test.cpp:7:3:7:15 | call to for_each | The $@ of iterator range function does not point to the end of an iterator. | test.cpp:7:28:7:32 | call to begin | argument |
| test.cpp:7:3:7:15 | call to for_each | The $@ of iterator range function does not point to the start of an iterator. | test.cpp:7:19:7:21 | call to end | argument |
| test.cpp:8:3:8:15 | call to for_each | The $@ of iterator range function does not point to the end of an iterator. | test.cpp:8:30:8:34 | call to begin | argument |
diff --git a/cpp/cert/test/rules/CTR55-CPP/DoNotUseAnAdditiveOperatorOnAnIterator.expected b/cpp/cert/test/rules/CTR55-CPP/DoNotUseAnAdditiveOperatorOnAnIterator.expected
index 0a06677b54..0ba2fad433 100644
--- a/cpp/cert/test/rules/CTR55-CPP/DoNotUseAnAdditiveOperatorOnAnIterator.expected
+++ b/cpp/cert/test/rules/CTR55-CPP/DoNotUseAnAdditiveOperatorOnAnIterator.expected
@@ -1,3 +1,12 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUseAnAdditiveOperatorOnAnIterator.ql:38,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUseAnAdditiveOperatorOnAnIterator.ql:38,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUseAnAdditiveOperatorOnAnIterator.ql:38,51-59)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUseAnAdditiveOperatorOnAnIterator.ql:39,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUseAnAdditiveOperatorOnAnIterator.ql:39,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUseAnAdditiveOperatorOnAnIterator.ql:39,52-60)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUseAnAdditiveOperatorOnAnIterator.ql:74,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUseAnAdditiveOperatorOnAnIterator.ql:74,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUseAnAdditiveOperatorOnAnIterator.ql:75,7-15)
| test.cpp:8:7:8:7 | i | Increment of iterator may overflow since its bounds are not checked. |
| test.cpp:9:9:9:9 | i | Increment of iterator may overflow since its bounds are not checked. |
| test.cpp:10:9:10:9 | i | Increment of iterator may overflow since its bounds are not checked. |
diff --git a/cpp/cert/test/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.expected b/cpp/cert/test/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.expected
index 0ee15c65b5..59caaa22d8 100644
--- a/cpp/cert/test/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.expected
+++ b/cpp/cert/test/rules/CTR56-CPP/DoNotUsePointerArithmeticOnPolymorphicObjects.expected
@@ -1,15 +1,19 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUsePointerArithmeticOnPolymorphicObjects.ql:41,62-70)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUsePointerArithmeticOnPolymorphicObjects.ql:42,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUsePointerArithmeticOnPolymorphicObjects.ql:51,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotUsePointerArithmeticOnPolymorphicObjects.ql:57,3-11)
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/EXP50-CPP/DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.expected b/cpp/cert/test/rules/EXP50-CPP/DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.expected
index b432856e8b..00f1a6ba03 100644
--- a/cpp/cert/test/rules/EXP50-CPP/DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.expected
+++ b/cpp/cert/test/rules/EXP50-CPP/DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.expected
@@ -1,3 +1,27 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:24,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:24,59-67)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:27,33-41)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:27,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:31,33-41)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:31,59-67)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:40,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:40,25-33)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:40,53-61)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:43,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:43,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:52,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:52,55-63)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:59,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:59,57-65)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:71,31-39)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:71,55-63)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:24,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:27,7-20)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:31,7-20)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:43,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:52,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:59,5-18)
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (DoNotDependOnTheOrderOfEvaluationForSideEffectsInFunctionCallsAsFunctionArguments.ql:71,5-18)
| test.cpp:82:3:82:4 | call to f2 | Depending on the order of evaluation for the arguments $@ and $@ for side effects on shared state is unspecified and can result in unexpected behavior. | test.cpp:82:6:82:7 | call to f5 | call to f5 | test.cpp:82:12:82:13 | call to f6 | call to f6 |
| test.cpp:84:3:84:4 | call to f2 | Depending on the order of evaluation for the arguments $@ and $@ for side effects on shared state is unspecified and can result in unexpected behavior. | test.cpp:84:6:84:7 | call to f5 | call to f5 | test.cpp:84:12:84:13 | call to f7 | call to f7 |
| test.cpp:87:3:87:4 | call to f2 | Depending on the order of evaluation for the arguments $@ and $@ for side effects on shared state is unspecified and can result in unexpected behavior. | test.cpp:87:9:87:10 | call to m1 | call to m1 | test.cpp:87:18:87:19 | call to m1 | call to m1 |
diff --git a/cpp/cert/test/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.expected b/cpp/cert/test/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.expected
index a50daa096e..c271269ab8 100644
--- a/cpp/cert/test/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.expected
+++ b/cpp/cert/test/rules/EXP51-CPP/DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.expected
@@ -1,6 +1,10 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.ql:19,44-52)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.ql:20,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.ql:22,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotDeleteAnArrayThroughAPointerOfTheIncorrectType.ql:27,33-41)
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/MEM52-CPP/DetectAndHandleMemoryAllocationErrors.expected b/cpp/cert/test/rules/MEM52-CPP/DetectAndHandleMemoryAllocationErrors.expected
index b7452ec199..b7b4891776 100644
--- a/cpp/cert/test/rules/MEM52-CPP/DetectAndHandleMemoryAllocationErrors.expected
+++ b/cpp/cert/test/rules/MEM52-CPP/DetectAndHandleMemoryAllocationErrors.expected
@@ -1,2 +1,9 @@
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DetectAndHandleMemoryAllocationErrors.ql:59,5-13)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DetectAndHandleMemoryAllocationErrors.ql:61,36-44)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DetectAndHandleMemoryAllocationErrors.ql:77,46-54)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DetectAndHandleMemoryAllocationErrors.ql:78,22-30)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DetectAndHandleMemoryAllocationErrors.ql:82,20-28)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DetectAndHandleMemoryAllocationErrors.ql:85,35-43)
+WARNING: module 'DataFlow' has been deprecated and may be removed in future (DetectAndHandleMemoryAllocationErrors.ql:90,38-46)
| test.cpp:24:7:24:34 | new | nothrow new allocation of $@ returns here without a subsequent check to see whether the pointer is valid. | test.cpp:24:7:24:34 | new | StructA * |
| test.cpp:40:17:40:38 | call to allocate_without_check | nothrow new allocation of $@ returns here without a subsequent check to see whether the pointer is valid. | test.cpp:35:17:35:44 | new | StructA * |
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/cert/test/rules/MSC51-CPP/BadlySeededRandomNumberGenerator.expected b/cpp/cert/test/rules/MSC51-CPP/BadlySeededRandomNumberGenerator.expected
index 0128221ffc..3743c3d414 100644
--- a/cpp/cert/test/rules/MSC51-CPP/BadlySeededRandomNumberGenerator.expected
+++ b/cpp/cert/test/rules/MSC51-CPP/BadlySeededRandomNumberGenerator.expected
@@ -1,3 +1,4 @@
+WARNING: module 'TaintTracking' has been deprecated and may be removed in future (BadlySeededRandomNumberGenerator.ql:37,7-20)
| test.cpp:9:33:9:33 | call to linear_congruential_engine | Random number generator linear_congruential_engine is default-initialized and is therefore not properly seeded. |
| test.cpp:10:30:10:31 | call to linear_congruential_engine | Random number generator linear_congruential_engine is default-initialized and is therefore not properly seeded. |
| test.cpp:11:21:11:22 | call to linear_congruential_engine | Random number generator linear_congruential_engine is default-initialized and is therefore not properly seeded. |
diff --git a/cpp/common/src/codeql-pack.lock.yml b/cpp/common/src/codeql-pack.lock.yml
index 514e6963d0..910a6e060e 100644
--- a/cpp/common/src/codeql-pack.lock.yml
+++ b/cpp/common/src/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/cpp/common/src/codingstandards/cpp/AccessPath.qll b/cpp/common/src/codingstandards/cpp/AccessPath.qll
index 2393d25db4..ff7601ed4b 100644
--- a/cpp/common/src/codingstandards/cpp/AccessPath.qll
+++ b/cpp/common/src/codingstandards/cpp/AccessPath.qll
@@ -1,5 +1,5 @@
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
newtype TFieldQualifier =
ExplicitQualifier(VariableAccess v) or
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/Allocations.qll b/cpp/common/src/codingstandards/cpp/Allocations.qll
index 5bc87221e2..db47b0b028 100644
--- a/cpp/common/src/codingstandards/cpp/Allocations.qll
+++ b/cpp/common/src/codingstandards/cpp/Allocations.qll
@@ -7,7 +7,7 @@
import cpp
import semmle.code.cpp.controlflow.SSA
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* Holds if `alloc` is a use of `malloc` or `new`. `kind` is
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/Clvalues.qll b/cpp/common/src/codingstandards/cpp/Clvalues.qll
new file mode 100644
index 0000000000..73fcd65eb1
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/Clvalues.qll
@@ -0,0 +1,17 @@
+import cpp
+
+/**
+ * An lvalue in C (as opposed to C++).
+ *
+ * Note that `Expr.isLValue()` matches for C++ lvalues, which is a larger set
+ * than the set of C lvalues.
+ */
+predicate isCLValue(Expr expr) {
+ expr instanceof PointerFieldAccess
+ or
+ expr.isLValue() and
+ not expr instanceof ConditionalExpr and
+ not expr instanceof AssignExpr and
+ not expr instanceof CommaExpr and
+ not exists(Cast c | c = expr.getConversion*())
+}
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/Concurrency.qll b/cpp/common/src/codingstandards/cpp/Concurrency.qll
index d856fa4515..5e7d154d59 100644
--- a/cpp/common/src/codingstandards/cpp/Concurrency.qll
+++ b/cpp/common/src/codingstandards/cpp/Concurrency.qll
@@ -1,5 +1,5 @@
import cpp
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
/**
* Models CFG nodes which should be added to a thread context.
diff --git a/cpp/common/src/codingstandards/cpp/ConstHelpers.qll b/cpp/common/src/codingstandards/cpp/ConstHelpers.qll
index 8cba3efde4..a7457dc845 100644
--- a/cpp/common/src/codingstandards/cpp/ConstHelpers.qll
+++ b/cpp/common/src/codingstandards/cpp/ConstHelpers.qll
@@ -4,7 +4,7 @@
import cpp
import codingstandards.cpp.SideEffect
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.FunctionParameter
/** A variable that can be modified (both the pointer and object pointed to if pointer type) */
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 d8d9739033..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 { }
@@ -14,7 +15,38 @@ abstract class EncapsulatingFunction extends Function { }
class MainFunction extends MainLikeFunction {
MainFunction() {
hasGlobalName("main") and
- getType() instanceof IntType
+ getType().resolveTypedefs() instanceof IntType
+ }
+}
+
+/**
+ * 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")
+ )
+ )
}
}
diff --git a/cpp/common/src/codingstandards/cpp/Expr.qll b/cpp/common/src/codingstandards/cpp/Expr.qll
index fe2877f849..0b650ae41b 100644
--- a/cpp/common/src/codingstandards/cpp/Expr.qll
+++ b/cpp/common/src/codingstandards/cpp/Expr.qll
@@ -148,9 +148,9 @@ module MisraExpr {
private predicate isCValue(Expr e) {
not e.isConstant() and
(
- exists(ReturnStmt return | e = return.getExpr())
+ exists(ReturnStmt return | e = return.getExpr().getExplicitlyConverted())
or
- exists(Call call | e = call.getAnArgument())
+ exists(FunctionCall call | e = call.getAnArgument().getExplicitlyConverted())
)
or
isCValue(e.(ParenthesisExpr).getExpr())
@@ -267,7 +267,9 @@ predicate isCompileTimeEvaluatedCall(Call call) {
parameterUsingDefaultValue.getAnAssignedValue() = defaultValue
|
isDirectCompileTimeEvaluatedExpression(defaultValue)
- )
+ ) and
+ // 4. the call's qualifier is compile time evaluated.
+ (not call.hasQualifier() or isCompileTimeEvaluatedExpression(call.getQualifier()))
}
/*
diff --git a/cpp/common/src/codingstandards/cpp/FgetsErrorManagement.qll b/cpp/common/src/codingstandards/cpp/FgetsErrorManagement.qll
index 7686714635..4f99b02e2e 100644
--- a/cpp/common/src/codingstandards/cpp/FgetsErrorManagement.qll
+++ b/cpp/common/src/codingstandards/cpp/FgetsErrorManagement.qll
@@ -4,7 +4,7 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.controlflow.Guards
/*
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/c/common/src/codingstandards/c/IrreplaceableFunctionLikeMacro.qll b/cpp/common/src/codingstandards/cpp/IrreplaceableFunctionLikeMacro.qll
similarity index 100%
rename from c/common/src/codingstandards/c/IrreplaceableFunctionLikeMacro.qll
rename to cpp/common/src/codingstandards/cpp/IrreplaceableFunctionLikeMacro.qll
diff --git a/cpp/common/src/codingstandards/cpp/Iterators.qll b/cpp/common/src/codingstandards/cpp/Iterators.qll
index 1b5199a806..76751aa87b 100644
--- a/cpp/common/src/codingstandards/cpp/Iterators.qll
+++ b/cpp/common/src/codingstandards/cpp/Iterators.qll
@@ -3,8 +3,8 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.TaintTracking
import codingstandards.cpp.StdNamespace
import codingstandards.cpp.rules.containeraccesswithoutrangecheck.ContainerAccessWithoutRangeCheck as ContainerAccessWithoutRangeCheck
import semmle.code.cpp.controlflow.Guards
@@ -37,7 +37,9 @@ class ContainerPointerOrReferenceAccess extends ContainerAccess {
) and
localTaint(DataFlow::exprNode(fc), DataFlow::exprNode(this)) and
(getUnderlyingType() instanceof ReferenceType or getUnderlyingType() instanceof PointerType) and
- fc.getQualifier().(VariableAccess).getTarget() = owningContainer
+ fc.getQualifier().(VariableAccess).getTarget() = owningContainer and
+ // Exclude cases where we see taint into the owning container
+ not this = owningContainer.getAnAccess()
)
}
diff --git a/cpp/common/src/codingstandards/cpp/Literals.qll b/cpp/common/src/codingstandards/cpp/Literals.qll
index c6845b181d..edec04152e 100644
--- a/cpp/common/src/codingstandards/cpp/Literals.qll
+++ b/cpp/common/src/codingstandards/cpp/Literals.qll
@@ -5,6 +5,8 @@
import cpp
import codingstandards.cpp.Cpp14Literal
+class IntegerLiteral = Cpp14Literal::IntegerLiteral;
+
/** Gets `Literal.getValueText()` truncated to at most 20 characters. */
string getTruncatedLiteralText(Literal l) {
exists(string text | text = l.getValueText() |
@@ -68,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/Loops.qll b/cpp/common/src/codingstandards/cpp/Loops.qll
index bfd68c49a0..aa3dc64ea5 100644
--- a/cpp/common/src/codingstandards/cpp/Loops.qll
+++ b/cpp/common/src/codingstandards/cpp/Loops.qll
@@ -204,7 +204,7 @@ predicate isLoopCounterModifiedInCondition(ForStmt forLoop, VariableAccess loopC
loopCounterAccess = getAnIterationVariable(forLoop).getAnAccess() and
(
loopCounterAccess.isModified() or
- loopCounterAccess.isAddressOfAccess()
+ loopCounterAccess.isAddressOfAccessNonConst()
)
}
@@ -219,7 +219,7 @@ predicate isLoopCounterModifiedInStatement(
loopCounterAccess = loopCounter.getAnAccess() and
(
loopCounterAccess.isModified() or
- loopCounterAccess.isAddressOfAccess()
+ loopCounterAccess.isAddressOfAccessNonConst()
) and
forLoop.getStmt().getChildStmt*() = loopCounterAccess.getEnclosingStmt()
}
diff --git a/cpp/autosar/src/rules/M14-6-1/NameInDependentBase.qll b/cpp/common/src/codingstandards/cpp/NameInDependentBase.qll
similarity index 99%
rename from cpp/autosar/src/rules/M14-6-1/NameInDependentBase.qll
rename to cpp/common/src/codingstandards/cpp/NameInDependentBase.qll
index b3d12c044b..e599f286ae 100644
--- a/cpp/autosar/src/rules/M14-6-1/NameInDependentBase.qll
+++ b/cpp/common/src/codingstandards/cpp/NameInDependentBase.qll
@@ -1,5 +1,4 @@
import cpp
-import codingstandards.cpp.autosar
/**
* Gets a dependent base type of the given template class.
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/cpp/common/src/codingstandards/cpp/Nullness.qll b/cpp/common/src/codingstandards/cpp/Nullness.qll
index d76db4afad..8751c54d9b 100644
--- a/cpp/common/src/codingstandards/cpp/Nullness.qll
+++ b/cpp/common/src/codingstandards/cpp/Nullness.qll
@@ -1,5 +1,5 @@
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
private class PointerToMember extends Variable {
PointerToMember() { this.getType() instanceof PointerToMemberType }
diff --git a/cpp/autosar/src/rules/A18-5-4/OperatorDelete.qll b/cpp/common/src/codingstandards/cpp/OperatorDelete.qll
similarity index 96%
rename from cpp/autosar/src/rules/A18-5-4/OperatorDelete.qll
rename to cpp/common/src/codingstandards/cpp/OperatorDelete.qll
index ada7d109cd..c9ff315866 100644
--- a/cpp/autosar/src/rules/A18-5-4/OperatorDelete.qll
+++ b/cpp/common/src/codingstandards/cpp/OperatorDelete.qll
@@ -1,5 +1,4 @@
import cpp
-import codingstandards.cpp.autosar
class StdNoThrow extends Class {
StdNoThrow() { hasQualifiedName("std", "nothrow_t") }
diff --git a/cpp/common/src/codingstandards/cpp/Overflow.qll b/cpp/common/src/codingstandards/cpp/Overflow.qll
index dca1386513..28a5c0d9db 100644
--- a/cpp/common/src/codingstandards/cpp/Overflow.qll
+++ b/cpp/common/src/codingstandards/cpp/Overflow.qll
@@ -6,7 +6,7 @@ import cpp
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
import SimpleRangeAnalysisCustomizations
import semmle.code.cpp.controlflow.Guards
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import codingstandards.cpp.Expr
import codingstandards.cpp.UndefinedBehavior
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/ReadErrorsAndEOF.qll b/cpp/common/src/codingstandards/cpp/ReadErrorsAndEOF.qll
index 7adb911c9f..c3c433d20d 100644
--- a/cpp/common/src/codingstandards/cpp/ReadErrorsAndEOF.qll
+++ b/cpp/common/src/codingstandards/cpp/ReadErrorsAndEOF.qll
@@ -1,5 +1,5 @@
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.standardlibrary.FileAccess
/**
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/Scope.qll b/cpp/common/src/codingstandards/cpp/Scope.qll
index d9a81b98e3..5438c17133 100644
--- a/cpp/common/src/codingstandards/cpp/Scope.qll
+++ b/cpp/common/src/codingstandards/cpp/Scope.qll
@@ -3,56 +3,86 @@
*/
import cpp
+import codingstandards.cpp.ConstHelpers
/**
- * Gets the parent scope of this `Element`, if any.
- * A scope is a `Type` (`Class` / `Enum`), a `Namespace`, a `Block`, a `Function`,
- * or certain kinds of `Statement`.
- * Differs from `Element::getParentScope` when `e` is a `LoopControlVariable`
+ * a `Variable` that is nonvolatile and const
+ * and of type `IntegralOrEnumType`
*/
-private Element getParentScope(Element e) {
- /*
- * A `Block` cannot have a `ForStmt` as its parent scope so we have to special case
- * for loop bodies to ensure that identifiers inside the loop bodies have the for stmt as a parent scope.
- * If this is not the case then `i2` in the following example cannot be in `i1`'s potential scope, because
- * the parent scope of `i1` is the `ForStmt` while the transitive closure of the parent scope for `i2` doesn't include
- * outer scope. Blocks can only have blocks as parent scopes.
- * void f() {
- * for( int i1; ... ) {
- * for (int i2; ...) {
- * }
- * }
- * }
- */
+class NonVolatileConstIntegralOrEnumVariable extends Variable {
+ NonVolatileConstIntegralOrEnumVariable() {
+ not this.isVolatile() and
+ this.isConst() and
+ this.getUnspecifiedType() instanceof IntegralOrEnumType
+ }
+}
- exists(Loop loop | loop.getStmt() = e and result = loop)
- or
- exists(IfStmt ifStmt |
- (ifStmt.getThen() = e or ifStmt.getElse() = e) and
- result = ifStmt
- )
- or
- exists(SwitchStmt switchStmt | switchStmt.getStmt() = e and result = switchStmt)
- or
- not result.(Loop).getStmt() = e and
- not result.(IfStmt).getThen() = e and
- not result.(IfStmt).getElse() = e and
- not result.(SwitchStmt).getStmt() = e and
- if exists(e.getParentScope())
- then result = e.getParentScope()
- else (
- // Statements do no have a parent scope, so return the enclosing block.
- result = e.(Stmt).getEnclosingBlock()
+/**
+ * Internal module, exposed for testing.
+ */
+module Internal {
+ /**
+ * Gets the parent scope of this `Element`, if any.
+ * A scope is a `Type` (`Class` / `Enum`), a `Namespace`, a `Block`, a `Function`,
+ * or certain kinds of `Statement`.
+ * Differs from `Element::getParentScope` when `e` is a `LoopControlVariable`
+ */
+ Element getParentScope(Element e) {
+ /*
+ * A `Block` cannot have a `ForStmt` as its parent scope so we have to special case
+ * for loop bodies to ensure that identifiers inside the loop bodies have the for stmt as a parent scope.
+ * If this is not the case then `i2` in the following example cannot be in `i1`'s potential scope, because
+ * the parent scope of `i1` is the `ForStmt` while the transitive closure of the parent scope for `i2` doesn't include
+ * outer scope. Blocks can only have blocks as parent scopes.
+ * void f() {
+ * for( int i1; ... ) {
+ * for (int i2; ...) {
+ * }
+ * }
+ * }
+ */
+
+ exists(Loop loop | loop.getAChild() = e and result = loop)
+ or
+ exists(IfStmt ifStmt |
+ (ifStmt.getThen() = e or ifStmt.getElse() = e) and
+ result = ifStmt
+ )
+ or
+ exists(SwitchStmt switchStmt | switchStmt.getStmt() = e and result = switchStmt)
+ or
+ // A catch-block parameter, whose parent is the `Handler`
+ exists(CatchBlock c | c.getParameter() = e and result = c.getParent())
or
- result = e.(Expr).getEnclosingBlock()
+ // A catch-block `Handler`, whose parent is the `TryStmt`
+ e.(Handler).getParent() = result
or
- // Catch block parameters don't have an enclosing scope, so attach them to the
- // the block itself
- exists(CatchBlock cb |
- e = cb.getParameter() and
- result = cb
+ // The parent scope of a lambda is the scope in which the lambda expression is defined.
+ //
+ // Lambda functions are defined in a generated `Closure` class, as the `operator()` function. We choose the
+ // enclosing statement of the lambda expression as the parent scope of the lambda function. This is so we can
+ // determine the order of definition if a variable is defined in the same scope as the lambda expression.
+ exists(Closure lambdaClosure |
+ lambdaClosure.getLambdaFunction() = e and
+ lambdaClosure.getLambdaExpression().getEnclosingStmt() = result
)
- )
+ or
+ not exists(Loop loop | loop.getAChild() = e) and
+ not exists(IfStmt ifStmt | ifStmt.getThen() = e or ifStmt.getElse() = e) and
+ not exists(SwitchStmt switchStmt | switchStmt.getStmt() = e) and
+ not exists(CatchBlock c | c.getParameter() = e) and
+ not e instanceof Handler and
+ not exists(Closure lambdaClosure | lambdaClosure.getLambdaFunction() = e) and
+ if exists(e.getParentScope())
+ then result = e.getParentScope()
+ else (
+ // Statements do not have a parent scope, so return the enclosing block.
+ result = e.(Stmt).getEnclosingBlock()
+ or
+ // Expressions do not have a parent scope, so return the enclosing block.
+ result = e.(Expr).getEnclosingBlock()
+ )
+ }
}
/** A variable which is defined by the user, rather than being from a third party or compiler generated. */
@@ -68,19 +98,29 @@ class UserVariable extends Variable {
/** An element which is the parent scope of at least one other element in the program. */
class Scope extends Element {
- Scope() { this = getParentScope(_) }
+ Scope() { this = Internal::getParentScope(_) }
- UserVariable getAVariable() { getParentScope(result) = this }
+ UserVariable getAVariable() { Internal::getParentScope(result) = this }
+
+ /**
+ * Gets the `Variable` with the given `name` that is declared in this scope.
+ */
+ UserVariable getVariable(string name) {
+ result = getAVariable() and
+ result.getName() = name
+ }
int getNumberOfVariables() { result = count(getAVariable()) }
Scope getAnAncestor() { result = this.getStrictParent+() }
- Scope getStrictParent() { result = getParentScope(this) }
+ Scope getAChildScope() { result.getStrictParent() = this }
+
+ Scope getStrictParent() { result = Internal::getParentScope(this) }
- Declaration getADeclaration() { getParentScope(result) = this }
+ Declaration getADeclaration() { Internal::getParentScope(result) = this }
- Expr getAnExpr() { this = getParentScope(result) }
+ Expr getAnExpr() { this = Internal::getParentScope(result) }
private predicate getLocationInfo(
PreprocessorBranchDirective pbd, string file1, string file2, int startline1, int startline2
@@ -112,43 +152,136 @@ class Scope extends Element {
predicate isGenerated() { this instanceof GeneratedBlockStmt }
int getDepth() {
- exists(Scope parent | parent = getParentScope(this) and result = 1 + parent.getDepth())
+ exists(Scope parent |
+ parent = Internal::getParentScope(this) and result = 1 + parent.getDepth()
+ )
or
- not exists(getParentScope(this)) and result = 0
+ not exists(Internal::getParentScope(this)) and result = 0
}
-}
-class GeneratedBlockStmt extends BlockStmt {
- GeneratedBlockStmt() { this.getLocation() instanceof UnknownLocation }
-}
+ /**
+ * Holds if `name` is declared in this scope, or in a nested scope.
+ */
+ private predicate isNameDeclaredInThisOrNestedScope(string name) {
+ name = getAVariable().getName()
+ or
+ isNameDeclaredInNestedScope(name)
+ }
+
+ /**
+ * Holds if `name` is declared in a nested scope.
+ */
+ private predicate isNameDeclaredInNestedScope(string name) {
+ this.getAChildScope().isNameDeclaredInThisOrNestedScope(name)
+ }
+
+ /**
+ * Holds if `name` is declared in this scope and is hidden in a child scope.
+ */
+ private predicate isDeclaredNameHiddenByChild(string name) {
+ isNameDeclaredInNestedScope(name) and
+ name = getAVariable().getName()
+ }
+
+ /**
+ * Gets a variable with `name` which is potentially hidden in at least one nested scope.
+ */
+ private UserVariable getAPotentiallyHiddenVariable(string name) {
+ result = getAVariable() and
+ result.getName() = name and
+ isDeclaredNameHiddenByChild(name)
+ }
-/** Gets a variable that is in the potential scope of variable `v`. */
-private UserVariable getPotentialScopeOfVariable_candidate(UserVariable v) {
- exists(Scope s |
- result = s.getAVariable() and
+ /**
+ * Holds if `name` is declared above this scope and hidden by this or a nested scope.
+ */
+ UserVariable getAVariableHiddenByThisOrNestedScope(string name) {
+ exists(Scope parent | parent = this.getStrictParent() |
+ result = parent.getAPotentiallyHiddenVariable(name) or
+ result = parent.getAVariableHiddenByThisOrNestedScope(name)
+ ) and
+ isNameDeclaredInThisOrNestedScope(name)
+ }
+
+ /**
+ * Holds if `hiddenVariable` and `hidingVariable` are a candidate hiding pair at this scope.
+ */
+ private predicate hidesCandidate(
+ UserVariable hiddenVariable, UserVariable hidingVariable, string name
+ ) {
(
- // Variable in an ancestor scope, but only if there are less than 100 variables in this scope
- v = s.getAnAncestor().getAVariable() and
- s.getNumberOfVariables() < 100
+ // Declared in this scope
+ hidingVariable = getVariable(name) and
+ hiddenVariable = getAVariableHiddenByThisOrNestedScope(name)
or
- // In the same scope, but not the same variable, and choose just one to report
- v = s.getAVariable() and
- not result = v and
- v.getName() <= result.getName()
+ // Declared in a child scope
+ exists(Scope child |
+ getAChildScope() = child and
+ child.hidesCandidate(hiddenVariable, hidingVariable, name)
+ )
)
- )
+ }
+
+ /**
+ * Holds if `hiddenVariable` is declared in this scope and hidden by `hidingVariable`.
+ */
+ predicate hides(UserVariable hiddenVariable, UserVariable hidingVariable, Scope childScope) {
+ exists(string name |
+ hiddenVariable = getAPotentiallyHiddenVariable(name) and
+ childScope = getAChildScope() and
+ childScope.hidesCandidate(hiddenVariable, hidingVariable, name)
+ )
+ }
}
-/** Gets a variable that is in the potential scope of variable `v`. */
-private UserVariable getOuterScopesOfVariable_candidate(UserVariable v) {
- exists(Scope s |
- result = s.getAVariable() and
- (
- // Variable in an ancestor scope, but only if there are less than 100 variables in this scope
- v = s.getAnAncestor().getAVariable() and
- s.getNumberOfVariables() < 100
+/**
+ * A scope representing the generated `operator()` of a lambda function.
+ */
+class LambdaScope extends Scope {
+ Closure closure;
+
+ LambdaScope() { this = closure.getLambdaFunction() }
+
+ override UserVariable getAVariableHiddenByThisOrNestedScope(string name) {
+ // Handle special cases for lambdas
+ exists(UserVariable hiddenVariable, LambdaExpression lambdaExpr |
+ // Find the variable that is potentially hidden inside the lambda
+ hiddenVariable = super.getAVariableHiddenByThisOrNestedScope(name) and
+ result = hiddenVariable and
+ lambdaExpr = closure.getLambdaExpression()
+ |
+ // A definition can be hidden if it is in scope and it is captured by the lambda,
+ exists(LambdaCapture cap |
+ lambdaExpr.getACapture() = cap and
+ // The outer declaration is captured by the lambda
+ hiddenVariable.getAnAccess() = cap.getInitializer()
+ )
+ or
+ // it is is non-local,
+ hiddenVariable instanceof GlobalVariable
+ or
+ // it has static or thread local storage duration,
+ (hiddenVariable.isThreadLocal() or hiddenVariable.isStatic())
+ or
+ //it is a reference that has been initialized with a constant expression.
+ hiddenVariable.getType().stripTopLevelSpecifiers() instanceof ReferenceType and
+ hiddenVariable.getInitializer().getExpr() instanceof Literal
+ or
+ // //it const non-volatile integral or enumeration type and has been initialized with a constant expression
+ hiddenVariable instanceof NonVolatileConstIntegralOrEnumVariable and
+ hiddenVariable.getInitializer().getExpr() instanceof Literal
+ or
+ //it is constexpr and has no mutable members
+ hiddenVariable.isConstexpr() and
+ not exists(Class c |
+ c = hiddenVariable.getType() and not c.getAMember() instanceof MutableVariable
+ )
)
- )
+ }
+}
+
+class GeneratedBlockStmt extends BlockStmt {
+ GeneratedBlockStmt() { this.getLocation() instanceof UnknownLocation }
}
/** Holds if there exists a translation unit that includes both `f1` and `f2`. */
@@ -161,21 +294,17 @@ predicate inSameTranslationUnit(File f1, File f2) {
}
/**
- * Gets a user variable which occurs in the "potential scope" of variable `v`.
- */
-cached
-UserVariable getPotentialScopeOfVariable(UserVariable v) {
- result = getPotentialScopeOfVariable_candidate(v) and
- inSameTranslationUnit(v.getFile(), result.getFile())
-}
-
-/**
- * Gets a user variable which occurs in the "outer scope" of variable `v`.
+ * Holds if there exists a translation unit that includes both `f1` and `f2`.
+ *
+ * This version is late bound.
*/
-cached
-UserVariable getPotentialScopeOfVariableStrict(UserVariable v) {
- result = getOuterScopesOfVariable_candidate(v) and
- inSameTranslationUnit(v.getFile(), result.getFile())
+bindingset[f1, f2]
+pragma[inline_late]
+predicate inSameTranslationUnitLate(File f1, File f2) {
+ exists(TranslationUnit c |
+ c.getAUserFile() = f1 and
+ c.getAUserFile() = f2
+ )
}
/** A file that is a C/C++ source file */
@@ -203,67 +332,27 @@ class TranslationUnit extends SourceFile {
}
}
-/** Holds if `v2` may hide `v1`. */
-private predicate hides_candidate(UserVariable v1, UserVariable v2) {
- not v1 = v2 and
- v2 = getPotentialScopeOfVariable(v1) and
- v1.getName() = v2.getName() and
- // Member variables cannot hide other variables nor be hidden because the can be referenced through their qualified name.
- not (v1.isMember() or v2.isMember())
-}
-
-/** Holds if `v2` may hide `v1`. */
-private predicate hides_candidateStrict(UserVariable v1, UserVariable v2) {
- not v1 = v2 and
- v2 = getPotentialScopeOfVariableStrict(v1) and
- v1.getName() = v2.getName() and
- // Member variables cannot hide other variables nor be hidden because the can be referenced through their qualified name.
- not (v1.isMember() or v2.isMember()) and
- (
- // If v1 is a local variable, ensure that v1 is declared before v2
+/** Holds if `v2` strictly (`v2` is in an inner scope compared to `v1`) hides `v1`. */
+predicate hides_candidateStrict(UserVariable v1, UserVariable v2) {
+ exists(Scope parentScope, Scope childScope | parentScope.hides(v1, v2, childScope) |
+ // If v1 is a local variable defined in a `DeclStmt` ensure that it is declared before `v2`,
+ // otherwise it would not be hidden
(
- v1 instanceof LocalVariable and
- // Ignore variables declared in conditional expressions, as they apply to
- // the nested scope
- not v1 = any(ConditionDeclExpr cde).getVariable() and
- // Ignore variables declared in loops
- not exists(Loop l | l.getADeclaration() = v1)
+ parentScope instanceof BlockStmt and
+ exists(DeclStmt ds | ds.getADeclaration() = v1) and
+ exists(parentScope.(BlockStmt).getIndexOfStmt(childScope))
)
implies
exists(BlockStmt bs, DeclStmt v1Stmt, Stmt v2Stmt |
- v1 = v1Stmt.getADeclaration() and
- getEnclosingStmt(v2).getParentStmt*() = v2Stmt
+ bs = parentScope and
+ v2Stmt = childScope and
+ v1Stmt.getADeclaration() = v1
|
bs.getIndexOfStmt(v1Stmt) <= bs.getIndexOfStmt(v2Stmt)
)
- )
-}
-
-/**
- * Gets the enclosing statement of the given variable, if any.
- */
-private Stmt getEnclosingStmt(LocalScopeVariable v) {
- result.(DeclStmt).getADeclaration() = v
- or
- exists(ConditionDeclExpr cde |
- cde.getVariable() = v and
- result = cde.getEnclosingStmt()
- )
- or
- exists(CatchBlock cb |
- cb.getParameter() = v and
- result = cb.getEnclosingStmt()
- )
-}
-
-/** Holds if `v2` hides `v1`. */
-predicate hides(UserVariable v1, UserVariable v2) {
- hides_candidate(v1, v2) and
- // Confirm that there's no closer candidate variable which `v2` hides
- not exists(UserVariable mid |
- hides_candidate(v1, mid) and
- hides_candidate(mid, v2)
- )
+ ) and
+ inSameTranslationUnitLate(v1.getFile(), v2.getFile()) and
+ not (v1.isMember() or v2.isMember())
}
/** Holds if `v2` strictly (`v2` is in an inner scope compared to `v1`) hides `v1`. */
@@ -291,6 +380,8 @@ predicate hasBlockScope(Declaration decl) { exists(BlockStmt b | b.getADeclarati
/**
* identifiers in nested (named/nonglobal) namespaces are exceptions to hiding due to being able access via fully qualified ids
*/
+bindingset[outerDecl, innerDecl]
+pragma[inline_late]
predicate excludedViaNestedNamespaces(UserVariable outerDecl, UserVariable innerDecl) {
exists(Namespace inner, Namespace outer |
outer.getAChildNamespace+() = inner and
diff --git a/cpp/common/src/codingstandards/cpp/SideEffect.qll b/cpp/common/src/codingstandards/cpp/SideEffect.qll
index 08cd9394d3..d83647ce76 100644
--- a/cpp/common/src/codingstandards/cpp/SideEffect.qll
+++ b/cpp/common/src/codingstandards/cpp/SideEffect.qll
@@ -1,7 +1,7 @@
/** A module to reason about side effects. */
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
private import exceptions.ExceptionFlow
private import codingstandards.cpp.Expr
private import codingstandards.cpp.Variable
@@ -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/SmartPointers.qll b/cpp/common/src/codingstandards/cpp/SmartPointers.qll
index dda645a399..0f01d886be 100644
--- a/cpp/common/src/codingstandards/cpp/SmartPointers.qll
+++ b/cpp/common/src/codingstandards/cpp/SmartPointers.qll
@@ -1,5 +1,5 @@
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
// Local cached version of localExprFlow to avoid bad magic
cached
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/VariablyModifiedTypes.qll b/cpp/common/src/codingstandards/cpp/VariablyModifiedTypes.qll
new file mode 100644
index 0000000000..9de533d050
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/VariablyModifiedTypes.qll
@@ -0,0 +1,224 @@
+import cpp
+
+/**
+ * A declaration involving a variably-modified type.
+ *
+ * Note, this holds for both VLA variable and VLA typedefs.
+ */
+class VmtDeclarationEntry extends DeclarationEntry {
+ Expr sizeExpr;
+ CandidateVlaType vlaType;
+ // `before` and `after` are captured for debugging, see doc comment for
+ // `declarationSubsumes`.
+ Location before;
+ Location after;
+
+ VmtDeclarationEntry() {
+ // Most of this library looks for candidate VLA types, by looking for arrays
+ // without a size. These may or may not be VLA types. To confirm an a
+ // candidate type is really a VLA type, we check that the location of the
+ // declaration subsumes a `VlaDimensionStmt` which indicates a real VLA.
+ sizeExpr = any(VlaDimensionStmt vla).getDimensionExpr() and
+ declarationSubsumes(this, sizeExpr.getLocation(), before, after) and
+ (
+ if this instanceof ParameterDeclarationEntry
+ then vlaType = this.getType().(VariablyModifiedTypeIfAdjusted).getInnerVlaType()
+ else vlaType = this.getType().(VariablyModifiedTypeIfUnadjusted).getInnerVlaType()
+ )
+ }
+
+ Expr getSizeExpr() { result = sizeExpr }
+
+ CandidateVlaType getVlaType() { result = vlaType }
+
+ /* VLAs may occur in macros, and result in duplication that messes up our analysis. */
+ predicate appearsDuplicated() {
+ exists(VmtDeclarationEntry other |
+ other != this and
+ other.getSizeExpr() = getSizeExpr()
+ )
+ }
+}
+
+/**
+ * Check that the declaration entry, which may be a parameter or a variable
+ * etc., seems to subsume the location of `inner`, including the declaration
+ * type text.
+ *
+ * The location of the `DeclarationEntry` itself points to the _identifier_
+ * that is declared. This range will not include the type of the declaration.
+ *
+ * For parameters, the `before` and `end` `Location` objects will be
+ * constrained to the closest earlier element (parameter or function body),
+ * these values can therefore be captured and inspected for debugging.
+ *
+ * For declarations which occur in statements, the `before` and `end`
+ * `Location` objects will be both constrained to be equal, and equal to,
+ * the `Location` of the containing `DeclStmt`.
+ */
+private predicate declarationSubsumes(
+ DeclarationEntry entry, Location inner, Location before, Location after
+) {
+ inner.getFile() = entry.getLocation().getFile() and
+ (
+ exists(ParameterDeclarationEntry param, FunctionDeclarationEntry func, int i |
+ param = entry and
+ func = param.getFunctionDeclarationEntry() and
+ func.getParameterDeclarationEntry(i) = param and
+ before = entry.getLocation() and
+ (
+ after = func.getParameterDeclarationEntry(i + 1).getLocation()
+ or
+ not exists(ParameterDeclarationEntry afterParam |
+ afterParam = func.getParameterDeclarationEntry(i + 1)
+ ) and
+ after = func.getBlock().getLocation()
+ )
+ ) and
+ before.isBefore(inner, _) and
+ inner.isBefore(after, _)
+ or
+ exists(DeclStmt s |
+ s.getADeclaration() = entry.getDeclaration() and
+ before = s.getLocation() and
+ after = before and
+ before.subsumes(inner)
+ )
+ )
+}
+
+/**
+ * A candidate to be a variably length array type (VLA).
+ *
+ * This class represents a candidate only, for a few reasons.
+ *
+ * Firstly, the `ArrayType` class does not know when it has variable size, so
+ * this class matches all array types with unknown size, including `x[]` which
+ * is not a VLA. To determine the difference, we must compare locations between
+ * where * these types are declared, and the location of `VlaDecl`s etc.
+ *
+ * Secondly, function parameters of array type are adjusted into pointers. This
+ * means that while a parameter type can be a `CandidateVlaType`, that
+ * parameter is not a VLA.
+ */
+class CandidateVlaType extends ArrayType {
+ CandidateVlaType() { not hasArraySize() }
+
+ Type getVariableBaseType() { result = this.getBaseType() }
+}
+
+/**
+ * A type that is a variably modified type (VMT) if it does not undergo
+ * parameter type adjustment.
+ *
+ * A variably modified type is a VLA type, or a type containing a VMT type, for
+ * instance, a pointer to a VLA or a pointer to a pointer to a VLA.
+ *
+ * Function parameters and function type parameters of type `T[]` are adjusted
+ * to type `T*`, which can turn VMTs into non-VMTs. To check if a parameter
+ * type is a VMT, use `VariablyModifiedTypeIfAdjusted`.
+ */
+class VariablyModifiedTypeIfUnadjusted extends Type {
+ CandidateVlaType innerVlaType;
+
+ VariablyModifiedTypeIfUnadjusted() {
+ // Take care that `int[x][y]` only matches for `innerVlaType = int[y]`.
+ if this instanceof CandidateVlaType
+ then innerVlaType = this
+ else innerVlaType = this.(NoAdjustmentVariablyModifiedType).getInnerVlaType()
+ }
+
+ CandidateVlaType getInnerVlaType() { result = innerVlaType }
+}
+
+/**
+ * A type that is a variably modified type (VMT) if it undergoes parameter type
+ * adjustment.
+ *
+ * A variably modified type is a VLA type, or a type containing a VMT type, for
+ * instance, a pointer to a VLA or a pointer to a pointer to a VLA.
+ *
+ * Function parameters and function type parameters of type `T[]` are adjusted
+ * to type `T*`, which can turn VMTs into non-VMTs. To check if a non-parameter
+ * type (for instance, the type of a local variable) is a VMT, use
+ * `VariablyModifiedTypeIfUnadjusted`.
+ */
+class VariablyModifiedTypeIfAdjusted extends Type {
+ CandidateVlaType innerVlaType;
+
+ VariablyModifiedTypeIfAdjusted() {
+ innerVlaType = this.(ParameterAdjustedVariablyModifiedType).getInnerVlaType()
+ or
+ innerVlaType = this.(NoAdjustmentVariablyModifiedType).getInnerVlaType()
+ }
+
+ CandidateVlaType getInnerVlaType() { result = innerVlaType }
+}
+
+/**
+ * A variably modified type candidate which is unaffected by parameter type
+ * adjustment (from `T[]` to `*T`).
+ *
+ * Parameter adjustment (from `T[]` to `*T`) occurs on all function parameter
+ * types for exactly one level of depth.
+ *
+ * A variably-modified type (VMT) is a type which includes an inner type that is
+ * a VLA type. That is to say, a pointer to a VLA is a VMT, and a pointer to a
+ * VMT is a VMT.
+ *
+ * Note: This class does *not* match all VLA types. While VLA types *are* VMTs,
+ * VMTs can be parameter-adjusted to pointers, which are not VLA types. This
+ * class *will* match multidimensional VLAs, as those are adjusted to pointers
+ * to VLAs, and pointers to VLAs are VMTs.
+ */
+class NoAdjustmentVariablyModifiedType extends Type {
+ CandidateVlaType vlaType;
+
+ NoAdjustmentVariablyModifiedType() {
+ exists(Type innerType |
+ (
+ innerType = this.(DerivedType).getBaseType()
+ or
+ innerType = this.(RoutineType).getReturnType()
+ or
+ innerType = this.(FunctionPointerType).getReturnType()
+ or
+ innerType = this.(TypedefType).getBaseType()
+ ) and
+ vlaType = innerType.(VariablyModifiedTypeIfUnadjusted).getInnerVlaType()
+ )
+ or
+ vlaType =
+ this.(FunctionPointerType)
+ .getAParameterType()
+ .(VariablyModifiedTypeIfAdjusted)
+ .getInnerVlaType()
+ or
+ vlaType =
+ this.(RoutineType).getAParameterType().(VariablyModifiedTypeIfAdjusted).getInnerVlaType()
+ }
+
+ CandidateVlaType getInnerVlaType() { result = vlaType }
+}
+
+/**
+ * An array type that adjusts to a variably-modified type (a type which is or
+ * contains a VLA type) when it is a parameter type.
+ *
+ * A variably-modified type (VMT) is a VLA type or a type which has an inner type
+ * that is a VMT type, for instance, a pointer to a VLA type.
+ *
+ * Parameter adjustment occurs on all function parameter types, changing type
+ * `T[]` to `*T` for exactly one level of depth. Therefore, a VLA type will not
+ * be a VLA type/VMT after parameter adjustment, unless it is an array of VMTs,
+ * such that it parameter adjustment produces a pointer to a VMT.
+ */
+class ParameterAdjustedVariablyModifiedType extends ArrayType {
+ CandidateVlaType innerVlaType;
+
+ ParameterAdjustedVariablyModifiedType() {
+ innerVlaType = getBaseType().(VariablyModifiedTypeIfUnadjusted).getInnerVlaType()
+ }
+
+ CandidateVlaType getInnerVlaType() { result = innerVlaType }
+}
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/allocations/PlacementNew.qll b/cpp/common/src/codingstandards/cpp/allocations/PlacementNew.qll
index 5547f2e151..2c9139d0ae 100644
--- a/cpp/common/src/codingstandards/cpp/allocations/PlacementNew.qll
+++ b/cpp/common/src/codingstandards/cpp/allocations/PlacementNew.qll
@@ -22,7 +22,7 @@
import cpp
import codingstandards.cpp.Conversion
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/*
* TODO You can also have alignas on types
diff --git a/cpp/common/src/codingstandards/cpp/dataflow/DataFlow.qll b/cpp/common/src/codingstandards/cpp/dataflow/DataFlow.qll
deleted file mode 100644
index c11bf80fc6..0000000000
--- a/cpp/common/src/codingstandards/cpp/dataflow/DataFlow.qll
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Provides a library for local (intra-procedural) and global (inter-procedural)
- * data flow analysis: deciding whether data can flow from a _source_ to a
- * _sink_.
- *
- * Unless configured otherwise, _flow_ means that the exact value of
- * the source may reach the sink. We do not track flow across pointer
- * dereferences or array indexing. To track these types of flow, where the
- * exact value may not be preserved, import
- * `semmle.code.cpp.dataflow.TaintTracking`.
- *
- * To use global (interprocedural) data flow, extend the class
- * `DataFlow::Configuration` as documented on that class. To use local
- * (intraprocedural) data flow between expressions, call
- * `DataFlow::localExprFlow`. For more general cases of local data flow, call
- * `DataFlow::localFlow` or `DataFlow::localFlowStep` with arguments of type
- * `DataFlow::Node`.
- *
- * NOTE: This is copied from `codeql/cpp-all` to avoid deprecation warnings
- * that cannot be avoided in tests.
- */
-
-import cpp
-
-/**
- * DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
- *
- * Provides classes for performing local (intra-procedural) and
- * global (inter-procedural) data flow analyses.
- */
-module DataFlow {
- private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific
- private import codeql.dataflow.DataFlow
- import DataFlowMake
- import semmle.code.cpp.dataflow.internal.DataFlowImpl1
-}
diff --git a/cpp/common/src/codingstandards/cpp/dataflow/DataFlow2.qll b/cpp/common/src/codingstandards/cpp/dataflow/DataFlow2.qll
deleted file mode 100644
index 83859535d8..0000000000
--- a/cpp/common/src/codingstandards/cpp/dataflow/DataFlow2.qll
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Provides a `DataFlow2` module, which is a copy of the `DataFlow` module. Use
- * this class when data-flow configurations must depend on each other. Two
- * classes extending `DataFlow::Configuration` should never depend on each
- * other, but one of them should instead depend on a
- * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a
- * `DataFlow4::Configuration`.
- *
- * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation.
- *
- * NOTE: This is copied from `codeql/cpp-all` to avoid deprecation warnings
- * that cannot be avoided in tests.
- */
-
-import cpp
-
-/**
- * DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow2` instead.
- *
- * Provides classes for performing local (intra-procedural) and
- * global (inter-procedural) data flow analyses.
- */
-module DataFlow2 {
- import semmle.code.cpp.dataflow.internal.DataFlowImpl2
-}
diff --git a/cpp/common/src/codingstandards/cpp/dataflow/TaintTracking.qll b/cpp/common/src/codingstandards/cpp/dataflow/TaintTracking.qll
deleted file mode 100644
index 2b43a53ccb..0000000000
--- a/cpp/common/src/codingstandards/cpp/dataflow/TaintTracking.qll
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Provides classes for performing local (intra-procedural) and
- * global (inter-procedural) taint-tracking analyses.
- *
- * We define _taint propagation_ informally to mean that a substantial part of
- * the information from the source is preserved at the sink. For example, taint
- * propagates from `x` to `x + 100`, but it does not propagate from `x` to `x >
- * 100` since we consider a single bit of information to be too little.
- *
- * To use global (interprocedural) taint tracking, extend the class
- * `TaintTracking::Configuration` as documented on that class. To use local
- * (intraprocedural) taint tracking between expressions, call
- * `TaintTracking::localExprTaint`. For more general cases of local taint
- * tracking, call `TaintTracking::localTaint` or
- * `TaintTracking::localTaintStep` with arguments of type `DataFlow::Node`.
- *
- * NOTE: This is copied from `codeql/cpp-all` to avoid deprecation warnings
- * that cannot be avoided in tests.
- */
-
-import codingstandards.cpp.dataflow.DataFlow
-import codingstandards.cpp.dataflow.DataFlow2
-
-/**
- * DEPRECATED: Use `semmle.code.cpp.dataflow.new.TaintTracking` instead.
- *
- * Provides classes for performing local (intra-procedural) and
- * global (inter-procedural) taint-tracking analyses.
- */
-module TaintTracking {
- import codingstandards.cpp.dataflow.internal.tainttracking1.TaintTrackingParameter::Public
- private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific
- private import semmle.code.cpp.dataflow.internal.TaintTrackingImplSpecific
- private import codeql.dataflow.TaintTracking
- import TaintFlowMake
- import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl
-}
diff --git a/cpp/common/src/codingstandards/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/cpp/common/src/codingstandards/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll
deleted file mode 100644
index 63e9c85e22..0000000000
--- a/cpp/common/src/codingstandards/cpp/dataflow/internal/tainttracking1/TaintTrackingParameter.qll
+++ /dev/null
@@ -1,6 +0,0 @@
-import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Public
-
-module Private {
- import codingstandards.cpp.dataflow.DataFlow::DataFlow as DataFlow
- import semmle.code.cpp.dataflow.internal.DataFlowImpl as DataFlowInternal
-}
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/Alignment.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Alignment.qll
new file mode 100644
index 0000000000..9447abf636
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Alignment.qll
@@ -0,0 +1,78 @@
+//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
+import cpp
+import RuleMetadata
+import codingstandards.cpp.exclusions.RuleMetadata
+
+newtype AlignmentQuery =
+ TRedeclarationOfObjectWithoutAlignmentQuery() or
+ TRedeclarationOfObjectWithUnmatchedAlignmentQuery() or
+ TAlignmentWithSizeZeroQuery() or
+ TMoreThanOneAlignmentSpecifierOnDeclarationQuery()
+
+predicate isAlignmentQueryMetadata(Query query, string queryId, string ruleId, string category) {
+ query =
+ // `Query` instance for the `redeclarationOfObjectWithoutAlignment` query
+ AlignmentPackage::redeclarationOfObjectWithoutAlignmentQuery() and
+ queryId =
+ // `@id` for the `redeclarationOfObjectWithoutAlignment` query
+ "c/misra/redeclaration-of-object-without-alignment" and
+ ruleId = "RULE-8-15" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `redeclarationOfObjectWithUnmatchedAlignment` query
+ AlignmentPackage::redeclarationOfObjectWithUnmatchedAlignmentQuery() and
+ queryId =
+ // `@id` for the `redeclarationOfObjectWithUnmatchedAlignment` query
+ "c/misra/redeclaration-of-object-with-unmatched-alignment" and
+ ruleId = "RULE-8-15" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `alignmentWithSizeZero` query
+ AlignmentPackage::alignmentWithSizeZeroQuery() and
+ queryId =
+ // `@id` for the `alignmentWithSizeZero` query
+ "c/misra/alignment-with-size-zero" and
+ ruleId = "RULE-8-16" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `moreThanOneAlignmentSpecifierOnDeclaration` query
+ AlignmentPackage::moreThanOneAlignmentSpecifierOnDeclarationQuery() and
+ queryId =
+ // `@id` for the `moreThanOneAlignmentSpecifierOnDeclaration` query
+ "c/misra/more-than-one-alignment-specifier-on-declaration" and
+ ruleId = "RULE-8-17" and
+ category = "advisory"
+}
+
+module AlignmentPackage {
+ Query redeclarationOfObjectWithoutAlignmentQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `redeclarationOfObjectWithoutAlignment` query
+ TQueryC(TAlignmentPackageQuery(TRedeclarationOfObjectWithoutAlignmentQuery()))
+ }
+
+ Query redeclarationOfObjectWithUnmatchedAlignmentQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `redeclarationOfObjectWithUnmatchedAlignment` query
+ TQueryC(TAlignmentPackageQuery(TRedeclarationOfObjectWithUnmatchedAlignmentQuery()))
+ }
+
+ Query alignmentWithSizeZeroQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `alignmentWithSizeZero` query
+ TQueryC(TAlignmentPackageQuery(TAlignmentWithSizeZeroQuery()))
+ }
+
+ Query moreThanOneAlignmentSpecifierOnDeclarationQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `moreThanOneAlignmentSpecifierOnDeclaration` query
+ TQueryC(TAlignmentPackageQuery(TMoreThanOneAlignmentSpecifierOnDeclarationQuery()))
+ }
+}
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/InvalidMemory3.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/InvalidMemory3.qll
new file mode 100644
index 0000000000..c4e39882ec
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/InvalidMemory3.qll
@@ -0,0 +1,61 @@
+//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
+import cpp
+import RuleMetadata
+import codingstandards.cpp.exclusions.RuleMetadata
+
+newtype InvalidMemory3Query =
+ TPointersToVariablyModifiedArrayTypesUsedQuery() or
+ TArrayToPointerConversionOfTemporaryObjectQuery() or
+ TModifiableLValueSubscriptedWithTemporaryLifetimeQuery()
+
+predicate isInvalidMemory3QueryMetadata(Query query, string queryId, string ruleId, string category) {
+ query =
+ // `Query` instance for the `pointersToVariablyModifiedArrayTypesUsed` query
+ InvalidMemory3Package::pointersToVariablyModifiedArrayTypesUsedQuery() and
+ queryId =
+ // `@id` for the `pointersToVariablyModifiedArrayTypesUsed` query
+ "c/misra/pointers-to-variably-modified-array-types-used" and
+ ruleId = "RULE-18-10" and
+ category = "mandatory"
+ or
+ query =
+ // `Query` instance for the `arrayToPointerConversionOfTemporaryObject` query
+ InvalidMemory3Package::arrayToPointerConversionOfTemporaryObjectQuery() and
+ queryId =
+ // `@id` for the `arrayToPointerConversionOfTemporaryObject` query
+ "c/misra/array-to-pointer-conversion-of-temporary-object" and
+ ruleId = "RULE-18-9" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `modifiableLValueSubscriptedWithTemporaryLifetime` query
+ InvalidMemory3Package::modifiableLValueSubscriptedWithTemporaryLifetimeQuery() and
+ queryId =
+ // `@id` for the `modifiableLValueSubscriptedWithTemporaryLifetime` query
+ "c/misra/modifiable-l-value-subscripted-with-temporary-lifetime" and
+ ruleId = "RULE-18-9" and
+ category = "required"
+}
+
+module InvalidMemory3Package {
+ Query pointersToVariablyModifiedArrayTypesUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `pointersToVariablyModifiedArrayTypesUsed` query
+ TQueryC(TInvalidMemory3PackageQuery(TPointersToVariablyModifiedArrayTypesUsedQuery()))
+ }
+
+ Query arrayToPointerConversionOfTemporaryObjectQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `arrayToPointerConversionOfTemporaryObject` query
+ TQueryC(TInvalidMemory3PackageQuery(TArrayToPointerConversionOfTemporaryObjectQuery()))
+ }
+
+ Query modifiableLValueSubscriptedWithTemporaryLifetimeQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `modifiableLValueSubscriptedWithTemporaryLifetime` query
+ TQueryC(TInvalidMemory3PackageQuery(TModifiableLValueSubscriptedWithTemporaryLifetimeQuery()))
+ }
+}
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 6425f27e28..6ab695fb99 100644
--- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll
+++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll
@@ -2,8 +2,11 @@
import cpp
import codingstandards.cpp.exclusions.RuleMetadata
//** Import packages for this language **/
+import Alignment
import Banned
+import Banned2
import BitfieldTypes
+import BitfieldTypes2
import Concurrency1
import Concurrency2
import Concurrency3
@@ -29,6 +32,7 @@ import Declarations8
import EssentialTypes
import Expressions
import FloatingTypes
+import FunctionTypes
import IO1
import IO2
import IO3
@@ -36,13 +40,16 @@ import IO4
import IntegerOverflow
import InvalidMemory1
import InvalidMemory2
+import InvalidMemory3
import Language1
import Language2
import Language3
+import Language4
import Memory1
import Memory2
import Memory3
import Misc
+import NoReturn
import OutOfBounds
import Pointers1
import Pointers2
@@ -71,11 +78,15 @@ import Strings2
import Strings3
import Syntax
import Types1
+import Types2
/** The TQuery type representing this language * */
newtype TCQuery =
+ TAlignmentPackageQuery(AlignmentQuery q) or
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
@@ -101,6 +112,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
@@ -108,13 +120,16 @@ newtype TCQuery =
TIntegerOverflowPackageQuery(IntegerOverflowQuery q) or
TInvalidMemory1PackageQuery(InvalidMemory1Query q) or
TInvalidMemory2PackageQuery(InvalidMemory2Query q) or
+ TInvalidMemory3PackageQuery(InvalidMemory3Query q) or
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
@@ -142,12 +157,16 @@ 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) {
+ isAlignmentQueryMetadata(query, queryId, ruleId, category) or
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
@@ -173,6 +192,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,13 +200,16 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
isIntegerOverflowQueryMetadata(query, queryId, ruleId, category) or
isInvalidMemory1QueryMetadata(query, queryId, ruleId, category) or
isInvalidMemory2QueryMetadata(query, queryId, ruleId, category) or
+ isInvalidMemory3QueryMetadata(query, queryId, ruleId, category) or
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
@@ -214,5 +237,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/ImportMisra23.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/ImportMisra23.qll
index 86b4b9c5ae..d31affb27c 100644
--- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/ImportMisra23.qll
+++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/ImportMisra23.qll
@@ -26,7 +26,68 @@ newtype ImportMisra23Query =
TCallToSetlocaleInvalidatesOldPointersMisraQuery() or
TCallToSetlocaleInvalidatesOldPointersWarnMisraQuery() or
TObjectUsedWhileInPotentiallyMovedFromStateQuery() or
- TReadsAndWritesOnStreamNotSeparatedByPositioningQuery()
+ TReadsAndWritesOnStreamNotSeparatedByPositioningQuery() or
+ TCommaOperatorShouldNotBeUsedQuery() or
+ TCopyAndMoveAssignmentsShallHandleSelfAssignmentQuery() or
+ TUseSingleLocalDeclaratorsQuery() or
+ TUseSingleGlobalOrMemberDeclaratorsQuery() or
+ TEnumerationNotDefinedWithAnExplicitUnderlyingTypeQuery() or
+ TAsmDeclarationShallNotBeUsedQuery() or
+ TNonUniqueEnumerationConstantQuery() or
+ TBitFieldShallHaveAnAppropriateTypeQuery() or
+ TSignedIntegerNamedBitFieldHaveALengthOfOneBitQuery() or
+ TVirtualAndNonVirtualClassInTheHierarchyQuery() or
+ TOverridingShallSpecifyDifferentDefaultArgumentsQuery() or
+ TPotentiallyVirtualPointerOnlyComparesToNullptrQuery() or
+ TObjectsDynamicTypeUsedFromConstructorOrDestructorQuery() or
+ TInitializeAllVirtualBaseClassesQuery() or
+ TInitializerListConstructorIsTheOnlyConstructorQuery() or
+ TAddressOfOperatorOverloadedQuery() or
+ TFunctionTemplatesExplicitlySpecializedQuery() or
+ TExceptionObjectHavePointerTypeQuery() or
+ TEmptyThrowOnlyWithinACatchHandlerQuery() or
+ TNoexceptFunctionShouldNotPropagateToTheCallerQuery() or
+ TFunctionLikeMacrosDefinedQuery() or
+ TMacroParameterFollowingHashQuery() or
+ TAMixedUseMacroArgumentSubjectToExpansionQuery() or
+ TCsignalFacilitiesUsedQuery() or
+ TCsignalTypesShallNotBeUsedQuery() or
+ TAtofAtoiAtolAndAtollUsedQuery() or
+ TMacroOffsetofShallNotBeUsedQuery() or
+ TGlobalSizedOperatorDeleteShallBeDefinedQuery() or
+ TGlobalUnsizedOperatorDeleteShallBeDefinedQuery() or
+ TVectorShouldNotBeSpecializedWithBoolQuery() or
+ TForwardingReferencesAndForwardNotUsedTogetherQuery() or
+ TCstdioFunctionsShallNotBeUsedQuery() or
+ TCstdioMacrosShallNotBeUsedQuery() or
+ TCstdioTypesShallNotBeUsedQuery() or
+ TBackslashCharacterMisuseQuery() or
+ TNonTerminatedEscapeSequencesQuery() or
+ TOctalConstantsUsedQuery() or
+ TUnsignedIntegerLiteralsNotAppropriatelySuffixedQuery() or
+ TLowercaseLStartsInLiteralSuffixQuery() or
+ TCharacterSequenceUsedWithinACStyleCommentQuery() or
+ TLineSplicingUsedInCommentsQuery() or
+ TGlobalNamespaceDeclarationsQuery() or
+ TNonGlobalFunctionMainQuery() or
+ TInheritedNonOverridableMemberFunctionQuery() or
+ TInheritedOverridableMemberFunctionQuery() or
+ TDefinitionShallBeConsideredForUnqualifiedLookupQuery() or
+ TNameShallBeReferredUsingAQualifiedIdOrThisQuery() or
+ TNameShallBeReferredUsingAQualifiedIdOrThisAuditQuery() or
+ TReturnReferenceOrPointerToAutomaticLocalVariableQuery() or
+ TNullptrNotTheOnlyFormOfTheNullPointerConstantQuery() or
+ TArrayPassedAsFunctionArgumentDecayToAPointerQuery() or
+ TResultOfAnAssignmentOperatorShouldNotBeUsedQuery() or
+ TFunctionsCallThemselvesEitherDirectlyOrIndirectlyQuery() or
+ TCastsBetweenAPointerToFunctionAndAnyOtherTypeQuery() or
+ TReinterpretCastShallNotBeUsedQuery() or
+ TUnsignedOperationWithConstantOperandsWrapsQuery() or
+ TBuiltInUnaryOperatorAppliedToUnsignedExpressionQuery() or
+ TSwitchBodyCompoundConditionQuery() or
+ TLoopBodyCompoundConditionQuery() or
+ TGotoStatementShouldNotBeUsedQuery() or
+ TGotoReferenceALabelInSurroundingBlockQuery()
predicate isImportMisra23QueryMetadata(Query query, string queryId, string ruleId, string category) {
query =
@@ -235,6 +296,555 @@ predicate isImportMisra23QueryMetadata(Query query, string queryId, string ruleI
"cpp/misra/reads-and-writes-on-stream-not-separated-by-positioning" and
ruleId = "RULE-30-0-2" and
category = "required"
+ or
+ query =
+ // `Query` instance for the `commaOperatorShouldNotBeUsed` query
+ ImportMisra23Package::commaOperatorShouldNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `commaOperatorShouldNotBeUsed` query
+ "cpp/misra/comma-operator-should-not-be-used" and
+ ruleId = "RULE-8-19-1" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `copyAndMoveAssignmentsShallHandleSelfAssignment` query
+ ImportMisra23Package::copyAndMoveAssignmentsShallHandleSelfAssignmentQuery() and
+ queryId =
+ // `@id` for the `copyAndMoveAssignmentsShallHandleSelfAssignment` query
+ "cpp/misra/copy-and-move-assignments-shall-handle-self-assignment" and
+ ruleId = "DIR-15-8-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `useSingleLocalDeclarators` query
+ ImportMisra23Package::useSingleLocalDeclaratorsQuery() and
+ queryId =
+ // `@id` for the `useSingleLocalDeclarators` query
+ "cpp/misra/use-single-local-declarators" and
+ ruleId = "RULE-10-0-1" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `useSingleGlobalOrMemberDeclarators` query
+ ImportMisra23Package::useSingleGlobalOrMemberDeclaratorsQuery() and
+ queryId =
+ // `@id` for the `useSingleGlobalOrMemberDeclarators` query
+ "cpp/misra/use-single-global-or-member-declarators" and
+ ruleId = "RULE-10-0-1" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `enumerationNotDefinedWithAnExplicitUnderlyingType` query
+ ImportMisra23Package::enumerationNotDefinedWithAnExplicitUnderlyingTypeQuery() and
+ queryId =
+ // `@id` for the `enumerationNotDefinedWithAnExplicitUnderlyingType` query
+ "cpp/misra/enumeration-not-defined-with-an-explicit-underlying-type" and
+ ruleId = "RULE-10-2-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `asmDeclarationShallNotBeUsed` query
+ ImportMisra23Package::asmDeclarationShallNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `asmDeclarationShallNotBeUsed` query
+ "cpp/misra/asm-declaration-shall-not-be-used" and
+ ruleId = "RULE-10-4-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `nonUniqueEnumerationConstant` query
+ ImportMisra23Package::nonUniqueEnumerationConstantQuery() and
+ queryId =
+ // `@id` for the `nonUniqueEnumerationConstant` query
+ "cpp/misra/non-unique-enumeration-constant" and
+ ruleId = "RULE-11-6-3" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `bitFieldShallHaveAnAppropriateType` query
+ ImportMisra23Package::bitFieldShallHaveAnAppropriateTypeQuery() and
+ queryId =
+ // `@id` for the `bitFieldShallHaveAnAppropriateType` query
+ "cpp/misra/bit-field-shall-have-an-appropriate-type" and
+ ruleId = "RULE-12-2-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `signedIntegerNamedBitFieldHaveALengthOfOneBit` query
+ ImportMisra23Package::signedIntegerNamedBitFieldHaveALengthOfOneBitQuery() and
+ queryId =
+ // `@id` for the `signedIntegerNamedBitFieldHaveALengthOfOneBit` query
+ "cpp/misra/signed-integer-named-bit-field-have-a-length-of-one-bit" and
+ ruleId = "RULE-12-2-3" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `virtualAndNonVirtualClassInTheHierarchy` query
+ ImportMisra23Package::virtualAndNonVirtualClassInTheHierarchyQuery() and
+ queryId =
+ // `@id` for the `virtualAndNonVirtualClassInTheHierarchy` query
+ "cpp/misra/virtual-and-non-virtual-class-in-the-hierarchy" and
+ ruleId = "RULE-13-1-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `overridingShallSpecifyDifferentDefaultArguments` query
+ ImportMisra23Package::overridingShallSpecifyDifferentDefaultArgumentsQuery() and
+ queryId =
+ // `@id` for the `overridingShallSpecifyDifferentDefaultArguments` query
+ "cpp/misra/overriding-shall-specify-different-default-arguments" and
+ ruleId = "RULE-13-3-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `potentiallyVirtualPointerOnlyComparesToNullptr` query
+ ImportMisra23Package::potentiallyVirtualPointerOnlyComparesToNullptrQuery() and
+ queryId =
+ // `@id` for the `potentiallyVirtualPointerOnlyComparesToNullptr` query
+ "cpp/misra/potentially-virtual-pointer-only-compares-to-nullptr" and
+ ruleId = "RULE-13-3-4" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `objectsDynamicTypeUsedFromConstructorOrDestructor` query
+ ImportMisra23Package::objectsDynamicTypeUsedFromConstructorOrDestructorQuery() and
+ queryId =
+ // `@id` for the `objectsDynamicTypeUsedFromConstructorOrDestructor` query
+ "cpp/misra/objects-dynamic-type-used-from-constructor-or-destructor" and
+ ruleId = "RULE-15-1-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `initializeAllVirtualBaseClasses` query
+ ImportMisra23Package::initializeAllVirtualBaseClassesQuery() and
+ queryId =
+ // `@id` for the `initializeAllVirtualBaseClasses` query
+ "cpp/misra/initialize-all-virtual-base-classes" and
+ ruleId = "RULE-15-1-2" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `initializerListConstructorIsTheOnlyConstructor` query
+ ImportMisra23Package::initializerListConstructorIsTheOnlyConstructorQuery() and
+ queryId =
+ // `@id` for the `initializerListConstructorIsTheOnlyConstructor` query
+ "cpp/misra/initializer-list-constructor-is-the-only-constructor" and
+ ruleId = "RULE-15-1-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `addressOfOperatorOverloaded` query
+ ImportMisra23Package::addressOfOperatorOverloadedQuery() and
+ queryId =
+ // `@id` for the `addressOfOperatorOverloaded` query
+ "cpp/misra/address-of-operator-overloaded" and
+ ruleId = "RULE-16-5-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `functionTemplatesExplicitlySpecialized` query
+ ImportMisra23Package::functionTemplatesExplicitlySpecializedQuery() and
+ queryId =
+ // `@id` for the `functionTemplatesExplicitlySpecialized` query
+ "cpp/misra/function-templates-explicitly-specialized" and
+ ruleId = "RULE-17-8-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `exceptionObjectHavePointerType` query
+ ImportMisra23Package::exceptionObjectHavePointerTypeQuery() and
+ queryId =
+ // `@id` for the `exceptionObjectHavePointerType` query
+ "cpp/misra/exception-object-have-pointer-type" and
+ ruleId = "RULE-18-1-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `emptyThrowOnlyWithinACatchHandler` query
+ ImportMisra23Package::emptyThrowOnlyWithinACatchHandlerQuery() and
+ queryId =
+ // `@id` for the `emptyThrowOnlyWithinACatchHandler` query
+ "cpp/misra/empty-throw-only-within-a-catch-handler" and
+ ruleId = "RULE-18-1-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `noexceptFunctionShouldNotPropagateToTheCaller` query
+ ImportMisra23Package::noexceptFunctionShouldNotPropagateToTheCallerQuery() and
+ queryId =
+ // `@id` for the `noexceptFunctionShouldNotPropagateToTheCaller` query
+ "cpp/misra/noexcept-function-should-not-propagate-to-the-caller" and
+ ruleId = "RULE-18-5-1" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `functionLikeMacrosDefined` query
+ ImportMisra23Package::functionLikeMacrosDefinedQuery() and
+ queryId =
+ // `@id` for the `functionLikeMacrosDefined` query
+ "cpp/misra/function-like-macros-defined" and
+ ruleId = "RULE-19-0-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `macroParameterFollowingHash` query
+ ImportMisra23Package::macroParameterFollowingHashQuery() and
+ queryId =
+ // `@id` for the `macroParameterFollowingHash` query
+ "cpp/misra/macro-parameter-following-hash" and
+ ruleId = "RULE-19-3-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `aMixedUseMacroArgumentSubjectToExpansion` query
+ ImportMisra23Package::aMixedUseMacroArgumentSubjectToExpansionQuery() and
+ queryId =
+ // `@id` for the `aMixedUseMacroArgumentSubjectToExpansion` query
+ "cpp/misra/a-mixed-use-macro-argument-subject-to-expansion" and
+ ruleId = "RULE-19-3-3" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `csignalFacilitiesUsed` query
+ ImportMisra23Package::csignalFacilitiesUsedQuery() and
+ queryId =
+ // `@id` for the `csignalFacilitiesUsed` query
+ "cpp/misra/csignal-facilities-used" and
+ ruleId = "RULE-21-10-3" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `csignalTypesShallNotBeUsed` query
+ ImportMisra23Package::csignalTypesShallNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `csignalTypesShallNotBeUsed` query
+ "cpp/misra/csignal-types-shall-not-be-used" and
+ ruleId = "RULE-21-10-3" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `atofAtoiAtolAndAtollUsed` query
+ ImportMisra23Package::atofAtoiAtolAndAtollUsedQuery() and
+ queryId =
+ // `@id` for the `atofAtoiAtolAndAtollUsed` query
+ "cpp/misra/atof-atoi-atol-and-atoll-used" and
+ ruleId = "RULE-21-2-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `macroOffsetofShallNotBeUsed` query
+ ImportMisra23Package::macroOffsetofShallNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `macroOffsetofShallNotBeUsed` query
+ "cpp/misra/macro-offsetof-shall-not-be-used" and
+ ruleId = "RULE-21-2-4" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `globalSizedOperatorDeleteShallBeDefined` query
+ ImportMisra23Package::globalSizedOperatorDeleteShallBeDefinedQuery() and
+ queryId =
+ // `@id` for the `globalSizedOperatorDeleteShallBeDefined` query
+ "cpp/misra/global-sized-operator-delete-shall-be-defined" and
+ ruleId = "RULE-21-6-4" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `globalUnsizedOperatorDeleteShallBeDefined` query
+ ImportMisra23Package::globalUnsizedOperatorDeleteShallBeDefinedQuery() and
+ queryId =
+ // `@id` for the `globalUnsizedOperatorDeleteShallBeDefined` query
+ "cpp/misra/global-unsized-operator-delete-shall-be-defined" and
+ ruleId = "RULE-21-6-4" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `vectorShouldNotBeSpecializedWithBool` query
+ ImportMisra23Package::vectorShouldNotBeSpecializedWithBoolQuery() and
+ queryId =
+ // `@id` for the `vectorShouldNotBeSpecializedWithBool` query
+ "cpp/misra/vector-should-not-be-specialized-with-bool" and
+ ruleId = "RULE-26-3-1" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `forwardingReferencesAndForwardNotUsedTogether` query
+ ImportMisra23Package::forwardingReferencesAndForwardNotUsedTogetherQuery() and
+ queryId =
+ // `@id` for the `forwardingReferencesAndForwardNotUsedTogether` query
+ "cpp/misra/forwarding-references-and-forward-not-used-together" and
+ ruleId = "RULE-28-6-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `cstdioFunctionsShallNotBeUsed` query
+ ImportMisra23Package::cstdioFunctionsShallNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `cstdioFunctionsShallNotBeUsed` query
+ "cpp/misra/cstdio-functions-shall-not-be-used" and
+ ruleId = "RULE-30-0-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `cstdioMacrosShallNotBeUsed` query
+ ImportMisra23Package::cstdioMacrosShallNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `cstdioMacrosShallNotBeUsed` query
+ "cpp/misra/cstdio-macros-shall-not-be-used" and
+ ruleId = "RULE-30-0-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `cstdioTypesShallNotBeUsed` query
+ ImportMisra23Package::cstdioTypesShallNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `cstdioTypesShallNotBeUsed` query
+ "cpp/misra/cstdio-types-shall-not-be-used" and
+ ruleId = "RULE-30-0-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `backslashCharacterMisuse` query
+ ImportMisra23Package::backslashCharacterMisuseQuery() and
+ queryId =
+ // `@id` for the `backslashCharacterMisuse` query
+ "cpp/misra/backslash-character-misuse" and
+ ruleId = "RULE-5-13-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `nonTerminatedEscapeSequences` query
+ ImportMisra23Package::nonTerminatedEscapeSequencesQuery() and
+ queryId =
+ // `@id` for the `nonTerminatedEscapeSequences` query
+ "cpp/misra/non-terminated-escape-sequences" and
+ ruleId = "RULE-5-13-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `octalConstantsUsed` query
+ ImportMisra23Package::octalConstantsUsedQuery() and
+ queryId =
+ // `@id` for the `octalConstantsUsed` query
+ "cpp/misra/octal-constants-used" and
+ ruleId = "RULE-5-13-3" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `unsignedIntegerLiteralsNotAppropriatelySuffixed` query
+ ImportMisra23Package::unsignedIntegerLiteralsNotAppropriatelySuffixedQuery() and
+ queryId =
+ // `@id` for the `unsignedIntegerLiteralsNotAppropriatelySuffixed` query
+ "cpp/misra/unsigned-integer-literals-not-appropriately-suffixed" and
+ ruleId = "RULE-5-13-4" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `lowercaseLStartsInLiteralSuffix` query
+ ImportMisra23Package::lowercaseLStartsInLiteralSuffixQuery() and
+ queryId =
+ // `@id` for the `lowercaseLStartsInLiteralSuffix` query
+ "cpp/misra/lowercase-l-starts-in-literal-suffix" and
+ ruleId = "RULE-5-13-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `characterSequenceUsedWithinACStyleComment` query
+ ImportMisra23Package::characterSequenceUsedWithinACStyleCommentQuery() and
+ queryId =
+ // `@id` for the `characterSequenceUsedWithinACStyleComment` query
+ "cpp/misra/character-sequence-used-within-ac-style-comment" and
+ ruleId = "RULE-5-7-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `lineSplicingUsedInComments` query
+ ImportMisra23Package::lineSplicingUsedInCommentsQuery() and
+ queryId =
+ // `@id` for the `lineSplicingUsedInComments` query
+ "cpp/misra/line-splicing-used-in-comments" and
+ ruleId = "RULE-5-7-3" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `globalNamespaceDeclarations` query
+ ImportMisra23Package::globalNamespaceDeclarationsQuery() and
+ queryId =
+ // `@id` for the `globalNamespaceDeclarations` query
+ "cpp/misra/global-namespace-declarations" and
+ ruleId = "RULE-6-0-3" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `nonGlobalFunctionMain` query
+ ImportMisra23Package::nonGlobalFunctionMainQuery() and
+ queryId =
+ // `@id` for the `nonGlobalFunctionMain` query
+ "cpp/misra/non-global-function-main" and
+ ruleId = "RULE-6-0-4" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `inheritedNonOverridableMemberFunction` query
+ ImportMisra23Package::inheritedNonOverridableMemberFunctionQuery() and
+ queryId =
+ // `@id` for the `inheritedNonOverridableMemberFunction` query
+ "cpp/misra/inherited-non-overridable-member-function" and
+ ruleId = "RULE-6-4-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `inheritedOverridableMemberFunction` query
+ ImportMisra23Package::inheritedOverridableMemberFunctionQuery() and
+ queryId =
+ // `@id` for the `inheritedOverridableMemberFunction` query
+ "cpp/misra/inherited-overridable-member-function" and
+ ruleId = "RULE-6-4-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `definitionShallBeConsideredForUnqualifiedLookup` query
+ ImportMisra23Package::definitionShallBeConsideredForUnqualifiedLookupQuery() and
+ queryId =
+ // `@id` for the `definitionShallBeConsideredForUnqualifiedLookup` query
+ "cpp/misra/definition-shall-be-considered-for-unqualified-lookup" and
+ ruleId = "RULE-6-4-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `nameShallBeReferredUsingAQualifiedIdOrThis` query
+ ImportMisra23Package::nameShallBeReferredUsingAQualifiedIdOrThisQuery() and
+ queryId =
+ // `@id` for the `nameShallBeReferredUsingAQualifiedIdOrThis` query
+ "cpp/misra/name-shall-be-referred-using-a-qualified-id-or-this" and
+ ruleId = "RULE-6-4-3" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `nameShallBeReferredUsingAQualifiedIdOrThisAudit` query
+ ImportMisra23Package::nameShallBeReferredUsingAQualifiedIdOrThisAuditQuery() and
+ queryId =
+ // `@id` for the `nameShallBeReferredUsingAQualifiedIdOrThisAudit` query
+ "cpp/misra/name-shall-be-referred-using-a-qualified-id-or-this-audit" and
+ ruleId = "RULE-6-4-3" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `returnReferenceOrPointerToAutomaticLocalVariable` query
+ ImportMisra23Package::returnReferenceOrPointerToAutomaticLocalVariableQuery() and
+ queryId =
+ // `@id` for the `returnReferenceOrPointerToAutomaticLocalVariable` query
+ "cpp/misra/return-reference-or-pointer-to-automatic-local-variable" and
+ ruleId = "RULE-6-8-2" and
+ category = "mandatory"
+ or
+ query =
+ // `Query` instance for the `nullptrNotTheOnlyFormOfTheNullPointerConstant` query
+ ImportMisra23Package::nullptrNotTheOnlyFormOfTheNullPointerConstantQuery() and
+ queryId =
+ // `@id` for the `nullptrNotTheOnlyFormOfTheNullPointerConstant` query
+ "cpp/misra/nullptr-not-the-only-form-of-the-null-pointer-constant" and
+ ruleId = "RULE-7-11-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `arrayPassedAsFunctionArgumentDecayToAPointer` query
+ ImportMisra23Package::arrayPassedAsFunctionArgumentDecayToAPointerQuery() and
+ queryId =
+ // `@id` for the `arrayPassedAsFunctionArgumentDecayToAPointer` query
+ "cpp/misra/array-passed-as-function-argument-decay-to-a-pointer" and
+ ruleId = "RULE-7-11-2" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `resultOfAnAssignmentOperatorShouldNotBeUsed` query
+ ImportMisra23Package::resultOfAnAssignmentOperatorShouldNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `resultOfAnAssignmentOperatorShouldNotBeUsed` query
+ "cpp/misra/result-of-an-assignment-operator-should-not-be-used" and
+ ruleId = "RULE-8-18-2" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `functionsCallThemselvesEitherDirectlyOrIndirectly` query
+ ImportMisra23Package::functionsCallThemselvesEitherDirectlyOrIndirectlyQuery() and
+ queryId =
+ // `@id` for the `functionsCallThemselvesEitherDirectlyOrIndirectly` query
+ "cpp/misra/functions-call-themselves-either-directly-or-indirectly" and
+ ruleId = "RULE-8-2-10" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `castsBetweenAPointerToFunctionAndAnyOtherType` query
+ ImportMisra23Package::castsBetweenAPointerToFunctionAndAnyOtherTypeQuery() and
+ queryId =
+ // `@id` for the `castsBetweenAPointerToFunctionAndAnyOtherType` query
+ "cpp/misra/casts-between-a-pointer-to-function-and-any-other-type" and
+ ruleId = "RULE-8-2-4" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `reinterpretCastShallNotBeUsed` query
+ ImportMisra23Package::reinterpretCastShallNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `reinterpretCastShallNotBeUsed` query
+ "cpp/misra/reinterpret-cast-shall-not-be-used" and
+ ruleId = "RULE-8-2-5" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `unsignedOperationWithConstantOperandsWraps` query
+ ImportMisra23Package::unsignedOperationWithConstantOperandsWrapsQuery() and
+ queryId =
+ // `@id` for the `unsignedOperationWithConstantOperandsWraps` query
+ "cpp/misra/unsigned-operation-with-constant-operands-wraps" and
+ ruleId = "RULE-8-20-1" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `builtInUnaryOperatorAppliedToUnsignedExpression` query
+ ImportMisra23Package::builtInUnaryOperatorAppliedToUnsignedExpressionQuery() and
+ queryId =
+ // `@id` for the `builtInUnaryOperatorAppliedToUnsignedExpression` query
+ "cpp/misra/built-in-unary-operator-applied-to-unsigned-expression" and
+ ruleId = "RULE-8-3-1" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `switchBodyCompoundCondition` query
+ ImportMisra23Package::switchBodyCompoundConditionQuery() and
+ queryId =
+ // `@id` for the `switchBodyCompoundCondition` query
+ "cpp/misra/switch-body-compound-condition" and
+ ruleId = "RULE-9-3-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `loopBodyCompoundCondition` query
+ ImportMisra23Package::loopBodyCompoundConditionQuery() and
+ queryId =
+ // `@id` for the `loopBodyCompoundCondition` query
+ "cpp/misra/loop-body-compound-condition" and
+ ruleId = "RULE-9-3-1" and
+ category = "required"
+ or
+ query =
+ // `Query` instance for the `gotoStatementShouldNotBeUsed` query
+ ImportMisra23Package::gotoStatementShouldNotBeUsedQuery() and
+ queryId =
+ // `@id` for the `gotoStatementShouldNotBeUsed` query
+ "cpp/misra/goto-statement-should-not-be-used" and
+ ruleId = "RULE-9-6-1" and
+ category = "advisory"
+ or
+ query =
+ // `Query` instance for the `gotoReferenceALabelInSurroundingBlock` query
+ ImportMisra23Package::gotoReferenceALabelInSurroundingBlockQuery() and
+ queryId =
+ // `@id` for the `gotoReferenceALabelInSurroundingBlock` query
+ "cpp/misra/goto-reference-a-label-in-surrounding-block" and
+ ruleId = "RULE-9-6-2" and
+ category = "required"
}
module ImportMisra23Package {
@@ -398,4 +1008,431 @@ module ImportMisra23Package {
// `Query` type for `readsAndWritesOnStreamNotSeparatedByPositioning` query
TQueryCPP(TImportMisra23PackageQuery(TReadsAndWritesOnStreamNotSeparatedByPositioningQuery()))
}
+
+ Query commaOperatorShouldNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `commaOperatorShouldNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TCommaOperatorShouldNotBeUsedQuery()))
+ }
+
+ Query copyAndMoveAssignmentsShallHandleSelfAssignmentQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `copyAndMoveAssignmentsShallHandleSelfAssignment` query
+ TQueryCPP(TImportMisra23PackageQuery(TCopyAndMoveAssignmentsShallHandleSelfAssignmentQuery()))
+ }
+
+ Query useSingleLocalDeclaratorsQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `useSingleLocalDeclarators` query
+ TQueryCPP(TImportMisra23PackageQuery(TUseSingleLocalDeclaratorsQuery()))
+ }
+
+ Query useSingleGlobalOrMemberDeclaratorsQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `useSingleGlobalOrMemberDeclarators` query
+ TQueryCPP(TImportMisra23PackageQuery(TUseSingleGlobalOrMemberDeclaratorsQuery()))
+ }
+
+ Query enumerationNotDefinedWithAnExplicitUnderlyingTypeQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `enumerationNotDefinedWithAnExplicitUnderlyingType` query
+ TQueryCPP(TImportMisra23PackageQuery(TEnumerationNotDefinedWithAnExplicitUnderlyingTypeQuery()))
+ }
+
+ Query asmDeclarationShallNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `asmDeclarationShallNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TAsmDeclarationShallNotBeUsedQuery()))
+ }
+
+ Query nonUniqueEnumerationConstantQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `nonUniqueEnumerationConstant` query
+ TQueryCPP(TImportMisra23PackageQuery(TNonUniqueEnumerationConstantQuery()))
+ }
+
+ Query bitFieldShallHaveAnAppropriateTypeQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `bitFieldShallHaveAnAppropriateType` query
+ TQueryCPP(TImportMisra23PackageQuery(TBitFieldShallHaveAnAppropriateTypeQuery()))
+ }
+
+ Query signedIntegerNamedBitFieldHaveALengthOfOneBitQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `signedIntegerNamedBitFieldHaveALengthOfOneBit` query
+ TQueryCPP(TImportMisra23PackageQuery(TSignedIntegerNamedBitFieldHaveALengthOfOneBitQuery()))
+ }
+
+ Query virtualAndNonVirtualClassInTheHierarchyQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `virtualAndNonVirtualClassInTheHierarchy` query
+ TQueryCPP(TImportMisra23PackageQuery(TVirtualAndNonVirtualClassInTheHierarchyQuery()))
+ }
+
+ Query overridingShallSpecifyDifferentDefaultArgumentsQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `overridingShallSpecifyDifferentDefaultArguments` query
+ TQueryCPP(TImportMisra23PackageQuery(TOverridingShallSpecifyDifferentDefaultArgumentsQuery()))
+ }
+
+ Query potentiallyVirtualPointerOnlyComparesToNullptrQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `potentiallyVirtualPointerOnlyComparesToNullptr` query
+ TQueryCPP(TImportMisra23PackageQuery(TPotentiallyVirtualPointerOnlyComparesToNullptrQuery()))
+ }
+
+ Query objectsDynamicTypeUsedFromConstructorOrDestructorQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `objectsDynamicTypeUsedFromConstructorOrDestructor` query
+ TQueryCPP(TImportMisra23PackageQuery(TObjectsDynamicTypeUsedFromConstructorOrDestructorQuery()))
+ }
+
+ Query initializeAllVirtualBaseClassesQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `initializeAllVirtualBaseClasses` query
+ TQueryCPP(TImportMisra23PackageQuery(TInitializeAllVirtualBaseClassesQuery()))
+ }
+
+ Query initializerListConstructorIsTheOnlyConstructorQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `initializerListConstructorIsTheOnlyConstructor` query
+ TQueryCPP(TImportMisra23PackageQuery(TInitializerListConstructorIsTheOnlyConstructorQuery()))
+ }
+
+ Query addressOfOperatorOverloadedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `addressOfOperatorOverloaded` query
+ TQueryCPP(TImportMisra23PackageQuery(TAddressOfOperatorOverloadedQuery()))
+ }
+
+ Query functionTemplatesExplicitlySpecializedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `functionTemplatesExplicitlySpecialized` query
+ TQueryCPP(TImportMisra23PackageQuery(TFunctionTemplatesExplicitlySpecializedQuery()))
+ }
+
+ Query exceptionObjectHavePointerTypeQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `exceptionObjectHavePointerType` query
+ TQueryCPP(TImportMisra23PackageQuery(TExceptionObjectHavePointerTypeQuery()))
+ }
+
+ Query emptyThrowOnlyWithinACatchHandlerQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `emptyThrowOnlyWithinACatchHandler` query
+ TQueryCPP(TImportMisra23PackageQuery(TEmptyThrowOnlyWithinACatchHandlerQuery()))
+ }
+
+ Query noexceptFunctionShouldNotPropagateToTheCallerQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `noexceptFunctionShouldNotPropagateToTheCaller` query
+ TQueryCPP(TImportMisra23PackageQuery(TNoexceptFunctionShouldNotPropagateToTheCallerQuery()))
+ }
+
+ Query functionLikeMacrosDefinedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `functionLikeMacrosDefined` query
+ TQueryCPP(TImportMisra23PackageQuery(TFunctionLikeMacrosDefinedQuery()))
+ }
+
+ Query macroParameterFollowingHashQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `macroParameterFollowingHash` query
+ TQueryCPP(TImportMisra23PackageQuery(TMacroParameterFollowingHashQuery()))
+ }
+
+ Query aMixedUseMacroArgumentSubjectToExpansionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `aMixedUseMacroArgumentSubjectToExpansion` query
+ TQueryCPP(TImportMisra23PackageQuery(TAMixedUseMacroArgumentSubjectToExpansionQuery()))
+ }
+
+ Query csignalFacilitiesUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `csignalFacilitiesUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TCsignalFacilitiesUsedQuery()))
+ }
+
+ Query csignalTypesShallNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `csignalTypesShallNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TCsignalTypesShallNotBeUsedQuery()))
+ }
+
+ Query atofAtoiAtolAndAtollUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `atofAtoiAtolAndAtollUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TAtofAtoiAtolAndAtollUsedQuery()))
+ }
+
+ Query macroOffsetofShallNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `macroOffsetofShallNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TMacroOffsetofShallNotBeUsedQuery()))
+ }
+
+ Query globalSizedOperatorDeleteShallBeDefinedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `globalSizedOperatorDeleteShallBeDefined` query
+ TQueryCPP(TImportMisra23PackageQuery(TGlobalSizedOperatorDeleteShallBeDefinedQuery()))
+ }
+
+ Query globalUnsizedOperatorDeleteShallBeDefinedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `globalUnsizedOperatorDeleteShallBeDefined` query
+ TQueryCPP(TImportMisra23PackageQuery(TGlobalUnsizedOperatorDeleteShallBeDefinedQuery()))
+ }
+
+ Query vectorShouldNotBeSpecializedWithBoolQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `vectorShouldNotBeSpecializedWithBool` query
+ TQueryCPP(TImportMisra23PackageQuery(TVectorShouldNotBeSpecializedWithBoolQuery()))
+ }
+
+ Query forwardingReferencesAndForwardNotUsedTogetherQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `forwardingReferencesAndForwardNotUsedTogether` query
+ TQueryCPP(TImportMisra23PackageQuery(TForwardingReferencesAndForwardNotUsedTogetherQuery()))
+ }
+
+ Query cstdioFunctionsShallNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `cstdioFunctionsShallNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TCstdioFunctionsShallNotBeUsedQuery()))
+ }
+
+ Query cstdioMacrosShallNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `cstdioMacrosShallNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TCstdioMacrosShallNotBeUsedQuery()))
+ }
+
+ Query cstdioTypesShallNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `cstdioTypesShallNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TCstdioTypesShallNotBeUsedQuery()))
+ }
+
+ Query backslashCharacterMisuseQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `backslashCharacterMisuse` query
+ TQueryCPP(TImportMisra23PackageQuery(TBackslashCharacterMisuseQuery()))
+ }
+
+ Query nonTerminatedEscapeSequencesQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `nonTerminatedEscapeSequences` query
+ TQueryCPP(TImportMisra23PackageQuery(TNonTerminatedEscapeSequencesQuery()))
+ }
+
+ Query octalConstantsUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `octalConstantsUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TOctalConstantsUsedQuery()))
+ }
+
+ Query unsignedIntegerLiteralsNotAppropriatelySuffixedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `unsignedIntegerLiteralsNotAppropriatelySuffixed` query
+ TQueryCPP(TImportMisra23PackageQuery(TUnsignedIntegerLiteralsNotAppropriatelySuffixedQuery()))
+ }
+
+ Query lowercaseLStartsInLiteralSuffixQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `lowercaseLStartsInLiteralSuffix` query
+ TQueryCPP(TImportMisra23PackageQuery(TLowercaseLStartsInLiteralSuffixQuery()))
+ }
+
+ Query characterSequenceUsedWithinACStyleCommentQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `characterSequenceUsedWithinACStyleComment` query
+ TQueryCPP(TImportMisra23PackageQuery(TCharacterSequenceUsedWithinACStyleCommentQuery()))
+ }
+
+ Query lineSplicingUsedInCommentsQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `lineSplicingUsedInComments` query
+ TQueryCPP(TImportMisra23PackageQuery(TLineSplicingUsedInCommentsQuery()))
+ }
+
+ Query globalNamespaceDeclarationsQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `globalNamespaceDeclarations` query
+ TQueryCPP(TImportMisra23PackageQuery(TGlobalNamespaceDeclarationsQuery()))
+ }
+
+ Query nonGlobalFunctionMainQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `nonGlobalFunctionMain` query
+ TQueryCPP(TImportMisra23PackageQuery(TNonGlobalFunctionMainQuery()))
+ }
+
+ Query inheritedNonOverridableMemberFunctionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `inheritedNonOverridableMemberFunction` query
+ TQueryCPP(TImportMisra23PackageQuery(TInheritedNonOverridableMemberFunctionQuery()))
+ }
+
+ Query inheritedOverridableMemberFunctionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `inheritedOverridableMemberFunction` query
+ TQueryCPP(TImportMisra23PackageQuery(TInheritedOverridableMemberFunctionQuery()))
+ }
+
+ Query definitionShallBeConsideredForUnqualifiedLookupQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `definitionShallBeConsideredForUnqualifiedLookup` query
+ TQueryCPP(TImportMisra23PackageQuery(TDefinitionShallBeConsideredForUnqualifiedLookupQuery()))
+ }
+
+ Query nameShallBeReferredUsingAQualifiedIdOrThisQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `nameShallBeReferredUsingAQualifiedIdOrThis` query
+ TQueryCPP(TImportMisra23PackageQuery(TNameShallBeReferredUsingAQualifiedIdOrThisQuery()))
+ }
+
+ Query nameShallBeReferredUsingAQualifiedIdOrThisAuditQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `nameShallBeReferredUsingAQualifiedIdOrThisAudit` query
+ TQueryCPP(TImportMisra23PackageQuery(TNameShallBeReferredUsingAQualifiedIdOrThisAuditQuery()))
+ }
+
+ Query returnReferenceOrPointerToAutomaticLocalVariableQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `returnReferenceOrPointerToAutomaticLocalVariable` query
+ TQueryCPP(TImportMisra23PackageQuery(TReturnReferenceOrPointerToAutomaticLocalVariableQuery()))
+ }
+
+ Query nullptrNotTheOnlyFormOfTheNullPointerConstantQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `nullptrNotTheOnlyFormOfTheNullPointerConstant` query
+ TQueryCPP(TImportMisra23PackageQuery(TNullptrNotTheOnlyFormOfTheNullPointerConstantQuery()))
+ }
+
+ Query arrayPassedAsFunctionArgumentDecayToAPointerQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `arrayPassedAsFunctionArgumentDecayToAPointer` query
+ TQueryCPP(TImportMisra23PackageQuery(TArrayPassedAsFunctionArgumentDecayToAPointerQuery()))
+ }
+
+ Query resultOfAnAssignmentOperatorShouldNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `resultOfAnAssignmentOperatorShouldNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TResultOfAnAssignmentOperatorShouldNotBeUsedQuery()))
+ }
+
+ Query functionsCallThemselvesEitherDirectlyOrIndirectlyQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `functionsCallThemselvesEitherDirectlyOrIndirectly` query
+ TQueryCPP(TImportMisra23PackageQuery(TFunctionsCallThemselvesEitherDirectlyOrIndirectlyQuery()))
+ }
+
+ Query castsBetweenAPointerToFunctionAndAnyOtherTypeQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `castsBetweenAPointerToFunctionAndAnyOtherType` query
+ TQueryCPP(TImportMisra23PackageQuery(TCastsBetweenAPointerToFunctionAndAnyOtherTypeQuery()))
+ }
+
+ Query reinterpretCastShallNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `reinterpretCastShallNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TReinterpretCastShallNotBeUsedQuery()))
+ }
+
+ Query unsignedOperationWithConstantOperandsWrapsQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `unsignedOperationWithConstantOperandsWraps` query
+ TQueryCPP(TImportMisra23PackageQuery(TUnsignedOperationWithConstantOperandsWrapsQuery()))
+ }
+
+ Query builtInUnaryOperatorAppliedToUnsignedExpressionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `builtInUnaryOperatorAppliedToUnsignedExpression` query
+ TQueryCPP(TImportMisra23PackageQuery(TBuiltInUnaryOperatorAppliedToUnsignedExpressionQuery()))
+ }
+
+ Query switchBodyCompoundConditionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `switchBodyCompoundCondition` query
+ TQueryCPP(TImportMisra23PackageQuery(TSwitchBodyCompoundConditionQuery()))
+ }
+
+ Query loopBodyCompoundConditionQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `loopBodyCompoundCondition` query
+ TQueryCPP(TImportMisra23PackageQuery(TLoopBodyCompoundConditionQuery()))
+ }
+
+ Query gotoStatementShouldNotBeUsedQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `gotoStatementShouldNotBeUsed` query
+ TQueryCPP(TImportMisra23PackageQuery(TGotoStatementShouldNotBeUsedQuery()))
+ }
+
+ Query gotoReferenceALabelInSurroundingBlockQuery() {
+ //autogenerate `Query` type
+ result =
+ // `Query` type for `gotoReferenceALabelInSurroundingBlock` query
+ TQueryCPP(TImportMisra23PackageQuery(TGotoReferenceALabelInSurroundingBlockQuery()))
+ }
}
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/lifetimes/CLifetimes.qll b/cpp/common/src/codingstandards/cpp/lifetimes/CLifetimes.qll
new file mode 100644
index 0000000000..9282260fb9
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/lifetimes/CLifetimes.qll
@@ -0,0 +1,48 @@
+import cpp
+import codingstandards.cpp.Clvalues
+
+/**
+ * A struct or union type that contains an array type.
+ */
+class StructOrUnionTypeWithArrayField extends Struct {
+ StructOrUnionTypeWithArrayField() {
+ this.getAField().getUnspecifiedType() instanceof ArrayType
+ or
+ // nested struct or union containing an array type
+ this.getAField().getUnspecifiedType().(Struct) instanceof StructOrUnionTypeWithArrayField
+ }
+}
+
+/**
+ * A non-lvalue expression with struct or or union type that has a field member
+ * of array type, has a temporary lifetime.
+ *
+ * The array members are also part of that object, and thus also have temporary
+ * lifetime.
+ */
+class TemporaryLifetimeExpr extends Expr {
+ TemporaryLifetimeExpr() {
+ getUnconverted().getUnspecifiedType() instanceof StructOrUnionTypeWithArrayField and
+ not isCLValue(this)
+ or
+ this.getUnconverted().(ArrayExpr).getArrayBase() instanceof TemporaryLifetimeArrayAccess
+ }
+}
+
+/**
+ * A field access on a temporary object that returns an array member.
+ */
+class TemporaryLifetimeArrayAccess extends FieldAccess {
+ // The temporary lifetime object which owns the array that is returned.
+ TemporaryLifetimeExpr temporary;
+
+ TemporaryLifetimeArrayAccess() {
+ getQualifier().getUnconverted() = temporary and
+ getUnspecifiedType() instanceof ArrayType
+ }
+
+ /**
+ * Get the temporary lifetime object which own the array that is returned.
+ */
+ Expr getTemporary() { result = temporary }
+}
diff --git a/cpp/common/src/codingstandards/cpp/lifetimes/lifetimeprofile/LifetimeProfile.qll b/cpp/common/src/codingstandards/cpp/lifetimes/lifetimeprofile/LifetimeProfile.qll
index 7990f50216..354dccdc56 100644
--- a/cpp/common/src/codingstandards/cpp/lifetimes/lifetimeprofile/LifetimeProfile.qll
+++ b/cpp/common/src/codingstandards/cpp/lifetimes/lifetimeprofile/LifetimeProfile.qll
@@ -1,5 +1,5 @@
import cpp
-private import codingstandards.cpp.dataflow.DataFlow
+private import semmle.code.cpp.dataflow.DataFlow
private import semmle.code.cpp.controlflow.Nullness
private import codingstandards.cpp.Dereferenced
private import codingstandards.cpp.Expr
diff --git a/cpp/common/src/codingstandards/cpp/resources/ResourceManagement.qll b/cpp/common/src/codingstandards/cpp/resources/ResourceManagement.qll
index 0798575495..db65dd4920 100644
--- a/cpp/common/src/codingstandards/cpp/resources/ResourceManagement.qll
+++ b/cpp/common/src/codingstandards/cpp/resources/ResourceManagement.qll
@@ -1,5 +1,5 @@
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
/**
* The `ResourceAcquisitionExpr` abstract class models resource
diff --git a/cpp/common/src/codingstandards/cpp/rules/accessofnonexistingmemberthroughpointertomember/AccessOfNonExistingMemberThroughPointerToMember.qll b/cpp/common/src/codingstandards/cpp/rules/accessofnonexistingmemberthroughpointertomember/AccessOfNonExistingMemberThroughPointerToMember.qll
index 138c0a89b5..ac135386f3 100644
--- a/cpp/common/src/codingstandards/cpp/rules/accessofnonexistingmemberthroughpointertomember/AccessOfNonExistingMemberThroughPointerToMember.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/accessofnonexistingmemberthroughpointertomember/AccessOfNonExistingMemberThroughPointerToMember.qll
@@ -7,7 +7,7 @@ import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.Expr
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
abstract class AccessOfNonExistingMemberThroughPointerToMemberSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/accessofundefinedmemberthroughnullpointer/AccessOfUndefinedMemberThroughNullPointer.qll b/cpp/common/src/codingstandards/cpp/rules/accessofundefinedmemberthroughnullpointer/AccessOfUndefinedMemberThroughNullPointer.qll
index ab8659efd8..e0fb382008 100644
--- a/cpp/common/src/codingstandards/cpp/rules/accessofundefinedmemberthroughnullpointer/AccessOfUndefinedMemberThroughNullPointer.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/accessofundefinedmemberthroughnullpointer/AccessOfUndefinedMemberThroughNullPointer.qll
@@ -7,7 +7,7 @@ import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.Nullness
import codingstandards.cpp.Expr
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import NullPointerToPointerMemberExpressionFlow::PathGraph
abstract class AccessOfUndefinedMemberThroughNullPointerSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/accessofundefinedmemberthroughuninitializedstaticpointer/AccessOfUndefinedMemberThroughUninitializedStaticPointer.qll b/cpp/common/src/codingstandards/cpp/rules/accessofundefinedmemberthroughuninitializedstaticpointer/AccessOfUndefinedMemberThroughUninitializedStaticPointer.qll
index ca1e2a4282..0271d7c6e7 100644
--- a/cpp/common/src/codingstandards/cpp/rules/accessofundefinedmemberthroughuninitializedstaticpointer/AccessOfUndefinedMemberThroughUninitializedStaticPointer.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/accessofundefinedmemberthroughuninitializedstaticpointer/AccessOfUndefinedMemberThroughUninitializedStaticPointer.qll
@@ -12,7 +12,7 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.EncapsulatingFunctions
diff --git a/cpp/common/src/codingstandards/cpp/rules/addressofoperatoroverloaded/AddressOfOperatorOverloaded.qll b/cpp/common/src/codingstandards/cpp/rules/addressofoperatoroverloaded/AddressOfOperatorOverloaded.qll
new file mode 100644
index 0000000000..603a75bd01
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/addressofoperatoroverloaded/AddressOfOperatorOverloaded.qll
@@ -0,0 +1,17 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The address-of operator shall not be overloaded.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Operator
+
+abstract class AddressOfOperatorOverloadedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof AddressOfOperatorOverloadedSharedQuery }
+
+query predicate problems(UnaryAddressOfOperator e, string message) {
+ not isExcluded(e, getQuery()) and message = "The unary & operator overloaded."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.qll b/cpp/common/src/codingstandards/cpp/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.qll
new file mode 100644
index 0000000000..da17706f54
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.qll
@@ -0,0 +1,34 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The argument to a mixed-use macro parameter shall not be subject to further
+ * expansion.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Macro
+
+abstract class AMixedUseMacroArgumentSubjectToExpansionSharedQuery extends Query { }
+
+Query getQuery() { result instanceof AMixedUseMacroArgumentSubjectToExpansionSharedQuery }
+
+query predicate problems(FunctionLikeMacro m, string message) {
+ exists(MacroInvocation mi, int i, string expanded, string param |
+ not isExcluded(m, getQuery()) and
+ mi = m.getAnInvocation() and
+ param = m.getParameter(i) and
+ (
+ exists(TokenPastingOperator op | op.getMacro() = m and op.getOperand() = param)
+ or
+ exists(StringizingOperator op | op.getMacro() = m and op.getOperand() = param)
+ ) and
+ // An expansion that is equal to "" means the expansion is not used and is optimized away by EDG. This happens when the expanded argument is an operand to `#` or `##`.
+ // This check ensure there is an expansion that is used.
+ expanded = mi.getExpandedArgument(i) and
+ not expanded = "" and
+ not mi.getUnexpandedArgument(i) = mi.getExpandedArgument(i) and
+ message =
+ "Macro " + m.getName() + " contains use of parameter " + param + " used in multiple contexts."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/arraypassedasfunctionargumentdecaytoapointer/ArrayPassedAsFunctionArgumentDecayToAPointer.qll b/cpp/common/src/codingstandards/cpp/rules/arraypassedasfunctionargumentdecaytoapointer/ArrayPassedAsFunctionArgumentDecayToAPointer.qll
new file mode 100644
index 0000000000..b7ec4917bd
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/arraypassedasfunctionargumentdecaytoapointer/ArrayPassedAsFunctionArgumentDecayToAPointer.qll
@@ -0,0 +1,46 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * An array passed as a function argument shall not decay to a pointer.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class ArrayPassedAsFunctionArgumentDecayToAPointerSharedQuery extends Query { }
+
+Query getQuery() { result instanceof ArrayPassedAsFunctionArgumentDecayToAPointerSharedQuery }
+
+predicate arrayToPointerDecay(Access ae, Parameter p) {
+ (
+ p.getType() instanceof PointerType and
+ // exclude parameters of void* because then it assumed the caller can pass in dimensions through other means.
+ // examples are uses in `memset` or `memcpy`
+ not p.getType() instanceof VoidPointerType
+ or
+ p.getType() instanceof ArrayType
+ ) and
+ ae.getType() instanceof ArrayType and
+ // exclude char[] arrays because we assume that we can determine its dimension by looking for a NULL byte.
+ not ae.getType().(ArrayType).getBaseType() instanceof CharType
+}
+
+query predicate problems(
+ Element e, string message, Variable array, string array_string, Parameter decayedArray,
+ string decayedArray_string, Function f, string f_string
+) {
+ exists(FunctionCall fc, VariableAccess arrayAccess, int i |
+ not isExcluded(e, getQuery()) and
+ arrayAccess = array.getAnAccess() and
+ f = fc.getTarget() and
+ arrayAccess = fc.getArgument(i) and
+ decayedArray = f.getParameter(i) and
+ arrayToPointerDecay(arrayAccess, decayedArray) and
+ not arrayAccess.isAffectedByMacro() and
+ e = fc.getArgument(i) and
+ array_string = array.getName() and
+ decayedArray_string = decayedArray.getName() and
+ f_string = f.getName() and
+ message = "The array $@ decays to the pointer $@ when passed as an argument to the function $@."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/asmdeclarationused/AsmDeclarationUsed.qll b/cpp/common/src/codingstandards/cpp/rules/asmdeclarationused/AsmDeclarationUsed.qll
new file mode 100644
index 0000000000..c6748683da
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/asmdeclarationused/AsmDeclarationUsed.qll
@@ -0,0 +1,16 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The asm declaration shall not be used.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class AsmDeclarationUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof AsmDeclarationUsedSharedQuery }
+
+query predicate problems(AsmStmt e, string message) {
+ not isExcluded(e, getQuery()) and message = "Use of asm declaration"
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.qll b/cpp/common/src/codingstandards/cpp/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.qll
new file mode 100644
index 0000000000..295e346913
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.qll
@@ -0,0 +1,24 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The library functions atof, atoi, atol and atoll from shall not be used.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+private string atoi() { result = ["atof", "atoi", "atol", "atoll"] }
+
+abstract class AtofAtoiAtolAndAtollUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof AtofAtoiAtolAndAtollUsedSharedQuery }
+
+query predicate problems(FunctionCall fc, string message) {
+ exists(Function f |
+ not isExcluded(fc, getQuery()) and
+ f = fc.getTarget() and
+ f.getName() = atoi() and
+ f.getFile().getBaseName() = "stdlib.h" and
+ message = "Call to banned function " + f.getName() + "."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/backslashcharactermisuse/BackslashCharacterMisuse.qll b/cpp/common/src/codingstandards/cpp/rules/backslashcharactermisuse/BackslashCharacterMisuse.qll
new file mode 100644
index 0000000000..34cb93fb39
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/backslashcharactermisuse/BackslashCharacterMisuse.qll
@@ -0,0 +1,23 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * In character literals and non-raw string literals, \ shall only be used to form a
+ * defined escape sequence or universal character name.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class BackslashCharacterMisuseSharedQuery extends Query { }
+
+Query getQuery() { result instanceof BackslashCharacterMisuseSharedQuery }
+
+query predicate problems(StringLiteral l, string message) {
+ exists(string es |
+ not isExcluded(l, getQuery()) and
+ es = l.getANonStandardEscapeSequence(_, _) and
+ // Exclude universal-character-names, which begin with \u or \U
+ not es.toLowerCase().matches("\\u") and
+ message = "This literal contains the non-standard escape sequence " + es + "."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/basicstringmaynotbenullterminated/BasicStringMayNotBeNullTerminated.qll b/cpp/common/src/codingstandards/cpp/rules/basicstringmaynotbenullterminated/BasicStringMayNotBeNullTerminated.qll
index cea798ae11..e27f09fd98 100644
--- a/cpp/common/src/codingstandards/cpp/rules/basicstringmaynotbenullterminated/BasicStringMayNotBeNullTerminated.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/basicstringmaynotbenullterminated/BasicStringMayNotBeNullTerminated.qll
@@ -8,8 +8,8 @@ import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import semmle.code.cpp.security.BufferWrite
import semmle.code.cpp.commons.Buffer
-import codingstandards.cpp.dataflow.DataFlow
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.TaintTracking
import codingstandards.cpp.PossiblyUnsafeStringOperation
abstract class BasicStringMayNotBeNullTerminatedSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.qll b/cpp/common/src/codingstandards/cpp/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.qll
new file mode 100644
index 0000000000..27048b2d25
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.qll
@@ -0,0 +1,41 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A bit-field shall have an appropriate type.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Compiler
+
+abstract class BitFieldShallHaveAnAppropriateTypeSharedQuery extends Query { }
+
+Query getQuery() { result instanceof BitFieldShallHaveAnAppropriateTypeSharedQuery }
+
+Type getSupportedBitFieldType(Compiler compiler) {
+ compiler instanceof UnsupportedCompiler and
+ (
+ result instanceof IntType and
+ (
+ result.(IntegralType).isExplicitlySigned() or
+ result.(IntegralType).isExplicitlyUnsigned()
+ )
+ or
+ result instanceof BoolType
+ )
+ or
+ (compiler instanceof Gcc or compiler instanceof Clang) and
+ (
+ result instanceof IntegralOrEnumType
+ or
+ result instanceof BoolType
+ )
+}
+
+query predicate problems(BitField bitField, string message) {
+ not isExcluded(bitField, getQuery()) and
+ /* A violation would neither be an appropriate primitive type nor an appropriate typedef. */
+ not getSupportedBitFieldType(getCompiler(bitField.getFile())) =
+ bitField.getType().resolveTypedefs() and
+ message = "Bit-field '" + bitField + "' is declared on type '" + bitField.getType() + "'."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/builtinunaryoperatorappliedtounsignedexpression/BuiltInUnaryOperatorAppliedToUnsignedExpression.qll b/cpp/common/src/codingstandards/cpp/rules/builtinunaryoperatorappliedtounsignedexpression/BuiltInUnaryOperatorAppliedToUnsignedExpression.qll
new file mode 100644
index 0000000000..0e516a43ec
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/builtinunaryoperatorappliedtounsignedexpression/BuiltInUnaryOperatorAppliedToUnsignedExpression.qll
@@ -0,0 +1,25 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The built-in unary - operator should not be applied to an expression of unsigned
+ * type.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class BuiltInUnaryOperatorAppliedToUnsignedExpressionSharedQuery extends Query { }
+
+Query getQuery() { result instanceof BuiltInUnaryOperatorAppliedToUnsignedExpressionSharedQuery }
+
+query predicate problems(Element e, string message) {
+ exists(UnaryMinusExpr ex, IntegralType t |
+ t = ex.getOperand().getExplicitlyConverted().getType().getUnderlyingType() and
+ t.isUnsigned() and
+ not ex.isAffectedByMacro() and
+ e = ex.getOperand() and
+ not isExcluded(e, getQuery()) and
+ message =
+ "The unary minus operator shall not be applied to an expression whose underlying type is unsigned."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.qll b/cpp/common/src/codingstandards/cpp/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.qll
new file mode 100644
index 0000000000..48fa1f0c86
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.qll
@@ -0,0 +1,20 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Casts shall not be performed between a pointer to function and any other type.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class CastsBetweenAPointerToFunctionAndAnyOtherTypeSharedQuery extends Query { }
+
+Query getQuery() { result instanceof CastsBetweenAPointerToFunctionAndAnyOtherTypeSharedQuery }
+
+query predicate problems(Cast c, string message) {
+ not isExcluded(c, getQuery()) and
+ not c.isImplicit() and
+ not c.isAffectedByMacro() and
+ c.getExpr().getType() instanceof FunctionPointerType and
+ message = "Cast converting a pointer to function."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/charactersequenceusedwithinacstylecomment/CharacterSequenceUsedWithinACStyleComment.qll b/cpp/common/src/codingstandards/cpp/rules/charactersequenceusedwithinacstylecomment/CharacterSequenceUsedWithinACStyleComment.qll
new file mode 100644
index 0000000000..676b2d3030
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/charactersequenceusedwithinacstylecomment/CharacterSequenceUsedWithinACStyleComment.qll
@@ -0,0 +1,18 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The presence of a nested /* comment can indicate accidentally commented out code.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class CharacterSequenceUsedWithinACStyleCommentSharedQuery extends Query { }
+
+Query getQuery() { result instanceof CharacterSequenceUsedWithinACStyleCommentSharedQuery }
+
+query predicate problems(CStyleComment c, string message) {
+ not isExcluded(c, getQuery()) and
+ exists(c.getContents().regexpFind("./\\*", _, _)) and
+ message = "C-style /* comment includes nested /*."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/commaoperatorused/CommaOperatorUsed.qll b/cpp/common/src/codingstandards/cpp/rules/commaoperatorused/CommaOperatorUsed.qll
index a6a80969b8..6985f7fc1e 100644
--- a/cpp/common/src/codingstandards/cpp/rules/commaoperatorused/CommaOperatorUsed.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/commaoperatorused/CommaOperatorUsed.qll
@@ -1,5 +1,6 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * The comma operator shall not be used.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/constlikereturnvalue/ConstLikeReturnValue.qll b/cpp/common/src/codingstandards/cpp/rules/constlikereturnvalue/ConstLikeReturnValue.qll
index f4636b6b13..a366991714 100644
--- a/cpp/common/src/codingstandards/cpp/rules/constlikereturnvalue/ConstLikeReturnValue.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/constlikereturnvalue/ConstLikeReturnValue.qll
@@ -1,11 +1,14 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * 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.
*/
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import DFFlow::PathGraph
abstract class ConstLikeReturnValueSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/containeraccesswithoutrangecheck/ContainerAccessWithoutRangeCheck.qll b/cpp/common/src/codingstandards/cpp/rules/containeraccesswithoutrangecheck/ContainerAccessWithoutRangeCheck.qll
index 71e18a5c05..fcf20afbc0 100644
--- a/cpp/common/src/codingstandards/cpp/rules/containeraccesswithoutrangecheck/ContainerAccessWithoutRangeCheck.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/containeraccesswithoutrangecheck/ContainerAccessWithoutRangeCheck.qll
@@ -12,7 +12,7 @@ import codingstandards.cpp.Operator
import semmle.code.cpp.controlflow.Guards
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
abstract class ContainerAccessWithoutRangeCheckSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/copyandmoveassignmentsshallhandleselfassignment/CopyAndMoveAssignmentsShallHandleSelfAssignment.qll b/cpp/common/src/codingstandards/cpp/rules/copyandmoveassignmentsshallhandleselfassignment/CopyAndMoveAssignmentsShallHandleSelfAssignment.qll
new file mode 100644
index 0000000000..ae87176517
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/copyandmoveassignmentsshallhandleselfassignment/CopyAndMoveAssignmentsShallHandleSelfAssignment.qll
@@ -0,0 +1,53 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * User-provided copy assignment operators and move assignment operators shall handle
+ * self-assignment.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Operator
+
+abstract class CopyAndMoveAssignmentsShallHandleSelfAssignmentSharedQuery extends Query { }
+
+Query getQuery() { result instanceof CopyAndMoveAssignmentsShallHandleSelfAssignmentSharedQuery }
+
+predicate isUserCopyOrUserMove(Operator o) {
+ o instanceof UserCopyOperator or
+ o instanceof UserMoveOperator
+}
+
+predicate callsStdSwap(Function f) {
+ exists(FunctionCall fc |
+ fc.getTarget().hasGlobalOrStdName("swap") and
+ fc.getEnclosingFunction() = f
+ )
+}
+
+predicate callsNoExceptSwap(Operator o) {
+ exists(Function f, FunctionCall fc |
+ callsStdSwap(f) and
+ fc.getEnclosingFunction() = o and
+ fc.getTarget() = f
+ )
+}
+
+predicate checksForSelfAssignment(Operator o) {
+ exists(IfStmt i, ComparisonOperation c |
+ i.getEnclosingFunction() = o and
+ i.getCondition() = c and
+ (
+ c.getLeftOperand().toString() = "this" or
+ c.getRightOperand().toString() = "this"
+ )
+ )
+}
+
+query predicate problems(Operator o, string message) {
+ not isExcluded(o, getQuery()) and
+ isUserCopyOrUserMove(o) and
+ not callsNoExceptSwap(o) and
+ not checksForSelfAssignment(o) and
+ message = "User defined copy or user defined move does not handle self-assignment correctly."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/csignalfunctionsused/CsignalFunctionsUsed.qll b/cpp/common/src/codingstandards/cpp/rules/csignalfunctionsused/CsignalFunctionsUsed.qll
new file mode 100644
index 0000000000..15c71018f9
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/csignalfunctionsused/CsignalFunctionsUsed.qll
@@ -0,0 +1,21 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Signal handling contains implementation-defined and undefined behaviour.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class CsignalFunctionsUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof CsignalFunctionsUsedSharedQuery }
+
+query predicate problems(FunctionCall fc, string message) {
+ exists(Function f |
+ not isExcluded(fc, getQuery()) and
+ f = fc.getTarget() and
+ f.hasGlobalOrStdName(["signal", "raise"]) and
+ message = "Use of function '" + f.getQualifiedName() + "'."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/csignaltypesused/CsignalTypesUsed.qll b/cpp/common/src/codingstandards/cpp/rules/csignaltypesused/CsignalTypesUsed.qll
new file mode 100644
index 0000000000..21de1066f6
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/csignaltypesused/CsignalTypesUsed.qll
@@ -0,0 +1,21 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Signal handling contains implementation-defined and undefined behaviour.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class CsignalTypesUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof CsignalTypesUsedSharedQuery }
+
+query predicate problems(TypeMention tm, string message) {
+ exists(UserType ut |
+ not isExcluded(tm, getQuery()) and
+ ut = tm.getMentionedType() and
+ ut.hasGlobalOrStdName("sig_atomic_t") and
+ message = "Use of type '" + ut.getQualifiedName() + "'."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/cstdiofunctionsused/CstdioFunctionsUsed.qll b/cpp/common/src/codingstandards/cpp/rules/cstdiofunctionsused/CstdioFunctionsUsed.qll
new file mode 100644
index 0000000000..284997dc19
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/cstdiofunctionsused/CstdioFunctionsUsed.qll
@@ -0,0 +1,38 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Streams and file I/O have a large number of unspecified, undefined, and
+ * implementation-defined behaviours associated with them.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class CstdioFunctionsUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof CstdioFunctionsUsedSharedQuery }
+
+query predicate problems(FunctionCall fc, string message) {
+ exists(Function f |
+ not isExcluded(fc, getQuery()) and
+ f = fc.getTarget() and
+ f.hasGlobalOrStdName([
+ "remove", "rename", "tmpfile", "tmpnam",
+ // File access
+ "fclose", "fflush", "fopen", "freopen", "setbuf", "setvbuf",
+ // Formatted input/output
+ "fprintf", "fscanf", "printf", "scanf", "snprintf", "sprintf", "sscanf", "vfprintf",
+ "vfscanf", "vprintf", "vscanf", "vsnprintf", "vsprintf", "vsscanf",
+ // Character input/output
+ "fgetc", "fgets", "fputc", "fputs", "getc", "getchar", "gets", "putc", "putchar", "puts",
+ "ungetc",
+ // Direct input/output
+ "fread", "fwrite",
+ // File positioning
+ "fgetpos", "fseek", "fsetpos", "ftell", "rewind",
+ // Error handling
+ "clearerr", "feof", "ferror", "perror"
+ ]) and
+ message = "Use of function '" + f.getQualifiedName() + "'."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/cstdiomacrosused/CstdioMacrosUsed.qll b/cpp/common/src/codingstandards/cpp/rules/cstdiomacrosused/CstdioMacrosUsed.qll
new file mode 100644
index 0000000000..d610b6a166
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/cstdiomacrosused/CstdioMacrosUsed.qll
@@ -0,0 +1,22 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Streams and file I/O have a large number of unspecified, undefined, and
+ * implementation-defined behaviours associated with them.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class CstdioMacrosUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof CstdioMacrosUsedSharedQuery }
+
+query predicate problems(MacroInvocation mi, string message) {
+ not isExcluded(mi, getQuery()) and
+ mi.getMacroName() in [
+ "BUFSIZ", "EOF", "FILENAME_MAX", "FOPEN_MAX", "L_tmpnam", "TMP_MAX", "_IOFBF", "IOLBF",
+ "_IONBF", "SEEK_CUR", "SEEK_END", "SEEK_SET"
+ ] and
+ message = "Use of macro '" + mi.getMacroName() + "'."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/cstdiotypesused/CstdioTypesUsed.qll b/cpp/common/src/codingstandards/cpp/rules/cstdiotypesused/CstdioTypesUsed.qll
new file mode 100644
index 0000000000..d517d78c8b
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/cstdiotypesused/CstdioTypesUsed.qll
@@ -0,0 +1,27 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Streams and file I/O have a large number of unspecified, undefined, and
+ * implementation-defined behaviours associated with them.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class CstdioTypesUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof CstdioTypesUsedSharedQuery }
+
+query predicate problems(TypeMention tm, string message) {
+ exists(UserType ut |
+ not isExcluded(tm, getQuery()) and
+ ut = tm.getMentionedType() and
+ ut.hasGlobalOrStdName(["FILE", "fpos_t"]) and
+ // Not in the standard library
+ exists(tm.getFile().getRelativePath()) and
+ // Not in our tests copy of the standard library
+ not tm.getFile().getRelativePath() =
+ ["includes/standard-library/stddef.h", "includes/standard-library/stdio.h"] and
+ message = "Use of type '" + ut.getQualifiedName() + "'."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenmovinglambdaobject/DanglingCaptureWhenMovingLambdaObject.qll b/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenmovinglambdaobject/DanglingCaptureWhenMovingLambdaObject.qll
index ab2b067279..902d0ecf1f 100644
--- a/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenmovinglambdaobject/DanglingCaptureWhenMovingLambdaObject.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenmovinglambdaobject/DanglingCaptureWhenMovingLambdaObject.qll
@@ -5,7 +5,7 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.Expr
diff --git a/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenreturninglambdaobject/DanglingCaptureWhenReturningLambdaObject.qll b/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenreturninglambdaobject/DanglingCaptureWhenReturningLambdaObject.qll
index c35b723ff3..4ab01520f6 100644
--- a/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenreturninglambdaobject/DanglingCaptureWhenReturningLambdaObject.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenreturninglambdaobject/DanglingCaptureWhenReturningLambdaObject.qll
@@ -5,7 +5,7 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
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/definitionnotconsideredforunqualifiedlookup/DefinitionNotConsideredForUnqualifiedLookup.qll b/cpp/common/src/codingstandards/cpp/rules/definitionnotconsideredforunqualifiedlookup/DefinitionNotConsideredForUnqualifiedLookup.qll
new file mode 100644
index 0000000000..c2b857d600
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/definitionnotconsideredforunqualifiedlookup/DefinitionNotConsideredForUnqualifiedLookup.qll
@@ -0,0 +1,70 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A using declaration that makes a symbol available for unqualified lookup does not
+ * included definitions defined after the using declaration which can result in
+ * unexpected behavior.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class DefinitionNotConsideredForUnqualifiedLookupSharedQuery extends Query { }
+
+Query getQuery() { result instanceof DefinitionNotConsideredForUnqualifiedLookupSharedQuery }
+
+/**
+ * Holds if `functionDecl` is a possible intended target of the `usingDecl`.
+ */
+pragma[noinline]
+predicate isPossibleIntendedTarget(
+ FunctionDeclarationEntry functionDecl, UsingDeclarationEntry usingDecl
+) {
+ // Extracted to improve the join order. With this approach, we first compute a set of using
+ // declarations and a set of possible intended targets
+ functionDecl.getDeclaration().isTopLevel() and
+ functionDecl.getDeclaration().getQualifiedName() = usingDecl.getDeclaration().getQualifiedName() and
+ functionDecl.getDeclaration().getNamespace().getParentNamespace*() = usingDecl.getParentScope()
+}
+
+/**
+ * Holds if `functionDecl` is a possible intended target of the `usingDecl`, and they exist at the
+ * given locations.
+ */
+pragma[noinline]
+predicate isPossibleIntendedTargetLocation(
+ FunctionDeclarationEntry functionDecl, UsingDeclarationEntry usingDecl, File usingsFile,
+ File unavailableFile, int usingsStartLine, int unavailableStartLine
+) {
+ // Extracted to improve the join order. With this approach, we take the set of possible intended
+ // targets computed in isPossibleIntendedTargets, and compute the files and start lines.
+ // This helps avoid the join order preferred by the optimiser if this is all written directly in
+ // the from-where-select, where it will eagerly join:
+ //
+ // usingDeclarationEntries -> enclosing files -> all other elements in those files
+ //
+ // which is expensive when there are a lot of files with using declarations
+ isPossibleIntendedTarget(functionDecl, usingDecl) and
+ usingsFile = usingDecl.getFile() and
+ unavailableFile = functionDecl.getFile() and
+ usingsStartLine = usingDecl.getLocation().getStartLine() and
+ unavailableStartLine = functionDecl.getLocation().getStartLine()
+}
+
+query predicate problems(
+ FunctionDeclarationEntry unavailableDecl, string message, UsingDeclarationEntry usingDecl,
+ string usingDecl_string
+) {
+ not isExcluded(unavailableDecl, getQuery()) and
+ exists(File usingsFile, File unavailableFile, int usingsStartLine, int unavailableStartLine |
+ isPossibleIntendedTargetLocation(unavailableDecl, usingDecl, usingsFile, unavailableFile,
+ usingsStartLine, unavailableStartLine) and
+ // An approximation of order where we want the using to preceed the new declaration.
+ usingsFile = unavailableFile and
+ usingsStartLine < unavailableStartLine
+ ) and
+ message =
+ "Definition for '" + unavailableDecl.getName() +
+ "' is not available for unqualified lookup because it is declared after $@" and
+ usingDecl_string = "using-declaration"
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/dereferenceofnullpointer/DereferenceOfNullPointer.qll b/cpp/common/src/codingstandards/cpp/rules/dereferenceofnullpointer/DereferenceOfNullPointer.qll
index 5e3328cb63..950b14df3d 100644
--- a/cpp/common/src/codingstandards/cpp/rules/dereferenceofnullpointer/DereferenceOfNullPointer.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/dereferenceofnullpointer/DereferenceOfNullPointer.qll
@@ -1,5 +1,6 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * Dereferencing a NULL pointer leads to undefined behavior.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/differentidentifiersnottypographicallyunambiguous/DifferentIdentifiersNotTypographicallyUnambiguous.qll b/cpp/common/src/codingstandards/cpp/rules/differentidentifiersnottypographicallyunambiguous/DifferentIdentifiersNotTypographicallyUnambiguous.qll
index 87a4580ab3..5c7475883e 100644
--- a/cpp/common/src/codingstandards/cpp/rules/differentidentifiersnottypographicallyunambiguous/DifferentIdentifiersNotTypographicallyUnambiguous.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/differentidentifiersnottypographicallyunambiguous/DifferentIdentifiersNotTypographicallyUnambiguous.qll
@@ -46,16 +46,32 @@ string step1(string s) {
string step2(string s) { s = "m_" and result = "rn" }
-predicate violation(UserVariable v1, UserVariable v2) {
- v2 = getPotentialScopeOfVariable(v1) and
+class VariableName extends string {
+ VariableName() { exists(UserVariable uv | uv.getName() = this) }
+
+ string getCanon() {
+ result =
+ this.toLowerCase()
+ .replaceAll("_", "")
+ .regexpReplaceAll("[il]", "1")
+ .replaceAll("s", "5")
+ .replaceAll("z", "2")
+ .replaceAll("b", "8")
+ .replaceAll("h", "n")
+ .replaceAll("m", "rn")
+ .replaceAll("o", "0")
+ }
+}
+
+predicate isConflictingName(VariableName name1, VariableName name2) {
exists(string s1, string s2 |
// over-approximate a match, because it is cheaper to compute
- getCanon(v1) = getCanon(v2) and
- v1 != v2 and
- not v1.getName() = v2.getName() and
+ name1.getCanon() = name2.getCanon() and
+ // Exclude identical names
+ not name1 = name2 and
// expand 'm' to 'm_' to match either 'm_' or 'rn'
- s1 = v1.getName().replaceAll("_", "").replaceAll("m", "m_") and
- s2 = v2.getName().replaceAll("_", "").replaceAll("m", "m_") and
+ s1 = name1.replaceAll("_", "").replaceAll("m", "m_") and
+ s2 = name2.replaceAll("_", "").replaceAll("m", "m_") and
// at this point the strings must have equal length, the substitutions do not expand nor contract the string
s1.length() = s2.length() and
forall(int i | i in [0 .. s1.length() - 1] |
@@ -87,6 +103,23 @@ predicate violation(UserVariable v1, UserVariable v2) {
)
}
+predicate violation(UserVariable v1, UserVariable v2) {
+ exists(string name1, string name2 |
+ isConflictingName(name1, name2) and
+ exists(Scope parentScope, Scope childScope |
+ parentScope.getVariable(name1) = v1 and
+ childScope.getVariable(name2) = v2
+ |
+ childScope.getStrictParent+() = parentScope
+ or
+ // Disambiguate names in the same scope by name order
+ childScope = parentScope and
+ name1 < name2
+ ) and
+ inSameTranslationUnitLate(v1.getFile(), v2.getFile())
+ )
+}
+
query predicate problems(
UserVariable v, string message, UserVariable v1, string v1Description, UserVariable v2,
string v2Description
diff --git a/cpp/common/src/codingstandards/cpp/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.qll b/cpp/common/src/codingstandards/cpp/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.qll
index 3d84366d9a..83266ed524 100644
--- a/cpp/common/src/codingstandards/cpp/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/donotaccessaclosedfile/DoNotAccessAClosedFile.qll
@@ -6,7 +6,7 @@
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.standardlibrary.FileAccess
import semmle.code.cpp.controlflow.SubBasicBlocks
diff --git a/cpp/common/src/codingstandards/cpp/rules/donotallowamutextogooutofscopewhilelocked/DoNotAllowAMutexToGoOutOfScopeWhileLocked.qll b/cpp/common/src/codingstandards/cpp/rules/donotallowamutextogooutofscopewhilelocked/DoNotAllowAMutexToGoOutOfScopeWhileLocked.qll
index 8a8155f971..759d235eb4 100644
--- a/cpp/common/src/codingstandards/cpp/rules/donotallowamutextogooutofscopewhilelocked/DoNotAllowAMutexToGoOutOfScopeWhileLocked.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/donotallowamutextogooutofscopewhilelocked/DoNotAllowAMutexToGoOutOfScopeWhileLocked.qll
@@ -17,7 +17,7 @@ import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.Concurrency
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
abstract class DoNotAllowAMutexToGoOutOfScopeWhileLockedSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/donotdestroyamutexwhileitislocked/DoNotDestroyAMutexWhileItIsLocked.qll b/cpp/common/src/codingstandards/cpp/rules/donotdestroyamutexwhileitislocked/DoNotDestroyAMutexWhileItIsLocked.qll
index 46335c3d94..d77ae8cf39 100644
--- a/cpp/common/src/codingstandards/cpp/rules/donotdestroyamutexwhileitislocked/DoNotDestroyAMutexWhileItIsLocked.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/donotdestroyamutexwhileitislocked/DoNotDestroyAMutexWhileItIsLocked.qll
@@ -15,7 +15,7 @@ import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.Concurrency
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
abstract class DoNotDestroyAMutexWhileItIsLockedSharedQuery extends Query { }
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..9fa60198d1
--- /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 semmle.code.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/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.qll b/cpp/common/src/codingstandards/cpp/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.qll
index 0aa8d64feb..adb9785814 100644
--- a/cpp/common/src/codingstandards/cpp/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.qll
@@ -6,7 +6,7 @@
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import ArrayToPointerDiffOperandFlow::PathGraph
module ArrayToPointerDiffOperandConfig implements DataFlow::ConfigSig {
diff --git a/cpp/common/src/codingstandards/cpp/rules/donotusepointerarithmetictoaddressdifferentarrays/DoNotUsePointerArithmeticToAddressDifferentArrays.qll b/cpp/common/src/codingstandards/cpp/rules/donotusepointerarithmetictoaddressdifferentarrays/DoNotUsePointerArithmeticToAddressDifferentArrays.qll
index dd10b840c5..57b4eb0bfb 100644
--- a/cpp/common/src/codingstandards/cpp/rules/donotusepointerarithmetictoaddressdifferentarrays/DoNotUsePointerArithmeticToAddressDifferentArrays.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/donotusepointerarithmetictoaddressdifferentarrays/DoNotUsePointerArithmeticToAddressDifferentArrays.qll
@@ -7,7 +7,7 @@
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
abstract class DoNotUsePointerArithmeticToAddressDifferentArraysSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.qll b/cpp/common/src/codingstandards/cpp/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.qll
index 155ed1a7f4..aa8fa29bfd 100644
--- a/cpp/common/src/codingstandards/cpp/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/donotuserelationaloperatorswithdifferingarrays/DoNotUseRelationalOperatorsWithDifferingArrays.qll
@@ -7,7 +7,7 @@
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import ArrayToRelationalOperationOperandFlow::PathGraph
abstract class DoNotUseRelationalOperatorsWithDifferingArraysSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/donotusesetjmporlongjmpshared/DoNotUseSetjmpOrLongjmpShared.qll b/cpp/common/src/codingstandards/cpp/rules/donotusesetjmporlongjmpshared/DoNotUseSetjmpOrLongjmpShared.qll
index 6c39b62fec..1441b6ec97 100644
--- a/cpp/common/src/codingstandards/cpp/rules/donotusesetjmporlongjmpshared/DoNotUseSetjmpOrLongjmpShared.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/donotusesetjmporlongjmpshared/DoNotUseSetjmpOrLongjmpShared.qll
@@ -1,5 +1,6 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * The macro setjmp and function longjmp shall not be used.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/emptythrowonlywithinacatchhandler/EmptyThrowOnlyWithinACatchHandler.qll b/cpp/common/src/codingstandards/cpp/rules/emptythrowonlywithinacatchhandler/EmptyThrowOnlyWithinACatchHandler.qll
new file mode 100644
index 0000000000..3dba1a3aa3
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/emptythrowonlywithinacatchhandler/EmptyThrowOnlyWithinACatchHandler.qll
@@ -0,0 +1,19 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Empty throws with no currently handled exception can cause abrupt program
+ * termination.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class EmptyThrowOnlyWithinACatchHandlerSharedQuery extends Query { }
+
+Query getQuery() { result instanceof EmptyThrowOnlyWithinACatchHandlerSharedQuery }
+
+query predicate problems(ReThrowExpr re, string message) {
+ not isExcluded(re, getQuery()) and
+ not re.getEnclosingElement+() instanceof CatchBlock and
+ message = "Rethrow outside catch block"
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/enumerationnotdefinedwithanexplicitunderlyingtype/EnumerationNotDefinedWithAnExplicitUnderlyingType.qll b/cpp/common/src/codingstandards/cpp/rules/enumerationnotdefinedwithanexplicitunderlyingtype/EnumerationNotDefinedWithAnExplicitUnderlyingType.qll
new file mode 100644
index 0000000000..d014e7be86
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/enumerationnotdefinedwithanexplicitunderlyingtype/EnumerationNotDefinedWithAnExplicitUnderlyingType.qll
@@ -0,0 +1,18 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Although scoped enum will implicitly define an underlying type of int, the underlying base type of enumeration should always be explicitly defined with a type that will be large enough to store all enumerators.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class EnumerationNotDefinedWithAnExplicitUnderlyingTypeSharedQuery extends Query { }
+
+Query getQuery() { result instanceof EnumerationNotDefinedWithAnExplicitUnderlyingTypeSharedQuery }
+
+query predicate problems(Enum e, string message) {
+ not isExcluded(e, getQuery()) and
+ not e.hasExplicitUnderlyingType() and
+ message = "Base type of enumeration is not explicitly specified."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/exceptionobjecthavepointertype/ExceptionObjectHavePointerType.qll b/cpp/common/src/codingstandards/cpp/rules/exceptionobjecthavepointertype/ExceptionObjectHavePointerType.qll
new file mode 100644
index 0000000000..1989afbc8b
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/exceptionobjecthavepointertype/ExceptionObjectHavePointerType.qll
@@ -0,0 +1,20 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Throwing an exception of pointer type can lead to use-after-free or memory leak
+ * issues.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class ExceptionObjectHavePointerTypeSharedQuery extends Query { }
+
+Query getQuery() { result instanceof ExceptionObjectHavePointerTypeSharedQuery }
+
+query predicate problems(Expr thrownExpr, string message) {
+ not isExcluded(thrownExpr, getQuery()) and
+ thrownExpr = any(ThrowExpr te).getExpr() and
+ thrownExpr.getType().getUnspecifiedType() instanceof PointerType and
+ message = "Exception object with pointer type " + thrownExpr.getType() + " is thrown here."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/forwardingreferencesandforwardnotusedtogether/ForwardingReferencesAndForwardNotUsedTogether.qll b/cpp/common/src/codingstandards/cpp/rules/forwardingreferencesandforwardnotusedtogether/ForwardingReferencesAndForwardNotUsedTogether.qll
new file mode 100644
index 0000000000..960b4ba2b6
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/forwardingreferencesandforwardnotusedtogether/ForwardingReferencesAndForwardNotUsedTogether.qll
@@ -0,0 +1,28 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Forwarding references and std::forward shall be used together.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.standardlibrary.Utility
+
+abstract class ForwardingReferencesAndForwardNotUsedTogetherSharedQuery extends Query { }
+
+Query getQuery() { result instanceof ForwardingReferencesAndForwardNotUsedTogetherSharedQuery }
+
+query predicate problems(FunctionCall c, string message, Parameter a, string a_string) {
+ not isExcluded(c, getQuery()) and
+ a_string = a.getName() and
+ a.getAnAccess() = c.getAnArgument() and
+ (
+ c instanceof StdMoveCall and
+ a instanceof ForwardParameter and
+ message = "Function `std::forward` should be used for forwarding the forward reference $@."
+ or
+ c instanceof StdForwardCall and
+ a instanceof ConsumeParameter and
+ message = "Function `std::move` should be used for forwarding rvalue reference $@."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.qll b/cpp/common/src/codingstandards/cpp/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.qll
new file mode 100644
index 0000000000..73e4181640
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.qll
@@ -0,0 +1,31 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Function-like macros shall not be defined.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.IrreplaceableFunctionLikeMacro
+
+abstract class FunctionLikeMacrosDefinedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof FunctionLikeMacrosDefinedSharedQuery }
+
+predicate partOfConstantExpr(MacroInvocation i) {
+ exists(Expr e |
+ e.isConstant() and
+ not i.getExpr() = e and
+ i.getExpr().getParent+() = e
+ )
+}
+
+query predicate problems(FunctionLikeMacro m, string message) {
+ not isExcluded(m, getQuery()) and
+ not m instanceof IrreplaceableFunctionLikeMacro and
+ //macros can have empty body
+ not m.getBody().length() = 0 and
+ //function call not allowed in a constant expression (where constant expr is parent)
+ forall(MacroInvocation i | i = m.getAnInvocation() | not partOfConstantExpr(i)) and
+ message = "Macro used instead of a function."
+}
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/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.qll b/cpp/common/src/codingstandards/cpp/rules/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.qll
new file mode 100644
index 0000000000..87f27c134f
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.qll
@@ -0,0 +1,35 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Using recursive functions can lead to stack overflows and limit scalability and
+ * portability of the program.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class FunctionsCallThemselvesEitherDirectlyOrIndirectlySharedQuery extends Query { }
+
+Query getQuery() { result instanceof FunctionsCallThemselvesEitherDirectlyOrIndirectlySharedQuery }
+
+class RecursiveCall extends FunctionCall {
+ RecursiveCall() {
+ this.getTarget().calls*(this.getEnclosingFunction()) and
+ not this.getTarget().hasSpecifier("is_constexpr")
+ }
+}
+
+query predicate problems(FunctionCall fc, string message, Function f, string f_name) {
+ exists(RecursiveCall call |
+ not isExcluded(call, getQuery()) and
+ f = fc.getTarget() and
+ f_name = fc.getTarget().getName() and
+ fc.getTarget() = call.getTarget() and
+ if fc.getTarget() = fc.getEnclosingFunction()
+ then message = "This call directly invokes its containing function $@."
+ else
+ message =
+ "The function " + fc.getEnclosingFunction() +
+ " is indirectly recursive via this call to $@."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/functiontemplatesexplicitlyspecialized/FunctionTemplatesExplicitlySpecialized.qll b/cpp/common/src/codingstandards/cpp/rules/functiontemplatesexplicitlyspecialized/FunctionTemplatesExplicitlySpecialized.qll
new file mode 100644
index 0000000000..d0f98d233e
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/functiontemplatesexplicitlyspecialized/FunctionTemplatesExplicitlySpecialized.qll
@@ -0,0 +1,21 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Function templates shall not be explicitly specialized.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class FunctionTemplatesExplicitlySpecializedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof FunctionTemplatesExplicitlySpecializedSharedQuery }
+
+query predicate problems(
+ FunctionTemplateSpecialization f, string message, TemplateFunction tf, string tf_string
+) {
+ not isExcluded(f, getQuery()) and
+ tf = f.getPrimaryTemplate() and
+ tf_string = f.getPrimaryTemplate().getFile().getBaseName() and
+ message = "Specialization of function template from primary template located in $@."
+}
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/globalnamespacedeclarations/GlobalNamespaceDeclarations.qll b/cpp/common/src/codingstandards/cpp/rules/globalnamespacedeclarations/GlobalNamespaceDeclarations.qll
new file mode 100644
index 0000000000..285ccd909a
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/globalnamespacedeclarations/GlobalNamespaceDeclarations.qll
@@ -0,0 +1,23 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The only declarations in the global namespace should be main, namespace declarations
+ * and extern "C" declarations.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class GlobalNamespaceDeclarationsSharedQuery extends Query { }
+
+Query getQuery() { result instanceof GlobalNamespaceDeclarationsSharedQuery }
+
+query predicate problems(DeclarationEntry e, string message) {
+ not isExcluded(e, getQuery()) and
+ e.getDeclaration().getNamespace() instanceof GlobalNamespace and
+ e.getDeclaration().isTopLevel() and
+ not exists(Function f | f = e.getDeclaration() | f.hasGlobalName("main") or f.hasCLinkage()) and
+ message =
+ "Declaration " + e.getName() +
+ " is in the global namespace and is not a main, a namespace, or an extern \"C\" declaration."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/globalsizedoperatordeletenotdefined/GlobalSizedOperatorDeleteNotDefined.qll b/cpp/common/src/codingstandards/cpp/rules/globalsizedoperatordeletenotdefined/GlobalSizedOperatorDeleteNotDefined.qll
new file mode 100644
index 0000000000..c445c06253
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/globalsizedoperatordeletenotdefined/GlobalSizedOperatorDeleteNotDefined.qll
@@ -0,0 +1,24 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * If a project has the unsized version of operator 'delete' globally defined, then the
+ * sized version shall be defined.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.OperatorDelete
+
+abstract class GlobalSizedOperatorDeleteNotDefinedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof GlobalSizedOperatorDeleteNotDefinedSharedQuery }
+
+query predicate problems(OperatorDelete unsized_delete, string message) {
+ not isExcluded(unsized_delete, getQuery()) and
+ not unsized_delete.isSizeDelete() and
+ not exists(OperatorDelete od | unsized_delete.isNoThrowDelete() = od.isNoThrowDelete() |
+ od.isSizeDelete()
+ ) and
+ message =
+ "Unsized function '" + unsized_delete.getName() + "' defined globally without sized version."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/globalunsizedoperatordeletenotdefined/GlobalUnsizedOperatorDeleteNotDefined.qll b/cpp/common/src/codingstandards/cpp/rules/globalunsizedoperatordeletenotdefined/GlobalUnsizedOperatorDeleteNotDefined.qll
new file mode 100644
index 0000000000..b99887ee03
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/globalunsizedoperatordeletenotdefined/GlobalUnsizedOperatorDeleteNotDefined.qll
@@ -0,0 +1,24 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * If a project has the sized version of operator 'delete' globally defined, then the
+ * unsized version shall be defined.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.OperatorDelete
+
+abstract class GlobalUnsizedOperatorDeleteNotDefinedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof GlobalUnsizedOperatorDeleteNotDefinedSharedQuery }
+
+query predicate problems(OperatorDelete sized_delete, string message) {
+ not isExcluded(sized_delete, getQuery()) and
+ sized_delete.isSizeDelete() and
+ not exists(OperatorDelete od | sized_delete.isNoThrowDelete() = od.isNoThrowDelete() |
+ not od.isSizeDelete()
+ ) and
+ message =
+ "Sized function '" + sized_delete.getName() + "' defined globally without unsized version."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.qll b/cpp/common/src/codingstandards/cpp/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.qll
new file mode 100644
index 0000000000..f329fff12d
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.qll
@@ -0,0 +1,60 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A goto statement shall reference a label in a surrounding block.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class GotoReferenceALabelInSurroundingBlockSharedQuery extends Query { }
+
+Query getQuery() { result instanceof GotoReferenceALabelInSurroundingBlockSharedQuery }
+
+predicate isPartOfSwitch(Stmt goto) {
+ exists(SwitchStmt switch | switch.getStmt() = goto.getParent())
+}
+
+SwitchCase getSwitchCase(Stmt stmt) {
+ exists(int index, SwitchStmt switch |
+ getStmtInSwitch(switch, stmt, index) and getStmtInSwitch(switch, result, index - 1)
+ )
+ or
+ exists(int index, SwitchStmt switch, Stmt other |
+ getStmtInSwitch(switch, stmt, index) and
+ getStmtInSwitch(switch, other, index - 1) and
+ not other instanceof SwitchCase and
+ result = getSwitchCase(other)
+ )
+}
+
+predicate getStmtInSwitch(SwitchStmt switch, Stmt s, int index) {
+ switch.getStmt().(BlockStmt).getStmt(index) = s
+}
+
+int statementDepth(Stmt statement) {
+ statement.getParent() = statement.getEnclosingFunction().getBlock() and result = 1
+ or
+ statementDepth(statement.getParent()) + 1 = result
+}
+
+query predicate problems(GotoStmt goto, string message, Stmt target, string target_string) {
+ not isExcluded(goto, getQuery()) and
+ exists(int gotoDepth, int targetDepth |
+ goto.getTarget() = target and
+ gotoDepth = statementDepth(goto) and
+ targetDepth = statementDepth(target) and
+ targetDepth >= gotoDepth and
+ (
+ targetDepth = gotoDepth
+ implies
+ (
+ not isPartOfSwitch(goto) and not goto.getParent() = target.getParent()
+ or
+ isPartOfSwitch(goto) and not getSwitchCase(goto) = getSwitchCase(target)
+ )
+ ) and
+ target_string = "label" and
+ message = "The goto statement and its $@ are not declared or enclosed in the same block."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.qll b/cpp/common/src/codingstandards/cpp/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.qll
new file mode 100644
index 0000000000..6a13ea083c
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.qll
@@ -0,0 +1,18 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The goto statement shall not be used.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class GotoStatementShouldNotBeUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof GotoStatementShouldNotBeUsedSharedQuery }
+
+query predicate problems(Stmt s, string message) {
+ not isExcluded(s, getQuery()) and
+ (s instanceof GotoStmt or s instanceof ComputedGotoStmt) and
+ message = "Use of goto."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/handleallexceptionsduringstartup/HandleAllExceptionsDuringStartup.qll b/cpp/common/src/codingstandards/cpp/rules/handleallexceptionsduringstartup/HandleAllExceptionsDuringStartup.qll
index ccc0a23460..8d859f726d 100644
--- a/cpp/common/src/codingstandards/cpp/rules/handleallexceptionsduringstartup/HandleAllExceptionsDuringStartup.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/handleallexceptionsduringstartup/HandleAllExceptionsDuringStartup.qll
@@ -1,5 +1,6 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * Exceptions thrown before main begins executing cannot be caught.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/hiddeninheritednonoverridablememberfunction/HiddenInheritedNonOverridableMemberFunction.qll b/cpp/common/src/codingstandards/cpp/rules/hiddeninheritednonoverridablememberfunction/HiddenInheritedNonOverridableMemberFunction.qll
new file mode 100644
index 0000000000..1c371da20c
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/hiddeninheritednonoverridablememberfunction/HiddenInheritedNonOverridableMemberFunction.qll
@@ -0,0 +1,58 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A non-overriding member function definition that hides an inherited member function
+ * can result in unexpected behavior.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Class
+
+abstract class HiddenInheritedNonOverridableMemberFunctionSharedQuery extends Query { }
+
+Query getQuery() { result instanceof HiddenInheritedNonOverridableMemberFunctionSharedQuery }
+
+/**
+ * Holds if the class has a non-virtual member function with the given name.
+ */
+pragma[noinline, nomagic]
+predicate hasNonVirtualMemberFunction(Class clazz, MemberFunction mf, string name) {
+ mf.getDeclaringType() = clazz and
+ mf.getName() = name and
+ not mf.isVirtual() and
+ // Exclude private member functions, which cannot be inherited.
+ not mf.isPrivate()
+}
+
+/**
+ * Holds if the member function is in a class with the given base class, and has the given name.
+ */
+pragma[noinline, nomagic]
+predicate hasDeclarationBaseClass(MemberFunction mf, Class baseClass, string functionName) {
+ baseClass = mf.getDeclaringType().getABaseClass() and
+ functionName = mf.getName()
+}
+
+query predicate problems(
+ MemberFunction overridingDecl, string message, MemberFunction hiddenDecl, string hiddenDecl_string
+) {
+ exists(Class baseClass, string name |
+ not isExcluded(overridingDecl, getQuery()) and // Check if we are overriding a non-virtual inherited member function
+ hasNonVirtualMemberFunction(baseClass, hiddenDecl, name) and
+ hasDeclarationBaseClass(overridingDecl, baseClass, name) and
+ // Where the hidden member function isn't explicitly brought in scope through a using declaration.
+ not exists(UsingDeclarationEntry ude |
+ ude.getDeclaration() = hiddenDecl and
+ ude.getEnclosingElement() = overridingDecl.getDeclaringType()
+ ) and
+ // Exclude compiler generated member functions which include things like copy constructor that hide base class
+ // copy constructors.
+ not overridingDecl.isCompilerGenerated() and
+ // Exclude special member functions, which cannot be inherited.
+ not overridingDecl instanceof SpecialMemberFunction and
+ message =
+ "Declaration for member '" + name + "' hides non-overridable inherited member function $@" and
+ hiddenDecl_string = hiddenDecl.getName()
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/hiddeninheritedoverridablememberfunction/HiddenInheritedOverridableMemberFunction.qll b/cpp/common/src/codingstandards/cpp/rules/hiddeninheritedoverridablememberfunction/HiddenInheritedOverridableMemberFunction.qll
new file mode 100644
index 0000000000..ef99e01973
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/hiddeninheritedoverridablememberfunction/HiddenInheritedOverridableMemberFunction.qll
@@ -0,0 +1,56 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * An overriding member function definition thats hides an overload of the overridden
+ * inherited member function can result in unexpected behavior.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class HiddenInheritedOverridableMemberFunctionSharedQuery extends Query { }
+
+Query getQuery() { result instanceof HiddenInheritedOverridableMemberFunctionSharedQuery }
+
+query predicate problems(
+ FunctionDeclarationEntry overridingDecl, string message, FunctionDeclarationEntry hiddenDecl,
+ string hiddenDecl_string
+) {
+ not isExcluded(overridingDecl, getQuery()) and
+ // Check if we are overriding a virtual inherited member function
+ hiddenDecl.getDeclaration().isVirtual() and
+ // Exclude private member functions, which cannot be inherited.
+ not hiddenDecl.getDeclaration().(MemberFunction).isPrivate() and
+ // The overriding declaration hides the hidden declaration if:
+ (
+ // 1. the overriding declaration overrides a function in a base class that is an overload of the hidden declaration
+ // and the hidden declaration isn't overriden in the same class.
+ exists(FunctionDeclarationEntry overridenDecl |
+ overridingDecl.getDeclaration().(MemberFunction).overrides(overridenDecl.getDeclaration()) and
+ overridenDecl.getDeclaration().getAnOverload() = hiddenDecl.getDeclaration() and
+ not exists(MemberFunction overridingFunc |
+ hiddenDecl.getDeclaration().(MemberFunction).getAnOverridingFunction() = overridingFunc and
+ overridingFunc.getDeclaringType() = overridingDecl.getDeclaration().getDeclaringType()
+ )
+ ) and
+ // and the hidden declaration isn't explicitly brought in scope through a using declaration.
+ not exists(UsingDeclarationEntry ude |
+ ude.getDeclaration() = hiddenDecl.getDeclaration() and
+ ude.getEnclosingElement() = overridingDecl.getDeclaration().getDeclaringType()
+ )
+ or
+ // 2. if the overriding declaration doesn't override a base member function but has the same name
+ // as the hidden declaration
+ not overridingDecl.getDeclaration().(MemberFunction).overrides(_) and
+ overridingDecl.getName() = hiddenDecl.getName() and
+ overridingDecl.getDeclaration().getDeclaringType().getABaseClass() =
+ hiddenDecl.getDeclaration().getDeclaringType()
+ ) and
+ // Limit the results to the declarations and not the definitions, if any.
+ (overridingDecl.getDeclaration().hasDefinition() implies not overridingDecl.isDefinition()) and
+ (hiddenDecl.getDeclaration().hasDefinition() implies not hiddenDecl.isDefinition()) and
+ message =
+ "Declaration for member '" + overridingDecl.getName() +
+ "' hides overridable inherited member function $@" and
+ hiddenDecl_string = hiddenDecl.getName()
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/identifierhidden/IdentifierHidden.qll b/cpp/common/src/codingstandards/cpp/rules/identifierhidden/IdentifierHidden.qll
index dc71ba843e..39d24299b8 100644
--- a/cpp/common/src/codingstandards/cpp/rules/identifierhidden/IdentifierHidden.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/identifierhidden/IdentifierHidden.qll
@@ -1,80 +1,19 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * Use of an identifier declared in an inner scope with an identical name to an
+ * identifier in an outer scope can lead to inadvertent errors if the incorrect
+ * identifier is modified.
*/
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.Scope
-import codingstandards.cpp.ConstHelpers
abstract class IdentifierHiddenSharedQuery extends Query { }
Query getQuery() { result instanceof IdentifierHiddenSharedQuery }
-/**
- * a `Variable` that is nonvolatile and const
- * and of type `IntegralOrEnumType`
- */
-class NonVolatileConstIntegralOrEnumVariable extends Variable {
- NonVolatileConstIntegralOrEnumVariable() {
- not this.isVolatile() and
- this.isConst() and
- this.getUnspecifiedType() instanceof IntegralOrEnumType
- }
-}
-
-/**
- * Holds if declaration `innerDecl`, declared in a lambda, hides a declaration `outerDecl` by the lambda.
- */
-predicate hiddenInLambda(UserVariable outerDecl, UserVariable innerDecl) {
- exists(
- Scope innerScope, LambdaExpression lambdaExpr, Scope lambdaExprScope, Scope outerScope,
- Closure lambdaClosure
- |
- // The variable `innerDecl` is declared inside of the lambda.
- innerScope.getADeclaration() = innerDecl and
- // Because a lambda is compiled down to a closure, we need to use the closure to determine if the declaration
- // is part of the lambda.
- innerScope.getAnAncestor() = lambdaClosure and
- // Next we determine the scope of the lambda expression to determine if `outerDecl` is visible in the scope of the lambda.
- lambdaClosure.getLambdaExpression() = lambdaExpr and
- lambdaExprScope.getAnExpr() = lambdaExpr and
- outerScope.getADeclaration() = outerDecl and
- lambdaExprScope.getStrictParent*() = outerScope and
- (
- // A definition can be hidden if it is in scope and it is captured by the lambda,
- exists(LambdaCapture cap |
- lambdaExpr.getACapture() = cap and
- // The outer declaration is captured by the lambda
- outerDecl.getAnAccess() = cap.getInitializer()
- )
- or
- // it is is non-local,
- outerDecl instanceof GlobalVariable
- or
- // it has static or thread local storage duration,
- (outerDecl.isThreadLocal() or outerDecl.isStatic())
- or
- //it is a reference that has been initialized with a constant expression.
- outerDecl.getType().stripTopLevelSpecifiers() instanceof ReferenceType and
- outerDecl.getInitializer().getExpr() instanceof Literal
- or
- // //it const non-volatile integral or enumeration type and has been initialized with a constant expression
- outerDecl instanceof NonVolatileConstIntegralOrEnumVariable and
- outerDecl.getInitializer().getExpr() instanceof Literal
- or
- //it is constexpr and has no mutable members
- outerDecl.isConstexpr() and
- not exists(Class c |
- c = outerDecl.getType() and not c.getAMember() instanceof MutableVariable
- )
- ) and
- // Finally, the variables must have the same names.
- innerDecl.getName() = outerDecl.getName()
- )
-}
-
query predicate problems(
UserVariable innerDecl, string message, UserVariable outerDecl, string varName
) {
@@ -83,7 +22,7 @@ query predicate problems(
//ignore template variables for this rule
not outerDecl instanceof TemplateVariable and
not innerDecl instanceof TemplateVariable and
- (hidesStrict(outerDecl, innerDecl) or hiddenInLambda(outerDecl, innerDecl)) and
+ hidesStrict(outerDecl, innerDecl) and
not excludedViaNestedNamespaces(outerDecl, innerDecl) and
varName = outerDecl.getName() and
message = "Variable is hiding variable $@."
diff --git a/cpp/common/src/codingstandards/cpp/rules/identifierwithexternallinkageonedefinitionshared/IdentifierWithExternalLinkageOneDefinitionShared.qll b/cpp/common/src/codingstandards/cpp/rules/identifierwithexternallinkageonedefinitionshared/IdentifierWithExternalLinkageOneDefinitionShared.qll
index 17808841eb..806315b43c 100644
--- a/cpp/common/src/codingstandards/cpp/rules/identifierwithexternallinkageonedefinitionshared/IdentifierWithExternalLinkageOneDefinitionShared.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/identifierwithexternallinkageonedefinitionshared/IdentifierWithExternalLinkageOneDefinitionShared.qll
@@ -1,5 +1,7 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * An identifier with multiple definitions in different translation units
+ * leads to undefined behavior.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/ifelseterminationconstruct/IfElseTerminationConstruct.qll b/cpp/common/src/codingstandards/cpp/rules/ifelseterminationconstruct/IfElseTerminationConstruct.qll
index 5755ed8f38..3c6f25e151 100644
--- a/cpp/common/src/codingstandards/cpp/rules/ifelseterminationconstruct/IfElseTerminationConstruct.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/ifelseterminationconstruct/IfElseTerminationConstruct.qll
@@ -1,5 +1,6 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * The final else statement is a defensive programming technique.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.qll b/cpp/common/src/codingstandards/cpp/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.qll
new file mode 100644
index 0000000000..ffb08283cd
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.qll
@@ -0,0 +1,48 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * All constructors of a class should explicitly initialize all of its virtual base
+ * classes and immediate base classes.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Constructor
+
+abstract class InitializeAllVirtualBaseClassesSharedQuery extends Query { }
+
+Query getQuery() { result instanceof InitializeAllVirtualBaseClassesSharedQuery }
+
+query predicate problems(
+ Constructor c, string message, Class declaringType, string declaringType_string, Class baseClass,
+ string baseClass_string
+) {
+ exists(string type |
+ not isExcluded(c, getQuery()) and
+ declaringType = c.getDeclaringType() and
+ (
+ declaringType.getABaseClass() = baseClass and type = ""
+ or
+ baseClass.(VirtualBaseClass).getAVirtuallyDerivedClass().getADerivedClass+() = declaringType and
+ type = " virtual"
+ ) and
+ // There is not an initializer on the constructor for this particular base class
+ not exists(ConstructorBaseClassInit init |
+ c.getAnInitializer() = init and
+ init.getInitializedClass() = baseClass and
+ not init.isCompilerGenerated()
+ ) and
+ // Must be a defined constructor
+ c.hasDefinition() and
+ // Not a compiler-generated constructor
+ 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 =
+ "Constructor for $@ does not explicitly call constructor for" + type + " base class $@."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/initializerlistconstructoristheonlyconstructor/InitializerListConstructorIsTheOnlyConstructor.qll b/cpp/common/src/codingstandards/cpp/rules/initializerlistconstructoristheonlyconstructor/InitializerListConstructorIsTheOnlyConstructor.qll
new file mode 100644
index 0000000000..e9579fcfba
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/initializerlistconstructoristheonlyconstructor/InitializerListConstructorIsTheOnlyConstructor.qll
@@ -0,0 +1,65 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A class shall only define an initializer-list constructor when it is the only
+ * constructor.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class InitializerListConstructorIsTheOnlyConstructorSharedQuery extends Query { }
+
+Query getQuery() { result instanceof InitializerListConstructorIsTheOnlyConstructorSharedQuery }
+
+class StdInitializerList extends Class {
+ StdInitializerList() { hasQualifiedName("std", "initializer_list") }
+}
+
+/**
+ * An _initializer-list constructor_ according to `[dcl.init.list]`.
+ *
+ * A `Constructor` where the first parameter refers to `std::initializer_list`, and any remaining
+ * parameters have default arguments.
+ */
+class InitializerListConstructor extends Constructor {
+ InitializerListConstructor() {
+ // The first parameter is a `std::intializer_list` parameter
+ exists(Type firstParamType | firstParamType = getParameter(0).getType() |
+ // Either directly `std::initializer_list`
+ firstParamType instanceof StdInitializerList
+ or
+ //A reference to `std::initializer_list`
+ firstParamType.(ReferenceType).getBaseType().getUnspecifiedType() instanceof
+ StdInitializerList
+ ) and
+ // All parameters other than the fi
+ forall(Parameter other | other = getParameter([1 .. (getNumberOfParameters() - 1)]) |
+ exists(other.getInitializer())
+ )
+ }
+}
+
+query predicate problems(
+ Constructor c, string message, InitializerListConstructor stdInitializerConstructor,
+ string stdInitializerConstructor_string
+) {
+ exists(string paramList |
+ not isExcluded(c, getQuery()) and
+ // Not an initializer-list constructor
+ not c instanceof InitializerListConstructor and
+ // Constructor is not a special member function constructor
+ not c instanceof CopyConstructor and
+ not c instanceof MoveConstructor and
+ not c.getNumberOfParameters() = 0 and // default constructor
+ // And there is an initalizer-list constructor
+ stdInitializerConstructor = c.getDeclaringType().getAConstructor() and
+ // Determine the parameter type list of the constructor
+ paramList =
+ concat(string parameter | parameter = c.getAParameter().getType().getName() | parameter, ",") and
+ message =
+ "The constructor " + c.getQualifiedName() + "(" + paramList +
+ ") may be ignored in favour of $@ when using braced initialization." and
+ stdInitializerConstructor_string = "the constructor accepting std::initializer_list"
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.qll b/cpp/common/src/codingstandards/cpp/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.qll
index 81a3251355..3949ff50a8 100644
--- a/cpp/common/src/codingstandards/cpp/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.qll
@@ -6,7 +6,7 @@
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
abstract class InvalidatedEnvStringPointersSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.qll b/cpp/common/src/codingstandards/cpp/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.qll
index fd8a969d00..8bc1b0c920 100644
--- a/cpp/common/src/codingstandards/cpp/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.qll
@@ -6,7 +6,7 @@
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.rules.invalidatedenvstringpointers.InvalidatedEnvStringPointers as EnvString
abstract class InvalidatedEnvStringPointersWarnSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/iofstreammissingpositioning/IOFstreamMissingPositioning.qll b/cpp/common/src/codingstandards/cpp/rules/iofstreammissingpositioning/IOFstreamMissingPositioning.qll
index 3a7e225369..89f847c5aa 100644
--- a/cpp/common/src/codingstandards/cpp/rules/iofstreammissingpositioning/IOFstreamMissingPositioning.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/iofstreammissingpositioning/IOFstreamMissingPositioning.qll
@@ -5,7 +5,7 @@
*/
import cpp
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import codingstandards.cpp.Exclusions
import codingstandards.cpp.standardlibrary.FileStreams
import codingstandards.cpp.standardlibrary.FileAccess
diff --git a/cpp/common/src/codingstandards/cpp/rules/linesplicingusedincomments/LineSplicingUsedInComments.qll b/cpp/common/src/codingstandards/cpp/rules/linesplicingusedincomments/LineSplicingUsedInComments.qll
new file mode 100644
index 0000000000..52dcf9a3f1
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/linesplicingusedincomments/LineSplicingUsedInComments.qll
@@ -0,0 +1,19 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Entering a newline following a '\\' character can erroneously commenting out
+ * regions of code.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class LineSplicingUsedInCommentsSharedQuery extends Query { }
+
+Query getQuery() { result instanceof LineSplicingUsedInCommentsSharedQuery }
+
+query predicate problems(CppStyleComment c, string message) {
+ not isExcluded(c, getQuery()) and
+ exists(c.getContents().regexpFind("\\\n", _, _)) and
+ message = "C++ comment includes \\ as the last character of a line"
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/loopcompoundcondition/LoopCompoundCondition.qll b/cpp/common/src/codingstandards/cpp/rules/loopcompoundcondition/LoopCompoundCondition.qll
new file mode 100644
index 0000000000..b71c193c8e
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/loopcompoundcondition/LoopCompoundCondition.qll
@@ -0,0 +1,19 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * If the body of a loop is not enclosed in braces, then this can lead to incorrect
+ * execution, and hard for developers to maintain.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class LoopCompoundConditionSharedQuery extends Query { }
+
+Query getQuery() { result instanceof LoopCompoundConditionSharedQuery }
+
+query predicate problems(Loop loop, string message) {
+ not isExcluded(loop, getQuery()) and
+ not loop.getStmt() instanceof BlockStmt and
+ message = "Loop body not enclosed within braces."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.qll b/cpp/common/src/codingstandards/cpp/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.qll
new file mode 100644
index 0000000000..b12cddba0b
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.qll
@@ -0,0 +1,20 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The lowercase form of L shall not be used as the first character in a literal
+ * suffix.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Literals
+
+abstract class LowercaseLStartsInLiteralSuffixSharedQuery extends Query { }
+
+Query getQuery() { result instanceof LowercaseLStartsInLiteralSuffixSharedQuery }
+
+query predicate problems(IntegerLiteral l, string message) {
+ not isExcluded(l, getQuery()) and
+ exists(l.getValueText().indexOf("l")) and
+ message = "Lowercase 'l' used as a literal suffix."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/macrooffsetofused/MacroOffsetofUsed.qll b/cpp/common/src/codingstandards/cpp/rules/macrooffsetofused/MacroOffsetofUsed.qll
new file mode 100644
index 0000000000..b475dc655e
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/macrooffsetofused/MacroOffsetofUsed.qll
@@ -0,0 +1,18 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The macro offsetof shall not be used.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class MacroOffsetofUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof MacroOffsetofUsedSharedQuery }
+
+query predicate problems(MacroInvocation mi, string message) {
+ not isExcluded(mi, getQuery()) and
+ mi.getMacroName() = "offsetof" and
+ message = "Use of banned macro " + mi.getMacroName() + "."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/macroparameterfollowinghash/MacroParameterFollowingHash.qll b/cpp/common/src/codingstandards/cpp/rules/macroparameterfollowinghash/MacroParameterFollowingHash.qll
new file mode 100644
index 0000000000..ae20368e67
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/macroparameterfollowinghash/MacroParameterFollowingHash.qll
@@ -0,0 +1,24 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A macro parameter immediately following a # operator shall not be immediately
+ * followed by a ## operator.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Macro
+
+abstract class MacroParameterFollowingHashSharedQuery extends Query { }
+
+Query getQuery() { result instanceof MacroParameterFollowingHashSharedQuery }
+
+query predicate problems(Macro m, string message) {
+ not isExcluded(m, getQuery()) and
+ exists(StringizingOperator one, TokenPastingOperator two |
+ one.getMacro() = m and
+ two.getMacro() = m and
+ one.getOffset() < two.getOffset()
+ ) and
+ message = "Macro definition uses an # operator followed by a ## operator."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/macroparameternotenclosedinparentheses/MacroParameterNotEnclosedInParentheses.qll b/cpp/common/src/codingstandards/cpp/rules/macroparameternotenclosedinparentheses/MacroParameterNotEnclosedInParentheses.qll
index 693ae36906..314d1dbe4c 100644
--- a/cpp/common/src/codingstandards/cpp/rules/macroparameternotenclosedinparentheses/MacroParameterNotEnclosedInParentheses.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/macroparameternotenclosedinparentheses/MacroParameterNotEnclosedInParentheses.qll
@@ -1,5 +1,8 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * In the definition of a function-like macro, each instance of a parameter
+ * shall be enclosed in parentheses, otherwise the result of preprocessor macro
+ * substitition may not be as expected.
*/
import cpp
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/movedfromobjectsunspecifiedstate/MovedFromObjectsUnspecifiedState.qll b/cpp/common/src/codingstandards/cpp/rules/movedfromobjectsunspecifiedstate/MovedFromObjectsUnspecifiedState.qll
index a0006eb643..f17da7e457 100644
--- a/cpp/common/src/codingstandards/cpp/rules/movedfromobjectsunspecifiedstate/MovedFromObjectsUnspecifiedState.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/movedfromobjectsunspecifiedstate/MovedFromObjectsUnspecifiedState.qll
@@ -4,7 +4,7 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.Exclusions
import codingstandards.cpp.standardlibrary.Utility
diff --git a/cpp/common/src/codingstandards/cpp/rules/multipleglobalormemberdeclarators/MultipleGlobalOrMemberDeclarators.qll b/cpp/common/src/codingstandards/cpp/rules/multipleglobalormemberdeclarators/MultipleGlobalOrMemberDeclarators.qll
new file mode 100644
index 0000000000..05821d7270
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/multipleglobalormemberdeclarators/MultipleGlobalOrMemberDeclarators.qll
@@ -0,0 +1,66 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A declaration should not declare more than one variable or member variable.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class MultipleGlobalOrMemberDeclaratorsSharedQuery extends Query { }
+
+Query getQuery() { result instanceof MultipleGlobalOrMemberDeclaratorsSharedQuery }
+
+/*
+ * Unfortunately, we do not have an equivalent of `DeclStmt` for non-local declarations, so we
+ * cannot determine whether a declaration was declared with another declaration.
+ *
+ * However, we can use location trickery to figure out if the declaration occurs close enough to
+ * another declaration that it _must_ have been declared within the same declaration sequence.
+ *
+ * We do this by requiring that the end location of a previous declaration is within a certain
+ * number of characters of the start location of the current declaration.
+ */
+
+/**
+ * A `Declaration` which is not in a local scope, and is written directly by the user.
+ *
+ * These act as "candidates" for declarations that could plausibly occur in a declaration sequence
+ * with other candidates.
+ */
+class NonLocalUserDeclaration extends Declaration {
+ NonLocalUserDeclaration() {
+ not this instanceof StackVariable and
+ not this instanceof TemplateParameter and
+ not this instanceof EnumConstant and
+ not this instanceof TypedefType and
+ not any(LambdaCapture lc).getField() = this and
+ not this.(Function).isCompilerGenerated() and
+ not this.(Variable).isCompilerGenerated() and
+ not this.(Parameter).getFunction().isCompilerGenerated() and
+ not this.isInMacroExpansion() and
+ not exists(Struct s, TypedefType t |
+ s.isAnonymous() and
+ t.getBaseType() = s and
+ this = s.getAMemberVariable()
+ )
+ }
+}
+
+/**
+ * Holds if `d1` is followed directly by `d2`.
+ */
+predicate isFollowingDeclaration(NonLocalUserDeclaration d1, NonLocalUserDeclaration d2) {
+ exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
+ d1.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
+ d2.getLocation().hasLocationInfo(filepath, startline, endcolumn + [2 .. 3], endline, _)
+ ) and
+ not d1.(UserType).stripType() = d2.(Variable).getType().stripType()
+}
+
+query predicate problems(NonLocalUserDeclaration d1, string message) {
+ not isExcluded(d1, getQuery()) and
+ isFollowingDeclaration(d1, _) and
+ not isFollowingDeclaration(_, d1) and
+ message = "Multiple declarations after " + d1.getName() + " in this declaration sequence."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/multiplelocaldeclarators/MultipleLocalDeclarators.qll b/cpp/common/src/codingstandards/cpp/rules/multiplelocaldeclarators/MultipleLocalDeclarators.qll
new file mode 100644
index 0000000000..2269f36d97
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/multiplelocaldeclarators/MultipleLocalDeclarators.qll
@@ -0,0 +1,20 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A declaration should not declare more than one variable or member variable.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class MultipleLocalDeclaratorsSharedQuery extends Query { }
+
+Query getQuery() { result instanceof MultipleLocalDeclaratorsSharedQuery }
+
+query predicate problems(DeclStmt ds, string message) {
+ not isExcluded(ds, getQuery()) and
+ count(Declaration d | d = ds.getADeclaration()) > 1 and
+ // Not a compiler generated `DeclStmt`, such as in the range-based for loop
+ not ds.isCompilerGenerated() and
+ message = "Declaration list contains more than one declaration."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.qll b/cpp/common/src/codingstandards/cpp/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.qll
new file mode 100644
index 0000000000..326886dda6
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.qll
@@ -0,0 +1,20 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A named bit-field with signed integer type shall not have a length of one bit.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class NamedBitFieldsWithSignedIntegerTypeSharedQuery extends Query { }
+
+Query getQuery() { result instanceof NamedBitFieldsWithSignedIntegerTypeSharedQuery }
+
+query predicate problems(BitField bitField, string message) {
+ not isExcluded(bitField, getQuery()) and
+ bitField.getDeclaredNumBits() = 1 and // Single-bit,
+ not bitField.isAnonymous() and // named,
+ bitField.getType().(IntegralType).isSigned() and // but its type is signed.
+ message = "A named bit-field with signed integral type should have at least 2 bits of storage."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/namenotreferredusingaqualifiedidorthis/NameNotReferredUsingAQualifiedIdOrThis.qll b/cpp/common/src/codingstandards/cpp/rules/namenotreferredusingaqualifiedidorthis/NameNotReferredUsingAQualifiedIdOrThis.qll
new file mode 100644
index 0000000000..a4c9255c89
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/namenotreferredusingaqualifiedidorthis/NameNotReferredUsingAQualifiedIdOrThis.qll
@@ -0,0 +1,37 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Not using a qualified-id or `this->` syntax for identifiers used in a class template
+ * makes the code more difficult to understand.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.NameInDependentBase
+
+abstract class NameNotReferredUsingAQualifiedIdOrThisSharedQuery extends Query { }
+
+Query getQuery() { result instanceof NameNotReferredUsingAQualifiedIdOrThisSharedQuery }
+
+query predicate problems(
+ NameQualifiableElement fn, string message, Element actualTarget, string targetName,
+ Element dependentTypeMemberWithSameName, string dependentType_string
+) {
+ not isExcluded(fn, getQuery()) and
+ missingNameQualifier(fn) and
+ exists(TemplateClass c |
+ fn = getConfusingFunctionAccess(c, targetName, actualTarget, dependentTypeMemberWithSameName)
+ or
+ fn = getConfusingFunctionCall(c, targetName, actualTarget, dependentTypeMemberWithSameName) and
+ not exists(Expr e | e = fn.(FunctionCall).getQualifier())
+ or
+ fn =
+ getConfusingMemberVariableAccess(c, targetName, actualTarget, dependentTypeMemberWithSameName) and
+ not exists(Expr e | e = fn.(VariableAccess).getQualifier())
+ ) and
+ not fn.isAffectedByMacro() and
+ message =
+ "Use of unqualified identifier " + targetName +
+ " targets $@ but a member with the name also exists $@." and
+ dependentType_string = "in the dependent base class"
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/namenotreferredusingaqualifiedidorthisaudit/NameNotReferredUsingAQualifiedIdOrThisAudit.qll b/cpp/common/src/codingstandards/cpp/rules/namenotreferredusingaqualifiedidorthisaudit/NameNotReferredUsingAQualifiedIdOrThisAudit.qll
new file mode 100644
index 0000000000..d0a6251908
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/namenotreferredusingaqualifiedidorthisaudit/NameNotReferredUsingAQualifiedIdOrThisAudit.qll
@@ -0,0 +1,38 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Not using a qualified-id or `this->` syntax for identifiers used in a class template
+ * makes the code more difficult to understand.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.NameInDependentBase
+
+abstract class NameNotReferredUsingAQualifiedIdOrThisAuditSharedQuery extends Query { }
+
+Query getQuery() { result instanceof NameNotReferredUsingAQualifiedIdOrThisAuditSharedQuery }
+
+query predicate problems(
+ NameQualifiableElement fn, string message, Element actualTarget, string targetName,
+ Element dependentTypeMemberWithSameName, string dependentType_string
+) {
+ not isExcluded(fn, getQuery()) and
+ not isCustomExcluded(fn) and
+ missingNameQualifier(fn) and
+ exists(TemplateClass c |
+ fn = getConfusingFunctionAccess(c, targetName, actualTarget, dependentTypeMemberWithSameName)
+ or
+ fn = getConfusingFunctionCall(c, targetName, actualTarget, dependentTypeMemberWithSameName) and
+ not exists(Expr e | e = fn.(FunctionCall).getQualifier())
+ or
+ not fn.(VariableAccess).getTarget() instanceof Parameter and
+ fn =
+ getConfusingMemberVariableAccess(c, targetName, actualTarget, dependentTypeMemberWithSameName) and
+ not exists(Expr e | e = fn.(VariableAccess).getQualifier())
+ ) and
+ message =
+ "Use of unqualified identifier " + targetName +
+ " targets $@ but a member with the name also exists $@." and
+ dependentType_string = "in the dependent base class"
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.qll b/cpp/common/src/codingstandards/cpp/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.qll
new file mode 100644
index 0000000000..bc3b620718
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.qll
@@ -0,0 +1,38 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * If a function is declared to be noexcept, noexcept(true) or noexcept(), then it shall not exit with an exception.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.exceptions.ExceptionFlow
+import ExceptionPathGraph
+import codingstandards.cpp.exceptions.ExceptionSpecifications
+
+abstract class NoexceptFunctionShouldNotPropagateToTheCallerSharedQuery extends Query { }
+
+Query getQuery() { result instanceof NoexceptFunctionShouldNotPropagateToTheCallerSharedQuery }
+
+class NoExceptThrowingFunction extends ExceptionThrowingFunction {
+ NoExceptThrowingFunction() {
+ // Can exit with an exception
+ exists(getAFunctionThrownType(_, _)) and
+ // But is marked noexcept(true) or equivalent
+ isNoExceptTrue(this)
+ }
+}
+
+query predicate problems(
+ NoExceptThrowingFunction f, ExceptionFlowNode exceptionSource, ExceptionFlowNode functionNode,
+ string message
+) {
+ exists(ExceptionType exceptionType |
+ not isExcluded(f, getQuery()) and
+ f.hasExceptionFlow(exceptionSource, functionNode, exceptionType) and
+ message =
+ "Function " + f.getName() + " is declared noexcept(true) but can throw exceptions of type " +
+ exceptionType.getExceptionName() + "."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/nonconstantformat/NonConstantFormat.qll b/cpp/common/src/codingstandards/cpp/rules/nonconstantformat/NonConstantFormat.qll
index 91b2b05a3f..248cde106f 100644
--- a/cpp/common/src/codingstandards/cpp/rules/nonconstantformat/NonConstantFormat.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/nonconstantformat/NonConstantFormat.qll
@@ -1,7 +1,7 @@
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.commons.Printf
abstract class NonConstantFormatSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/nonglobalfunctionmain/NonGlobalFunctionMain.qll b/cpp/common/src/codingstandards/cpp/rules/nonglobalfunctionmain/NonGlobalFunctionMain.qll
new file mode 100644
index 0000000000..7366849d0c
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/nonglobalfunctionmain/NonGlobalFunctionMain.qll
@@ -0,0 +1,20 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The identifier main shall not be used for a function other than the global function
+ * main.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class NonGlobalFunctionMainSharedQuery extends Query { }
+
+Query getQuery() { result instanceof NonGlobalFunctionMainSharedQuery }
+
+query predicate problems(Function f, string message) {
+ not isExcluded(f, getQuery()) and
+ f.hasName("main") and
+ not f.hasGlobalName("main") and
+ message = "Identifier main used for a function other than the global function main."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.qll b/cpp/common/src/codingstandards/cpp/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.qll
new file mode 100644
index 0000000000..f23965ea7c
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.qll
@@ -0,0 +1,44 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Octal escape sequences, hexadecimal escape sequences, and universal character names
+ * shall be terminated.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class NonTerminatedEscapeSequencesSharedQuery extends Query { }
+
+Query getQuery() { result instanceof NonTerminatedEscapeSequencesSharedQuery }
+
+bindingset[s]
+predicate isOctalEscape(string s) {
+ s.charAt(0) = "\\" and
+ exists(int i | i = [0 .. 7] | i.toString() = s.charAt(1))
+}
+
+bindingset[s]
+predicate isHexEscape(string s) { s.indexOf("\\x") = 0 }
+
+query predicate problems(Literal l, string message) {
+ not isExcluded(l, getQuery()) and
+ exists(int idx, string sl, string escapeKind, string s |
+ sl = l.getValueText() and
+ idx = sl.indexOf("\\") and
+ s = sl.substring(idx, sl.length()) and
+ // Note: Octal representations must be 1-3 digits. There is no limitation on a
+ // Hex literal as long as the characters are valid. This query does not consider
+ // if the hex literal being constructed will overflow.
+ (
+ isHexEscape(s) and
+ not s.regexpMatch("^((\\\\x[0-9A-F]+(?=[\"'\\\\])))[\\s\\S]*") and
+ escapeKind = "hexadecimal"
+ or
+ isOctalEscape(s) and
+ not s.regexpMatch("^(((\\\\[0-7]{1,3})(?=[\"'\\\\])))[\\s\\S]*") and
+ escapeKind = "octal"
+ ) and
+ message = "Invalid " + escapeKind + " escape in string literal at '" + s + "'."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.qll b/cpp/common/src/codingstandards/cpp/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.qll
new file mode 100644
index 0000000000..f7afe8b3e7
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.qll
@@ -0,0 +1,38 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Within an enumerator list, the value of an implicitly-specified enumeration constant
+ * shall be unique.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class NonUniqueEnumerationConstantSharedQuery extends Query { }
+
+Query getQuery() { result instanceof NonUniqueEnumerationConstantSharedQuery }
+
+/**
+ * An `EnumConstant` that has an implicitly specified value:
+ * `enum e { explicit = 1, implicit }`
+ */
+class ImplicitlySpecifiedEnumConstant extends EnumConstant {
+ ImplicitlySpecifiedEnumConstant() {
+ //implicitly specified have an initializer with location: `file://:0:0:0:0`
+ not this.getInitializer().getLocation().getFile() = this.getFile()
+ }
+}
+
+query predicate problems(
+ ImplicitlySpecifiedEnumConstant imp, string message, EnumConstant exp, string exp_string
+) {
+ not isExcluded(imp, getQuery()) and
+ not isExcluded(exp, getQuery()) and
+ not exp = imp and
+ imp.getValue() = exp.getValue() and
+ imp.getDeclaringEnum() = exp.getDeclaringEnum() and
+ //can technically be the same declared enum across multiple headers but those are not relevant to this rule
+ imp.getFile() = exp.getFile() and
+ message = "Nonunique value of enum constant compared to $@" and
+ exp_string = exp.getName()
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/notdistinctidentifier/NotDistinctIdentifier.qll b/cpp/common/src/codingstandards/cpp/rules/notdistinctidentifier/NotDistinctIdentifier.qll
index 2d6767f664..102c53428b 100644
--- a/cpp/common/src/codingstandards/cpp/rules/notdistinctidentifier/NotDistinctIdentifier.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/notdistinctidentifier/NotDistinctIdentifier.qll
@@ -1,5 +1,6 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * Using nondistinct external identifiers results in undefined behaviour.
*/
import cpp
@@ -11,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
) {
@@ -19,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/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.qll b/cpp/common/src/codingstandards/cpp/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.qll
new file mode 100644
index 0000000000..2b24aa9410
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.qll
@@ -0,0 +1,25 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * nullptr shall be the only form of the null-pointer-constant.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import semmle.code.cpp.commons.NULL
+
+abstract class NullptrNotTheOnlyFormOfTheNullPointerConstantSharedQuery extends Query { }
+
+Query getQuery() { result instanceof NullptrNotTheOnlyFormOfTheNullPointerConstantSharedQuery }
+
+query predicate problems(Literal l, string message) {
+ not isExcluded(l, getQuery()) and // Not the type of the nullptr literal
+ not l.getType() instanceof NullPointerType and
+ // Converted to a pointer type
+ l.getConversion().getType().getUnspecifiedType() instanceof PointerType and
+ // Value of zero
+ l.getValue() = "0" and
+ // Not the StringLiteral "0"
+ not l instanceof StringLiteral and
+ message = l.getValueText() + " is used as the null-pointer-constant but is not nullptr."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/objectsdynamictypeusedfromconstructorordestructor/ObjectsDynamicTypeUsedFromConstructorOrDestructor.qll b/cpp/common/src/codingstandards/cpp/rules/objectsdynamictypeusedfromconstructorordestructor/ObjectsDynamicTypeUsedFromConstructorOrDestructor.qll
new file mode 100644
index 0000000000..1303646ef5
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/objectsdynamictypeusedfromconstructorordestructor/ObjectsDynamicTypeUsedFromConstructorOrDestructor.qll
@@ -0,0 +1,91 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * An object’s dynamic type shall not be used from within its constructor or
+ * destructor.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class ObjectsDynamicTypeUsedFromConstructorOrDestructorSharedQuery extends Query { }
+
+Query getQuery() { result instanceof ObjectsDynamicTypeUsedFromConstructorOrDestructorSharedQuery }
+
+predicate thisCall(FunctionCall c) {
+ c.getQualifier() instanceof ThisExpr or
+ c.getQualifier().(PointerDereferenceExpr).getChild(0) instanceof ThisExpr
+}
+
+predicate virtualThisCall(FunctionCall c, Function overridingFunction) {
+ c.isVirtual() and
+ thisCall(c) and
+ overridingFunction = c.getTarget().(VirtualFunction).getAnOverridingFunction()
+}
+
+class DynamicTypeExpr extends Expr {
+ DynamicTypeExpr() {
+ this instanceof TypeidOperator and
+ this.getEnclosingFunction().getDeclaringType().isPolymorphic()
+ or
+ this instanceof DynamicCast
+ or
+ virtualThisCall(this.(FunctionCall), _)
+ }
+}
+
+/*
+ * Catch most cases: go into functions in the same class, but only catch direct
+ * references to "this".
+ */
+
+predicate nonVirtualMemberFunction(MemberFunction mf, Class c) {
+ mf = c.getAMemberFunction() and
+ not mf instanceof Constructor and
+ not mf instanceof Destructor and
+ not mf.isVirtual()
+}
+
+predicate callFromNonVirtual(MemberFunction source, Class c, MemberFunction targ) {
+ exists(FunctionCall fc |
+ fc.getEnclosingFunction() = source and fc.getTarget() = targ and thisCall(fc)
+ ) and
+ targ = c.getAMemberFunction() and
+ nonVirtualMemberFunction(source, c)
+}
+
+predicate indirectlyInvokesDynamicTypeExpr(MemberFunction caller, DynamicTypeExpr target) {
+ target =
+ any(DynamicTypeExpr expr |
+ expr.getEnclosingFunction() = caller and
+ nonVirtualMemberFunction(caller, caller.getDeclaringType())
+ )
+ or
+ exists(MemberFunction mid |
+ indirectlyInvokesDynamicTypeExpr(mid, target) and
+ callFromNonVirtual(caller, caller.getDeclaringType(), mid)
+ )
+}
+
+query predicate problems(
+ DynamicTypeExpr expr, string explanation, MemberFunction mf, string mf_string
+) {
+ not isExcluded(expr, getQuery()) and
+ (
+ mf instanceof Constructor or
+ mf instanceof Destructor
+ ) and
+ mf_string = mf.getQualifiedName() and
+ exists(FunctionCall call |
+ mf = expr.getEnclosingFunction() and
+ explanation = "$@ uses the dynamic type of its own object."
+ or
+ mf != expr.getEnclosingFunction() and
+ mf = call.getEnclosingFunction() and
+ thisCall(call) and
+ indirectlyInvokesDynamicTypeExpr(call.getTarget(), expr) and
+ explanation =
+ "$@ calls " + call.getTarget().getQualifiedName() +
+ ", which uses the dynamic type of its own object."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/onlyfreememoryallocateddynamicallyshared/OnlyFreeMemoryAllocatedDynamicallyShared.qll b/cpp/common/src/codingstandards/cpp/rules/onlyfreememoryallocateddynamicallyshared/OnlyFreeMemoryAllocatedDynamicallyShared.qll
index bede451e24..89c732ff5a 100644
--- a/cpp/common/src/codingstandards/cpp/rules/onlyfreememoryallocateddynamicallyshared/OnlyFreeMemoryAllocatedDynamicallyShared.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/onlyfreememoryallocateddynamicallyshared/OnlyFreeMemoryAllocatedDynamicallyShared.qll
@@ -7,7 +7,7 @@ import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.Allocations
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import NonDynamicPointerToFreeFlow::PathGraph
/**
diff --git a/cpp/common/src/codingstandards/cpp/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.qll b/cpp/common/src/codingstandards/cpp/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.qll
new file mode 100644
index 0000000000..acfa177561
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.qll
@@ -0,0 +1,37 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Parameters in an overriding virtual function shall not specify different default
+ * arguments.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class OverridingShallSpecifyDifferentDefaultArgumentsSharedQuery extends Query { }
+
+Query getQuery() { result instanceof OverridingShallSpecifyDifferentDefaultArgumentsSharedQuery }
+
+query predicate problems(VirtualFunction f2, string message, VirtualFunction f1, string f1_string) {
+ not isExcluded(f2, getQuery()) and
+ not isExcluded(f1, getQuery()) and
+ f2 = f1.getAnOverridingFunction() and
+ exists(Parameter p1, Parameter p2 |
+ p1 = f1.getAParameter() and
+ p2 = f2.getParameter(p1.getIndex())
+ |
+ if p1.hasInitializer()
+ then
+ // if there is no initializer
+ not p2.hasInitializer()
+ or
+ // if there is one and it doesn't match
+ not p1.getInitializer().getExpr().getValueText() =
+ p2.getInitializer().getExpr().getValueText()
+ else
+ // if p1 doesn't have an initializer p2 shouldn't either
+ p2.hasInitializer()
+ ) and
+ message = "Overriding function does not have the same default parameters as $@" and
+ f1_string = "overridden function"
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.qll b/cpp/common/src/codingstandards/cpp/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.qll
index e24fb91539..2ee92b1611 100644
--- a/cpp/common/src/codingstandards/cpp/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.qll
@@ -8,7 +8,7 @@ import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.SmartPointers
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import PointerToSmartPointerConstructorFlowFlow::PathGraph
abstract class OwnedPointerValueStoredInUnrelatedSmartPointerSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/placementnewinsufficientstorage/PlacementNewInsufficientStorage.qll b/cpp/common/src/codingstandards/cpp/rules/placementnewinsufficientstorage/PlacementNewInsufficientStorage.qll
index dc26d13b87..6b2c6c87c9 100644
--- a/cpp/common/src/codingstandards/cpp/rules/placementnewinsufficientstorage/PlacementNewInsufficientStorage.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/placementnewinsufficientstorage/PlacementNewInsufficientStorage.qll
@@ -7,7 +7,7 @@ import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.allocations.PlacementNew
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import PlacementNewOriginFlow::PathGraph
abstract class PlacementNewInsufficientStorageSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/placementnewnotproperlyaligned/PlacementNewNotProperlyAligned.qll b/cpp/common/src/codingstandards/cpp/rules/placementnewnotproperlyaligned/PlacementNewNotProperlyAligned.qll
index 72286f2d79..d250061a23 100644
--- a/cpp/common/src/codingstandards/cpp/rules/placementnewnotproperlyaligned/PlacementNewNotProperlyAligned.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/placementnewnotproperlyaligned/PlacementNewNotProperlyAligned.qll
@@ -7,7 +7,7 @@ import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.allocations.PlacementNew
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import PlacementNewOriginFlow::PathGraph
abstract class PlacementNewNotProperlyAlignedSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.qll b/cpp/common/src/codingstandards/cpp/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.qll
new file mode 100644
index 0000000000..667480a43a
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.qll
@@ -0,0 +1,32 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * A comparison of a potentially virtual pointer to member function shall only be with
+ * nullptr.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class PotentiallyVirtualPointerOnlyComparesToNullptrSharedQuery extends Query { }
+
+Query getQuery() { result instanceof PotentiallyVirtualPointerOnlyComparesToNullptrSharedQuery }
+
+query predicate problems(
+ EqualityOperation equalityComparison, string message, MemberFunction virtualFunction,
+ string virtualFunction_string, Expr otherOperand, string otherOperand_string
+) {
+ not isExcluded(equalityComparison, getQuery()) and
+ exists(FunctionAccess accessOperand |
+ virtualFunction.isVirtual() and
+ equalityComparison.getAnOperand() = accessOperand and
+ accessOperand.getTarget() = virtualFunction and
+ otherOperand = equalityComparison.getAnOperand() and
+ not otherOperand = accessOperand and
+ not otherOperand.getType() instanceof NullPointerType and
+ message =
+ "A pointer to member virtual function $@ is tested for equality with non-null-pointer-constant $@." and
+ virtualFunction_string = virtualFunction.getName() and
+ otherOperand_string = otherOperand.toString()
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/predicatefunctionobjectsshouldnotbemutable/PredicateFunctionObjectsShouldNotBeMutable.qll b/cpp/common/src/codingstandards/cpp/rules/predicatefunctionobjectsshouldnotbemutable/PredicateFunctionObjectsShouldNotBeMutable.qll
index a8b6ab7576..bf47c1f649 100644
--- a/cpp/common/src/codingstandards/cpp/rules/predicatefunctionobjectsshouldnotbemutable/PredicateFunctionObjectsShouldNotBeMutable.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/predicatefunctionobjectsshouldnotbemutable/PredicateFunctionObjectsShouldNotBeMutable.qll
@@ -1,5 +1,7 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * "Non-static data members or captured values of predicate function objects
+ * that are state related to this object's identity shall not be copied.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/preprocessingdirectivewithinmacroargument/PreprocessingDirectiveWithinMacroArgument.qll b/cpp/common/src/codingstandards/cpp/rules/preprocessingdirectivewithinmacroargument/PreprocessingDirectiveWithinMacroArgument.qll
index 8b8609ab7b..8361a07a31 100644
--- a/cpp/common/src/codingstandards/cpp/rules/preprocessingdirectivewithinmacroargument/PreprocessingDirectiveWithinMacroArgument.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/preprocessingdirectivewithinmacroargument/PreprocessingDirectiveWithinMacroArgument.qll
@@ -1,5 +1,7 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * Arguments to a function-like macro shall not contain tokens that look like
+ * pre-processing directives or else behaviour after macro expansion is unpredictable.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/reinterpretcastused/ReinterpretCastUsed.qll b/cpp/common/src/codingstandards/cpp/rules/reinterpretcastused/ReinterpretCastUsed.qll
new file mode 100644
index 0000000000..b49a488ab2
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/reinterpretcastused/ReinterpretCastUsed.qll
@@ -0,0 +1,16 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The statement reinterpret_cast shall not be used.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class ReinterpretCastUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof ReinterpretCastUsedSharedQuery }
+
+query predicate problems(ReinterpretCast rc, string message) {
+ not isExcluded(rc, getQuery()) and message = "Use of reinterpret_cast."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.qll b/cpp/common/src/codingstandards/cpp/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.qll
new file mode 100644
index 0000000000..04a106b5c4
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.qll
@@ -0,0 +1,18 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The result of an assignment operator should not be used.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class ResultOfAnAssignmentOperatorShouldNotBeUsedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof ResultOfAnAssignmentOperatorShouldNotBeUsedSharedQuery }
+
+query predicate problems(AssignExpr e, string message) {
+ not isExcluded(e, getQuery()) and
+ not exists(ExprStmt s | s.getExpr() = e) and
+ message = "Use of an assignment operator's result."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/returnreferenceorpointertoautomaticlocalvariable/ReturnReferenceOrPointerToAutomaticLocalVariable.qll b/cpp/common/src/codingstandards/cpp/rules/returnreferenceorpointertoautomaticlocalvariable/ReturnReferenceOrPointerToAutomaticLocalVariable.qll
new file mode 100644
index 0000000000..cd623f711c
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/returnreferenceorpointertoautomaticlocalvariable/ReturnReferenceOrPointerToAutomaticLocalVariable.qll
@@ -0,0 +1,36 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Functions that return a reference or a pointer to an automatic variable (including
+ * parameters) potentially lead to undefined behaviour.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class ReturnReferenceOrPointerToAutomaticLocalVariableSharedQuery extends Query { }
+
+Query getQuery() { result instanceof ReturnReferenceOrPointerToAutomaticLocalVariableSharedQuery }
+
+query predicate problems(
+ ReturnStmt rs, string message, Function f, string f_string, Variable auto, string auto_string
+) {
+ exists(VariableAccess va, string returnType |
+ not isExcluded(rs, getQuery()) and
+ f = rs.getEnclosingFunction() and
+ (
+ f.getType() instanceof ReferenceType and va = rs.getExpr() and returnType = "reference"
+ or
+ f.getType() instanceof PointerType and
+ va = rs.getExpr().(AddressOfExpr).getOperand() and
+ returnType = "pointer"
+ ) and
+ auto = va.getTarget() and
+ not auto.isStatic() and
+ not f.isCompilerGenerated() and
+ not auto.getType() instanceof ReferenceType and
+ message = "The $@ returns a " + returnType + "to an $@ variable" and
+ f_string = f.getName() and
+ auto_string = "automatic"
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/stringnumberconversionmissingerrorcheck/StringNumberConversionMissingErrorCheck.qll b/cpp/common/src/codingstandards/cpp/rules/stringnumberconversionmissingerrorcheck/StringNumberConversionMissingErrorCheck.qll
index 98fd51a58f..fd56f5d899 100644
--- a/cpp/common/src/codingstandards/cpp/rules/stringnumberconversionmissingerrorcheck/StringNumberConversionMissingErrorCheck.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/stringnumberconversionmissingerrorcheck/StringNumberConversionMissingErrorCheck.qll
@@ -7,7 +7,7 @@ import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.TaintTracking
import codingstandards.cpp.standardlibrary.CharStreams
abstract class StringNumberConversionMissingErrorCheckSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/switchcasepositioncondition/SwitchCasePositionCondition.qll b/cpp/common/src/codingstandards/cpp/rules/switchcasepositioncondition/SwitchCasePositionCondition.qll
index 68ba9850af..979621762d 100644
--- a/cpp/common/src/codingstandards/cpp/rules/switchcasepositioncondition/SwitchCasePositionCondition.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/switchcasepositioncondition/SwitchCasePositionCondition.qll
@@ -1,5 +1,6 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * The switch statement syntax is weak and may lead to unspecified behaviour.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/switchcompoundcondition/SwitchCompoundCondition.qll b/cpp/common/src/codingstandards/cpp/rules/switchcompoundcondition/SwitchCompoundCondition.qll
new file mode 100644
index 0000000000..ab888abfec
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/switchcompoundcondition/SwitchCompoundCondition.qll
@@ -0,0 +1,46 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * If the body of a switch is not enclosed in braces, then this can lead to incorrect
+ * execution, and hard for developers to maintain.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class SwitchCompoundConditionSharedQuery extends Query { }
+
+Query getQuery() { result instanceof SwitchCompoundConditionSharedQuery }
+
+/**
+ * Class to differentiate between extractor generated blockstmt and actual blockstmt. The extractor
+ * will generate an artificial blockstmt when there is a single case and statement, e.g.
+ * ```
+ * switch(x)
+ * case 1:
+ * f();
+ * ```
+ * This is because our AST model considers the `case` to be a statement in its own right, so the
+ * extractor needs an aritifical block to hold both the case and the statement.
+ */
+class ArtificialBlock extends BlockStmt {
+ ArtificialBlock() {
+ exists(Location block, Location firstStatement |
+ block = getLocation() and firstStatement = getStmt(0).getLocation()
+ |
+ // We can identify artificial blocks as those where the start of the statement is at the same
+ // location as the start of the first statement in the block i.e. there was no opening brace.
+ block.getStartLine() = firstStatement.getStartLine() and
+ block.getStartColumn() = firstStatement.getStartColumn()
+ )
+ }
+}
+
+query predicate problems(SwitchStmt switch, string message) {
+ (
+ switch.getStmt() instanceof ArtificialBlock or
+ not switch.getStmt() instanceof BlockStmt
+ ) and
+ not isExcluded(switch, getQuery()) and
+ message = "Switch body not enclosed within braces."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/switchnotwellformed/SwitchNotWellFormed.qll b/cpp/common/src/codingstandards/cpp/rules/switchnotwellformed/SwitchNotWellFormed.qll
index ee04228a95..cb2e61c3ad 100644
--- a/cpp/common/src/codingstandards/cpp/rules/switchnotwellformed/SwitchNotWellFormed.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/switchnotwellformed/SwitchNotWellFormed.qll
@@ -1,5 +1,6 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * The switch statement syntax is weak and may lead to unspecified behaviour.
*/
import cpp
diff --git a/cpp/common/src/codingstandards/cpp/rules/throwingoperatornewreturnsnull/ThrowingOperatorNewReturnsNull.qll b/cpp/common/src/codingstandards/cpp/rules/throwingoperatornewreturnsnull/ThrowingOperatorNewReturnsNull.qll
index 9dbefeaa75..e28ef7ab07 100644
--- a/cpp/common/src/codingstandards/cpp/rules/throwingoperatornewreturnsnull/ThrowingOperatorNewReturnsNull.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/throwingoperatornewreturnsnull/ThrowingOperatorNewReturnsNull.qll
@@ -4,7 +4,7 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.allocations.CustomOperatorNewDelete
import codingstandards.cpp.exceptions.ExceptionSpecifications
import codingstandards.cpp.Customizations
diff --git a/cpp/common/src/codingstandards/cpp/rules/typeomitted/TypeOmitted.qll b/cpp/common/src/codingstandards/cpp/rules/typeomitted/TypeOmitted.qll
index 8c1cb3b80a..0906a1de4f 100644
--- a/cpp/common/src/codingstandards/cpp/rules/typeomitted/TypeOmitted.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/typeomitted/TypeOmitted.qll
@@ -1,5 +1,6 @@
/**
- * Provides a library which includes a `problems` predicate for reporting....
+ * Provides a library with a `problems` predicate for the following issue:
+ * Omission of type specifiers may not be supported by some compilers.
*/
import cpp
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
new file mode 100644
index 0000000000..a9535d9bfc
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.qll
@@ -0,0 +1,31 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Unsigned integer literals shall be appropriately suffixed.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Cpp14Literal
+
+abstract class UnsignedIntegerLiteralsNotAppropriatelySuffixedSharedQuery extends Query { }
+
+Query getQuery() { result instanceof UnsignedIntegerLiteralsNotAppropriatelySuffixedSharedQuery }
+
+query predicate problems(Cpp14Literal::NumericLiteral nl, string message) {
+ exists(string literalKind |
+ not isExcluded(nl, getQuery()) and
+ (
+ 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
+ // The literal already has a `u` or `U` suffix.
+ not nl.getValueText().regexpMatch(".*[lL]*[uU][lL]*") and
+ message = literalKind + " literal is an unsigned integer but does not include a 'U' suffix."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.qll b/cpp/common/src/codingstandards/cpp/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.qll
new file mode 100644
index 0000000000..bc0c6d8fc1
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.qll
@@ -0,0 +1,33 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * An unsigned arithmetic operation with constant operands should not wrap.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Overflow
+import semmle.code.cpp.controlflow.Guards
+import semmle.code.cpp.valuenumbering.GlobalValueNumbering
+
+abstract class UnsignedOperationWithConstantOperandsWrapsSharedQuery extends Query { }
+
+Query getQuery() { result instanceof UnsignedOperationWithConstantOperandsWrapsSharedQuery }
+
+query predicate problems(InterestingOverflowingOperation op, string message) {
+ not isExcluded(op, getQuery()) and
+ op.getType().getUnderlyingType().(IntegralType).isUnsigned() and
+ // Not within a guard condition
+ not exists(GuardCondition gc | gc.getAChild*() = op) and
+ // Not guarded by a check, where the check is not an invalid overflow check
+ not op.hasValidPreCheck() and
+ // Is not checked after the operation
+ not op.hasValidPostCheck() and
+ // Permitted by exception 3
+ not op instanceof LShiftExpr and
+ // Permitted by exception 2 - zero case is handled in separate query
+ not op instanceof DivExpr and
+ not op instanceof RemExpr and
+ message =
+ "Operation " + op.getOperator() + " of type " + op.getType().getUnderlyingType() + " may wrap."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.qll b/cpp/common/src/codingstandards/cpp/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.qll
new file mode 100644
index 0000000000..f5d1834723
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.qll
@@ -0,0 +1,19 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * Octal constants shall not be used.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.Cpp14Literal
+
+abstract class UseOfNonZeroOctalLiteralSharedQuery extends Query { }
+
+Query getQuery() { result instanceof UseOfNonZeroOctalLiteralSharedQuery }
+
+query predicate problems(Cpp14Literal::OctalLiteral octalLiteral, string message) {
+ not isExcluded(octalLiteral, getQuery()) and
+ not octalLiteral.getValue() = "0" and
+ message = "Non zero octal literal " + octalLiteral.getValueText() + "."
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/useonlyarrayindexingforpointerarithmetic/UseOnlyArrayIndexingForPointerArithmetic.qll b/cpp/common/src/codingstandards/cpp/rules/useonlyarrayindexingforpointerarithmetic/UseOnlyArrayIndexingForPointerArithmetic.qll
index c421ae3cc9..3b0abbad0d 100644
--- a/cpp/common/src/codingstandards/cpp/rules/useonlyarrayindexingforpointerarithmetic/UseOnlyArrayIndexingForPointerArithmetic.qll
+++ b/cpp/common/src/codingstandards/cpp/rules/useonlyarrayindexingforpointerarithmetic/UseOnlyArrayIndexingForPointerArithmetic.qll
@@ -6,7 +6,7 @@
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
abstract class UseOnlyArrayIndexingForPointerArithmeticSharedQuery extends Query { }
diff --git a/cpp/common/src/codingstandards/cpp/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.qll b/cpp/common/src/codingstandards/cpp/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.qll
new file mode 100644
index 0000000000..ca23306c55
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.qll
@@ -0,0 +1,36 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * The std::vector specialization differs from all other containers
+ * std::vector such that sizeof bool is implementation defined which causes errors
+ * when using some STL algorithms.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+import codingstandards.cpp.StdNamespace
+
+abstract class VectorShouldNotBeSpecializedWithBoolSharedQuery extends Query { }
+
+Query getQuery() { result instanceof VectorShouldNotBeSpecializedWithBoolSharedQuery }
+
+predicate isVectorBool(ClassTemplateInstantiation c) {
+ c.getNamespace() instanceof StdNS and
+ c.getTemplateArgument(0) instanceof BoolType and
+ c.getSimpleName() = "vector"
+}
+
+predicate isUsingVectorBool(ClassTemplateInstantiation c) {
+ isVectorBool(c) or
+ isUsingVectorBool(c.getTemplateArgument(_))
+}
+
+query predicate problems(Variable v, string message) {
+ exists(ClassTemplateInstantiation c |
+ not isExcluded(v, getQuery()) and
+ v.getUnderlyingType() = c and
+ not v.isFromTemplateInstantiation(_) and
+ isUsingVectorBool(c) and
+ message = "Use of std::vector specialization."
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/rules/virtualandnonvirtualclassinthehierarchy/VirtualAndNonVirtualClassInTheHierarchy.qll b/cpp/common/src/codingstandards/cpp/rules/virtualandnonvirtualclassinthehierarchy/VirtualAndNonVirtualClassInTheHierarchy.qll
new file mode 100644
index 0000000000..f29d69d1ac
--- /dev/null
+++ b/cpp/common/src/codingstandards/cpp/rules/virtualandnonvirtualclassinthehierarchy/VirtualAndNonVirtualClassInTheHierarchy.qll
@@ -0,0 +1,40 @@
+/**
+ * Provides a library with a `problems` predicate for the following issue:
+ * An accessible base class shall not be both virtual and non-virtual in the same
+ * hierarchy.
+ */
+
+import cpp
+import codingstandards.cpp.Customizations
+import codingstandards.cpp.Exclusions
+
+abstract class VirtualAndNonVirtualClassInTheHierarchySharedQuery extends Query { }
+
+Query getQuery() { result instanceof VirtualAndNonVirtualClassInTheHierarchySharedQuery }
+
+query predicate problems(
+ Class c3, string message, Class base, string base_string, ClassDerivation cd1, string cd1_string,
+ Class c2, string c2_string
+) {
+ exists(Class c1, ClassDerivation cd2 |
+ not isExcluded(c3, getQuery()) and
+ // for each pair of classes, get all of their derivations
+ cd1 = c1.getADerivation() and
+ cd2 = c2.getADerivation() and
+ // where they share the same base class
+ base = cd1.getBaseClass() and
+ base = cd2.getBaseClass() and
+ // but one is virtual, and one is not, and the derivations are in different classes
+ cd1.isVirtual() and
+ not cd2.isVirtual() and
+ // and there is some 'other class' that derives from both of these classes
+ c3.derivesFrom*(c1) and
+ c3.derivesFrom*(c2) and
+ // and the base class is accessible from the 'other class'
+ c3.getAMemberFunction().getEnclosingAccessHolder().canAccessClass(base, c3) and
+ message = "Class inherits base class $@, which is derived virtual by $@ and non-virtual by $@." and
+ base_string = base.getName() and
+ cd1_string = cd1.getDerivedClass().toString() and
+ c2_string = cd2.getDerivedClass().toString()
+ )
+}
diff --git a/cpp/common/src/codingstandards/cpp/standardlibrary/FileStreams.qll b/cpp/common/src/codingstandards/cpp/standardlibrary/FileStreams.qll
index c4724d36c2..709e80dc1a 100644
--- a/cpp/common/src/codingstandards/cpp/standardlibrary/FileStreams.qll
+++ b/cpp/common/src/codingstandards/cpp/standardlibrary/FileStreams.qll
@@ -10,8 +10,8 @@
*/
import cpp
-import codingstandards.cpp.dataflow.DataFlow
-import codingstandards.cpp.dataflow.TaintTracking
+import semmle.code.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.TaintTracking
private import codingstandards.cpp.Operator
/**
diff --git a/cpp/common/src/codingstandards/cpp/trustboundary/UninitializedField.qll b/cpp/common/src/codingstandards/cpp/trustboundary/UninitializedField.qll
index e6a2bbe706..f58f1352a7 100644
--- a/cpp/common/src/codingstandards/cpp/trustboundary/UninitializedField.qll
+++ b/cpp/common/src/codingstandards/cpp/trustboundary/UninitializedField.qll
@@ -5,7 +5,7 @@
*/
import cpp
-private import codingstandards.cpp.dataflow.DataFlow
+private import semmle.code.cpp.dataflow.DataFlow
private import semmle.code.cpp.controlflow.SubBasicBlocks
private import semmle.code.cpp.padding.Padding as Padding
private import semmle.code.cpp.dataflow.internal.FlowVar
diff --git a/cpp/common/src/qlpack.yml b/cpp/common/src/qlpack.yml
index 764c164fcd..1ae6dfd997 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.40.0-dev
license: MIT
dependencies:
- codeql/cpp-all: 0.9.3
+ codeql/cpp-all: 1.4.2
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..910a6e060e 100644
--- a/cpp/common/test/codeql-pack.lock.yml
+++ b/cpp/common/test/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
compiled: false
diff --git a/cpp/common/test/deviations/deviation_permits_basic_test/UnusedReturnValue.ql b/cpp/common/test/deviations/deviation_permits_basic_test/UnusedReturnValue.ql
index 2517965fc1..38b75bda3c 100644
--- a/cpp/common/test/deviations/deviation_permits_basic_test/UnusedReturnValue.ql
+++ b/cpp/common/test/deviations/deviation_permits_basic_test/UnusedReturnValue.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.CodingStandards
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.exclusions.cpp.RuleMetadata
/* This is a copy of an AUTOSAR rule, which we are using for testing purposes. */
diff --git a/cpp/common/test/deviations/deviations_basic_test/UnusedReturnValue.ql b/cpp/common/test/deviations/deviations_basic_test/UnusedReturnValue.ql
index 2517965fc1..38b75bda3c 100644
--- a/cpp/common/test/deviations/deviations_basic_test/UnusedReturnValue.ql
+++ b/cpp/common/test/deviations/deviations_basic_test/UnusedReturnValue.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.CodingStandards
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.exclusions.cpp.RuleMetadata
/* This is a copy of an AUTOSAR rule, which we are using for testing purposes. */
diff --git a/cpp/common/test/deviations/deviations_report_deviated/UnusedReturnValue.ql b/cpp/common/test/deviations/deviations_report_deviated/UnusedReturnValue.ql
index 2517965fc1..38b75bda3c 100644
--- a/cpp/common/test/deviations/deviations_report_deviated/UnusedReturnValue.ql
+++ b/cpp/common/test/deviations/deviations_report_deviated/UnusedReturnValue.ql
@@ -16,7 +16,7 @@
import cpp
import codingstandards.cpp.CodingStandards
-import codingstandards.cpp.dataflow.DataFlow
+import semmle.code.cpp.dataflow.DataFlow
import codingstandards.cpp.exclusions.cpp.RuleMetadata
/* This is a copy of an AUTOSAR rule, which we are using for testing purposes. */
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/includes/standard-library/assert.h b/cpp/common/test/includes/standard-library/assert.h
index e69de29bb2..e8ba88d635 100644
--- a/cpp/common/test/includes/standard-library/assert.h
+++ b/cpp/common/test/includes/standard-library/assert.h
@@ -0,0 +1,6 @@
+#ifndef _GHLIBCPP_ASSERT
+#define _GHLIBCPP_ASSERT
+
+#define assert(x) (void)0
+
+#endif // _GHLIBCPP_ASSERT
\ No newline at end of file
diff --git a/cpp/common/test/includes/standard-library/cassert b/cpp/common/test/includes/standard-library/cassert
index e69de29bb2..0477057664 100644
--- a/cpp/common/test/includes/standard-library/cassert
+++ b/cpp/common/test/includes/standard-library/cassert
@@ -0,0 +1 @@
+#include "assert.h"
\ No newline at end of file
diff --git a/cpp/common/test/includes/standard-library/ctime b/cpp/common/test/includes/standard-library/ctime
index f99aab4fb3..9448e0615e 100644
--- a/cpp/common/test/includes/standard-library/ctime
+++ b/cpp/common/test/includes/standard-library/ctime
@@ -1,39 +1,17 @@
#ifndef _GHLIBCPP_CTIME
#define _GHLIBCPP_CTIME
-
-namespace std
-{
- typedef unsigned long clock_t;
- typedef unsigned long time_t;
-
- typedef unsigned long size_t;
- struct tm
- {
- int tm_sec;
- int tm_min;
- int tm_hour;
- int tm_mday;
- int tm_mon;
- int tm_year;
- int tm_wday;
- int tm_yday;
- int tm_isdst;
- };
-
-
- clock_t clock (void);
- double difftime (clock_t end, clock_t beginning);
- time_t mktime (struct tm * timeptr);
- time_t time (time_t* timer);
- char* asctime (const struct tm * timeptr);
-
- char* ctime (const time_t * timer);
- struct tm * gmtime (const time_t * timer);
- struct tm * localtime (const time_t * timer);
- size_t strftime (char* ptr, size_t maxsize, const char* format,
- const struct tm* timeptr );
-
-}
-
-
-#endif
\ No newline at end of file
+#include
+namespace std {
+using ::clock_t;
+using ::clock;
+using ::time_t;
+using ::time;
+using ::tm;
+using ::difftime;
+using ::asctime;
+using ::ctime;
+using ::localtime;
+using ::gmtime;
+using ::mktime;
+} // namespace std
+#endif // _GHLIBCPP_CTIME
\ No newline at end of file
diff --git a/cpp/common/test/includes/standard-library/locale.h b/cpp/common/test/includes/standard-library/locale.h
index 346c4eeef5..19a8905531 100644
--- a/cpp/common/test/includes/standard-library/locale.h
+++ b/cpp/common/test/includes/standard-library/locale.h
@@ -1,8 +1,38 @@
#ifndef _GHLIBCPP_LOCALE
#define _GHLIBCPP_LOCALE
-struct lconv;
-char *setlocale(int, const char *);
-lconv *localeconv();
+#define LC_ALL 6
+
+struct lconv {
+ char *decimal_point;
+ char *thousands_sep;
+ char *grouping;
+
+ char *int_curr_symbol;
+ char *currency_symbol;
+ char *mon_decimal_point;
+ char *mon_thousands_sep;
+ char *mon_grouping;
+ char *positive_sign;
+ char *negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ char int_p_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_cs_precedes;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+};
+
+
+char *setlocale (int, const char *);
+struct lconv *localeconv(void);
#endif // _GHLIBCPP_LOCALE
\ No newline at end of file
diff --git a/cpp/common/test/includes/standard-library/stddef.h b/cpp/common/test/includes/standard-library/stddef.h
index 496de53167..96e9849973 100644
--- a/cpp/common/test/includes/standard-library/stddef.h
+++ b/cpp/common/test/includes/standard-library/stddef.h
@@ -17,5 +17,11 @@ using size_t = decltype(sizeof(char));
#define offsetof(t, d) __builtin_offsetof(t, d) /*implementation-defined*/
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
// namespace std
#endif // _GHLIBCPP_STDDEF
\ No newline at end of file
diff --git a/cpp/common/test/includes/standard-library/stdlib.h b/cpp/common/test/includes/standard-library/stdlib.h
index c8ff7a7592..67f1abd694 100644
--- a/cpp/common/test/includes/standard-library/stdlib.h
+++ b/cpp/common/test/includes/standard-library/stdlib.h
@@ -15,6 +15,8 @@ int system(const char *command);
char *getenv(const char *name);
+int setenv (const char *, const char *, int);
+
int atoi(const char *str);
long int atol(const char *str);
long long int atoll(const char *str);
diff --git a/cpp/common/test/includes/standard-library/string.h b/cpp/common/test/includes/standard-library/string.h
index c4d06b6e7b..d94a186f0e 100644
--- a/cpp/common/test/includes/standard-library/string.h
+++ b/cpp/common/test/includes/standard-library/string.h
@@ -36,6 +36,8 @@ char *strstr(char *str1, const char *str2);
char *strtok(char *str, const char *delimiters);
+char *strdup (const char *);
+
void *memcpy(void *dest, const void *src, size_t count);
void *memset(void *dest, int ch, size_t count);
void *memmove(void *dest, const void *src, size_t count);
diff --git a/cpp/common/test/includes/standard-library/time.h b/cpp/common/test/includes/standard-library/time.h
index e69de29bb2..cc7ff1673a 100644
--- a/cpp/common/test/includes/standard-library/time.h
+++ b/cpp/common/test/includes/standard-library/time.h
@@ -0,0 +1,32 @@
+#ifndef _GHLIBCPP_TIME
+#define _GHLIBCPP_TIME
+
+typedef unsigned long clock_t;
+typedef unsigned long time_t;
+
+typedef unsigned long size_t;
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+};
+
+clock_t clock(void);
+double difftime(clock_t end, clock_t beginning);
+time_t mktime(struct tm *timeptr);
+time_t time(time_t *timer);
+char *asctime(const struct tm *timeptr);
+
+char *ctime(const time_t *timer);
+struct tm *gmtime(const time_t *timer);
+struct tm *localtime(const time_t *timer);
+size_t strftime(char *ptr, size_t maxsize, const char *format,
+ const struct tm *timeptr);
+
+#endif // _GHLIBCPP_TIME
\ No newline at end of file
diff --git a/cpp/common/test/library/codingstandards/cpp/mainlikefunctions/typedefint/MainLikeFunction.expected b/cpp/common/test/library/codingstandards/cpp/mainlikefunctions/typedefint/MainLikeFunction.expected
new file mode 100644
index 0000000000..fa98ca7648
--- /dev/null
+++ b/cpp/common/test/library/codingstandards/cpp/mainlikefunctions/typedefint/MainLikeFunction.expected
@@ -0,0 +1 @@
+| test.cpp:5:9:5:12 | main |
diff --git a/cpp/common/test/library/codingstandards/cpp/mainlikefunctions/typedefint/MainLikeFunction.ql b/cpp/common/test/library/codingstandards/cpp/mainlikefunctions/typedefint/MainLikeFunction.ql
new file mode 100644
index 0000000000..ed1757631e
--- /dev/null
+++ b/cpp/common/test/library/codingstandards/cpp/mainlikefunctions/typedefint/MainLikeFunction.ql
@@ -0,0 +1,5 @@
+import cpp
+import codingstandards.cpp.EncapsulatingFunctions
+
+from MainFunction m
+select m
diff --git a/cpp/common/test/library/codingstandards/cpp/mainlikefunctions/typedefint/test.cpp b/cpp/common/test/library/codingstandards/cpp/mainlikefunctions/typedefint/test.cpp
new file mode 100644
index 0000000000..7b514505f1
--- /dev/null
+++ b/cpp/common/test/library/codingstandards/cpp/mainlikefunctions/typedefint/test.cpp
@@ -0,0 +1,8 @@
+typedef signed int int32_t;
+
+// @brief main
+// @return exit code
+int32_t main(void) {
+ int32_t ret{0};
+ return ret;
+}
diff --git a/cpp/common/test/library/codingstandards/cpp/scope/ParentScope.expected b/cpp/common/test/library/codingstandards/cpp/scope/ParentScope.expected
new file mode 100644
index 0000000000..90aa3b30c8
--- /dev/null
+++ b/cpp/common/test/library/codingstandards/cpp/scope/ParentScope.expected
@@ -0,0 +1,91 @@
+| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | operator= |
+| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | operator= |
+| file://:0:0:0:0 | (unnamed parameter 0) | test.cpp:8:7:8:7 | operator= |
+| file://:0:0:0:0 | (unnamed parameter 0) | test.cpp:8:7:8:7 | operator= |
+| file://:0:0:0:0 | (unnamed parameter 0) | test.cpp:27:28:27:28 | (unnamed constructor) |
+| file://:0:0:0:0 | (unnamed parameter 0) | test.cpp:27:28:27:28 | (unnamed constructor) |
+| file://:0:0:0:0 | (unnamed parameter 0) | test.cpp:27:28:27:28 | operator= |
+| file://:0:0:0:0 | __va_list_tag | file://:0:0:0:0 | (global namespace) |
+| file://:0:0:0:0 | fp_offset | file://:0:0:0:0 | __va_list_tag |
+| file://:0:0:0:0 | gp_offset | file://:0:0:0:0 | __va_list_tag |
+| file://:0:0:0:0 | operator= | file://:0:0:0:0 | __va_list_tag |
+| file://:0:0:0:0 | operator= | file://:0:0:0:0 | __va_list_tag |
+| file://:0:0:0:0 | overflow_arg_area | file://:0:0:0:0 | __va_list_tag |
+| file://:0:0:0:0 | reg_save_area | file://:0:0:0:0 | __va_list_tag |
+| test.cpp:1:5:1:7 | id1 | file://:0:0:0:0 | (global namespace) |
+| test.cpp:3:11:3:13 | ns1 | file://:0:0:0:0 | (global namespace) |
+| test.cpp:4:5:4:7 | id1 | test.cpp:3:11:3:13 | ns1 |
+| test.cpp:6:11:6:13 | ns1::ns2 | test.cpp:3:11:3:13 | ns1 |
+| test.cpp:7:5:7:7 | id1 | test.cpp:6:11:6:13 | ns1::ns2 |
+| test.cpp:8:7:8:7 | C1 | test.cpp:8:7:8:8 | C1 |
+| test.cpp:8:7:8:7 | operator= | test.cpp:8:7:8:8 | C1 |
+| test.cpp:8:7:8:7 | operator= | test.cpp:8:7:8:8 | C1 |
+| test.cpp:8:7:8:8 | C1 | test.cpp:6:11:6:13 | ns1::ns2 |
+| test.cpp:9:7:9:9 | id1 | test.cpp:8:7:8:8 | C1 |
+| test.cpp:10:8:10:17 | test_scope | test.cpp:8:7:8:8 | C1 |
+| test.cpp:10:23:10:25 | id1 | test.cpp:10:8:10:17 | test_scope |
+| test.cpp:10:28:34:3 | { ... } | test.cpp:10:8:10:17 | test_scope |
+| test.cpp:11:5:33:5 | for(...;...;...) ... | test.cpp:10:28:34:3 | { ... } |
+| test.cpp:11:10:11:17 | declaration | test.cpp:11:5:33:5 | for(...;...;...) ... |
+| test.cpp:11:14:11:16 | id1 | test.cpp:11:5:33:5 | for(...;...;...) ... |
+| test.cpp:11:19:11:21 | id1 | test.cpp:10:28:34:3 | { ... } |
+| test.cpp:11:19:11:25 | ... < ... | test.cpp:11:5:33:5 | for(...;...;...) ... |
+| test.cpp:11:25:11:25 | 1 | test.cpp:10:28:34:3 | { ... } |
+| test.cpp:11:28:11:30 | id1 | test.cpp:10:28:34:3 | { ... } |
+| test.cpp:11:28:11:32 | ... ++ | test.cpp:11:5:33:5 | for(...;...;...) ... |
+| test.cpp:11:35:33:5 | { ... } | test.cpp:11:5:33:5 | for(...;...;...) ... |
+| test.cpp:12:7:32:7 | for(...;...;...) ... | test.cpp:11:35:33:5 | { ... } |
+| test.cpp:12:12:12:19 | declaration | test.cpp:12:7:32:7 | for(...;...;...) ... |
+| test.cpp:12:16:12:18 | id1 | test.cpp:12:7:32:7 | for(...;...;...) ... |
+| test.cpp:12:21:12:23 | id1 | test.cpp:11:35:33:5 | { ... } |
+| test.cpp:12:21:12:27 | ... < ... | test.cpp:12:7:32:7 | for(...;...;...) ... |
+| test.cpp:12:27:12:27 | 1 | test.cpp:11:35:33:5 | { ... } |
+| test.cpp:12:30:12:32 | id1 | test.cpp:11:35:33:5 | { ... } |
+| test.cpp:12:30:12:34 | ... ++ | test.cpp:12:7:32:7 | for(...;...;...) ... |
+| test.cpp:12:37:32:7 | { ... } | test.cpp:12:7:32:7 | for(...;...;...) ... |
+| test.cpp:13:9:31:9 | { ... } | test.cpp:12:37:32:7 | { ... } |
+| test.cpp:14:11:14:18 | declaration | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:14:15:14:17 | id1 | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:16:11:20:11 | if (...) ... | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:16:15:16:17 | id1 | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:16:15:16:22 | ... == ... | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:16:22:16:22 | 0 | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:16:25:18:11 | { ... } | test.cpp:16:11:20:11 | if (...) ... |
+| test.cpp:17:13:17:20 | declaration | test.cpp:16:25:18:11 | { ... } |
+| test.cpp:17:17:17:19 | id1 | test.cpp:16:25:18:11 | { ... } |
+| test.cpp:18:18:20:11 | { ... } | test.cpp:16:11:20:11 | if (...) ... |
+| test.cpp:19:13:19:20 | declaration | test.cpp:18:18:20:11 | { ... } |
+| test.cpp:19:17:19:19 | id1 | test.cpp:18:18:20:11 | { ... } |
+| test.cpp:21:11:25:11 | switch (...) ... | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:21:19:21:21 | id1 | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:21:24:25:11 | { ... } | test.cpp:21:11:25:11 | switch (...) ... |
+| test.cpp:22:11:22:17 | case ...: | test.cpp:21:24:25:11 | { ... } |
+| test.cpp:22:16:22:16 | 0 | test.cpp:21:24:25:11 | { ... } |
+| test.cpp:23:13:23:20 | declaration | test.cpp:21:24:25:11 | { ... } |
+| test.cpp:23:17:23:19 | id1 | test.cpp:21:24:25:11 | { ... } |
+| test.cpp:24:13:24:18 | break; | test.cpp:21:24:25:11 | { ... } |
+| test.cpp:25:11:25:11 | label ...: | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:26:11:28:11 | try { ... } | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:26:15:28:11 | { ... } | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:27:13:27:53 | declaration | test.cpp:26:15:28:11 | { ... } |
+| test.cpp:27:18:27:24 | lambda1 | test.cpp:26:15:28:11 | { ... } |
+| test.cpp:27:27:27:52 | [...](...){...} | test.cpp:26:15:28:11 | { ... } |
+| test.cpp:27:27:27:52 | {...} | test.cpp:26:15:28:11 | { ... } |
+| test.cpp:27:28:27:28 | (unnamed constructor) | file://:0:0:0:0 | decltype([...](...){...}) |
+| test.cpp:27:28:27:28 | (unnamed constructor) | file://:0:0:0:0 | decltype([...](...){...}) |
+| test.cpp:27:28:27:28 | (unnamed constructor) | file://:0:0:0:0 | decltype([...](...){...}) |
+| test.cpp:27:28:27:28 | operator= | file://:0:0:0:0 | decltype([...](...){...}) |
+| test.cpp:27:29:27:29 | id1 | file://:0:0:0:0 | decltype([...](...){...}) |
+| test.cpp:27:29:27:31 | id1 | test.cpp:26:15:28:11 | { ... } |
+| test.cpp:27:33:27:33 | operator() | test.cpp:27:13:27:53 | declaration |
+| test.cpp:27:36:27:52 | { ... } | test.cpp:27:33:27:33 | operator() |
+| test.cpp:27:38:27:50 | declaration | test.cpp:27:36:27:52 | { ... } |
+| test.cpp:27:42:27:44 | id1 | test.cpp:27:36:27:52 | { ... } |
+| test.cpp:27:47:27:49 | 10 | test.cpp:27:36:27:52 | { ... } |
+| test.cpp:27:52:27:52 | return ... | test.cpp:27:36:27:52 | { ... } |
+| test.cpp:28:24:28:26 | id1 | test.cpp:28:29:30:11 | |
+| test.cpp:28:29:30:11 | | test.cpp:26:11:28:11 | try { ... } |
+| test.cpp:28:29:30:11 | { ... } | test.cpp:13:9:31:9 | { ... } |
+| test.cpp:29:13:29:20 | declaration | test.cpp:28:29:30:11 | { ... } |
+| test.cpp:29:17:29:19 | id1 | test.cpp:28:29:30:11 | { ... } |
+| test.cpp:34:3:34:3 | return ... | test.cpp:10:28:34:3 | { ... } |
diff --git a/cpp/common/test/library/codingstandards/cpp/scope/ParentScope.ql b/cpp/common/test/library/codingstandards/cpp/scope/ParentScope.ql
new file mode 100644
index 0000000000..47d27fb0f0
--- /dev/null
+++ b/cpp/common/test/library/codingstandards/cpp/scope/ParentScope.ql
@@ -0,0 +1,5 @@
+import codingstandards.cpp.Scope
+
+from Element e, Element parent
+where Internal::getParentScope(e) = parent
+select e, parent
diff --git a/cpp/common/test/library/codingstandards/cpp/scope/test.cpp b/cpp/common/test/library/codingstandards/cpp/scope/test.cpp
new file mode 100644
index 0000000000..a0b617916d
--- /dev/null
+++ b/cpp/common/test/library/codingstandards/cpp/scope/test.cpp
@@ -0,0 +1,37 @@
+int id1;
+
+namespace ns1 {
+int id1; // COMPLIANT
+
+namespace ns2 {
+int id1; // COMPLIANT
+class C1 {
+ int id1;
+ void test_scope(int id1) {
+ for (int id1; id1 < 1; id1++) {
+ for (int id1; id1 < 1; id1++) {
+ {
+ int id1;
+
+ if (id1 == 0) {
+ int id1;
+ } else {
+ int id1;
+ }
+ switch (id1) {
+ case 0:
+ int id1;
+ break;
+ }
+ try {
+ auto lambda1 = [id1]() { int id1 = 10; };
+ } catch (int id1) {
+ int id1;
+ }
+ }
+ }
+ }
+ }
+};
+} // namespace ns2
+} // namespace ns1
diff --git a/cpp/common/test/qlpack.yml b/cpp/common/test/qlpack.yml
index 3ce9a6da2a..90236b203e 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.40.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/autosar/test/rules/M5-3-3/UnaryOperatorOverloaded.expected b/cpp/common/test/rules/addressofoperatoroverloaded/AddressOfOperatorOverloaded.expected
similarity index 100%
rename from cpp/autosar/test/rules/M5-3-3/UnaryOperatorOverloaded.expected
rename to cpp/common/test/rules/addressofoperatoroverloaded/AddressOfOperatorOverloaded.expected
diff --git a/cpp/common/test/rules/addressofoperatoroverloaded/AddressOfOperatorOverloaded.ql b/cpp/common/test/rules/addressofoperatoroverloaded/AddressOfOperatorOverloaded.ql
new file mode 100644
index 0000000000..ee8ba0d5d5
--- /dev/null
+++ b/cpp/common/test/rules/addressofoperatoroverloaded/AddressOfOperatorOverloaded.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.addressofoperatoroverloaded.AddressOfOperatorOverloaded
+
+class TestFileQuery extends AddressOfOperatorOverloadedSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M5-3-3/test.cpp b/cpp/common/test/rules/addressofoperatoroverloaded/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M5-3-3/test.cpp
rename to cpp/common/test/rules/addressofoperatoroverloaded/test.cpp
diff --git a/cpp/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.expected b/cpp/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.expected
new file mode 100644
index 0000000000..71355bf4cc
--- /dev/null
+++ b/cpp/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.expected
@@ -0,0 +1,2 @@
+| test.cpp:5:1:5:41 | #define BAD_MACRO_WITH_ARG(x) (x) + wow ## x | Macro BAD_MACRO_WITH_ARG contains use of parameter x used in multiple contexts. |
+| test.cpp:6:1:6:48 | #define BAD_MACRO_WITH_ARG_TWO(x,y) (x) + wow ## x | Macro BAD_MACRO_WITH_ARG_TWO contains use of parameter x used in multiple contexts. |
diff --git a/cpp/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.ql b/cpp/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.ql
new file mode 100644
index 0000000000..5aa514e86d
--- /dev/null
+++ b/cpp/common/test/rules/amixedusemacroargumentsubjecttoexpansion/AMixedUseMacroArgumentSubjectToExpansion.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.amixedusemacroargumentsubjecttoexpansion.AMixedUseMacroArgumentSubjectToExpansion
+
+class TestFileQuery extends AMixedUseMacroArgumentSubjectToExpansionSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-20-12/test.c b/cpp/common/test/rules/amixedusemacroargumentsubjecttoexpansion/test.cpp
similarity index 86%
rename from c/misra/test/rules/RULE-20-12/test.c
rename to cpp/common/test/rules/amixedusemacroargumentsubjecttoexpansion/test.cpp
index 768238f36d..e96e2f7414 100644
--- a/c/misra/test/rules/RULE-20-12/test.c
+++ b/cpp/common/test/rules/amixedusemacroargumentsubjecttoexpansion/test.cpp
@@ -1,4 +1,5 @@
-
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
#define GOOD_MACRO_WITH_ARG(X) ((X)*X##_scale) // COMPLIANT
#define MACRO 1
#define BAD_MACRO_WITH_ARG(x) (x) + wow##x // NON_COMPLIANT
diff --git a/cpp/autosar/test/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.expected b/cpp/common/test/rules/arraypassedasfunctionargumentdecaytoapointer/ArrayPassedAsFunctionArgumentDecayToAPointer.expected
similarity index 100%
rename from cpp/autosar/test/rules/M5-2-12/IdentifierWithArrayTypePassedAsFunctionArgumentDecayToAPointer.expected
rename to cpp/common/test/rules/arraypassedasfunctionargumentdecaytoapointer/ArrayPassedAsFunctionArgumentDecayToAPointer.expected
diff --git a/cpp/common/test/rules/arraypassedasfunctionargumentdecaytoapointer/ArrayPassedAsFunctionArgumentDecayToAPointer.ql b/cpp/common/test/rules/arraypassedasfunctionargumentdecaytoapointer/ArrayPassedAsFunctionArgumentDecayToAPointer.ql
new file mode 100644
index 0000000000..929e5affdf
--- /dev/null
+++ b/cpp/common/test/rules/arraypassedasfunctionargumentdecaytoapointer/ArrayPassedAsFunctionArgumentDecayToAPointer.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.arraypassedasfunctionargumentdecaytoapointer.ArrayPassedAsFunctionArgumentDecayToAPointer
+
+class TestFileQuery extends ArrayPassedAsFunctionArgumentDecayToAPointerSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M5-2-12/test.cpp b/cpp/common/test/rules/arraypassedasfunctionargumentdecaytoapointer/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M5-2-12/test.cpp
rename to cpp/common/test/rules/arraypassedasfunctionargumentdecaytoapointer/test.cpp
diff --git a/cpp/autosar/test/rules/A7-4-1/AsmDeclarationUsed.expected b/cpp/common/test/rules/asmdeclarationused/AsmDeclarationUsed.expected
similarity index 100%
rename from cpp/autosar/test/rules/A7-4-1/AsmDeclarationUsed.expected
rename to cpp/common/test/rules/asmdeclarationused/AsmDeclarationUsed.expected
diff --git a/cpp/common/test/rules/asmdeclarationused/AsmDeclarationUsed.ql b/cpp/common/test/rules/asmdeclarationused/AsmDeclarationUsed.ql
new file mode 100644
index 0000000000..5e60570f5a
--- /dev/null
+++ b/cpp/common/test/rules/asmdeclarationused/AsmDeclarationUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.asmdeclarationused.AsmDeclarationUsed
+
+class TestFileQuery extends AsmDeclarationUsedSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A7-4-1/test.cpp b/cpp/common/test/rules/asmdeclarationused/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A7-4-1/test.cpp
rename to cpp/common/test/rules/asmdeclarationused/test.cpp
diff --git a/cpp/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.expected b/cpp/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.expected
new file mode 100644
index 0000000000..9a849af3f4
--- /dev/null
+++ b/cpp/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.expected
@@ -0,0 +1,4 @@
+| test.cpp:8:14:8:17 | call to atof | Call to banned function atof. |
+| test.cpp:9:12:9:15 | call to atoi | Call to banned function atoi. |
+| test.cpp:10:13:10:16 | call to atol | Call to banned function atol. |
+| test.cpp:11:18:11:22 | call to atoll | Call to banned function atoll. |
diff --git a/cpp/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.ql b/cpp/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.ql
new file mode 100644
index 0000000000..6da5fe6097
--- /dev/null
+++ b/cpp/common/test/rules/atofatoiatolandatollused/AtofAtoiAtolAndAtollUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.atofatoiatolandatollused.AtofAtoiAtolAndAtollUsed
+
+class TestFileQuery extends AtofAtoiAtolAndAtollUsedSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-21-7/test.c b/cpp/common/test/rules/atofatoiatolandatollused/test.cpp
similarity index 66%
rename from c/misra/test/rules/RULE-21-7/test.c
rename to cpp/common/test/rules/atofatoiatolandatollused/test.cpp
index 141dd061d3..c995df6aad 100644
--- a/c/misra/test/rules/RULE-21-7/test.c
+++ b/cpp/common/test/rules/atofatoiatolandatollused/test.cpp
@@ -1,8 +1,10 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
#include
#include
void f2();
void f1() {
- char l1[5] = "abcde";
+ char l1[5] = "abcd";
float l2 = atof(l1); // NON_COMLIANT
int l3 = atoi(l1); // NON_COMPLIANT
long l4 = atol(l1); // NON_COMPLIANT
diff --git a/cpp/autosar/test/rules/A2-13-1/EscapeSequenceOutsideISO.expected b/cpp/common/test/rules/backslashcharactermisuse/BackslashCharacterMisuse.expected
similarity index 100%
rename from cpp/autosar/test/rules/A2-13-1/EscapeSequenceOutsideISO.expected
rename to cpp/common/test/rules/backslashcharactermisuse/BackslashCharacterMisuse.expected
diff --git a/cpp/common/test/rules/backslashcharactermisuse/BackslashCharacterMisuse.ql b/cpp/common/test/rules/backslashcharactermisuse/BackslashCharacterMisuse.ql
new file mode 100644
index 0000000000..aa32fa3096
--- /dev/null
+++ b/cpp/common/test/rules/backslashcharactermisuse/BackslashCharacterMisuse.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.backslashcharactermisuse.BackslashCharacterMisuse
+
+class TestFileQuery extends BackslashCharacterMisuseSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A2-13-1/test.cpp b/cpp/common/test/rules/backslashcharactermisuse/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A2-13-1/test.cpp
rename to cpp/common/test/rules/backslashcharactermisuse/test.cpp
diff --git a/cpp/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.expected b/cpp/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.expected
new file mode 100644
index 0000000000..346a557e32
--- /dev/null
+++ b/cpp/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.expected
@@ -0,0 +1,4 @@
+| test.cpp:9:7:9:8 | x1 | Bit-field 'x1' is declared on type 'int'. |
+| test.cpp:13:15:13:16 | x5 | Bit-field 'x5' is declared on type 'signed long'. |
+| test.cpp:15:15:15:16 | x6 | Bit-field 'x6' is declared on type 'signed char'. |
+| test.cpp:17:14:17:15 | x7 | Bit-field 'x7' is declared on type 'Color'. |
diff --git a/cpp/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.ql b/cpp/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.ql
new file mode 100644
index 0000000000..a3e1ecc76c
--- /dev/null
+++ b/cpp/common/test/rules/bitfieldshallhaveanappropriatetype/BitFieldShallHaveAnAppropriateType.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.bitfieldshallhaveanappropriatetype.BitFieldShallHaveAnAppropriateType
+
+class TestFileQuery extends BitFieldShallHaveAnAppropriateTypeSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/bitfieldshallhaveanappropriatetype/test.cpp b/cpp/common/test/rules/bitfieldshallhaveanappropriatetype/test.cpp
new file mode 100644
index 0000000000..96b28997c4
--- /dev/null
+++ b/cpp/common/test/rules/bitfieldshallhaveanappropriatetype/test.cpp
@@ -0,0 +1,18 @@
+
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+typedef unsigned int UINT16;
+
+enum Color { R, G, B };
+
+struct SampleStruct {
+ int x1 : 2; // NON_COMPLIANT - not explicitly signed or unsigned
+ unsigned int x2 : 2; // COMPLIANT - explicitly unsigned
+ signed int x3 : 2; // COMPLIANT - explicitly signed
+ UINT16 x4 : 2; // COMPLIANT - type alias resolves to a compliant type
+ signed long x5 : 2; // NON_COMPLIANT - cannot declare bit field for long, even
+ // if it's signed
+ signed char x6 : 2; // NON_COMPLIANT - cannot declare bit field for char, even
+ // if it's signed
+ enum Color x7 : 3; // NON_COMPLIANT - cannot declare bit field for enum
+} sample_struct;
diff --git a/cpp/autosar/test/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.expected b/cpp/common/test/rules/builtinunaryoperatorappliedtounsignedexpression/BuiltInUnaryOperatorAppliedToUnsignedExpression.expected
similarity index 100%
rename from cpp/autosar/test/rules/M5-3-2/UnaryMinusOperatorAppliedToAnExpressionWhoseUnderlyingTypeIsUnsigned.expected
rename to cpp/common/test/rules/builtinunaryoperatorappliedtounsignedexpression/BuiltInUnaryOperatorAppliedToUnsignedExpression.expected
diff --git a/cpp/common/test/rules/builtinunaryoperatorappliedtounsignedexpression/BuiltInUnaryOperatorAppliedToUnsignedExpression.ql b/cpp/common/test/rules/builtinunaryoperatorappliedtounsignedexpression/BuiltInUnaryOperatorAppliedToUnsignedExpression.ql
new file mode 100644
index 0000000000..3f5110e299
--- /dev/null
+++ b/cpp/common/test/rules/builtinunaryoperatorappliedtounsignedexpression/BuiltInUnaryOperatorAppliedToUnsignedExpression.ql
@@ -0,0 +1,5 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.builtinunaryoperatorappliedtounsignedexpression.BuiltInUnaryOperatorAppliedToUnsignedExpression
+
+class TestFileQuery extends BuiltInUnaryOperatorAppliedToUnsignedExpressionSharedQuery, TestQuery {
+}
diff --git a/cpp/autosar/test/rules/M5-3-2/test.cpp b/cpp/common/test/rules/builtinunaryoperatorappliedtounsignedexpression/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M5-3-2/test.cpp
rename to cpp/common/test/rules/builtinunaryoperatorappliedtounsignedexpression/test.cpp
diff --git a/cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.expected b/cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.expected
new file mode 100644
index 0000000000..24493879f0
--- /dev/null
+++ b/cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.expected
@@ -0,0 +1,2 @@
+| test.cpp:3:3:3:34 | reinterpret_cast<..(*)(..)>... | Cast converting a pointer to function. |
+| test.cpp:4:3:4:30 | reinterpret_cast... | Cast converting a pointer to function. |
diff --git a/cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.ql b/cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.ql
new file mode 100644
index 0000000000..fd716b8570
--- /dev/null
+++ b/cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/CastsBetweenAPointerToFunctionAndAnyOtherType.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.castsbetweenapointertofunctionandanyothertype.CastsBetweenAPointerToFunctionAndAnyOtherType
+
+class TestFileQuery extends CastsBetweenAPointerToFunctionAndAnyOtherTypeSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M5-2-6/test.cpp b/cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/test.cpp
similarity index 99%
rename from cpp/autosar/test/rules/M5-2-6/test.cpp
rename to cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/test.cpp
index ac14351b00..aad03a054e 100644
--- a/cpp/autosar/test/rules/M5-2-6/test.cpp
+++ b/cpp/common/test/rules/castsbetweenapointertofunctionandanyothertype/test.cpp
@@ -1,3 +1,4 @@
+
void f(int) {
reinterpret_cast(&f); // NON_COMPLIANT
reinterpret_cast(&f); // NON_COMPLIANT
diff --git a/cpp/autosar/test/rules/M2-7-1/SlashStarUsedWithinACStyleComment.expected b/cpp/common/test/rules/charactersequenceusedwithinacstylecomment/CharacterSequenceUsedWithinACStyleComment.expected
similarity index 100%
rename from cpp/autosar/test/rules/M2-7-1/SlashStarUsedWithinACStyleComment.expected
rename to cpp/common/test/rules/charactersequenceusedwithinacstylecomment/CharacterSequenceUsedWithinACStyleComment.expected
diff --git a/cpp/common/test/rules/charactersequenceusedwithinacstylecomment/CharacterSequenceUsedWithinACStyleComment.ql b/cpp/common/test/rules/charactersequenceusedwithinacstylecomment/CharacterSequenceUsedWithinACStyleComment.ql
new file mode 100644
index 0000000000..3fd1cf77ba
--- /dev/null
+++ b/cpp/common/test/rules/charactersequenceusedwithinacstylecomment/CharacterSequenceUsedWithinACStyleComment.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.charactersequenceusedwithinacstylecomment.CharacterSequenceUsedWithinACStyleComment
+
+class TestFileQuery extends CharacterSequenceUsedWithinACStyleCommentSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M2-7-1/test.cpp b/cpp/common/test/rules/charactersequenceusedwithinacstylecomment/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M2-7-1/test.cpp
rename to cpp/common/test/rules/charactersequenceusedwithinacstylecomment/test.cpp
diff --git a/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected b/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
new file mode 100644
index 0000000000..2caa0d197c
--- /dev/null
+++ b/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.expected
@@ -0,0 +1,20 @@
+problems
+| test.cpp:11:8:11:12 | c_str | test.cpp:18:16:18:21 | call to getenv | test.cpp:11:8:11:12 | c_str | The object returned by the function getenv should not be modified. |
+| 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 | 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 |
+| test.cpp:18:16:18:21 | call to getenv | semmle.label | call to getenv |
+| test.cpp:24:9:24:12 | env1 | semmle.label | env1 |
+| test.cpp:64:11:64:20 | call to localeconv | semmle.label | call to localeconv |
+| test.cpp:67:5:67:9 | conv4 | semmle.label | conv4 |
+| test.cpp:72:25:72:34 | call to localeconv | semmle.label | call to localeconv |
+| test.cpp:76:5:76:8 | conv | semmle.label | conv |
+subpaths
diff --git a/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.ql b/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.ql
new file mode 100644
index 0000000000..53c27eb3ce
--- /dev/null
+++ b/cpp/common/test/rules/constlikereturnvalue/ConstLikeReturnValue.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.constlikereturnvalue.ConstLikeReturnValue
+
+class TestFileQuery extends ConstLikeReturnValueSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/constlikereturnvalue/test.cpp b/cpp/common/test/rules/constlikereturnvalue/test.cpp
new file mode 100644
index 0000000000..19db17faee
--- /dev/null
+++ b/cpp/common/test/rules/constlikereturnvalue/test.cpp
@@ -0,0 +1,96 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#include
+#include
+#include
+#include
+
+void trstr(char *c_str, char orig, char rep) {
+ while (*c_str != '\0') {
+ if (*c_str == orig) {
+ *c_str = rep; // NON_COMPLIANT
+ }
+ ++c_str;
+ }
+}
+
+void f1(void) {
+ char *env1 = getenv("TEST_ENV");
+ char *copy_of_env;
+ copy_of_env = env1; // COMPLIANT
+
+ if (env1 == NULL) {
+ }
+ trstr(env1, '"', '_');
+}
+
+void f2(void) {
+ const char *env2;
+ char *copy_of_env;
+
+ env2 = getenv("TEST_ENV");
+ if (env2 == NULL) {
+ }
+
+ copy_of_env = (char *)malloc(strlen(env2) + 1);
+ if (copy_of_env == NULL) {
+ }
+
+ strcpy(copy_of_env, env2);
+ trstr(copy_of_env, '"', '_'); // COMPLIANT
+}
+
+void f3(void) {
+ const char *env3;
+ char *copy_of_env;
+
+ env3 = getenv("TEST_ENV");
+ if (env3 == NULL) {
+ }
+
+ copy_of_env = strdup(env3);
+ if (copy_of_env == NULL) {
+ }
+
+ trstr(copy_of_env, '"', '_'); // COMPLIANT
+ if (setenv("TEST_ENV", copy_of_env, 1) != 0) {
+ }
+}
+
+void f4(void) {
+ struct lconv *conv4 = localeconv();
+
+ setlocale(LC_ALL, "C"); // COMPLIANT
+ conv4 = localeconv(); // COMPLIANT
+
+ if ('\0' == conv4->decimal_point[0]) {
+ conv4->decimal_point = "."; // NON_COMPLIANT
+ }
+}
+
+void f4alias(void) {
+ struct lconv *conv4 = localeconv();
+ struct lconv *conv = conv4;
+
+ if ('\0' == conv4->decimal_point[0]) {
+ conv->decimal_point = "."; // NON_COMPLIANT
+ }
+}
+
+void f5(void) {
+ const struct lconv *conv5 = localeconv();
+ if (conv5 == NULL) {
+ }
+
+ struct lconv *copy_of_conv = (struct lconv *)malloc(sizeof(struct lconv));
+ if (copy_of_conv == NULL) {
+ }
+
+ memcpy(copy_of_conv, conv5, sizeof(struct lconv));
+
+ if ('\0' == copy_of_conv->decimal_point[0]) {
+ copy_of_conv->decimal_point = "."; // COMPLIANT
+ }
+
+ free(copy_of_conv);
+}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.expected b/cpp/common/test/rules/copyandmoveassignmentsshallhandleselfassignment/CopyAndMoveAssignmentsShallHandleSelfAssignment.expected
similarity index 100%
rename from cpp/autosar/test/rules/A12-8-5/CopyAssignmentAndAMoveHandleSelfAssignment.expected
rename to cpp/common/test/rules/copyandmoveassignmentsshallhandleselfassignment/CopyAndMoveAssignmentsShallHandleSelfAssignment.expected
diff --git a/cpp/common/test/rules/copyandmoveassignmentsshallhandleselfassignment/CopyAndMoveAssignmentsShallHandleSelfAssignment.ql b/cpp/common/test/rules/copyandmoveassignmentsshallhandleselfassignment/CopyAndMoveAssignmentsShallHandleSelfAssignment.ql
new file mode 100644
index 0000000000..9e84431f65
--- /dev/null
+++ b/cpp/common/test/rules/copyandmoveassignmentsshallhandleselfassignment/CopyAndMoveAssignmentsShallHandleSelfAssignment.ql
@@ -0,0 +1,5 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.copyandmoveassignmentsshallhandleselfassignment.CopyAndMoveAssignmentsShallHandleSelfAssignment
+
+class TestFileQuery extends CopyAndMoveAssignmentsShallHandleSelfAssignmentSharedQuery, TestQuery {
+}
diff --git a/cpp/autosar/test/rules/A12-8-5/test.cpp b/cpp/common/test/rules/copyandmoveassignmentsshallhandleselfassignment/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A12-8-5/test.cpp
rename to cpp/common/test/rules/copyandmoveassignmentsshallhandleselfassignment/test.cpp
diff --git a/cpp/autosar/test/rules/M18-7-1/CsignalFunctionsUsed.expected b/cpp/common/test/rules/csignalfunctionsused/CsignalFunctionsUsed.expected
similarity index 100%
rename from cpp/autosar/test/rules/M18-7-1/CsignalFunctionsUsed.expected
rename to cpp/common/test/rules/csignalfunctionsused/CsignalFunctionsUsed.expected
diff --git a/cpp/common/test/rules/csignalfunctionsused/CsignalFunctionsUsed.ql b/cpp/common/test/rules/csignalfunctionsused/CsignalFunctionsUsed.ql
new file mode 100644
index 0000000000..1d39069ae7
--- /dev/null
+++ b/cpp/common/test/rules/csignalfunctionsused/CsignalFunctionsUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.csignalfunctionsused.CsignalFunctionsUsed
+
+class TestFileQuery extends CsignalFunctionsUsedSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M18-7-1/test.cpp b/cpp/common/test/rules/csignalfunctionsused/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M18-7-1/test.cpp
rename to cpp/common/test/rules/csignalfunctionsused/test.cpp
diff --git a/cpp/autosar/test/rules/M18-7-1/CsignalTypesUsed.expected b/cpp/common/test/rules/csignaltypesused/CsignalTypesUsed.expected
similarity index 100%
rename from cpp/autosar/test/rules/M18-7-1/CsignalTypesUsed.expected
rename to cpp/common/test/rules/csignaltypesused/CsignalTypesUsed.expected
diff --git a/cpp/common/test/rules/csignaltypesused/CsignalTypesUsed.ql b/cpp/common/test/rules/csignaltypesused/CsignalTypesUsed.ql
new file mode 100644
index 0000000000..76cc8aad04
--- /dev/null
+++ b/cpp/common/test/rules/csignaltypesused/CsignalTypesUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.csignaltypesused.CsignalTypesUsed
+
+class TestFileQuery extends CsignalTypesUsedSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/csignaltypesused/test.cpp b/cpp/common/test/rules/csignaltypesused/test.cpp
new file mode 100644
index 0000000000..e621160b81
--- /dev/null
+++ b/cpp/common/test/rules/csignaltypesused/test.cpp
@@ -0,0 +1,13 @@
+#include
+
+void signal_handler(int signal) {}
+
+void test_signal_is_used() {
+ std::sig_atomic_t atom; // NON_COMPLIANT
+ std::signal(SIGINT, signal_handler); // NON_COMPLIANT
+ std::raise(SIGINT); // NON_COMPLIANT
+
+ sig_atomic_t atom1; // NON_COMPLIANT
+ signal(SIGINT, signal_handler); // NON_COMPLIANT
+ raise(SIGINT); // NON_COMPLIANT
+}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M27-0-1/CstdioFunctionsUsed.expected b/cpp/common/test/rules/cstdiofunctionsused/CstdioFunctionsUsed.expected
similarity index 100%
rename from cpp/autosar/test/rules/M27-0-1/CstdioFunctionsUsed.expected
rename to cpp/common/test/rules/cstdiofunctionsused/CstdioFunctionsUsed.expected
diff --git a/cpp/common/test/rules/cstdiofunctionsused/CstdioFunctionsUsed.ql b/cpp/common/test/rules/cstdiofunctionsused/CstdioFunctionsUsed.ql
new file mode 100644
index 0000000000..16dbb974b6
--- /dev/null
+++ b/cpp/common/test/rules/cstdiofunctionsused/CstdioFunctionsUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.cstdiofunctionsused.CstdioFunctionsUsed
+
+class TestFileQuery extends CstdioFunctionsUsedSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M27-0-1/test.cpp b/cpp/common/test/rules/cstdiofunctionsused/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M27-0-1/test.cpp
rename to cpp/common/test/rules/cstdiofunctionsused/test.cpp
diff --git a/cpp/autosar/test/rules/M27-0-1/CstdioMacrosUsed.expected b/cpp/common/test/rules/cstdiomacrosused/CstdioMacrosUsed.expected
similarity index 100%
rename from cpp/autosar/test/rules/M27-0-1/CstdioMacrosUsed.expected
rename to cpp/common/test/rules/cstdiomacrosused/CstdioMacrosUsed.expected
diff --git a/cpp/common/test/rules/cstdiomacrosused/CstdioMacrosUsed.ql b/cpp/common/test/rules/cstdiomacrosused/CstdioMacrosUsed.ql
new file mode 100644
index 0000000000..79ab6086b1
--- /dev/null
+++ b/cpp/common/test/rules/cstdiomacrosused/CstdioMacrosUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.cstdiomacrosused.CstdioMacrosUsed
+
+class TestFileQuery extends CstdioMacrosUsedSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/cstdiomacrosused/test.cpp b/cpp/common/test/rules/cstdiomacrosused/test.cpp
new file mode 100644
index 0000000000..27447ba06a
--- /dev/null
+++ b/cpp/common/test/rules/cstdiomacrosused/test.cpp
@@ -0,0 +1,61 @@
+#include
+#include
+void *test_cstdio_is_used() {
+ std::FILE *f = std::fopen("foo.txt", "r"); // NON_COMPLIANT
+
+ std::fpos_t init_position; // NON_COMPLIANT
+ std::fgetpos(f, &init_position); // NON_COMPLIANT
+
+ while (!std::feof(f)) { // NON_COMPLIANT
+ char c = std::fgetc(f); // NON_COMPLIANT
+ if (c == EOF) // NON_COMPLIANT
+ std::rewind(f); // NON_COMPLIANT
+ }
+ if (std::ferror(f)) { // NON_COMPLIANT
+ std::clearerr(f); // NON_COMPLIANT
+ std::fclose(f); // NON_COMPLIANT
+ std::perror("fgetc"); // NON_COMPLIANT
+ }
+
+ std::fseek(f, (size_t)0, SEEK_SET); // NON_COMPLIANT
+ std::fseek(f, (size_t)0, SEEK_END); // NON_COMPLIANT
+ char buf[BUFSIZ]; // NON_COMPLIANT
+ std::fread(buf, 1, sizeof(buf), f); // NON_COMPLIANT
+
+ std::fsetpos(f, &init_position); // NON_COMPLIANT
+ std::fflush(f); // NON_COMPLIANT
+ std::fclose(f); // NON_COMPLIANT
+
+ std::printf("DEBUG: TMP_MAX=%d FILENAME_MAX=%d FOPEN_MAX=%d\n", TMP_MAX,
+ FILENAME_MAX, FOPEN_MAX); // NON_COMPLIANT
+ std::puts("all done!"); // NON_COMPLIANT
+
+ // global namespace
+ FILE *f1 = fopen("foo.txt", "r"); // NON_COMPLIANT
+
+ fpos_t init_position1;
+ fgetpos(f1, &init_position1); // NON_COMPLIANT
+
+ while (!feof(f1)) { // NON_COMPLIANT
+ char c = fgetc(f1); // NON_COMPLIANT
+ if (c == EOF) // NON_COMPLIANT
+ rewind(f1); // NON_COMPLIANT
+ }
+ if (ferror(f1)) { // NON_COMPLIANT
+ clearerr(f1); // NON_COMPLIANT
+ fclose(f1); // NON_COMPLIANT
+ perror("fgetc"); // NON_COMPLIANT
+ }
+
+ fseek(f1, (size_t)0, SEEK_SET); // NON_COMPLIANT
+ fread(buf, 1, sizeof(buf), f1); // NON_COMPLIANT
+
+ fsetpos(f1, &init_position1); // NON_COMPLIANT
+ fflush(f1); // NON_COMPLIANT
+ fclose(f1); // NON_COMPLIANT
+
+ printf("foo"); // NON_COMPLIANT
+ puts("all done!"); // NON_COMPLIANT
+
+ return NULL; // COMPLIANT - NULL is not uniquely defined by cstdio
+}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M27-0-1/CstdioTypesUsed.expected b/cpp/common/test/rules/cstdiotypesused/CstdioTypesUsed.expected
similarity index 100%
rename from cpp/autosar/test/rules/M27-0-1/CstdioTypesUsed.expected
rename to cpp/common/test/rules/cstdiotypesused/CstdioTypesUsed.expected
diff --git a/cpp/common/test/rules/cstdiotypesused/CstdioTypesUsed.ql b/cpp/common/test/rules/cstdiotypesused/CstdioTypesUsed.ql
new file mode 100644
index 0000000000..c5bac15c65
--- /dev/null
+++ b/cpp/common/test/rules/cstdiotypesused/CstdioTypesUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.cstdiotypesused.CstdioTypesUsed
+
+class TestFileQuery extends CstdioTypesUsedSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/cstdiotypesused/test.cpp b/cpp/common/test/rules/cstdiotypesused/test.cpp
new file mode 100644
index 0000000000..27447ba06a
--- /dev/null
+++ b/cpp/common/test/rules/cstdiotypesused/test.cpp
@@ -0,0 +1,61 @@
+#include
+#include
+void *test_cstdio_is_used() {
+ std::FILE *f = std::fopen("foo.txt", "r"); // NON_COMPLIANT
+
+ std::fpos_t init_position; // NON_COMPLIANT
+ std::fgetpos(f, &init_position); // NON_COMPLIANT
+
+ while (!std::feof(f)) { // NON_COMPLIANT
+ char c = std::fgetc(f); // NON_COMPLIANT
+ if (c == EOF) // NON_COMPLIANT
+ std::rewind(f); // NON_COMPLIANT
+ }
+ if (std::ferror(f)) { // NON_COMPLIANT
+ std::clearerr(f); // NON_COMPLIANT
+ std::fclose(f); // NON_COMPLIANT
+ std::perror("fgetc"); // NON_COMPLIANT
+ }
+
+ std::fseek(f, (size_t)0, SEEK_SET); // NON_COMPLIANT
+ std::fseek(f, (size_t)0, SEEK_END); // NON_COMPLIANT
+ char buf[BUFSIZ]; // NON_COMPLIANT
+ std::fread(buf, 1, sizeof(buf), f); // NON_COMPLIANT
+
+ std::fsetpos(f, &init_position); // NON_COMPLIANT
+ std::fflush(f); // NON_COMPLIANT
+ std::fclose(f); // NON_COMPLIANT
+
+ std::printf("DEBUG: TMP_MAX=%d FILENAME_MAX=%d FOPEN_MAX=%d\n", TMP_MAX,
+ FILENAME_MAX, FOPEN_MAX); // NON_COMPLIANT
+ std::puts("all done!"); // NON_COMPLIANT
+
+ // global namespace
+ FILE *f1 = fopen("foo.txt", "r"); // NON_COMPLIANT
+
+ fpos_t init_position1;
+ fgetpos(f1, &init_position1); // NON_COMPLIANT
+
+ while (!feof(f1)) { // NON_COMPLIANT
+ char c = fgetc(f1); // NON_COMPLIANT
+ if (c == EOF) // NON_COMPLIANT
+ rewind(f1); // NON_COMPLIANT
+ }
+ if (ferror(f1)) { // NON_COMPLIANT
+ clearerr(f1); // NON_COMPLIANT
+ fclose(f1); // NON_COMPLIANT
+ perror("fgetc"); // NON_COMPLIANT
+ }
+
+ fseek(f1, (size_t)0, SEEK_SET); // NON_COMPLIANT
+ fread(buf, 1, sizeof(buf), f1); // NON_COMPLIANT
+
+ fsetpos(f1, &init_position1); // NON_COMPLIANT
+ fflush(f1); // NON_COMPLIANT
+ fclose(f1); // NON_COMPLIANT
+
+ printf("foo"); // NON_COMPLIANT
+ puts("all done!"); // NON_COMPLIANT
+
+ return NULL; // COMPLIANT - NULL is not uniquely defined by cstdio
+}
\ No newline at end of file
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/autosar/test/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.expected b/cpp/common/test/rules/definitionnotconsideredforunqualifiedlookup/DefinitionNotConsideredForUnqualifiedLookup.expected
similarity index 100%
rename from cpp/autosar/test/rules/A7-3-1/DefinitionNotConsideredForUnqualifiedLookup.expected
rename to cpp/common/test/rules/definitionnotconsideredforunqualifiedlookup/DefinitionNotConsideredForUnqualifiedLookup.expected
diff --git a/cpp/common/test/rules/definitionnotconsideredforunqualifiedlookup/DefinitionNotConsideredForUnqualifiedLookup.ql b/cpp/common/test/rules/definitionnotconsideredforunqualifiedlookup/DefinitionNotConsideredForUnqualifiedLookup.ql
new file mode 100644
index 0000000000..05457c997c
--- /dev/null
+++ b/cpp/common/test/rules/definitionnotconsideredforunqualifiedlookup/DefinitionNotConsideredForUnqualifiedLookup.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.definitionnotconsideredforunqualifiedlookup.DefinitionNotConsideredForUnqualifiedLookup
+
+class TestFileQuery extends DefinitionNotConsideredForUnqualifiedLookupSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A7-3-1/test.cpp b/cpp/common/test/rules/definitionnotconsideredforunqualifiedlookup/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A7-3-1/test.cpp
rename to cpp/common/test/rules/definitionnotconsideredforunqualifiedlookup/test.cpp
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..2d293e6928 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 | Config |
+| 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 | Config |
+| 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..cab80e0fe0 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 | Config |
+| 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 | Config |
+| 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 | Config |
+| 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/autosar/test/rules/M15-1-3/EmptyThrowOutsideCatch.expected b/cpp/common/test/rules/emptythrowonlywithinacatchhandler/EmptyThrowOnlyWithinACatchHandler.expected
similarity index 100%
rename from cpp/autosar/test/rules/M15-1-3/EmptyThrowOutsideCatch.expected
rename to cpp/common/test/rules/emptythrowonlywithinacatchhandler/EmptyThrowOnlyWithinACatchHandler.expected
diff --git a/cpp/common/test/rules/emptythrowonlywithinacatchhandler/EmptyThrowOnlyWithinACatchHandler.ql b/cpp/common/test/rules/emptythrowonlywithinacatchhandler/EmptyThrowOnlyWithinACatchHandler.ql
new file mode 100644
index 0000000000..a07b861639
--- /dev/null
+++ b/cpp/common/test/rules/emptythrowonlywithinacatchhandler/EmptyThrowOnlyWithinACatchHandler.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.emptythrowonlywithinacatchhandler.EmptyThrowOnlyWithinACatchHandler
+
+class TestFileQuery extends EmptyThrowOnlyWithinACatchHandlerSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M15-1-3/test.cpp b/cpp/common/test/rules/emptythrowonlywithinacatchhandler/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M15-1-3/test.cpp
rename to cpp/common/test/rules/emptythrowonlywithinacatchhandler/test.cpp
diff --git a/cpp/autosar/test/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.expected b/cpp/common/test/rules/enumerationnotdefinedwithanexplicitunderlyingtype/EnumerationNotDefinedWithAnExplicitUnderlyingType.expected
similarity index 100%
rename from cpp/autosar/test/rules/A7-2-2/EnumerationUnderlyingBaseTypeNotExplicitlyDefined.expected
rename to cpp/common/test/rules/enumerationnotdefinedwithanexplicitunderlyingtype/EnumerationNotDefinedWithAnExplicitUnderlyingType.expected
diff --git a/cpp/common/test/rules/enumerationnotdefinedwithanexplicitunderlyingtype/EnumerationNotDefinedWithAnExplicitUnderlyingType.ql b/cpp/common/test/rules/enumerationnotdefinedwithanexplicitunderlyingtype/EnumerationNotDefinedWithAnExplicitUnderlyingType.ql
new file mode 100644
index 0000000000..999f505c5f
--- /dev/null
+++ b/cpp/common/test/rules/enumerationnotdefinedwithanexplicitunderlyingtype/EnumerationNotDefinedWithAnExplicitUnderlyingType.ql
@@ -0,0 +1,5 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.enumerationnotdefinedwithanexplicitunderlyingtype.EnumerationNotDefinedWithAnExplicitUnderlyingType
+
+class TestFileQuery extends EnumerationNotDefinedWithAnExplicitUnderlyingTypeSharedQuery, TestQuery {
+}
diff --git a/cpp/autosar/test/rules/A7-2-2/test.cpp b/cpp/common/test/rules/enumerationnotdefinedwithanexplicitunderlyingtype/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A7-2-2/test.cpp
rename to cpp/common/test/rules/enumerationnotdefinedwithanexplicitunderlyingtype/test.cpp
diff --git a/cpp/autosar/test/rules/A15-1-2/PointerExceptionObject.expected b/cpp/common/test/rules/exceptionobjecthavepointertype/ExceptionObjectHavePointerType.expected
similarity index 100%
rename from cpp/autosar/test/rules/A15-1-2/PointerExceptionObject.expected
rename to cpp/common/test/rules/exceptionobjecthavepointertype/ExceptionObjectHavePointerType.expected
diff --git a/cpp/common/test/rules/exceptionobjecthavepointertype/ExceptionObjectHavePointerType.ql b/cpp/common/test/rules/exceptionobjecthavepointertype/ExceptionObjectHavePointerType.ql
new file mode 100644
index 0000000000..d0727790d3
--- /dev/null
+++ b/cpp/common/test/rules/exceptionobjecthavepointertype/ExceptionObjectHavePointerType.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.exceptionobjecthavepointertype.ExceptionObjectHavePointerType
+
+class TestFileQuery extends ExceptionObjectHavePointerTypeSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A15-1-2/test.cpp b/cpp/common/test/rules/exceptionobjecthavepointertype/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A15-1-2/test.cpp
rename to cpp/common/test/rules/exceptionobjecthavepointertype/test.cpp
diff --git a/cpp/autosar/test/rules/A18-9-2/ForwardingValuesToOtherFunctions.expected b/cpp/common/test/rules/forwardingreferencesandforwardnotusedtogether/ForwardingReferencesAndForwardNotUsedTogether.expected
similarity index 100%
rename from cpp/autosar/test/rules/A18-9-2/ForwardingValuesToOtherFunctions.expected
rename to cpp/common/test/rules/forwardingreferencesandforwardnotusedtogether/ForwardingReferencesAndForwardNotUsedTogether.expected
diff --git a/cpp/common/test/rules/forwardingreferencesandforwardnotusedtogether/ForwardingReferencesAndForwardNotUsedTogether.ql b/cpp/common/test/rules/forwardingreferencesandforwardnotusedtogether/ForwardingReferencesAndForwardNotUsedTogether.ql
new file mode 100644
index 0000000000..4f08530f35
--- /dev/null
+++ b/cpp/common/test/rules/forwardingreferencesandforwardnotusedtogether/ForwardingReferencesAndForwardNotUsedTogether.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.forwardingreferencesandforwardnotusedtogether.ForwardingReferencesAndForwardNotUsedTogether
+
+class TestFileQuery extends ForwardingReferencesAndForwardNotUsedTogetherSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A18-9-2/test.cpp b/cpp/common/test/rules/forwardingreferencesandforwardnotusedtogether/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A18-9-2/test.cpp
rename to cpp/common/test/rules/forwardingreferencesandforwardnotusedtogether/test.cpp
diff --git a/cpp/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.expected b/cpp/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.expected
new file mode 100644
index 0000000000..62787cca0b
--- /dev/null
+++ b/cpp/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.expected
@@ -0,0 +1,2 @@
+| test.cpp:8:1:8:25 | #define MACRO4(x) (x + 1) | Macro used instead of a function. |
+| test.cpp:13:1:13:48 | #define MACRO9() printf_custom("output = %d", 7) | Macro used instead of a function. |
diff --git a/cpp/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.ql b/cpp/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.ql
new file mode 100644
index 0000000000..29088c4458
--- /dev/null
+++ b/cpp/common/test/rules/functionlikemacrosdefined/FunctionLikeMacrosDefined.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.functionlikemacrosdefined.FunctionLikeMacrosDefined
+
+class TestFileQuery extends FunctionLikeMacrosDefinedSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/functionlikemacrosdefined/test.cpp b/cpp/common/test/rules/functionlikemacrosdefined/test.cpp
new file mode 100644
index 0000000000..f39236ca3b
--- /dev/null
+++ b/cpp/common/test/rules/functionlikemacrosdefined/test.cpp
@@ -0,0 +1,42 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#include
+
+#define MACRO(OP, L, R) ((L)OP(R)) // COMPLIANT
+#define MACRO2(L, R) (L + R) // COMPLIANT
+#define MACRO3(L, R) (L " " R " " L) // COMPLIANT
+#define MACRO4(x) (x + 1) // NON_COMPLIANT
+#define MACRO5(L, LR) (LR + 1) // COMPLIANT
+#define MACRO6(x) printf_custom("output = %d", test##x) // COMPLIANT
+#define MACRO7(x) #x // COMPLIANT
+#define MACRO8(x) "NOP" // COMPLIANT
+#define MACRO9() printf_custom("output = %d", 7) // NON_COMPLIANT
+#define MACRO10(x) // COMPLIANT
+#define MY_ASSERT(X) assert(X) // NON_COMPLIANT[FALSE_NEGATIVE]
+
+char a1[MACRO2(1, 1) + 6];
+extern int printf_custom(char *, int);
+int test1;
+
+void f() {
+ int i = MACRO(+, 1, 1);
+ int i2 = MACRO2(7, 10);
+
+ static int i3 = MACRO2(1, 1);
+
+ char *i4 = MACRO3("prefix", "suffix");
+
+ int i5 = MACRO4(1);
+
+ int i6 = MACRO4(MACRO2(1, 1));
+
+ int i7 = MACRO5(1, 1);
+
+ MACRO6(1);
+
+ char *i10 = MACRO7("prefix");
+
+ asm(MACRO8(1));
+
+ MY_ASSERT(1);
+}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-5-2/RecursiveFunctions.expected b/cpp/common/test/rules/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.expected
similarity index 100%
rename from cpp/autosar/test/rules/A7-5-2/RecursiveFunctions.expected
rename to cpp/common/test/rules/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.expected
diff --git a/cpp/common/test/rules/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.ql b/cpp/common/test/rules/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.ql
new file mode 100644
index 0000000000..e95ba9b7f7
--- /dev/null
+++ b/cpp/common/test/rules/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.ql
@@ -0,0 +1,5 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.functionscallthemselveseitherdirectlyorindirectly.FunctionsCallThemselvesEitherDirectlyOrIndirectly
+
+class TestFileQuery extends FunctionsCallThemselvesEitherDirectlyOrIndirectlySharedQuery, TestQuery {
+}
diff --git a/cpp/autosar/test/rules/A7-5-2/test.cpp b/cpp/common/test/rules/functionscallthemselveseitherdirectlyorindirectly/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A7-5-2/test.cpp
rename to cpp/common/test/rules/functionscallthemselveseitherdirectlyorindirectly/test.cpp
diff --git a/cpp/autosar/test/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.expected b/cpp/common/test/rules/functiontemplatesexplicitlyspecialized/FunctionTemplatesExplicitlySpecialized.expected
similarity index 100%
rename from cpp/autosar/test/rules/A14-8-2/ExplicitSpecializationsOfFunctionTemplatesUsed.expected
rename to cpp/common/test/rules/functiontemplatesexplicitlyspecialized/FunctionTemplatesExplicitlySpecialized.expected
diff --git a/cpp/common/test/rules/functiontemplatesexplicitlyspecialized/FunctionTemplatesExplicitlySpecialized.ql b/cpp/common/test/rules/functiontemplatesexplicitlyspecialized/FunctionTemplatesExplicitlySpecialized.ql
new file mode 100644
index 0000000000..a64a9786b6
--- /dev/null
+++ b/cpp/common/test/rules/functiontemplatesexplicitlyspecialized/FunctionTemplatesExplicitlySpecialized.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.functiontemplatesexplicitlyspecialized.FunctionTemplatesExplicitlySpecialized
+
+class TestFileQuery extends FunctionTemplatesExplicitlySpecializedSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A14-8-2/test.cpp b/cpp/common/test/rules/functiontemplatesexplicitlyspecialized/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A14-8-2/test.cpp
rename to cpp/common/test/rules/functiontemplatesexplicitlyspecialized/test.cpp
diff --git a/cpp/autosar/test/rules/M7-3-1/GlobalNamespaceMembershipViolation.expected b/cpp/common/test/rules/globalnamespacedeclarations/GlobalNamespaceDeclarations.expected
similarity index 100%
rename from cpp/autosar/test/rules/M7-3-1/GlobalNamespaceMembershipViolation.expected
rename to cpp/common/test/rules/globalnamespacedeclarations/GlobalNamespaceDeclarations.expected
diff --git a/cpp/common/test/rules/globalnamespacedeclarations/GlobalNamespaceDeclarations.ql b/cpp/common/test/rules/globalnamespacedeclarations/GlobalNamespaceDeclarations.ql
new file mode 100644
index 0000000000..19482c5b09
--- /dev/null
+++ b/cpp/common/test/rules/globalnamespacedeclarations/GlobalNamespaceDeclarations.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.globalnamespacedeclarations.GlobalNamespaceDeclarations
+
+class TestFileQuery extends GlobalNamespaceDeclarationsSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M7-3-1/test.cpp b/cpp/common/test/rules/globalnamespacedeclarations/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M7-3-1/test.cpp
rename to cpp/common/test/rules/globalnamespacedeclarations/test.cpp
diff --git a/cpp/autosar/test/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.expected b/cpp/common/test/rules/globalsizedoperatordeletenotdefined/GlobalSizedOperatorDeleteNotDefined.expected
similarity index 100%
rename from cpp/autosar/test/rules/A18-5-4/GlobalSizedOperatorDeleteNotDefined.expected
rename to cpp/common/test/rules/globalsizedoperatordeletenotdefined/GlobalSizedOperatorDeleteNotDefined.expected
diff --git a/cpp/common/test/rules/globalsizedoperatordeletenotdefined/GlobalSizedOperatorDeleteNotDefined.ql b/cpp/common/test/rules/globalsizedoperatordeletenotdefined/GlobalSizedOperatorDeleteNotDefined.ql
new file mode 100644
index 0000000000..61d492f0c6
--- /dev/null
+++ b/cpp/common/test/rules/globalsizedoperatordeletenotdefined/GlobalSizedOperatorDeleteNotDefined.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.globalsizedoperatordeletenotdefined.GlobalSizedOperatorDeleteNotDefined
+
+class TestFileQuery extends GlobalSizedOperatorDeleteNotDefinedSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A18-5-4/test.cpp b/cpp/common/test/rules/globalsizedoperatordeletenotdefined/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A18-5-4/test.cpp
rename to cpp/common/test/rules/globalsizedoperatordeletenotdefined/test.cpp
diff --git a/cpp/common/test/rules/globalunsizedoperatordeletenotdefined/GlobalUnsizedOperatorDeleteNotDefined.expected b/cpp/common/test/rules/globalunsizedoperatordeletenotdefined/GlobalUnsizedOperatorDeleteNotDefined.expected
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cpp/common/test/rules/globalunsizedoperatordeletenotdefined/GlobalUnsizedOperatorDeleteNotDefined.ql b/cpp/common/test/rules/globalunsizedoperatordeletenotdefined/GlobalUnsizedOperatorDeleteNotDefined.ql
new file mode 100644
index 0000000000..c415cbcd70
--- /dev/null
+++ b/cpp/common/test/rules/globalunsizedoperatordeletenotdefined/GlobalUnsizedOperatorDeleteNotDefined.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.globalunsizedoperatordeletenotdefined.GlobalUnsizedOperatorDeleteNotDefined
+
+class TestFileQuery extends GlobalUnsizedOperatorDeleteNotDefinedSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/globalunsizedoperatordeletenotdefined/test.cpp b/cpp/common/test/rules/globalunsizedoperatordeletenotdefined/test.cpp
new file mode 100644
index 0000000000..8f77a41637
--- /dev/null
+++ b/cpp/common/test/rules/globalunsizedoperatordeletenotdefined/test.cpp
@@ -0,0 +1,3 @@
+
+void operator delete(void *ptr) {} // NON_COMPLIANT
+// void operator delete(void *ptr, std::size_t sz) {}
diff --git a/cpp/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.expected b/cpp/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.expected
new file mode 100644
index 0000000000..416f949eaa
--- /dev/null
+++ b/cpp/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.expected
@@ -0,0 +1,2 @@
+| test.cpp:42:3:42:10 | goto ... | The goto statement and its $@ are not declared or enclosed in the same block. | test.cpp:46:3:46:5 | label ...: | label |
+| test.cpp:57:5:57:12 | goto ... | The goto statement and its $@ are not declared or enclosed in the same block. | test.cpp:60:3:60:5 | label ...: | label |
diff --git a/cpp/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.ql b/cpp/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.ql
new file mode 100644
index 0000000000..f553135683
--- /dev/null
+++ b/cpp/common/test/rules/gotoreferencealabelinsurroundingblock/GotoReferenceALabelInSurroundingBlock.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.gotoreferencealabelinsurroundingblock.GotoReferenceALabelInSurroundingBlock
+
+class TestFileQuery extends GotoReferenceALabelInSurroundingBlockSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/gotoreferencealabelinsurroundingblock/test.cpp b/cpp/common/test/rules/gotoreferencealabelinsurroundingblock/test.cpp
new file mode 100644
index 0000000000..07ebb4b13a
--- /dev/null
+++ b/cpp/common/test/rules/gotoreferencealabelinsurroundingblock/test.cpp
@@ -0,0 +1,87 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+/*void f1() {
+ int i = 0; goto L1;
+ for (;i < 100; i++) {
+ L1: // NON_COMPLIANT - this is compiler checked
+ break;
+ }
+}*/
+
+void f2() {
+ int i = 0;
+ if (i >= 0) {
+ for (int j = 0; j < 10; j++) {
+ goto L2;
+ }
+ }
+L2: // COMPLIANT
+ return;
+}
+
+void f3() {
+ int i = 0;
+ if (i >= 0) {
+ for (int j = 0; j < 10; j++) {
+ goto L3;
+ L3: // COMPLIANT
+ break;
+ }
+ }
+}
+
+void f4() {
+ int i = 0;
+L4: // COMPLIANT
+ if (i >= 0) {
+ goto L4;
+ }
+}
+
+void f5(int p) {
+ goto L1;
+
+ switch (p) {
+ case 0:
+ L1:; // NON_COMPLIANT
+ break;
+ default:
+ break;
+ }
+}
+
+void f6(int p) {
+
+ switch (p) {
+ case 0:
+ goto L1;
+ break;
+ default:
+ L1: // NON_COMPLIANT
+ break;
+ }
+}
+
+void f7(int p) {
+L1: // COMPLIANT
+ switch (p) {
+ case 0:
+ goto L1;
+ break;
+ default:
+ break;
+ }
+}
+
+void f8(int p) {
+
+ switch (p) {
+ case 0:
+ goto L1;
+ ;
+ L1:; // COMPLIANT
+ break;
+ default:
+ break;
+ }
+}
diff --git a/cpp/common/test/rules/gotostatementcondition/GotoStatementCondition.expected b/cpp/common/test/rules/gotostatementcondition/GotoStatementCondition.expected
index c1b2f35eda..9e9d81e62c 100644
--- a/cpp/common/test/rules/gotostatementcondition/GotoStatementCondition.expected
+++ b/cpp/common/test/rules/gotostatementcondition/GotoStatementCondition.expected
@@ -1,4 +1,4 @@
-| test.cpp:7:3:7:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.cpp:7:3:7:10 | goto ... | l1 | test.cpp:3:1:3:3 | label ...: | label ...: |
-| test.cpp:19:3:19:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.cpp:19:3:19:10 | goto ... | l2 | test.cpp:15:1:15:3 | label ...: | label ...: |
-| test.cpp:21:3:21:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.cpp:21:3:21:10 | goto ... | l1 | test.cpp:14:1:14:3 | label ...: | label ...: |
-| test.cpp:26:3:26:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.cpp:26:3:26:10 | goto ... | l1 | test.cpp:25:1:25:3 | label ...: | label ...: |
+| test.cpp:9:3:9:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.cpp:9:3:9:10 | goto ... | l1 | test.cpp:5:1:5:3 | label ...: | label ...: |
+| test.cpp:21:3:21:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.cpp:21:3:21:10 | goto ... | l2 | test.cpp:17:1:17:3 | label ...: | label ...: |
+| test.cpp:23:3:23:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.cpp:23:3:23:10 | goto ... | l1 | test.cpp:16:1:16:3 | label ...: | label ...: |
+| test.cpp:28:3:28:10 | goto ... | The $@ statement jumps to a $@ that is not declared later in the same function. | test.cpp:28:3:28:10 | goto ... | l1 | test.cpp:27:1:27:3 | label ...: | label ...: |
diff --git a/cpp/common/test/rules/gotostatementcondition/test.cpp b/cpp/common/test/rules/gotostatementcondition/test.cpp
index 225c1b32f6..5854b21983 100644
--- a/cpp/common/test/rules/gotostatementcondition/test.cpp
+++ b/cpp/common/test/rules/gotostatementcondition/test.cpp
@@ -1,3 +1,5 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
void f1(int p1) {
l1:
diff --git a/cpp/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.expected b/cpp/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.expected
new file mode 100644
index 0000000000..48547e3cca
--- /dev/null
+++ b/cpp/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.expected
@@ -0,0 +1 @@
+| test.cpp:6:3:6:14 | goto ... | Use of goto. |
diff --git a/cpp/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.ql b/cpp/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.ql
new file mode 100644
index 0000000000..1a117d5ddd
--- /dev/null
+++ b/cpp/common/test/rules/gotostatementshouldnotbeused/GotoStatementShouldNotBeUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.gotostatementshouldnotbeused.GotoStatementShouldNotBeUsed
+
+class TestFileQuery extends GotoStatementShouldNotBeUsedSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/gotostatementshouldnotbeused/test.cpp b/cpp/common/test/rules/gotostatementshouldnotbeused/test.cpp
new file mode 100644
index 0000000000..0763208625
--- /dev/null
+++ b/cpp/common/test/rules/gotostatementshouldnotbeused/test.cpp
@@ -0,0 +1,11 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+void test_goto() {
+ int x = 1;
+
+ goto label1; // NON_COMPLIANT
+
+label1:
+
+ x = 2;
+}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.expected b/cpp/common/test/rules/hiddeninheritednonoverridablememberfunction/HiddenInheritedNonOverridableMemberFunction.expected
similarity index 100%
rename from cpp/autosar/test/rules/A7-3-1/HiddenInheritedNonOverridableMemberFunction.expected
rename to cpp/common/test/rules/hiddeninheritednonoverridablememberfunction/HiddenInheritedNonOverridableMemberFunction.expected
diff --git a/cpp/common/test/rules/hiddeninheritednonoverridablememberfunction/HiddenInheritedNonOverridableMemberFunction.ql b/cpp/common/test/rules/hiddeninheritednonoverridablememberfunction/HiddenInheritedNonOverridableMemberFunction.ql
new file mode 100644
index 0000000000..30953eacf3
--- /dev/null
+++ b/cpp/common/test/rules/hiddeninheritednonoverridablememberfunction/HiddenInheritedNonOverridableMemberFunction.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.hiddeninheritednonoverridablememberfunction.HiddenInheritedNonOverridableMemberFunction
+
+class TestFileQuery extends HiddenInheritedNonOverridableMemberFunctionSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/hiddeninheritednonoverridablememberfunction/test.cpp b/cpp/common/test/rules/hiddeninheritednonoverridablememberfunction/test.cpp
new file mode 100644
index 0000000000..c0904238c3
--- /dev/null
+++ b/cpp/common/test/rules/hiddeninheritednonoverridablememberfunction/test.cpp
@@ -0,0 +1,94 @@
+struct S1 {
+ int i;
+};
+
+class C1 {
+public:
+ void f1(int);
+
+ virtual void f2(int);
+ virtual void f2(double);
+ virtual void f2(S1);
+
+private:
+ void f3(int);
+ void f4(int);
+};
+
+class C2 : public C1 {
+public:
+ void f1(double); // NON_COMPLIANT
+
+ void f2(double) override; // NON_COMPLIANT
+};
+
+class C3 : public C1 {
+public:
+ void f2(char *); // NON_COMPLIANT
+};
+
+class C4 : public C1 {
+public:
+ using C1::f1;
+ void f1(double); // COMPLIANT
+
+ using C1::f2;
+ void f2(double) override; // COMPLIANT
+};
+
+namespace ns1 {
+void f1(int);
+}
+
+using ns1::f1;
+
+namespace ns1 {
+void f1(double); // NON_COMPLIANT
+}
+
+void f1() {
+ C2 l1;
+ l1.f1(0); // calls C2::f1(double) instead of C1::f1(int)
+ l1.f2(0); // calls C2::f2(double) instead of C1::f2(int)
+ // S1 s1;
+ // l1.f2(s1); Won't compile because there is no suitable conversion from S1 to
+ // double.
+ C1 &l2{l1};
+ l2.f1(0); // calls C1::f1(int)
+
+ C4 l3;
+ l3.f1(0); // calls C1::f1(int)
+ l3.f1(0.0); // calls C3::f1(double)
+ l3.f2(0); // calls C1::f2(int)
+ l3.f2(0.0); // calls C3::f2(double)
+ S1 l4;
+ l3.f2(l4); // calls C1:f2(S1)
+}
+
+class C5 : public C1 {
+public:
+ void f1(double); // COMPLIANT
+ using C1::f1; // order of using and f1 declaration is not relevant
+
+ void f2(double) override; // COMPLIANT
+ using C1::f2; // order of using and f2 declaration is not relevant
+};
+
+void f2() {
+ C5 c5;
+ c5.f1(0); // calls C1::f1(int)
+ c5.f1(0.0); // calls C5::f1(double)
+ c5.f2(0); // calls C1::f2(int)
+ c5.f2(0.0); // calls C5::f2(double)
+}
+
+class C6 : public C1 {
+public:
+ C6 &operator=(const C6 &); // COMPLIANT
+};
+
+class C7 : public C1 {
+ void f3(int); // COMPLIANT
+
+ void f4(int); // COMPLIANT
+};
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.expected b/cpp/common/test/rules/hiddeninheritedoverridablememberfunction/HiddenInheritedOverridableMemberFunction.expected
similarity index 100%
rename from cpp/autosar/test/rules/A7-3-1/HiddenInheritedOverridableMemberFunction.expected
rename to cpp/common/test/rules/hiddeninheritedoverridablememberfunction/HiddenInheritedOverridableMemberFunction.expected
diff --git a/cpp/common/test/rules/hiddeninheritedoverridablememberfunction/HiddenInheritedOverridableMemberFunction.ql b/cpp/common/test/rules/hiddeninheritedoverridablememberfunction/HiddenInheritedOverridableMemberFunction.ql
new file mode 100644
index 0000000000..072f672efb
--- /dev/null
+++ b/cpp/common/test/rules/hiddeninheritedoverridablememberfunction/HiddenInheritedOverridableMemberFunction.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.hiddeninheritedoverridablememberfunction.HiddenInheritedOverridableMemberFunction
+
+class TestFileQuery extends HiddenInheritedOverridableMemberFunctionSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/hiddeninheritedoverridablememberfunction/test.cpp b/cpp/common/test/rules/hiddeninheritedoverridablememberfunction/test.cpp
new file mode 100644
index 0000000000..c0904238c3
--- /dev/null
+++ b/cpp/common/test/rules/hiddeninheritedoverridablememberfunction/test.cpp
@@ -0,0 +1,94 @@
+struct S1 {
+ int i;
+};
+
+class C1 {
+public:
+ void f1(int);
+
+ virtual void f2(int);
+ virtual void f2(double);
+ virtual void f2(S1);
+
+private:
+ void f3(int);
+ void f4(int);
+};
+
+class C2 : public C1 {
+public:
+ void f1(double); // NON_COMPLIANT
+
+ void f2(double) override; // NON_COMPLIANT
+};
+
+class C3 : public C1 {
+public:
+ void f2(char *); // NON_COMPLIANT
+};
+
+class C4 : public C1 {
+public:
+ using C1::f1;
+ void f1(double); // COMPLIANT
+
+ using C1::f2;
+ void f2(double) override; // COMPLIANT
+};
+
+namespace ns1 {
+void f1(int);
+}
+
+using ns1::f1;
+
+namespace ns1 {
+void f1(double); // NON_COMPLIANT
+}
+
+void f1() {
+ C2 l1;
+ l1.f1(0); // calls C2::f1(double) instead of C1::f1(int)
+ l1.f2(0); // calls C2::f2(double) instead of C1::f2(int)
+ // S1 s1;
+ // l1.f2(s1); Won't compile because there is no suitable conversion from S1 to
+ // double.
+ C1 &l2{l1};
+ l2.f1(0); // calls C1::f1(int)
+
+ C4 l3;
+ l3.f1(0); // calls C1::f1(int)
+ l3.f1(0.0); // calls C3::f1(double)
+ l3.f2(0); // calls C1::f2(int)
+ l3.f2(0.0); // calls C3::f2(double)
+ S1 l4;
+ l3.f2(l4); // calls C1:f2(S1)
+}
+
+class C5 : public C1 {
+public:
+ void f1(double); // COMPLIANT
+ using C1::f1; // order of using and f1 declaration is not relevant
+
+ void f2(double) override; // COMPLIANT
+ using C1::f2; // order of using and f2 declaration is not relevant
+};
+
+void f2() {
+ C5 c5;
+ c5.f1(0); // calls C1::f1(int)
+ c5.f1(0.0); // calls C5::f1(double)
+ c5.f2(0); // calls C1::f2(int)
+ c5.f2(0.0); // calls C5::f2(double)
+}
+
+class C6 : public C1 {
+public:
+ C6 &operator=(const C6 &); // COMPLIANT
+};
+
+class C7 : public C1 {
+ void f3(int); // COMPLIANT
+
+ void f4(int); // COMPLIANT
+};
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.expected b/cpp/common/test/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.expected
similarity index 100%
rename from cpp/autosar/test/rules/A12-1-1/ExplicitConstructorBaseClassInitialization.expected
rename to cpp/common/test/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.expected
diff --git a/cpp/common/test/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.ql b/cpp/common/test/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.ql
new file mode 100644
index 0000000000..89f720b125
--- /dev/null
+++ b/cpp/common/test/rules/initializeallvirtualbaseclasses/InitializeAllVirtualBaseClasses.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.initializeallvirtualbaseclasses.InitializeAllVirtualBaseClasses
+
+class TestFileQuery extends InitializeAllVirtualBaseClassesSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A12-1-1/test.cpp b/cpp/common/test/rules/initializeallvirtualbaseclasses/test.cpp
similarity index 88%
rename from cpp/autosar/test/rules/A12-1-1/test.cpp
rename to cpp/common/test/rules/initializeallvirtualbaseclasses/test.cpp
index 7721da8b01..8e6b318b19 100644
--- a/cpp/autosar/test/rules/A12-1-1/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/autosar/test/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.expected b/cpp/common/test/rules/initializerlistconstructoristheonlyconstructor/InitializerListConstructorIsTheOnlyConstructor.expected
similarity index 100%
rename from cpp/autosar/test/rules/A8-5-4/ConfusingUseOfInitializerListConstructors.expected
rename to cpp/common/test/rules/initializerlistconstructoristheonlyconstructor/InitializerListConstructorIsTheOnlyConstructor.expected
diff --git a/cpp/common/test/rules/initializerlistconstructoristheonlyconstructor/InitializerListConstructorIsTheOnlyConstructor.ql b/cpp/common/test/rules/initializerlistconstructoristheonlyconstructor/InitializerListConstructorIsTheOnlyConstructor.ql
new file mode 100644
index 0000000000..a2b023a3dd
--- /dev/null
+++ b/cpp/common/test/rules/initializerlistconstructoristheonlyconstructor/InitializerListConstructorIsTheOnlyConstructor.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.initializerlistconstructoristheonlyconstructor.InitializerListConstructorIsTheOnlyConstructor
+
+class TestFileQuery extends InitializerListConstructorIsTheOnlyConstructorSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A8-5-4/test.cpp b/cpp/common/test/rules/initializerlistconstructoristheonlyconstructor/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A8-5-4/test.cpp
rename to cpp/common/test/rules/initializerlistconstructoristheonlyconstructor/test.cpp
diff --git a/cpp/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.expected b/cpp/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.expected
new file mode 100644
index 0000000000..9a39d3a88d
--- /dev/null
+++ b/cpp/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.expected
@@ -0,0 +1,6 @@
+| test.cpp:21:14:21:19 | tmpvar | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.cpp:13:12:13:17 | call to getenv | call to getenv | test.cpp:17:13:17:18 | call to getenv | call to getenv |
+| test.cpp:134:14:134:17 | temp | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.cpp:130:12:130:17 | call to getenv | call to getenv | test.cpp:131:11:131:16 | call to getenv | call to getenv |
+| test.cpp:134:20:134:22 | tmp | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.cpp:131:11:131:16 | call to getenv | call to getenv | test.cpp:130:12:130:17 | call to getenv | call to getenv |
+| test.cpp:165:14:165:26 | tmpvar_global | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.cpp:157:19:157:24 | call to getenv | call to getenv | test.cpp:161:20:161:25 | call to getenv | call to getenv |
+| test.cpp:188:18:188:18 | r | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.cpp:185:7:185:15 | call to setlocale | call to setlocale | test.cpp:187:8:187:17 | call to localeconv | call to localeconv |
+| test.cpp:208:10:208:15 | tmpvar | This pointer was returned by a $@ and may have been overwritten by the susequent $@. | test.cpp:202:12:202:17 | call to getenv | call to getenv | test.cpp:206:3:206:8 | call to f11fun | call to f11fun |
diff --git a/cpp/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.ql b/cpp/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.ql
new file mode 100644
index 0000000000..b82c43333a
--- /dev/null
+++ b/cpp/common/test/rules/invalidatedenvstringpointers/InvalidatedEnvStringPointers.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.invalidatedenvstringpointers.InvalidatedEnvStringPointers
+
+class TestFileQuery extends InvalidatedEnvStringPointersSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/invalidatedenvstringpointers/test.cpp b/cpp/common/test/rules/invalidatedenvstringpointers/test.cpp
new file mode 100644
index 0000000000..74e3d1b8f5
--- /dev/null
+++ b/cpp/common/test/rules/invalidatedenvstringpointers/test.cpp
@@ -0,0 +1,209 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#include
+#include
+#include
+#include
+#include
+
+void f1(void) {
+ char *tmpvar;
+ char *tempvar;
+
+ tmpvar = getenv("TMP");
+ if (!tmpvar) {
+ /* Handle error */
+ }
+ tempvar = getenv("TEMP");
+ if (!tempvar) {
+ /* Handle error */
+ }
+ if (strcmp(tmpvar, tempvar) == 0) { // NON_COMPLIANT
+ printf("TMP and TEMP are the same.\n");
+ } else {
+ printf("TMP and TEMP are NOT the same.\n");
+ }
+}
+
+void f2(void) {
+ char *tmpvar;
+ char *tempvar;
+
+ const char *temp = getenv("TMP");
+ if (temp != NULL) {
+ tmpvar = (char *)malloc(strlen(temp) + 1);
+ if (tmpvar != NULL) {
+ strcpy(tmpvar, temp);
+ } else {
+ /* Handle error */
+ }
+ } else {
+ /* Handle error */
+ }
+
+ temp = getenv("TEMP");
+ if (temp != NULL) {
+ tempvar = (char *)malloc(strlen(temp) + 1);
+ if (tempvar != NULL) {
+ strcpy(tempvar, temp);
+ } else {
+ /* Handle error */
+ }
+ } else {
+ /* Handle error */
+ }
+
+ if (strcmp(tmpvar, tempvar) == 0) { // COMPLIANT
+ printf("TMP and TEMP are the same.\n");
+ } else {
+ printf("TMP and TEMP are NOT the same.\n");
+ }
+ free(tmpvar);
+ free(tempvar);
+}
+
+#define __STDC_WANT_LIB_EXT1__ 1
+
+void f3(void) {
+ char *tmpvar;
+ char *tempvar;
+
+ const char *temp = getenv("TMP");
+ if (temp != NULL) {
+ tmpvar = strdup(temp);
+ if (tmpvar == NULL) {
+ /* Handle error */
+ }
+ } else {
+ /* Handle error */
+ }
+
+ temp = getenv("TEMP");
+ if (temp != NULL) {
+ tempvar = strdup(temp);
+ if (tempvar == NULL) {
+ /* Handle error */
+ }
+ } else {
+ /* Handle error */
+ }
+
+ if (strcmp(tmpvar, tempvar) == 0) { // COMPLIANT
+ printf("TMP and TEMP are the same.\n");
+ } else {
+ printf("TMP and TEMP are NOT the same.\n");
+ }
+ free(tmpvar);
+ tmpvar = NULL;
+ free(tempvar);
+ tempvar = NULL;
+}
+
+void f4(void) {
+ char *temp = getenv("VAR1");
+ printf(temp);
+ temp = getenv("VAR2");
+ printf(temp); // COMPLIANT
+}
+
+void f5(void) {
+ const char *envVars[] = {
+ "v1",
+ "v2",
+ "v3",
+ };
+ for (int i = 0; i < 3; i++) {
+ char *temp = getenv(envVars[i]);
+ printf(temp); // COMPLIANT
+ }
+}
+
+void f5b(void) {
+ const char *envVars[] = {
+ "v1",
+ "v2",
+ "v3",
+ };
+ char *temp;
+ char *tmp;
+ for (int i = 0; i < 3; i++) {
+ temp = getenv(envVars[i]);
+ tmp = getenv(envVars[i]);
+ }
+
+ if (strcmp(temp, tmp) == 0) { // NON_COMPLIANT
+ printf("TMP and TEMP are the same.\n");
+ } else {
+ printf("TMP and TEMP are NOT the same.\n");
+ }
+}
+
+void f6(void) {
+ const char *envVars[] = {
+ "v1",
+ "v2",
+ "v3",
+ };
+ char *temp[3];
+ for (int i = 0; i < 3; i++) {
+ temp[i] = getenv(envVars[i]);
+ }
+ printf(temp[0]); // NON_COMPLIANT[FALSE_NEGATIVE]
+}
+
+char *tmpvar_global;
+char *tempvar_global;
+void f7(void) {
+ tmpvar_global = getenv("TMP");
+ if (!tmpvar_global) {
+ /* Handle error */
+ }
+ tempvar_global = getenv("TEMP");
+ if (!tempvar_global) {
+ /* Handle error */
+ }
+ if (strcmp(tmpvar_global, tempvar_global) == 0) { // NON_COMPLIANT
+ printf("TMP and TEMP are the same.\n");
+ } else {
+ printf("TMP and TEMP are NOT the same.\n");
+ }
+}
+
+extern void f8fun();
+void f8(void) {
+ char *temp = getenv("VAR1");
+ printf(temp);
+ f8fun(); // this function might call getenv()
+ temp = getenv("VAR2");
+ printf(temp); // NON_COMPLIANT[FALSE_NEGATIVE]
+}
+
+void f9(void) {
+ const char *r;
+ struct lconv *lc;
+ char c[128];
+ r = setlocale(LC_ALL, "ja_JP.UTF-8");
+ strcpy(c, r);
+ lc = localeconv();
+ printf("%s\n", r); // NON_COMPLIANT
+ printf("%s\n", c); // COMPLIANT
+ printf("%s\n", lc->currency_symbol); // COMPLIANT
+}
+
+void f10(void) {
+ struct tm tm = *localtime(&(time_t){time(NULL)});
+ printf("%s", asctime(&tm)); // COMPLIANT
+}
+
+void f11fun(void) { char *tempvar = getenv("TEMP"); }
+void f11(void) {
+ char *tmpvar;
+
+ tmpvar = getenv("TMP");
+ if (!tmpvar) {
+ /* Handle error */
+ }
+ f11fun();
+
+ printf(tmpvar); // NON_COMPLIANT
+}
diff --git a/cpp/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.expected b/cpp/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.expected
new file mode 100644
index 0000000000..9061fcfbc4
--- /dev/null
+++ b/cpp/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.expected
@@ -0,0 +1,2 @@
+| test.cpp:15:19:15:24 | call to getenv | The value of variable $@ might become invalid after a subsequent call to function `getenv`. | test.cpp:12:7:12:19 | tmpvar_global | tmpvar_global |
+| test.cpp:18:20:18:25 | call to getenv | The value of variable $@ might become invalid after a subsequent call to function `getenv`. | test.cpp:9:9:9:20 | tmpvar_field | tmpvar_field |
diff --git a/cpp/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.ql b/cpp/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.ql
new file mode 100644
index 0000000000..7a56af210d
--- /dev/null
+++ b/cpp/common/test/rules/invalidatedenvstringpointerswarn/InvalidatedEnvStringPointersWarn.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.invalidatedenvstringpointerswarn.InvalidatedEnvStringPointersWarn
+
+class TestFileQuery extends InvalidatedEnvStringPointersWarnSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/invalidatedenvstringpointerswarn/test.cpp b/cpp/common/test/rules/invalidatedenvstringpointerswarn/test.cpp
new file mode 100644
index 0000000000..5001e538a1
--- /dev/null
+++ b/cpp/common/test/rules/invalidatedenvstringpointerswarn/test.cpp
@@ -0,0 +1,21 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#include
+#include
+#include
+#include
+
+struct test_struct {
+ char *tmpvar_field;
+};
+
+char *tmpvar_global;
+
+void f1(void) {
+ tmpvar_global = getenv("TMP"); // NON_COMPLIANT
+
+ struct test_struct s;
+ s.tmpvar_field = getenv("TEMP"); // NON_COMPLIANT
+
+ char *tmpvar_local = getenv("TEMP"); // COMPLIANT
+}
diff --git a/cpp/autosar/test/rules/A2-7-1/SingleLineCommentEndsWithSlash.expected b/cpp/common/test/rules/linesplicingusedincomments/LineSplicingUsedInComments.expected
similarity index 100%
rename from cpp/autosar/test/rules/A2-7-1/SingleLineCommentEndsWithSlash.expected
rename to cpp/common/test/rules/linesplicingusedincomments/LineSplicingUsedInComments.expected
diff --git a/cpp/common/test/rules/linesplicingusedincomments/LineSplicingUsedInComments.ql b/cpp/common/test/rules/linesplicingusedincomments/LineSplicingUsedInComments.ql
new file mode 100644
index 0000000000..55803eab88
--- /dev/null
+++ b/cpp/common/test/rules/linesplicingusedincomments/LineSplicingUsedInComments.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.linesplicingusedincomments.LineSplicingUsedInComments
+
+class TestFileQuery extends LineSplicingUsedInCommentsSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A2-7-1/test.cpp b/cpp/common/test/rules/linesplicingusedincomments/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A2-7-1/test.cpp
rename to cpp/common/test/rules/linesplicingusedincomments/test.cpp
diff --git a/cpp/autosar/test/rules/M6-3-1/LoopCompoundCondition.expected b/cpp/common/test/rules/loopcompoundcondition/LoopCompoundCondition.expected
similarity index 100%
rename from cpp/autosar/test/rules/M6-3-1/LoopCompoundCondition.expected
rename to cpp/common/test/rules/loopcompoundcondition/LoopCompoundCondition.expected
diff --git a/cpp/common/test/rules/loopcompoundcondition/LoopCompoundCondition.ql b/cpp/common/test/rules/loopcompoundcondition/LoopCompoundCondition.ql
new file mode 100644
index 0000000000..3961d76d15
--- /dev/null
+++ b/cpp/common/test/rules/loopcompoundcondition/LoopCompoundCondition.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.loopcompoundcondition.LoopCompoundCondition
+
+class TestFileQuery extends LoopCompoundConditionSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M6-3-1/test.cpp b/cpp/common/test/rules/loopcompoundcondition/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M6-3-1/test.cpp
rename to cpp/common/test/rules/loopcompoundcondition/test.cpp
diff --git a/cpp/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.expected b/cpp/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.expected
new file mode 100644
index 0000000000..545b6d3441
--- /dev/null
+++ b/cpp/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.expected
@@ -0,0 +1,16 @@
+| test.cpp:5:10:5:11 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:6:10:6:12 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:9:10:9:12 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:10:10:10:12 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:15:11:15:12 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:16:11:16:13 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:19:11:19:13 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:20:11:20:13 | 0 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:25:10:25:14 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:26:10:26:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:29:10:29:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:30:10:30:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:35:11:35:14 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:36:11:36:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:39:11:39:15 | 1 | Lowercase 'l' used as a literal suffix. |
+| test.cpp:40:11:40:15 | 1 | Lowercase 'l' used as a literal suffix. |
diff --git a/cpp/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.ql b/cpp/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.ql
new file mode 100644
index 0000000000..ab353ca8a9
--- /dev/null
+++ b/cpp/common/test/rules/lowercaselstartsinliteralsuffix/LowercaseLStartsInLiteralSuffix.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.lowercaselstartsinliteralsuffix.LowercaseLStartsInLiteralSuffix
+
+class TestFileQuery extends LowercaseLStartsInLiteralSuffixSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-7-3/cpp/README.md b/cpp/common/test/rules/lowercaselstartsinliteralsuffix/README.md
similarity index 100%
rename from c/misra/test/rules/RULE-7-3/cpp/README.md
rename to cpp/common/test/rules/lowercaselstartsinliteralsuffix/README.md
diff --git a/cpp/common/test/rules/lowercaselstartsinliteralsuffix/test.cpp b/cpp/common/test/rules/lowercaselstartsinliteralsuffix/test.cpp
new file mode 100644
index 0000000000..27be2a327d
--- /dev/null
+++ b/cpp/common/test/rules/lowercaselstartsinliteralsuffix/test.cpp
@@ -0,0 +1,46 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+int x = false; // COMPLIANT - reported as FP in #319
+int a1 = 0L; // COMPLIANT
+int a2 = 0l; // NON_COMPLIANT
+int a3 = 0ll; // NON_COMPLIANT
+int a4 = 0LL; // COMPLIANT
+int a5 = 0uL; // COMPLIANT
+int a6 = 0ul; // NON_COMPLIANT
+int a7 = 0lu; // NON_COMPLIANT
+int a8 = 0Lu; // COMPLIANT
+int a9 = 0LU; // COMPLIANT
+
+long b1 = 0L; // COMPLIANT
+long b2 = 0l; // NON_COMPLIANT
+long b3 = 0ll; // NON_COMPLIANT
+long b4 = 0LL; // COMPLIANT
+long b5 = 0uL; // COMPLIANT
+long b6 = 0ul; // NON_COMPLIANT
+long b7 = 0lu; // NON_COMPLIANT
+long b8 = 0Lu; // COMPLIANT
+long b9 = 0LU; // COMPLIANT
+
+int c1 = 0x01L; // COMPLIANT
+int c2 = 0x01l; // NON_COMPLIANT
+int c3 = 0x01ll; // NON_COMPLIANT
+int c4 = 0x01LL; // COMPLIANT
+int c5 = 0x01uL; // COMPLIANT
+int c6 = 0x01ul; // NON_COMPLIANT
+int c7 = 0x01lu; // NON_COMPLIANT
+int c8 = 0x01Lu; // COMPLIANT
+int c9 = 0x01LU; // COMPLIANT
+
+long d1 = 001L; // COMPLIANT
+long d2 = 001l; // NON_COMPLIANT
+long d3 = 001ll; // NON_COMPLIANT
+long d4 = 001LL; // COMPLIANT
+long d5 = 001uL; // COMPLIANT
+long d6 = 001ul; // NON_COMPLIANT
+long d7 = 001lu; // NON_COMPLIANT
+long d8 = 001Lu; // COMPLIANT
+long d9 = 001LU; // COMPLIANT
+
+char *e1 = "";
+char *e2 = "ul";
+char *e3 = "UL";
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.expected b/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected
similarity index 100%
rename from cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.expected
rename to cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected
diff --git a/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected.gcc b/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected.gcc
new file mode 100644
index 0000000000..87bf6e1b01
--- /dev/null
+++ b/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected.gcc
@@ -0,0 +1 @@
+| test.cpp:9:32:9:51 | offsetof(TYPE,MEMBER) | Use of banned macro offsetof. |
diff --git a/cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.expected.qcc b/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected.qcc
similarity index 100%
rename from cpp/autosar/test/rules/M18-2-1/MacroOffsetofUsed.expected.qcc
rename to cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.expected.qcc
diff --git a/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.ql b/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.ql
new file mode 100644
index 0000000000..44e30b1a2f
--- /dev/null
+++ b/cpp/common/test/rules/macrooffsetofused/MacroOffsetofUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.macrooffsetofused.MacroOffsetofUsed
+
+class TestFileQuery extends MacroOffsetofUsedSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M18-2-1/test.cpp b/cpp/common/test/rules/macrooffsetofused/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M18-2-1/test.cpp
rename to cpp/common/test/rules/macrooffsetofused/test.cpp
diff --git a/cpp/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.expected b/cpp/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.expected
new file mode 100644
index 0000000000..6a3d5c5da7
--- /dev/null
+++ b/cpp/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.expected
@@ -0,0 +1 @@
+| test.cpp:27:1:27:29 | #define MACROTHIRTEEN(X) #X ## X | Macro definition uses an # operator followed by a ## operator. |
diff --git a/cpp/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.ql b/cpp/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.ql
new file mode 100644
index 0000000000..f753b75463
--- /dev/null
+++ b/cpp/common/test/rules/macroparameterfollowinghash/MacroParameterFollowingHash.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.macroparameterfollowinghash.MacroParameterFollowingHash
+
+class TestFileQuery extends MacroParameterFollowingHashSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-20-11/test.c b/cpp/common/test/rules/macroparameterfollowinghash/test.cpp
similarity index 83%
rename from c/misra/test/rules/RULE-20-11/test.c
rename to cpp/common/test/rules/macroparameterfollowinghash/test.cpp
index ad2c205970..5e6f187445 100644
--- a/c/misra/test/rules/RULE-20-11/test.c
+++ b/cpp/common/test/rules/macroparameterfollowinghash/test.cpp
@@ -1,3 +1,5 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
#define MACROONE 1 // COMPLIANT
#define MACROTWO '#\'-#' + '#' // COMPLIANT
diff --git a/cpp/autosar/test/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.expected b/cpp/common/test/rules/multipleglobalormemberdeclarators/MultipleGlobalOrMemberDeclarators.expected
similarity index 100%
rename from cpp/autosar/test/rules/M8-0-1/MultipleGlobalOrMemberDeclarators.expected
rename to cpp/common/test/rules/multipleglobalormemberdeclarators/MultipleGlobalOrMemberDeclarators.expected
diff --git a/cpp/common/test/rules/multipleglobalormemberdeclarators/MultipleGlobalOrMemberDeclarators.ql b/cpp/common/test/rules/multipleglobalormemberdeclarators/MultipleGlobalOrMemberDeclarators.ql
new file mode 100644
index 0000000000..2f4d3cbdea
--- /dev/null
+++ b/cpp/common/test/rules/multipleglobalormemberdeclarators/MultipleGlobalOrMemberDeclarators.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.multipleglobalormemberdeclarators.MultipleGlobalOrMemberDeclarators
+
+class TestFileQuery extends MultipleGlobalOrMemberDeclaratorsSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M8-0-1/test.cpp b/cpp/common/test/rules/multipleglobalormemberdeclarators/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M8-0-1/test.cpp
rename to cpp/common/test/rules/multipleglobalormemberdeclarators/test.cpp
diff --git a/cpp/autosar/test/rules/M8-0-1/MultipleLocalDeclarators.expected b/cpp/common/test/rules/multiplelocaldeclarators/MultipleLocalDeclarators.expected
similarity index 100%
rename from cpp/autosar/test/rules/M8-0-1/MultipleLocalDeclarators.expected
rename to cpp/common/test/rules/multiplelocaldeclarators/MultipleLocalDeclarators.expected
diff --git a/cpp/common/test/rules/multiplelocaldeclarators/MultipleLocalDeclarators.ql b/cpp/common/test/rules/multiplelocaldeclarators/MultipleLocalDeclarators.ql
new file mode 100644
index 0000000000..7e2fe57b24
--- /dev/null
+++ b/cpp/common/test/rules/multiplelocaldeclarators/MultipleLocalDeclarators.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.multiplelocaldeclarators.MultipleLocalDeclarators
+
+class TestFileQuery extends MultipleLocalDeclaratorsSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/multiplelocaldeclarators/test.cpp b/cpp/common/test/rules/multiplelocaldeclarators/test.cpp
new file mode 100644
index 0000000000..cf664e4b34
--- /dev/null
+++ b/cpp/common/test/rules/multiplelocaldeclarators/test.cpp
@@ -0,0 +1,24 @@
+int g1, g2; // NON_COMPLIANT
+int g3; // COMPLIANT
+
+namespace n1 {
+int n_v1, n_v2; // NON_COMPLIANT
+int n_v3; // COMPLIANT
+} // namespace n1
+
+void f() {
+ int l1, l2; // NON_COMPLIANT
+ int l3; // COMPLIANT
+}
+
+class ClassA {
+ int m1, m2; // NON_COMPLIANT
+ int m3; // COMPLIANT
+};
+
+#include
+void test_loop(std::vector v) {
+ for (const auto b : v) { // COMPLIANT - DeclStmt is compiler generated
+ b;
+ }
+}
\ No newline at end of file
diff --git a/cpp/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.expected b/cpp/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.expected
new file mode 100644
index 0000000000..8ddc10e90c
--- /dev/null
+++ b/cpp/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.expected
@@ -0,0 +1,5 @@
+| test.cpp:6:7:6:8 | x1 | A named bit-field with signed integral type should have at least 2 bits of storage. |
+| test.cpp:9:14:9:15 | x2 | A named bit-field with signed integral type should have at least 2 bits of storage. |
+| test.cpp:11:7:11:8 | x3 | A named bit-field with signed integral type should have at least 2 bits of storage. |
+| test.cpp:13:7:13:8 | x4 | A named bit-field with signed integral type should have at least 2 bits of storage. |
+| test.cpp:22:14:22:14 | x | A named bit-field with signed integral type should have at least 2 bits of storage. |
diff --git a/cpp/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.ql b/cpp/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.ql
new file mode 100644
index 0000000000..a82fa7905a
--- /dev/null
+++ b/cpp/common/test/rules/namedbitfieldswithsignedintegertype/NamedBitFieldsWithSignedIntegerType.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.namedbitfieldswithsignedintegertype.NamedBitFieldsWithSignedIntegerType
+
+class TestFileQuery extends NamedBitFieldsWithSignedIntegerTypeSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-6-2/test.c b/cpp/common/test/rules/namedbitfieldswithsignedintegertype/test.cpp
similarity index 70%
rename from c/misra/test/rules/RULE-6-2/test.c
rename to cpp/common/test/rules/namedbitfieldswithsignedintegertype/test.cpp
index 8182dfdb5d..0d6e838f83 100644
--- a/c/misra/test/rules/RULE-6-2/test.c
+++ b/cpp/common/test/rules/namedbitfieldswithsignedintegertype/test.cpp
@@ -1,3 +1,5 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
#include
struct SampleStruct {
@@ -15,3 +17,12 @@ struct SampleStruct {
// to carry more than 1 bit
signed char : 1; // COMPLIANT: single-bit bit-field but unnamed
} sample_struct;
+
+struct S {
+ signed int x : 1; // NON-COMPLIANT
+ signed int y : 5; // COMPLIANT
+ signed int z : 7; // COMPLIANT
+ signed int : 0; // COMPLIANT
+ signed int : 1; // COMPLIANT
+ signed int : 2; // COMPLIANT
+};
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.expected b/cpp/common/test/rules/namenotreferredusingaqualifiedidorthis/NameNotReferredUsingAQualifiedIdOrThis.expected
similarity index 100%
rename from cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThis.expected
rename to cpp/common/test/rules/namenotreferredusingaqualifiedidorthis/NameNotReferredUsingAQualifiedIdOrThis.expected
diff --git a/cpp/common/test/rules/namenotreferredusingaqualifiedidorthis/NameNotReferredUsingAQualifiedIdOrThis.ql b/cpp/common/test/rules/namenotreferredusingaqualifiedidorthis/NameNotReferredUsingAQualifiedIdOrThis.ql
new file mode 100644
index 0000000000..731d7b1f84
--- /dev/null
+++ b/cpp/common/test/rules/namenotreferredusingaqualifiedidorthis/NameNotReferredUsingAQualifiedIdOrThis.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.namenotreferredusingaqualifiedidorthis.NameNotReferredUsingAQualifiedIdOrThis
+
+class TestFileQuery extends NameNotReferredUsingAQualifiedIdOrThisSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M14-6-1/test.cpp b/cpp/common/test/rules/namenotreferredusingaqualifiedidorthis/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M14-6-1/test.cpp
rename to cpp/common/test/rules/namenotreferredusingaqualifiedidorthis/test.cpp
diff --git a/cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.expected b/cpp/common/test/rules/namenotreferredusingaqualifiedidorthisaudit/NameNotReferredUsingAQualifiedIdOrThisAudit.expected
similarity index 100%
rename from cpp/autosar/test/rules/M14-6-1/NameNotReferredUsingAQualifiedIdOrThisAudit.expected
rename to cpp/common/test/rules/namenotreferredusingaqualifiedidorthisaudit/NameNotReferredUsingAQualifiedIdOrThisAudit.expected
diff --git a/cpp/common/test/rules/namenotreferredusingaqualifiedidorthisaudit/NameNotReferredUsingAQualifiedIdOrThisAudit.ql b/cpp/common/test/rules/namenotreferredusingaqualifiedidorthisaudit/NameNotReferredUsingAQualifiedIdOrThisAudit.ql
new file mode 100644
index 0000000000..46ffea0b3d
--- /dev/null
+++ b/cpp/common/test/rules/namenotreferredusingaqualifiedidorthisaudit/NameNotReferredUsingAQualifiedIdOrThisAudit.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.namenotreferredusingaqualifiedidorthisaudit.NameNotReferredUsingAQualifiedIdOrThisAudit
+
+class TestFileQuery extends NameNotReferredUsingAQualifiedIdOrThisAuditSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/namenotreferredusingaqualifiedidorthisaudit/test.cpp b/cpp/common/test/rules/namenotreferredusingaqualifiedidorthisaudit/test.cpp
new file mode 100644
index 0000000000..b16e6b40dc
--- /dev/null
+++ b/cpp/common/test/rules/namenotreferredusingaqualifiedidorthisaudit/test.cpp
@@ -0,0 +1,87 @@
+typedef int TYPE;
+void g();
+void g1();
+int m;
+
+template class B {
+public:
+ typedef T TYPE;
+ void g();
+ int m;
+};
+
+template class A : B {
+public:
+ void m1() {
+ m = 0; // NON_COMPLIANT
+ g(); // NON_COMPLIANT
+ TYPE t = 0; // NON_COMPLIANT[FALSE_NEGATIVE]
+ void (*p)() = &g; // NON_COMPLIANT
+ }
+ void m2() {
+ ::m = 0; // COMPLIANT
+ ::g(); // COMPLIANT
+ ::TYPE t1 = 0; // COMPLIANT
+ B::m = 0; // COMPLIANT
+ this->m = 0; // COMPLIANT
+ this->g(); // COMPLIANT
+ void (B::*p)() = &B::g; // COMPLIANT
+ typename B::TYPE t2 = 0; // COMPLIANT
+ g1(); // COMPLIANT, identifier not found in B
+ }
+ void m3(int m) {
+ m = 0; // COMPLIANT, hides member
+ }
+ void m4() {
+ int m = 0;
+ m = 0; // COMPLIANT, hides member
+ }
+};
+
+void f() {
+ A a;
+ a.m1();
+ a.m2();
+ a.m3(1);
+ a.m4();
+}
+
+class D {
+public:
+ typedef int TYPE;
+ void g();
+ void g(int x);
+ static void sg();
+ static void sg(int x);
+ int m;
+};
+
+class C : D {
+public:
+ void m1() {
+ m = 0; // COMPLIANT - does not apply to non-class templates
+ g(); // COMPLIANT - does not apply to non-class templates
+ sg(); // COMPLIANT - does not apply to non-class templates
+ TYPE t1 = 0; // COMPLIANT - does not apply to non-class templates
+ // void (*p)() = &g; // NON_COMPILABLE - not valid to take address of member
+ // function without qualifier
+ }
+};
+
+template class E : D {
+public:
+ void m1() {
+ m = 0; // COMPLIANT - does not apply to non dependent base types
+ g(); // COMPLIANT - does not apply to non dependent base types
+ TYPE t1 = 0; // COMPLIANT - does not apply to non dependent base types
+ // void (*p)() = &g; // NON_COMPILABLE - not valid to take address of member
+ // function without qualifier
+ }
+};
+
+void f2() {
+ C c;
+ c.m1();
+ E e;
+ e.m1();
+}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A15-4-2/NoExceptFunctionThrows.expected b/cpp/common/test/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.expected
similarity index 99%
rename from cpp/autosar/test/rules/A15-4-2/NoExceptFunctionThrows.expected
rename to cpp/common/test/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.expected
index b2f8391b15..db392fd8f6 100644
--- a/cpp/autosar/test/rules/A15-4-2/NoExceptFunctionThrows.expected
+++ b/cpp/common/test/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.expected
@@ -1,3 +1,9 @@
+problems
+| test.cpp:4:6:4:15 | test_throw | test.cpp:5:3:5:20 | throw ... [ExceptionA] | test.cpp:4:6:4:15 | test_throw [ExceptionA] | Function test_throw is declared noexcept(true) but can throw exceptions of type ExceptionA. |
+| test.cpp:10:6:10:27 | noexceptIndirectThrowA | test.cpp:8:17:8:34 | throw ... [ExceptionA] | test.cpp:10:6:10:27 | noexceptIndirectThrowA [ExceptionA] | Function noexceptIndirectThrowA is declared noexcept(true) but can throw exceptions of type ExceptionA. |
+| test.cpp:12:6:12:24 | test_indirect_throw | test.cpp:8:17:8:34 | throw ... [ExceptionA] | test.cpp:12:6:12:24 | test_indirect_throw [ExceptionA] | Function test_indirect_throw is declared noexcept(true) but can throw exceptions of type ExceptionA. |
+| test.cpp:16:6:16:26 | test_indirect_throw_2 | test.cpp:8:17:8:34 | throw ... [ExceptionA] | test.cpp:16:6:16:26 | test_indirect_throw_2 [ExceptionA] | Function test_indirect_throw_2 is declared noexcept(true) but can throw exceptions of type ExceptionA. |
+| test.cpp:33:6:33:26 | test_indirect_throw_6 | test.cpp:8:17:8:34 | throw ... [ExceptionA] | test.cpp:33:6:33:26 | test_indirect_throw_6 [ExceptionA] | Function test_indirect_throw_6 is declared noexcept(true) but can throw exceptions of type ExceptionA. |
edges
| test.cpp:5:3:5:20 | throw ... [ExceptionA] | test.cpp:4:6:4:15 | test_throw [ExceptionA] |
| test.cpp:8:6:8:11 | throwA [ExceptionA] | test.cpp:9:25:9:30 | call to throwA [ExceptionA] |
@@ -11,9 +17,3 @@ edges
| test.cpp:13:3:13:8 | call to throwA [ExceptionA] | test.cpp:12:6:12:24 | test_indirect_throw [ExceptionA] |
| test.cpp:17:3:17:8 | call to throwA [ExceptionA] | test.cpp:16:6:16:26 | test_indirect_throw_2 [ExceptionA] |
| test.cpp:34:3:34:16 | call to indirectThrowA [ExceptionA] | test.cpp:33:6:33:26 | test_indirect_throw_6 [ExceptionA] |
-#select
-| test.cpp:4:6:4:15 | test_throw | test.cpp:5:3:5:20 | throw ... [ExceptionA] | test.cpp:4:6:4:15 | test_throw [ExceptionA] | Function test_throw is declared noexcept(true) but can throw exceptions of type ExceptionA. |
-| test.cpp:10:6:10:27 | noexceptIndirectThrowA | test.cpp:8:17:8:34 | throw ... [ExceptionA] | test.cpp:10:6:10:27 | noexceptIndirectThrowA [ExceptionA] | Function noexceptIndirectThrowA is declared noexcept(true) but can throw exceptions of type ExceptionA. |
-| test.cpp:12:6:12:24 | test_indirect_throw | test.cpp:8:17:8:34 | throw ... [ExceptionA] | test.cpp:12:6:12:24 | test_indirect_throw [ExceptionA] | Function test_indirect_throw is declared noexcept(true) but can throw exceptions of type ExceptionA. |
-| test.cpp:16:6:16:26 | test_indirect_throw_2 | test.cpp:8:17:8:34 | throw ... [ExceptionA] | test.cpp:16:6:16:26 | test_indirect_throw_2 [ExceptionA] | Function test_indirect_throw_2 is declared noexcept(true) but can throw exceptions of type ExceptionA. |
-| test.cpp:33:6:33:26 | test_indirect_throw_6 | test.cpp:8:17:8:34 | throw ... [ExceptionA] | test.cpp:33:6:33:26 | test_indirect_throw_6 [ExceptionA] | Function test_indirect_throw_6 is declared noexcept(true) but can throw exceptions of type ExceptionA. |
diff --git a/cpp/common/test/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.ql b/cpp/common/test/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.ql
new file mode 100644
index 0000000000..e8906287da
--- /dev/null
+++ b/cpp/common/test/rules/noexceptfunctionshouldnotpropagatetothecaller/NoexceptFunctionShouldNotPropagateToTheCaller.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.noexceptfunctionshouldnotpropagatetothecaller.NoexceptFunctionShouldNotPropagateToTheCaller
+
+class TestFileQuery extends NoexceptFunctionShouldNotPropagateToTheCallerSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A15-4-2/test.cpp b/cpp/common/test/rules/noexceptfunctionshouldnotpropagatetothecaller/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A15-4-2/test.cpp
rename to cpp/common/test/rules/noexceptfunctionshouldnotpropagatetothecaller/test.cpp
diff --git a/cpp/autosar/test/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.expected b/cpp/common/test/rules/nonglobalfunctionmain/NonGlobalFunctionMain.expected
similarity index 100%
rename from cpp/autosar/test/rules/M7-3-2/IdentifierMainUsedForAFunctionOtherThanTheGlobalFunctionMain.expected
rename to cpp/common/test/rules/nonglobalfunctionmain/NonGlobalFunctionMain.expected
diff --git a/cpp/common/test/rules/nonglobalfunctionmain/NonGlobalFunctionMain.ql b/cpp/common/test/rules/nonglobalfunctionmain/NonGlobalFunctionMain.ql
new file mode 100644
index 0000000000..02edcf3732
--- /dev/null
+++ b/cpp/common/test/rules/nonglobalfunctionmain/NonGlobalFunctionMain.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.nonglobalfunctionmain.NonGlobalFunctionMain
+
+class TestFileQuery extends NonGlobalFunctionMainSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M7-3-2/test.cpp b/cpp/common/test/rules/nonglobalfunctionmain/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M7-3-2/test.cpp
rename to cpp/common/test/rules/nonglobalfunctionmain/test.cpp
diff --git a/cpp/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.expected b/cpp/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.expected
new file mode 100644
index 0000000000..3051e32537
--- /dev/null
+++ b/cpp/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.expected
@@ -0,0 +1,21 @@
+| test.cpp:37:18:37:24 | \u001aG | Invalid hexadecimal escape in string literal at '\\x1AG"'. |
+| test.cpp:40:18:40:23 | \u00029 | Invalid octal escape in string literal at '\\029"'. |
+| test.cpp:43:18:43:24 | \n7 | Invalid octal escape in string literal at '\\0127"'. |
+| test.cpp:44:18:44:24 | \r7 | Invalid octal escape in string literal at '\\0157"'. |
+| test.cpp:46:19:46:29 | \n\n9 | Invalid octal escape in string literal at '\\0129"'. |
+| test.cpp:47:19:47:28 | \n\u00019 | Invalid octal escape in string literal at '\\019"'. |
+| test.cpp:50:19:50:31 | \nAAA\u000f | Invalid octal escape in string literal at '\\012AAA\\017"'. |
+| test.cpp:53:19:53:39 | Some Data \n\u000fA | Invalid octal escape in string literal at '\\017A"'. |
+| test.cpp:54:19:55:21 | Some Data \n\u000fA5 | Invalid octal escape in string literal at '\\017A"\n "5"'. |
+| test.cpp:56:19:58:25 | Some Data \n\u000fA\n1 | Invalid octal escape in string literal at '\\0121"'. |
+| test.cpp:62:19:63:26 | \u0011G\u00012 | Invalid octal escape in string literal at '\\0012"'. |
+| test.cpp:64:19:65:25 | \u0011GG\u0001 | Invalid hexadecimal escape in string literal at '\\x11G"\n "G\\001"'. |
+| test.cpp:66:19:67:26 | \u0011GG\u00013 | Invalid hexadecimal escape in string literal at '\\x11G"\n "G\\0013"'. |
+| test.cpp:66:19:67:26 | \u0011GG\u00013 | Invalid octal escape in string literal at '\\0013"'. |
+| test.cpp:73:18:73:42 | Some Data \n\u000fA5 | Invalid octal escape in string literal at '\\017A" "5"'. |
+| test.cpp:74:18:74:49 | Some Data \n\u000fA\n1 | Invalid octal escape in string literal at '\\0121"'. |
+| test.cpp:76:18:76:32 | \u0011G\u00012 | Invalid octal escape in string literal at '\\0012"'. |
+| test.cpp:77:18:77:32 | \u0011GG\u0001 | Invalid hexadecimal escape in string literal at '\\x11G" "G\\001"'. |
+| test.cpp:78:18:78:33 | \u0011GG\u00013 | Invalid hexadecimal escape in string literal at '\\x11G" "G\\0013"'. |
+| test.cpp:78:18:78:33 | \u0011GG\u00013 | Invalid octal escape in string literal at '\\0013"'. |
+| test.cpp:81:11:81:16 | 10 | Invalid hexadecimal escape in string literal at '\\x0a''. |
diff --git a/cpp/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.ql b/cpp/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.ql
new file mode 100644
index 0000000000..c1aae3c31b
--- /dev/null
+++ b/cpp/common/test/rules/nonterminatedescapesequences/NonTerminatedEscapeSequences.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.nonterminatedescapesequences.NonTerminatedEscapeSequences
+
+class TestFileQuery extends NonTerminatedEscapeSequencesSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-4-1/test.c b/cpp/common/test/rules/nonterminatedescapesequences/test.cpp
similarity index 61%
rename from c/misra/test/rules/RULE-4-1/test.c
rename to cpp/common/test/rules/nonterminatedescapesequences/test.cpp
index 4a0dcaa6ac..aa1093b791 100644
--- a/c/misra/test/rules/RULE-4-1/test.c
+++ b/cpp/common/test/rules/nonterminatedescapesequences/test.cpp
@@ -1,3 +1,31 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+#include
+
+struct SampleStruct {
+ int x1 : 1; // NON_COMPLIANT: very likely be signed, but if it's not, the
+ // query will automatically handle it since we use signed(), not
+ // isExplicitlySigned().
+ signed int x2 : 1; // NON_COMPLIANT: single-bit named field with a signed type
+ signed char
+ x3 : 1; // NON_COMPLIANT: single-bit named field with a signed type
+ signed short
+ x4 : 1; // NON_COMPLIANT: single-bit named field with a signed type
+ unsigned int
+ x5 : 1; // COMPLIANT: single-bit named field but with an unsigned type
+ signed int x6 : 2; // COMPLIANT: named field with a signed type but declared
+ // to carry more than 1 bit
+ signed char : 1; // COMPLIANT: single-bit bit-field but unnamed
+} sample_struct;
+
+struct S {
+ signed int x : 1; // NON-COMPLIANT
+ signed int y : 5; // COMPLIANT
+ signed int z : 7; // COMPLIANT
+ signed int : 0; // COMPLIANT
+ signed int : 1; // COMPLIANT
+ signed int : 2; // COMPLIANT
+};
const char *a1 = "\x11"
"G"; // COMPLIANT
diff --git a/cpp/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.expected b/cpp/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.expected
new file mode 100644
index 0000000000..662a21b5d6
--- /dev/null
+++ b/cpp/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.expected
@@ -0,0 +1 @@
+| test.cpp:5:19:5:20 | c4 | Nonunique value of enum constant compared to $@ | test.cpp:5:23:5:24 | c5 | c5 |
diff --git a/cpp/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.ql b/cpp/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.ql
new file mode 100644
index 0000000000..97ba6f516e
--- /dev/null
+++ b/cpp/common/test/rules/nonuniqueenumerationconstant/NonUniqueEnumerationConstant.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.nonuniqueenumerationconstant.NonUniqueEnumerationConstant
+
+class TestFileQuery extends NonUniqueEnumerationConstantSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/nonuniqueenumerationconstant/test.cpp b/cpp/common/test/rules/nonuniqueenumerationconstant/test.cpp
new file mode 100644
index 0000000000..0712cb59e4
--- /dev/null
+++ b/cpp/common/test/rules/nonuniqueenumerationconstant/test.cpp
@@ -0,0 +1,6 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+enum e { c = 3 }; // COMPLIANT
+enum e1 { c1 = 3, c2 }; // COMPLIANT
+enum e3 { c3 = 3, c4, c5 = 4 }; // NON_COMPLIANT
+enum e4 { c6 = 3, c7, c8, c9 = 6 }; // COMPLIANT
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.expected b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.expected
similarity index 100%
rename from cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.expected
rename to cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.expected
diff --git a/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.expected.clang b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.expected.clang
similarity index 100%
rename from cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.expected.clang
rename to cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.expected.clang
diff --git a/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.expected.gcc b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.expected.gcc
similarity index 100%
rename from cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.expected.gcc
rename to cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.expected.gcc
diff --git a/cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.expected.qcc b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.expected.qcc
similarity index 100%
rename from cpp/autosar/test/rules/A4-10-1/NullPointerConstantNotNullptr.expected.qcc
rename to cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.expected.qcc
diff --git a/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.ql b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.ql
new file mode 100644
index 0000000000..e3d6c4841f
--- /dev/null
+++ b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/NullptrNotTheOnlyFormOfTheNullPointerConstant.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.nullptrnottheonlyformofthenullpointerconstant.NullptrNotTheOnlyFormOfTheNullPointerConstant
+
+class TestFileQuery extends NullptrNotTheOnlyFormOfTheNullPointerConstantSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A4-10-1/test.cpp b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A4-10-1/test.cpp
rename to cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/test.cpp
diff --git a/cpp/autosar/test/rules/A4-10-1/test.cpp.clang b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/test.cpp.clang
similarity index 100%
rename from cpp/autosar/test/rules/A4-10-1/test.cpp.clang
rename to cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/test.cpp.clang
diff --git a/cpp/autosar/test/rules/A4-10-1/test.cpp.gcc b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/test.cpp.gcc
similarity index 100%
rename from cpp/autosar/test/rules/A4-10-1/test.cpp.gcc
rename to cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/test.cpp.gcc
diff --git a/cpp/autosar/test/rules/A4-10-1/test.cpp.qcc b/cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/test.cpp.qcc
similarity index 100%
rename from cpp/autosar/test/rules/A4-10-1/test.cpp.qcc
rename to cpp/common/test/rules/nullptrnottheonlyformofthenullpointerconstant/test.cpp.qcc
diff --git a/cpp/autosar/test/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.expected b/cpp/common/test/rules/objectsdynamictypeusedfromconstructorordestructor/ObjectsDynamicTypeUsedFromConstructorOrDestructor.expected
similarity index 100%
rename from cpp/autosar/test/rules/M12-1-1/DynamicTypeOfThisUsedFromConstructorOrDestructor.expected
rename to cpp/common/test/rules/objectsdynamictypeusedfromconstructorordestructor/ObjectsDynamicTypeUsedFromConstructorOrDestructor.expected
diff --git a/cpp/common/test/rules/objectsdynamictypeusedfromconstructorordestructor/ObjectsDynamicTypeUsedFromConstructorOrDestructor.ql b/cpp/common/test/rules/objectsdynamictypeusedfromconstructorordestructor/ObjectsDynamicTypeUsedFromConstructorOrDestructor.ql
new file mode 100644
index 0000000000..151af6a5a3
--- /dev/null
+++ b/cpp/common/test/rules/objectsdynamictypeusedfromconstructorordestructor/ObjectsDynamicTypeUsedFromConstructorOrDestructor.ql
@@ -0,0 +1,5 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.objectsdynamictypeusedfromconstructorordestructor.ObjectsDynamicTypeUsedFromConstructorOrDestructor
+
+class TestFileQuery extends ObjectsDynamicTypeUsedFromConstructorOrDestructorSharedQuery, TestQuery {
+}
diff --git a/cpp/autosar/test/rules/M12-1-1/test.cpp b/cpp/common/test/rules/objectsdynamictypeusedfromconstructorordestructor/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M12-1-1/test.cpp
rename to cpp/common/test/rules/objectsdynamictypeusedfromconstructorordestructor/test.cpp
diff --git a/cpp/common/test/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.expected b/cpp/common/test/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.expected
new file mode 100644
index 0000000000..d2d80e0572
--- /dev/null
+++ b/cpp/common/test/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.expected
@@ -0,0 +1,2 @@
+| test.cpp:16:8:16:8 | f | Overriding function does not have the same default parameters as $@ | test.cpp:4:16:4:16 | f | overridden function |
+| test.cpp:21:8:21:8 | f | Overriding function does not have the same default parameters as $@ | test.cpp:4:16:4:16 | f | overridden function |
diff --git a/cpp/common/test/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.ql b/cpp/common/test/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.ql
new file mode 100644
index 0000000000..2bb15bb684
--- /dev/null
+++ b/cpp/common/test/rules/overridingshallspecifydifferentdefaultarguments/OverridingShallSpecifyDifferentDefaultArguments.ql
@@ -0,0 +1,5 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.overridingshallspecifydifferentdefaultarguments.OverridingShallSpecifyDifferentDefaultArguments
+
+class TestFileQuery extends OverridingShallSpecifyDifferentDefaultArgumentsSharedQuery, TestQuery {
+}
diff --git a/cpp/autosar/test/rules/M8-3-1/test.cpp b/cpp/common/test/rules/overridingshallspecifydifferentdefaultarguments/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M8-3-1/test.cpp
rename to cpp/common/test/rules/overridingshallspecifydifferentdefaultarguments/test.cpp
diff --git a/cpp/common/test/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.expected b/cpp/common/test/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.expected
index 3d00ff0d6a..7790582443 100644
--- a/cpp/common/test/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.expected
+++ b/cpp/common/test/rules/ownedpointervaluestoredinunrelatedsmartpointer/OwnedPointerValueStoredInUnrelatedSmartPointer.expected
@@ -6,21 +6,22 @@ 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:28 | v1 | test.cpp:5:27:5:29 | call to shared_ptr | provenance | Config |
+| 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 | Config |
+| test.cpp:6:28:6:29 | p1 | test.cpp:6:31:6:33 | call to get | provenance | Config |
+| 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/autosar/test/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.expected b/cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.expected
similarity index 63%
rename from cpp/autosar/test/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.expected
rename to cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.expected
index 81f26e5130..71c0662377 100644
--- a/cpp/autosar/test/rules/A5-10-1/PointerToMemberVirtualFunctionWithNullPointerConstant.expected
+++ b/cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.expected
@@ -1,2 +1,2 @@
-| test.cpp:14:14:14:29 | ... == ... | A pointer to member virtual function $@ is tested for equality with non-null-pointer-constant $@. | test.cpp:6:16:6:17 | F3 | F3 | test.cpp:14:24:14:29 | F1 | F1 |
-| test.cpp:15:14:15:29 | ... == ... | A pointer to member virtual function $@ is tested for equality with non-null-pointer-constant $@. | test.cpp:6:16:6:17 | F3 | F3 | test.cpp:15:24:15:29 | F2 | F2 |
+| test.cpp:14:14:14:29 | ... == ... | A pointer to member virtual function $@ is tested for equality with non-null-pointer-constant $@. | test.cpp:6:16:6:17 | F3 | F3 | test.cpp:14:24:14:29 | F1 | F1 |
+| test.cpp:15:14:15:29 | ... == ... | A pointer to member virtual function $@ is tested for equality with non-null-pointer-constant $@. | test.cpp:6:16:6:17 | F3 | F3 | test.cpp:15:24:15:29 | F2 | F2 |
diff --git a/cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.ql b/cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.ql
new file mode 100644
index 0000000000..84263abc91
--- /dev/null
+++ b/cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/PotentiallyVirtualPointerOnlyComparesToNullptr.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.potentiallyvirtualpointeronlycomparestonullptr.PotentiallyVirtualPointerOnlyComparesToNullptr
+
+class TestFileQuery extends PotentiallyVirtualPointerOnlyComparesToNullptrSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A5-10-1/test.cpp b/cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A5-10-1/test.cpp
rename to cpp/common/test/rules/potentiallyvirtualpointeronlycomparestonullptr/test.cpp
diff --git a/cpp/autosar/test/rules/A5-2-4/ReinterpretCastUsed.expected b/cpp/common/test/rules/reinterpretcastused/ReinterpretCastUsed.expected
similarity index 100%
rename from cpp/autosar/test/rules/A5-2-4/ReinterpretCastUsed.expected
rename to cpp/common/test/rules/reinterpretcastused/ReinterpretCastUsed.expected
diff --git a/cpp/common/test/rules/reinterpretcastused/ReinterpretCastUsed.ql b/cpp/common/test/rules/reinterpretcastused/ReinterpretCastUsed.ql
new file mode 100644
index 0000000000..b58a7f4dbb
--- /dev/null
+++ b/cpp/common/test/rules/reinterpretcastused/ReinterpretCastUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.reinterpretcastused.ReinterpretCastUsed
+
+class TestFileQuery extends ReinterpretCastUsedSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A5-2-4/test.cpp b/cpp/common/test/rules/reinterpretcastused/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A5-2-4/test.cpp
rename to cpp/common/test/rules/reinterpretcastused/test.cpp
diff --git a/cpp/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.expected b/cpp/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.expected
new file mode 100644
index 0000000000..3f2720dd76
--- /dev/null
+++ b/cpp/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.expected
@@ -0,0 +1,3 @@
+| test.cpp:9:7:9:12 | ... = ... | Use of an assignment operator's result. |
+| test.cpp:13:11:13:16 | ... = ... | Use of an assignment operator's result. |
+| test.cpp:15:8:15:13 | ... = ... | Use of an assignment operator's result. |
diff --git a/cpp/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql b/cpp/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
new file mode 100644
index 0000000000..286e4424a4
--- /dev/null
+++ b/cpp/common/test/rules/resultofanassignmentoperatorshouldnotbeused/ResultOfAnAssignmentOperatorShouldNotBeUsed.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.resultofanassignmentoperatorshouldnotbeused.ResultOfAnAssignmentOperatorShouldNotBeUsed
+
+class TestFileQuery extends ResultOfAnAssignmentOperatorShouldNotBeUsedSharedQuery, TestQuery { }
diff --git a/c/misra/test/rules/RULE-13-4/test.c b/cpp/common/test/rules/resultofanassignmentoperatorshouldnotbeused/test.cpp
similarity index 59%
rename from c/misra/test/rules/RULE-13-4/test.c
rename to cpp/common/test/rules/resultofanassignmentoperatorshouldnotbeused/test.cpp
index aeabb60fac..21fb4c0910 100644
--- a/c/misra/test/rules/RULE-13-4/test.c
+++ b/cpp/common/test/rules/resultofanassignmentoperatorshouldnotbeused/test.cpp
@@ -1,3 +1,5 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
void test() {
int l1, l2;
int l3[1];
diff --git a/cpp/autosar/test/rules/M7-5-1/FunctionReturnAutomaticVarCondition.expected b/cpp/common/test/rules/returnreferenceorpointertoautomaticlocalvariable/ReturnReferenceOrPointerToAutomaticLocalVariable.expected
similarity index 100%
rename from cpp/autosar/test/rules/M7-5-1/FunctionReturnAutomaticVarCondition.expected
rename to cpp/common/test/rules/returnreferenceorpointertoautomaticlocalvariable/ReturnReferenceOrPointerToAutomaticLocalVariable.expected
diff --git a/cpp/common/test/rules/returnreferenceorpointertoautomaticlocalvariable/ReturnReferenceOrPointerToAutomaticLocalVariable.ql b/cpp/common/test/rules/returnreferenceorpointertoautomaticlocalvariable/ReturnReferenceOrPointerToAutomaticLocalVariable.ql
new file mode 100644
index 0000000000..c6c9c9e8fc
--- /dev/null
+++ b/cpp/common/test/rules/returnreferenceorpointertoautomaticlocalvariable/ReturnReferenceOrPointerToAutomaticLocalVariable.ql
@@ -0,0 +1,5 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.returnreferenceorpointertoautomaticlocalvariable.ReturnReferenceOrPointerToAutomaticLocalVariable
+
+class TestFileQuery extends ReturnReferenceOrPointerToAutomaticLocalVariableSharedQuery, TestQuery {
+}
diff --git a/cpp/autosar/test/rules/M7-5-1/test.cpp b/cpp/common/test/rules/returnreferenceorpointertoautomaticlocalvariable/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M7-5-1/test.cpp
rename to cpp/common/test/rules/returnreferenceorpointertoautomaticlocalvariable/test.cpp
diff --git a/cpp/autosar/test/rules/M6-3-1/SwitchCompoundCondition.expected b/cpp/common/test/rules/switchcompoundcondition/SwitchCompoundCondition.expected
similarity index 100%
rename from cpp/autosar/test/rules/M6-3-1/SwitchCompoundCondition.expected
rename to cpp/common/test/rules/switchcompoundcondition/SwitchCompoundCondition.expected
diff --git a/cpp/common/test/rules/switchcompoundcondition/SwitchCompoundCondition.ql b/cpp/common/test/rules/switchcompoundcondition/SwitchCompoundCondition.ql
new file mode 100644
index 0000000000..8fb855036c
--- /dev/null
+++ b/cpp/common/test/rules/switchcompoundcondition/SwitchCompoundCondition.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.switchcompoundcondition.SwitchCompoundCondition
+
+class TestFileQuery extends SwitchCompoundConditionSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/switchcompoundcondition/test.cpp b/cpp/common/test/rules/switchcompoundcondition/test.cpp
new file mode 100644
index 0000000000..487c007fdc
--- /dev/null
+++ b/cpp/common/test/rules/switchcompoundcondition/test.cpp
@@ -0,0 +1,56 @@
+void test_loop_missing_braces(int expression) {
+ for (int i = 0; i < expression; i++) // BAD
+ expression = expression % 2;
+}
+
+void test_loop_valid_braces_check(int expression) {
+ for (int i = 0; i < expression; i++) { // GOOD
+ expression = expression % 2;
+ }
+
+ int j = 10;
+ while (expression < 10) // BAD
+ j = j + 10;
+}
+
+void test_loop_mix_validity(int expression) {
+ do // BAD
+ expression = expression % 2;
+ while (expression < 10);
+
+ while (expression > 10) // GOOD
+ {
+ expression = expression * 2;
+ }
+
+ do { // GOOD
+ expression = expression % 2;
+ } while (expression < 5);
+}
+
+void test_switch_valid_braces(int i, int expression) {
+ // GOOD
+ switch (expression) {
+ case 0:
+ while (i < 10) {
+ i = i + expression;
+ }
+ break;
+ case 1:
+ if (i > 10) {
+ i = i * i;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void test_switch_invalid_braces(int i, int expression) {
+ // BAD
+ switch (expression)
+ case 0:
+ while (i < 10) {
+ i = i + expression;
+ }
+}
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
new file mode 100644
index 0000000000..3326ede548
--- /dev/null
+++ b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.expected
@@ -0,0 +1,18 @@
+| 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/UnsignedIntegerLiteralsNotAppropriatelySuffixed.ql b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.ql
new file mode 100644
index 0000000000..30f07a3f22
--- /dev/null
+++ b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/UnsignedIntegerLiteralsNotAppropriatelySuffixed.ql
@@ -0,0 +1,5 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.unsignedintegerliteralsnotappropriatelysuffixed.UnsignedIntegerLiteralsNotAppropriatelySuffixed
+
+class TestFileQuery extends UnsignedIntegerLiteralsNotAppropriatelySuffixedSharedQuery, TestQuery {
+}
diff --git a/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp
new file mode 100644
index 0000000000..fcbd51b3de
--- /dev/null
+++ b/cpp/common/test/rules/unsignedintegerliteralsnotappropriatelysuffixed/test.cpp
@@ -0,0 +1,546 @@
+// 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/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.expected b/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.expected
new file mode 100644
index 0000000000..3902cae09d
--- /dev/null
+++ b/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.expected
@@ -0,0 +1,4 @@
+| test.cpp:7:3:7:9 | ... + ... | Operation + of type unsigned int may wrap. |
+| test.cpp:8:3:8:10 | ... += ... | Operation += of type unsigned int may wrap. |
+| test.cpp:61:3:61:9 | ... - ... | Operation - of type unsigned int may wrap. |
+| test.cpp:62:3:62:10 | ... -= ... | Operation -= of type unsigned int may wrap. |
diff --git a/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.ql b/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.ql
new file mode 100644
index 0000000000..b88e7637c1
--- /dev/null
+++ b/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/UnsignedOperationWithConstantOperandsWraps.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.unsignedoperationwithconstantoperandswraps.UnsignedOperationWithConstantOperandsWraps
+
+class TestFileQuery extends UnsignedOperationWithConstantOperandsWrapsSharedQuery, TestQuery { }
diff --git a/c/cert/test/rules/INT30-C/test.c b/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/test.cpp
similarity index 94%
rename from c/cert/test/rules/INT30-C/test.c
rename to cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/test.cpp
index 433cf534f4..8f76fbeeeb 100644
--- a/c/cert/test/rules/INT30-C/test.c
+++ b/cpp/common/test/rules/unsignedoperationwithconstantoperandswraps/test.cpp
@@ -1,3 +1,6 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+
#include
void test_add_simple(unsigned int i1, unsigned int i2) {
diff --git a/cpp/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.expected b/cpp/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.expected
new file mode 100644
index 0000000000..e4280f2f1a
--- /dev/null
+++ b/cpp/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.expected
@@ -0,0 +1,2 @@
+| test.cpp:5:3:5:5 | 10 | Non zero octal literal 012. |
+| test.cpp:6:3:6:5 | 44 | Non zero octal literal 054. |
diff --git a/cpp/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.ql b/cpp/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.ql
new file mode 100644
index 0000000000..0404a7bc0c
--- /dev/null
+++ b/cpp/common/test/rules/useofnonzerooctalliteral/UseOfNonZeroOctalLiteral.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.useofnonzerooctalliteral.UseOfNonZeroOctalLiteral
+
+class TestFileQuery extends UseOfNonZeroOctalLiteralSharedQuery, TestQuery { }
diff --git a/cpp/common/test/rules/useofnonzerooctalliteral/test.cpp b/cpp/common/test/rules/useofnonzerooctalliteral/test.cpp
new file mode 100644
index 0000000000..0bf928c9ec
--- /dev/null
+++ b/cpp/common/test/rules/useofnonzerooctalliteral/test.cpp
@@ -0,0 +1,7 @@
+// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND
+// CHANGES SHOULD BE REFLECTED THERE AS WELL.
+void test_non_zero_octal() {
+ 0; // COMPLIANT - octal literal zero permitted
+ 012; // NON_COMPLIANT
+ 054; // NON_COMPLIANT
+}
\ No newline at end of file
diff --git a/cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.expected b/cpp/common/test/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.expected
similarity index 100%
rename from cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.expected
rename to cpp/common/test/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.expected
diff --git a/cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.expected.qcc b/cpp/common/test/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.expected.qcc
similarity index 100%
rename from cpp/autosar/test/rules/A18-1-2/VectorboolSpecializationUsed.expected.qcc
rename to cpp/common/test/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.expected.qcc
diff --git a/cpp/common/test/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.ql b/cpp/common/test/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.ql
new file mode 100644
index 0000000000..a965d5e5d6
--- /dev/null
+++ b/cpp/common/test/rules/vectorshouldnotbespecializedwithbool/VectorShouldNotBeSpecializedWithBool.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.vectorshouldnotbespecializedwithbool.VectorShouldNotBeSpecializedWithBool
+
+class TestFileQuery extends VectorShouldNotBeSpecializedWithBoolSharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/A18-1-2/test.cpp b/cpp/common/test/rules/vectorshouldnotbespecializedwithbool/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/A18-1-2/test.cpp
rename to cpp/common/test/rules/vectorshouldnotbespecializedwithbool/test.cpp
diff --git a/cpp/autosar/test/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.expected b/cpp/common/test/rules/virtualandnonvirtualclassinthehierarchy/VirtualAndNonVirtualClassInTheHierarchy.expected
similarity index 100%
rename from cpp/autosar/test/rules/M10-1-3/AccessibleBaseClassBothVirtualAndNonVirtualInHierarchy.expected
rename to cpp/common/test/rules/virtualandnonvirtualclassinthehierarchy/VirtualAndNonVirtualClassInTheHierarchy.expected
diff --git a/cpp/common/test/rules/virtualandnonvirtualclassinthehierarchy/VirtualAndNonVirtualClassInTheHierarchy.ql b/cpp/common/test/rules/virtualandnonvirtualclassinthehierarchy/VirtualAndNonVirtualClassInTheHierarchy.ql
new file mode 100644
index 0000000000..2137cbeb66
--- /dev/null
+++ b/cpp/common/test/rules/virtualandnonvirtualclassinthehierarchy/VirtualAndNonVirtualClassInTheHierarchy.ql
@@ -0,0 +1,4 @@
+// GENERATED FILE - DO NOT MODIFY
+import codingstandards.cpp.rules.virtualandnonvirtualclassinthehierarchy.VirtualAndNonVirtualClassInTheHierarchy
+
+class TestFileQuery extends VirtualAndNonVirtualClassInTheHierarchySharedQuery, TestQuery { }
diff --git a/cpp/autosar/test/rules/M10-1-3/test.cpp b/cpp/common/test/rules/virtualandnonvirtualclassinthehierarchy/test.cpp
similarity index 100%
rename from cpp/autosar/test/rules/M10-1-3/test.cpp
rename to cpp/common/test/rules/virtualandnonvirtualclassinthehierarchy/test.cpp
diff --git a/cpp/misra/src/codeql-pack.lock.yml b/cpp/misra/src/codeql-pack.lock.yml
index 514e6963d0..910a6e060e 100644
--- a/cpp/misra/src/codeql-pack.lock.yml
+++ b/cpp/misra/src/codeql-pack.lock.yml
@@ -2,13 +2,23 @@
lockVersion: 1.0.0
dependencies:
codeql/cpp-all:
- version: 0.9.3
+ version: 1.4.2
codeql/dataflow:
- version: 0.0.4
+ version: 1.1.1
+ codeql/mad:
+ version: 1.0.7
+ codeql/rangeanalysis:
+ version: 1.0.7
codeql/ssa:
- version: 0.1.5
+ version: 1.0.7
codeql/tutorial:
- version: 0.1.5
+ version: 1.0.7
+ codeql/typeflow:
+ version: 1.0.7
+ codeql/typetracking:
+ version: 1.0.7
codeql/util:
- version: 0.1.5
+ version: 1.0.7
+ codeql/xml:
+ version: 1.0.7
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..96fc96ce24 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.40.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: 1.4.2
diff --git a/cpp/misra/src/rules/DIR-15-8-1/CopyAndMoveAssignmentsShallHandleSelfAssignment.ql b/cpp/misra/src/rules/DIR-15-8-1/CopyAndMoveAssignmentsShallHandleSelfAssignment.ql
new file mode 100644
index 0000000000..daf6e89530
--- /dev/null
+++ b/cpp/misra/src/rules/DIR-15-8-1/CopyAndMoveAssignmentsShallHandleSelfAssignment.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/copy-and-move-assignments-shall-handle-self-assignment
+ * @name DIR-15-8-1: User-provided copy assignment operators and move assignment operators shall handle self-assignment
+ * @description User-provided copy assignment operators and move assignment operators shall handle
+ * self-assignment.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/dir-15-8-1
+ * external/misra/allocated-target/implementation
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.copyandmoveassignmentsshallhandleselfassignment.CopyAndMoveAssignmentsShallHandleSelfAssignment
+
+class CopyAndMoveAssignmentsShallHandleSelfAssignmentQuery extends CopyAndMoveAssignmentsShallHandleSelfAssignmentSharedQuery
+{
+ CopyAndMoveAssignmentsShallHandleSelfAssignmentQuery() {
+ this = ImportMisra23Package::copyAndMoveAssignmentsShallHandleSelfAssignmentQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-10-0-1/UseSingleGlobalOrMemberDeclarators.ql b/cpp/misra/src/rules/RULE-10-0-1/UseSingleGlobalOrMemberDeclarators.ql
new file mode 100644
index 0000000000..ffbc5bacaf
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-10-0-1/UseSingleGlobalOrMemberDeclarators.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/use-single-global-or-member-declarators
+ * @name RULE-10-0-1: Multiple declarations in the same global or member declaration sequence
+ * @description A declaration should not declare more than one variable or member variable.
+ * @kind problem
+ * @precision medium
+ * @problem.severity recommendation
+ * @tags external/misra/id/rule-10-0-1
+ * readability
+ * maintainability
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/advisory
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.multipleglobalormemberdeclarators.MultipleGlobalOrMemberDeclarators
+
+class UseSingleGlobalOrMemberDeclaratorsQuery extends MultipleGlobalOrMemberDeclaratorsSharedQuery {
+ UseSingleGlobalOrMemberDeclaratorsQuery() {
+ this = ImportMisra23Package::useSingleGlobalOrMemberDeclaratorsQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-10-0-1/UseSingleLocalDeclarators.ql b/cpp/misra/src/rules/RULE-10-0-1/UseSingleLocalDeclarators.ql
new file mode 100644
index 0000000000..6d756daa87
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-10-0-1/UseSingleLocalDeclarators.ql
@@ -0,0 +1,22 @@
+/**
+ * @id cpp/misra/use-single-local-declarators
+ * @name RULE-10-0-1: Multiple declarations in the same local statement
+ * @description A declaration should not declare more than one variable or member variable.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity recommendation
+ * @tags external/misra/id/rule-10-0-1
+ * readability
+ * maintainability
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/advisory
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.multiplelocaldeclarators.MultipleLocalDeclarators
+
+class UseSingleLocalDeclaratorsQuery extends MultipleLocalDeclaratorsSharedQuery {
+ UseSingleLocalDeclaratorsQuery() { this = ImportMisra23Package::useSingleLocalDeclaratorsQuery() }
+}
diff --git a/cpp/misra/src/rules/RULE-10-2-1/EnumerationNotDefinedWithAnExplicitUnderlyingType.ql b/cpp/misra/src/rules/RULE-10-2-1/EnumerationNotDefinedWithAnExplicitUnderlyingType.ql
new file mode 100644
index 0000000000..ab4b6a19a1
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-10-2-1/EnumerationNotDefinedWithAnExplicitUnderlyingType.ql
@@ -0,0 +1,23 @@
+/**
+ * @id cpp/misra/enumeration-not-defined-with-an-explicit-underlying-type
+ * @name RULE-10-2-1: An enumeration shall be defined with an explicit underlying type
+ * @description An enumeration shall be defined with an explicit underlying type.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-10-2-1
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.enumerationnotdefinedwithanexplicitunderlyingtype.EnumerationNotDefinedWithAnExplicitUnderlyingType
+
+class EnumerationNotDefinedWithAnExplicitUnderlyingTypeQuery extends EnumerationNotDefinedWithAnExplicitUnderlyingTypeSharedQuery
+{
+ EnumerationNotDefinedWithAnExplicitUnderlyingTypeQuery() {
+ this = ImportMisra23Package::enumerationNotDefinedWithAnExplicitUnderlyingTypeQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-10-4-1/AsmDeclarationShallNotBeUsed.ql b/cpp/misra/src/rules/RULE-10-4-1/AsmDeclarationShallNotBeUsed.ql
new file mode 100644
index 0000000000..5a2f4c4265
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-10-4-1/AsmDeclarationShallNotBeUsed.ql
@@ -0,0 +1,22 @@
+/**
+ * @id cpp/misra/asm-declaration-shall-not-be-used
+ * @name RULE-10-4-1: The asm declaration shall not be used
+ * @description The asm declaration shall not be used.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-10-4-1
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.asmdeclarationused.AsmDeclarationUsed
+
+class AsmDeclarationShallNotBeUsedQuery extends AsmDeclarationUsedSharedQuery {
+ AsmDeclarationShallNotBeUsedQuery() {
+ this = ImportMisra23Package::asmDeclarationShallNotBeUsedQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-11-6-3/NonUniqueEnumerationConstant.ql b/cpp/misra/src/rules/RULE-11-6-3/NonUniqueEnumerationConstant.ql
new file mode 100644
index 0000000000..faa0880a75
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-11-6-3/NonUniqueEnumerationConstant.ql
@@ -0,0 +1,23 @@
+/**
+ * @id cpp/misra/non-unique-enumeration-constant
+ * @name RULE-11-6-3: Within an enumerator list, the value of an implicitly-specified enumeration constant shall be unique
+ * @description Within an enumerator list, the value of an implicitly-specified enumeration constant
+ * shall be unique.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-11-6-3
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.nonuniqueenumerationconstant.NonUniqueEnumerationConstant
+
+class NonUniqueEnumerationConstantQuery extends NonUniqueEnumerationConstantSharedQuery {
+ NonUniqueEnumerationConstantQuery() {
+ this = ImportMisra23Package::nonUniqueEnumerationConstantQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-12-2-2/BitFieldShallHaveAnAppropriateType.ql b/cpp/misra/src/rules/RULE-12-2-2/BitFieldShallHaveAnAppropriateType.ql
new file mode 100644
index 0000000000..f5041252f9
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-12-2-2/BitFieldShallHaveAnAppropriateType.ql
@@ -0,0 +1,22 @@
+/**
+ * @id cpp/misra/bit-field-shall-have-an-appropriate-type
+ * @name RULE-12-2-2: A bit-field shall have an appropriate type
+ * @description A bit-field shall have an appropriate type.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-12-2-2
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.bitfieldshallhaveanappropriatetype.BitFieldShallHaveAnAppropriateType
+
+class BitFieldShallHaveAnAppropriateTypeQuery extends BitFieldShallHaveAnAppropriateTypeSharedQuery {
+ BitFieldShallHaveAnAppropriateTypeQuery() {
+ this = ImportMisra23Package::bitFieldShallHaveAnAppropriateTypeQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-12-2-3/SignedIntegerNamedBitFieldHaveALengthOfOneBit.ql b/cpp/misra/src/rules/RULE-12-2-3/SignedIntegerNamedBitFieldHaveALengthOfOneBit.ql
new file mode 100644
index 0000000000..df547bbec8
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-12-2-3/SignedIntegerNamedBitFieldHaveALengthOfOneBit.ql
@@ -0,0 +1,23 @@
+/**
+ * @id cpp/misra/signed-integer-named-bit-field-have-a-length-of-one-bit
+ * @name RULE-12-2-3: A named bit-field with signed integer type shall not have a length of one bit
+ * @description A named bit-field with signed integer type shall not have a length of one bit.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-12-2-3
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.namedbitfieldswithsignedintegertype.NamedBitFieldsWithSignedIntegerType
+
+class SignedIntegerNamedBitFieldHaveALengthOfOneBitQuery extends NamedBitFieldsWithSignedIntegerTypeSharedQuery
+{
+ SignedIntegerNamedBitFieldHaveALengthOfOneBitQuery() {
+ this = ImportMisra23Package::signedIntegerNamedBitFieldHaveALengthOfOneBitQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-13-1-2/VirtualAndNonVirtualClassInTheHierarchy.ql b/cpp/misra/src/rules/RULE-13-1-2/VirtualAndNonVirtualClassInTheHierarchy.ql
new file mode 100644
index 0000000000..75030afbfb
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-13-1-2/VirtualAndNonVirtualClassInTheHierarchy.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/virtual-and-non-virtual-class-in-the-hierarchy
+ * @name RULE-13-1-2: An accessible base class shall not be both virtual and non-virtual in the same hierarchy
+ * @description An accessible base class shall not be both virtual and non-virtual in the same
+ * hierarchy.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-13-1-2
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.virtualandnonvirtualclassinthehierarchy.VirtualAndNonVirtualClassInTheHierarchy
+
+class VirtualAndNonVirtualClassInTheHierarchyQuery extends VirtualAndNonVirtualClassInTheHierarchySharedQuery
+{
+ VirtualAndNonVirtualClassInTheHierarchyQuery() {
+ this = ImportMisra23Package::virtualAndNonVirtualClassInTheHierarchyQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-13-3-2/OverridingShallSpecifyDifferentDefaultArguments.ql b/cpp/misra/src/rules/RULE-13-3-2/OverridingShallSpecifyDifferentDefaultArguments.ql
new file mode 100644
index 0000000000..519589984e
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-13-3-2/OverridingShallSpecifyDifferentDefaultArguments.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/overriding-shall-specify-different-default-arguments
+ * @name RULE-13-3-2: Parameters in an overriding virtual function shall not specify different default arguments
+ * @description Parameters in an overriding virtual function shall not specify different default
+ * arguments.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-13-3-2
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.overridingshallspecifydifferentdefaultarguments.OverridingShallSpecifyDifferentDefaultArguments
+
+class OverridingShallSpecifyDifferentDefaultArgumentsQuery extends OverridingShallSpecifyDifferentDefaultArgumentsSharedQuery
+{
+ OverridingShallSpecifyDifferentDefaultArgumentsQuery() {
+ this = ImportMisra23Package::overridingShallSpecifyDifferentDefaultArgumentsQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-13-3-4/PotentiallyVirtualPointerOnlyComparesToNullptr.ql b/cpp/misra/src/rules/RULE-13-3-4/PotentiallyVirtualPointerOnlyComparesToNullptr.ql
new file mode 100644
index 0000000000..1c528396e0
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-13-3-4/PotentiallyVirtualPointerOnlyComparesToNullptr.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/potentially-virtual-pointer-only-compares-to-nullptr
+ * @name RULE-13-3-4: A comparison of a potentially virtual pointer to member function shall only be with nullptr
+ * @description A comparison of a potentially virtual pointer to member function shall only be with
+ * nullptr.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-13-3-4
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.potentiallyvirtualpointeronlycomparestonullptr.PotentiallyVirtualPointerOnlyComparesToNullptr
+
+class PotentiallyVirtualPointerOnlyComparesToNullptrQuery extends PotentiallyVirtualPointerOnlyComparesToNullptrSharedQuery
+{
+ PotentiallyVirtualPointerOnlyComparesToNullptrQuery() {
+ this = ImportMisra23Package::potentiallyVirtualPointerOnlyComparesToNullptrQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-15-1-1/ObjectsDynamicTypeUsedFromConstructorOrDestructor.ql b/cpp/misra/src/rules/RULE-15-1-1/ObjectsDynamicTypeUsedFromConstructorOrDestructor.ql
new file mode 100644
index 0000000000..f23c1afab8
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-15-1-1/ObjectsDynamicTypeUsedFromConstructorOrDestructor.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/objects-dynamic-type-used-from-constructor-or-destructor
+ * @name RULE-15-1-1: An object’s dynamic type shall not be used from within its constructor or destructor
+ * @description An object’s dynamic type shall not be used from within its constructor or
+ * destructor.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-15-1-1
+ * scope/system
+ * external/misra/enforcement/undecidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.objectsdynamictypeusedfromconstructorordestructor.ObjectsDynamicTypeUsedFromConstructorOrDestructor
+
+class ObjectsDynamicTypeUsedFromConstructorOrDestructorQuery extends ObjectsDynamicTypeUsedFromConstructorOrDestructorSharedQuery
+{
+ ObjectsDynamicTypeUsedFromConstructorOrDestructorQuery() {
+ this = ImportMisra23Package::objectsDynamicTypeUsedFromConstructorOrDestructorQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-15-1-2/InitializeAllVirtualBaseClasses.ql b/cpp/misra/src/rules/RULE-15-1-2/InitializeAllVirtualBaseClasses.ql
new file mode 100644
index 0000000000..3dd7b7e3e2
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-15-1-2/InitializeAllVirtualBaseClasses.ql
@@ -0,0 +1,23 @@
+/**
+ * @id cpp/misra/initialize-all-virtual-base-classes
+ * @name RULE-15-1-2: All constructors of a class should explicitly initialize all of its virtual base classes and
+ * @description All constructors of a class should explicitly initialize all of its virtual base
+ * classes and immediate base classes.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-15-1-2
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/advisory
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.initializeallvirtualbaseclasses.InitializeAllVirtualBaseClasses
+
+class InitializeAllVirtualBaseClassesQuery extends InitializeAllVirtualBaseClassesSharedQuery {
+ InitializeAllVirtualBaseClassesQuery() {
+ this = ImportMisra23Package::initializeAllVirtualBaseClassesQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-15-1-5/InitializerListConstructorIsTheOnlyConstructor.ql b/cpp/misra/src/rules/RULE-15-1-5/InitializerListConstructorIsTheOnlyConstructor.ql
new file mode 100644
index 0000000000..c7cf1856cd
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-15-1-5/InitializerListConstructorIsTheOnlyConstructor.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/initializer-list-constructor-is-the-only-constructor
+ * @name RULE-15-1-5: A class shall only define an initializer-list constructor when it is the only constructor
+ * @description A class shall only define an initializer-list constructor when it is the only
+ * constructor.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-15-1-5
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.initializerlistconstructoristheonlyconstructor.InitializerListConstructorIsTheOnlyConstructor
+
+class InitializerListConstructorIsTheOnlyConstructorQuery extends InitializerListConstructorIsTheOnlyConstructorSharedQuery
+{
+ InitializerListConstructorIsTheOnlyConstructorQuery() {
+ this = ImportMisra23Package::initializerListConstructorIsTheOnlyConstructorQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-16-5-2/AddressOfOperatorOverloaded.ql b/cpp/misra/src/rules/RULE-16-5-2/AddressOfOperatorOverloaded.ql
new file mode 100644
index 0000000000..937ec4e9e3
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-16-5-2/AddressOfOperatorOverloaded.ql
@@ -0,0 +1,22 @@
+/**
+ * @id cpp/misra/address-of-operator-overloaded
+ * @name RULE-16-5-2: The address-of operator shall not be overloaded
+ * @description The address-of operator shall not be overloaded.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-16-5-2
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.addressofoperatoroverloaded.AddressOfOperatorOverloaded
+
+class AddressOfOperatorOverloadedQuery extends AddressOfOperatorOverloadedSharedQuery {
+ AddressOfOperatorOverloadedQuery() {
+ this = ImportMisra23Package::addressOfOperatorOverloadedQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-17-8-1/FunctionTemplatesExplicitlySpecialized.ql b/cpp/misra/src/rules/RULE-17-8-1/FunctionTemplatesExplicitlySpecialized.ql
new file mode 100644
index 0000000000..c7b306946b
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-17-8-1/FunctionTemplatesExplicitlySpecialized.ql
@@ -0,0 +1,23 @@
+/**
+ * @id cpp/misra/function-templates-explicitly-specialized
+ * @name RULE-17-8-1: Function templates shall not be explicitly specialized
+ * @description Function templates shall not be explicitly specialized.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-17-8-1
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.functiontemplatesexplicitlyspecialized.FunctionTemplatesExplicitlySpecialized
+
+class FunctionTemplatesExplicitlySpecializedQuery extends FunctionTemplatesExplicitlySpecializedSharedQuery
+{
+ FunctionTemplatesExplicitlySpecializedQuery() {
+ this = ImportMisra23Package::functionTemplatesExplicitlySpecializedQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-18-1-1/ExceptionObjectHavePointerType.ql b/cpp/misra/src/rules/RULE-18-1-1/ExceptionObjectHavePointerType.ql
new file mode 100644
index 0000000000..cbae5c1da4
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-18-1-1/ExceptionObjectHavePointerType.ql
@@ -0,0 +1,22 @@
+/**
+ * @id cpp/misra/exception-object-have-pointer-type
+ * @name RULE-18-1-1: An exception object shall not have pointer type
+ * @description An exception object shall not have pointer type.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-18-1-1
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.exceptionobjecthavepointertype.ExceptionObjectHavePointerType
+
+class ExceptionObjectHavePointerTypeQuery extends ExceptionObjectHavePointerTypeSharedQuery {
+ ExceptionObjectHavePointerTypeQuery() {
+ this = ImportMisra23Package::exceptionObjectHavePointerTypeQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-18-1-2/EmptyThrowOnlyWithinACatchHandler.ql b/cpp/misra/src/rules/RULE-18-1-2/EmptyThrowOnlyWithinACatchHandler.ql
new file mode 100644
index 0000000000..15ca773943
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-18-1-2/EmptyThrowOnlyWithinACatchHandler.ql
@@ -0,0 +1,22 @@
+/**
+ * @id cpp/misra/empty-throw-only-within-a-catch-handler
+ * @name RULE-18-1-2: An empty throw shall only occur within the compound-statement of a catch handler
+ * @description An empty throw shall only occur within the compound-statement of a catch handler.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-18-1-2
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.emptythrowonlywithinacatchhandler.EmptyThrowOnlyWithinACatchHandler
+
+class EmptyThrowOnlyWithinACatchHandlerQuery extends EmptyThrowOnlyWithinACatchHandlerSharedQuery {
+ EmptyThrowOnlyWithinACatchHandlerQuery() {
+ this = ImportMisra23Package::emptyThrowOnlyWithinACatchHandlerQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-18-5-1/NoexceptFunctionShouldNotPropagateToTheCaller.ql b/cpp/misra/src/rules/RULE-18-5-1/NoexceptFunctionShouldNotPropagateToTheCaller.ql
new file mode 100644
index 0000000000..61d8a0ebd4
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-18-5-1/NoexceptFunctionShouldNotPropagateToTheCaller.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/noexcept-function-should-not-propagate-to-the-caller
+ * @name RULE-18-5-1: A noexcept function should not attempt to propagate an exception to the calling function
+ * @description A noexcept function should not attempt to propagate an exception to the calling
+ * function.
+ * @kind path-problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-18-5-1
+ * scope/system
+ * external/misra/enforcement/undecidable
+ * external/misra/obligation/advisory
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.noexceptfunctionshouldnotpropagatetothecaller.NoexceptFunctionShouldNotPropagateToTheCaller
+
+class NoexceptFunctionShouldNotPropagateToTheCallerQuery extends NoexceptFunctionShouldNotPropagateToTheCallerSharedQuery
+{
+ NoexceptFunctionShouldNotPropagateToTheCallerQuery() {
+ this = ImportMisra23Package::noexceptFunctionShouldNotPropagateToTheCallerQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-19-0-2/FunctionLikeMacrosDefined.ql b/cpp/misra/src/rules/RULE-19-0-2/FunctionLikeMacrosDefined.ql
new file mode 100644
index 0000000000..d9e4d5a810
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-19-0-2/FunctionLikeMacrosDefined.ql
@@ -0,0 +1,20 @@
+/**
+ * @id cpp/misra/function-like-macros-defined
+ * @name RULE-19-0-2: Function-like macros shall not be defined
+ * @description Function-like macros shall not be defined.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-19-0-2
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.functionlikemacrosdefined.FunctionLikeMacrosDefined
+
+class FunctionLikeMacrosDefinedQuery extends FunctionLikeMacrosDefinedSharedQuery {
+ FunctionLikeMacrosDefinedQuery() { this = ImportMisra23Package::functionLikeMacrosDefinedQuery() }
+}
diff --git a/cpp/misra/src/rules/RULE-19-3-2/MacroParameterFollowingHash.ql b/cpp/misra/src/rules/RULE-19-3-2/MacroParameterFollowingHash.ql
new file mode 100644
index 0000000000..12e95ced04
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-19-3-2/MacroParameterFollowingHash.ql
@@ -0,0 +1,23 @@
+/**
+ * @id cpp/misra/macro-parameter-following-hash
+ * @name RULE-19-3-2: A macro parameter immediately following a # operator shall not be immediately followed by a ##
+ * @description A macro parameter immediately following a # operator shall not be immediately
+ * followed by a ## operator.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-19-3-2
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.macroparameterfollowinghash.MacroParameterFollowingHash
+
+class MacroParameterFollowingHashQuery extends MacroParameterFollowingHashSharedQuery {
+ MacroParameterFollowingHashQuery() {
+ this = ImportMisra23Package::macroParameterFollowingHashQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-19-3-3/AMixedUseMacroArgumentSubjectToExpansion.ql b/cpp/misra/src/rules/RULE-19-3-3/AMixedUseMacroArgumentSubjectToExpansion.ql
new file mode 100644
index 0000000000..9cb0a7e9c5
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-19-3-3/AMixedUseMacroArgumentSubjectToExpansion.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/a-mixed-use-macro-argument-subject-to-expansion
+ * @name RULE-19-3-3: The argument to a mixed-use macro parameter shall not be subject to further expansion
+ * @description The argument to a mixed-use macro parameter shall not be subject to further
+ * expansion.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-19-3-3
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.amixedusemacroargumentsubjecttoexpansion.AMixedUseMacroArgumentSubjectToExpansion
+
+class AMixedUseMacroArgumentSubjectToExpansionQuery extends AMixedUseMacroArgumentSubjectToExpansionSharedQuery
+{
+ AMixedUseMacroArgumentSubjectToExpansionQuery() {
+ this = ImportMisra23Package::aMixedUseMacroArgumentSubjectToExpansionQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-21-10-3/CsignalFacilitiesUsed.ql b/cpp/misra/src/rules/RULE-21-10-3/CsignalFacilitiesUsed.ql
new file mode 100644
index 0000000000..3e8c58a8da
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-21-10-3/CsignalFacilitiesUsed.ql
@@ -0,0 +1,22 @@
+/**
+ * @id cpp/misra/csignal-facilities-used
+ * @name RULE-21-10-3: The facilities provided by the standard header file shall not be used
+ * @description Signal handling contains implementation-defined and undefined behaviour.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-21-10-3
+ * maintainability
+ * correctness
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.csignalfunctionsused.CsignalFunctionsUsed
+
+class CsignalFacilitiesUsedQuery extends CsignalFunctionsUsedSharedQuery {
+ CsignalFacilitiesUsedQuery() { this = ImportMisra23Package::csignalFacilitiesUsedQuery() }
+}
diff --git a/cpp/misra/src/rules/RULE-21-10-3/CsignalTypesShallNotBeUsed.ql b/cpp/misra/src/rules/RULE-21-10-3/CsignalTypesShallNotBeUsed.ql
new file mode 100644
index 0000000000..0fe1b1dfba
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-21-10-3/CsignalTypesShallNotBeUsed.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/csignal-types-shall-not-be-used
+ * @name RULE-21-10-3: The signal-handling types of shall not be used
+ * @description The types provided by the standard header file shall not be used.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-21-10-3
+ * maintainability
+ * correctness
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.csignaltypesused.CsignalTypesUsed
+
+class CsignalTypesShallNotBeUsedQuery extends CsignalTypesUsedSharedQuery {
+ CsignalTypesShallNotBeUsedQuery() {
+ this = ImportMisra23Package::csignalTypesShallNotBeUsedQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-21-2-1/AtofAtoiAtolAndAtollUsed.ql b/cpp/misra/src/rules/RULE-21-2-1/AtofAtoiAtolAndAtollUsed.ql
new file mode 100644
index 0000000000..e5b48d55a7
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-21-2-1/AtofAtoiAtolAndAtollUsed.ql
@@ -0,0 +1,20 @@
+/**
+ * @id cpp/misra/atof-atoi-atol-and-atoll-used
+ * @name RULE-21-2-1: The library functions atof, atoi, atol and atoll from shall not be used
+ * @description The library functions atof, atoi, atol and atoll from shall not be used.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-21-2-1
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.atofatoiatolandatollused.AtofAtoiAtolAndAtollUsed
+
+class AtofAtoiAtolAndAtollUsedQuery extends AtofAtoiAtolAndAtollUsedSharedQuery {
+ AtofAtoiAtolAndAtollUsedQuery() { this = ImportMisra23Package::atofAtoiAtolAndAtollUsedQuery() }
+}
diff --git a/cpp/misra/src/rules/RULE-21-2-4/MacroOffsetofShallNotBeUsed.ql b/cpp/misra/src/rules/RULE-21-2-4/MacroOffsetofShallNotBeUsed.ql
new file mode 100644
index 0000000000..fa6df051ca
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-21-2-4/MacroOffsetofShallNotBeUsed.ql
@@ -0,0 +1,22 @@
+/**
+ * @id cpp/misra/macro-offsetof-shall-not-be-used
+ * @name RULE-21-2-4: The macro offsetof shall not be used
+ * @description The macro offsetof shall not be used.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-21-2-4
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.macrooffsetofused.MacroOffsetofUsed
+
+class MacroOffsetofShallNotBeUsedQuery extends MacroOffsetofUsedSharedQuery {
+ MacroOffsetofShallNotBeUsedQuery() {
+ this = ImportMisra23Package::macroOffsetofShallNotBeUsedQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-21-6-4/GlobalSizedOperatorDeleteShallBeDefined.ql b/cpp/misra/src/rules/RULE-21-6-4/GlobalSizedOperatorDeleteShallBeDefined.ql
new file mode 100644
index 0000000000..eb9be3af15
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-21-6-4/GlobalSizedOperatorDeleteShallBeDefined.ql
@@ -0,0 +1,25 @@
+/**
+ * @id cpp/misra/global-sized-operator-delete-shall-be-defined
+ * @name RULE-21-6-4: Sized 'operator delete' must be defined globally if unsized 'operator delete' is defined globally
+ * @description If a project defines the unsized version of a global operator delete, then the sized
+ * version shall be defined.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-21-6-4
+ * maintainability
+ * scope/system
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.globalsizedoperatordeletenotdefined.GlobalSizedOperatorDeleteNotDefined
+
+class GlobalSizedOperatorDeleteShallBeDefinedQuery extends GlobalSizedOperatorDeleteNotDefinedSharedQuery
+{
+ GlobalSizedOperatorDeleteShallBeDefinedQuery() {
+ this = ImportMisra23Package::globalSizedOperatorDeleteShallBeDefinedQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-21-6-4/GlobalUnsizedOperatorDeleteShallBeDefined.ql b/cpp/misra/src/rules/RULE-21-6-4/GlobalUnsizedOperatorDeleteShallBeDefined.ql
new file mode 100644
index 0000000000..8a80b36e3f
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-21-6-4/GlobalUnsizedOperatorDeleteShallBeDefined.ql
@@ -0,0 +1,25 @@
+/**
+ * @id cpp/misra/global-unsized-operator-delete-shall-be-defined
+ * @name RULE-21-6-4: Unsized 'operator delete' must be defined globally if sized 'operator delete' is defined globally
+ * @description If a project defines the sized version of a global operator delete, then the unsized
+ * version shall be defined.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-21-6-4
+ * maintainability
+ * scope/system
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.globalunsizedoperatordeletenotdefined.GlobalUnsizedOperatorDeleteNotDefined
+
+class GlobalUnsizedOperatorDeleteShallBeDefinedQuery extends GlobalUnsizedOperatorDeleteNotDefinedSharedQuery
+{
+ GlobalUnsizedOperatorDeleteShallBeDefinedQuery() {
+ this = ImportMisra23Package::globalUnsizedOperatorDeleteShallBeDefinedQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-26-3-1/VectorShouldNotBeSpecializedWithBool.ql b/cpp/misra/src/rules/RULE-26-3-1/VectorShouldNotBeSpecializedWithBool.ql
new file mode 100644
index 0000000000..90037b5f29
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-26-3-1/VectorShouldNotBeSpecializedWithBool.ql
@@ -0,0 +1,23 @@
+/**
+ * @id cpp/misra/vector-should-not-be-specialized-with-bool
+ * @name RULE-26-3-1: std::vector should not be specialized with bool
+ * @description std::vector should not be specialized with bool.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-26-3-1
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/advisory
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.vectorshouldnotbespecializedwithbool.VectorShouldNotBeSpecializedWithBool
+
+class VectorShouldNotBeSpecializedWithBoolQuery extends VectorShouldNotBeSpecializedWithBoolSharedQuery
+{
+ VectorShouldNotBeSpecializedWithBoolQuery() {
+ this = ImportMisra23Package::vectorShouldNotBeSpecializedWithBoolQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-28-6-2/ForwardingReferencesAndForwardNotUsedTogether.ql b/cpp/misra/src/rules/RULE-28-6-2/ForwardingReferencesAndForwardNotUsedTogether.ql
new file mode 100644
index 0000000000..dc407512cc
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-28-6-2/ForwardingReferencesAndForwardNotUsedTogether.ql
@@ -0,0 +1,23 @@
+/**
+ * @id cpp/misra/forwarding-references-and-forward-not-used-together
+ * @name RULE-28-6-2: Forwarding references and std::forward shall be used together
+ * @description Forwarding references and std::forward shall be used together.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity error
+ * @tags external/misra/id/rule-28-6-2
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.forwardingreferencesandforwardnotusedtogether.ForwardingReferencesAndForwardNotUsedTogether
+
+class ForwardingReferencesAndForwardNotUsedTogetherQuery extends ForwardingReferencesAndForwardNotUsedTogetherSharedQuery
+{
+ ForwardingReferencesAndForwardNotUsedTogetherQuery() {
+ this = ImportMisra23Package::forwardingReferencesAndForwardNotUsedTogetherQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-30-0-1/CstdioFunctionsShallNotBeUsed.ql b/cpp/misra/src/rules/RULE-30-0-1/CstdioFunctionsShallNotBeUsed.ql
new file mode 100644
index 0000000000..58c8a500f4
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-30-0-1/CstdioFunctionsShallNotBeUsed.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/cstdio-functions-shall-not-be-used
+ * @name RULE-30-0-1: The stream input/output library functions shall not be used
+ * @description The C Library input/output functions shall not be used.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-30-0-1
+ * maintainability
+ * correctness
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.cstdiofunctionsused.CstdioFunctionsUsed
+
+class CstdioFunctionsShallNotBeUsedQuery extends CstdioFunctionsUsedSharedQuery {
+ CstdioFunctionsShallNotBeUsedQuery() {
+ this = ImportMisra23Package::cstdioFunctionsShallNotBeUsedQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-30-0-1/CstdioMacrosShallNotBeUsed.ql b/cpp/misra/src/rules/RULE-30-0-1/CstdioMacrosShallNotBeUsed.ql
new file mode 100644
index 0000000000..8f0b9438e3
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-30-0-1/CstdioMacrosShallNotBeUsed.ql
@@ -0,0 +1,24 @@
+/**
+ * @id cpp/misra/cstdio-macros-shall-not-be-used
+ * @name RULE-30-0-1: The stream input/output library macros shall not be used
+ * @description The C Library input/output functions shall not be used.
+ * @kind problem
+ * @precision very-high
+ * @problem.severity warning
+ * @tags external/misra/id/rule-30-0-1
+ * maintainability
+ * correctness
+ * scope/single-translation-unit
+ * external/misra/enforcement/decidable
+ * external/misra/obligation/required
+ */
+
+import cpp
+import codingstandards.cpp.misra
+import codingstandards.cpp.rules.cstdiomacrosused.CstdioMacrosUsed
+
+class CstdioMacrosShallNotBeUsedQuery extends CstdioMacrosUsedSharedQuery {
+ CstdioMacrosShallNotBeUsedQuery() {
+ this = ImportMisra23Package::cstdioMacrosShallNotBeUsedQuery()
+ }
+}
diff --git a/cpp/misra/src/rules/RULE-30-0-1/CstdioTypesShallNotBeUsed.ql b/cpp/misra/src/rules/RULE-30-0-1/CstdioTypesShallNotBeUsed.ql
new file mode 100644
index 0000000000..6966c85068
--- /dev/null
+++ b/cpp/misra/src/rules/RULE-30-0-1/CstdioTypesShallNotBeUsed.ql
@@ -0,0 +1,22 @@
+/**
+ * @id cpp/misra/cstdio-types-shall-not-be-used
+ * @name RULE-30-0-1: The stream input/output library