mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
upgrading to 2.16.3, resolving zipslip merge conflict
This commit is contained in:
3
.github/workflows/check-change-note.yml
vendored
3
.github/workflows/check-change-note.yml
vendored
@@ -1,5 +1,8 @@
|
|||||||
name: Check change note
|
name: Check change note
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
pull-requests: read
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
types: [labeled, unlabeled, opened, synchronize, reopened, ready_for_review]
|
types: [labeled, unlabeled, opened, synchronize, reopened, ready_for_review]
|
||||||
|
|||||||
3
.github/workflows/check-implicit-this.yml
vendored
3
.github/workflows/check-implicit-this.yml
vendored
@@ -9,6 +9,9 @@ on:
|
|||||||
- main
|
- main
|
||||||
- "rc/*"
|
- "rc/*"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
3
.github/workflows/check-qldoc.yml
vendored
3
.github/workflows/check-qldoc.yml
vendored
@@ -10,6 +10,9 @@ on:
|
|||||||
- main
|
- main
|
||||||
- "rc/*"
|
- "rc/*"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
qldoc:
|
qldoc:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
3
.github/workflows/check-query-ids.yml
vendored
3
.github/workflows/check-query-ids.yml
vendored
@@ -11,6 +11,9 @@ on:
|
|||||||
- "rc/*"
|
- "rc/*"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
name: Check query IDs
|
name: Check query IDs
|
||||||
|
|||||||
3
.github/workflows/close-stale.yml
vendored
3
.github/workflows/close-stale.yml
vendored
@@ -5,6 +5,9 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: "30 1 * * *"
|
- cron: "30 1 * * *"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
stale:
|
stale:
|
||||||
if: github.repository == 'github/codeql'
|
if: github.repository == 'github/codeql'
|
||||||
|
|||||||
4
.github/workflows/compile-queries.yml
vendored
4
.github/workflows/compile-queries.yml
vendored
@@ -8,8 +8,12 @@ on:
|
|||||||
- "codeql-cli-*"
|
- "codeql-cli-*"
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
compile-queries:
|
compile-queries:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
4
.github/workflows/csharp-qltest.yml
vendored
4
.github/workflows/csharp-qltest.yml
vendored
@@ -25,6 +25,9 @@ defaults:
|
|||||||
run:
|
run:
|
||||||
working-directory: csharp
|
working-directory: csharp
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
qlupgrade:
|
qlupgrade:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -46,6 +49,7 @@ jobs:
|
|||||||
xargs codeql execute upgrades testdb
|
xargs codeql execute upgrades testdb
|
||||||
diff -q testdb/semmlecode.csharp.dbscheme downgrades/initial/semmlecode.csharp.dbscheme
|
diff -q testdb/semmlecode.csharp.dbscheme downgrades/initial/semmlecode.csharp.dbscheme
|
||||||
qltest:
|
qltest:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|||||||
4
.github/workflows/csv-coverage-metrics.yml
vendored
4
.github/workflows/csv-coverage-metrics.yml
vendored
@@ -14,6 +14,10 @@ on:
|
|||||||
- ".github/workflows/csv-coverage-metrics.yml"
|
- ".github/workflows/csv-coverage-metrics.yml"
|
||||||
- ".github/actions/fetch-codeql/action.yml"
|
- ".github/actions/fetch-codeql/action.yml"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-java:
|
publish-java:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ on:
|
|||||||
- main
|
- main
|
||||||
- "rc/*"
|
- "rc/*"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
generate:
|
generate:
|
||||||
name: Generate framework coverage artifacts
|
name: Generate framework coverage artifacts
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ on:
|
|||||||
types:
|
types:
|
||||||
- completed
|
- completed
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
name: Check framework coverage differences and comment
|
name: Check framework coverage differences and comment
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ name: Build framework coverage timeseries reports
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
4
.github/workflows/csv-coverage-update.yml
vendored
4
.github/workflows/csv-coverage-update.yml
vendored
@@ -5,6 +5,10 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update:
|
update:
|
||||||
name: Update framework coverage report
|
name: Update framework coverage report
|
||||||
|
|||||||
3
.github/workflows/csv-coverage.yml
vendored
3
.github/workflows/csv-coverage.yml
vendored
@@ -7,6 +7,9 @@ on:
|
|||||||
description: "github/codeql repo SHA used for looking up the CSV models"
|
description: "github/codeql repo SHA used for looking up the CSV models"
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
5
.github/workflows/fast-forward.yml
vendored
5
.github/workflows/fast-forward.yml
vendored
@@ -7,13 +7,14 @@ name: Fast-forward tracking branch for selected CodeQL version
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
fast-forward:
|
fast-forward:
|
||||||
name: Fast-forward tracking branch for selected CodeQL version
|
name: Fast-forward tracking branch for selected CodeQL version
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.repository == 'github/codeql'
|
if: github.repository == 'github/codeql'
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
env:
|
env:
|
||||||
BRANCH_NAME: 'lgtm.com'
|
BRANCH_NAME: 'lgtm.com'
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
9
.github/workflows/go-tests-other-os.yml
vendored
9
.github/workflows/go-tests-other-os.yml
vendored
@@ -8,7 +8,11 @@ on:
|
|||||||
- .github/actions/**
|
- .github/actions/**
|
||||||
- codeql-workspace.yml
|
- codeql-workspace.yml
|
||||||
env:
|
env:
|
||||||
GO_VERSION: '~1.21.0'
|
GO_VERSION: '~1.22.0'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-mac:
|
test-mac:
|
||||||
name: Test MacOS
|
name: Test MacOS
|
||||||
@@ -18,6 +22,7 @@ jobs:
|
|||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
cache: false
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
@@ -46,6 +51,7 @@ jobs:
|
|||||||
make test cache="${{ steps.query-cache.outputs.cache-dir }}"
|
make test cache="${{ steps.query-cache.outputs.cache-dir }}"
|
||||||
|
|
||||||
test-win:
|
test-win:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
name: Test Windows
|
name: Test Windows
|
||||||
runs-on: windows-latest-xl
|
runs-on: windows-latest-xl
|
||||||
steps:
|
steps:
|
||||||
@@ -53,6 +59,7 @@ jobs:
|
|||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
cache: false
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
|
|||||||
9
.github/workflows/go-tests.yml
vendored
9
.github/workflows/go-tests.yml
vendored
@@ -15,10 +15,16 @@ on:
|
|||||||
- .github/workflows/go-tests.yml
|
- .github/workflows/go-tests.yml
|
||||||
- .github/actions/**
|
- .github/actions/**
|
||||||
- codeql-workspace.yml
|
- codeql-workspace.yml
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GO_VERSION: '~1.21.0'
|
GO_VERSION: '~1.22.0'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-linux:
|
test-linux:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
name: Test Linux (Ubuntu)
|
name: Test Linux (Ubuntu)
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
steps:
|
steps:
|
||||||
@@ -26,6 +32,7 @@ jobs:
|
|||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.GO_VERSION }}
|
go-version: ${{ env.GO_VERSION }}
|
||||||
|
cache: false
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
|
|||||||
7
.github/workflows/labeler.yml
vendored
7
.github/workflows/labeler.yml
vendored
@@ -2,11 +2,12 @@ name: "Pull Request Labeler"
|
|||||||
on:
|
on:
|
||||||
- pull_request_target
|
- pull_request_target
|
||||||
|
|
||||||
jobs:
|
permissions:
|
||||||
triage:
|
|
||||||
permissions:
|
|
||||||
contents: read
|
contents: read
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
triage:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/labeler@v4
|
- uses: actions/labeler@v4
|
||||||
|
|||||||
3
.github/workflows/mad_regenerate-models.yml
vendored
3
.github/workflows/mad_regenerate-models.yml
vendored
@@ -11,6 +11,9 @@ on:
|
|||||||
- ".github/workflows/mad_regenerate-models.yml"
|
- ".github/workflows/mad_regenerate-models.yml"
|
||||||
- ".github/actions/fetch-codeql/action.yml"
|
- ".github/actions/fetch-codeql/action.yml"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
regenerate-models:
|
regenerate-models:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
2
.github/workflows/qhelp-pr-preview.yml
vendored
2
.github/workflows/qhelp-pr-preview.yml
vendored
@@ -77,7 +77,7 @@ jobs:
|
|||||||
done < "${RUNNER_TEMP}/paths.txt" >> comment_body.txt
|
done < "${RUNNER_TEMP}/paths.txt" >> comment_body.txt
|
||||||
exit "${EXIT_CODE}"
|
exit "${EXIT_CODE}"
|
||||||
|
|
||||||
- if: always()
|
- if: ${{ !cancelled() }}
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: comment
|
name: comment
|
||||||
|
|||||||
9
.github/workflows/ql-for-ql-build.yml
vendored
9
.github/workflows/ql-for-ql-build.yml
vendored
@@ -9,8 +9,13 @@ on:
|
|||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
steps:
|
steps:
|
||||||
### Build the queries ###
|
### Build the queries ###
|
||||||
@@ -19,7 +24,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Find codeql
|
- name: Find codeql
|
||||||
id: find-codeql
|
id: find-codeql
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@main
|
||||||
with:
|
with:
|
||||||
languages: javascript # does not matter
|
languages: javascript # does not matter
|
||||||
- uses: ./.github/actions/os-version
|
- uses: ./.github/actions/os-version
|
||||||
@@ -65,7 +70,7 @@ jobs:
|
|||||||
exclude:*/ql/lib/upgrades/
|
exclude:*/ql/lib/upgrades/
|
||||||
exclude:java/ql/integration-tests
|
exclude:java/ql/integration-tests
|
||||||
- name: Upload sarif to code-scanning
|
- name: Upload sarif to code-scanning
|
||||||
uses: github/codeql-action/upload-sarif@v2
|
uses: github/codeql-action/upload-sarif@main
|
||||||
with:
|
with:
|
||||||
sarif_file: ql-for-ql.sarif
|
sarif_file: ql-for-ql.sarif
|
||||||
category: ql-for-ql
|
category: ql-for-ql
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ on:
|
|||||||
- ql/ql/src/ql.dbscheme
|
- ql/ql/src/ql.dbscheme
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
measure:
|
measure:
|
||||||
env:
|
env:
|
||||||
@@ -25,7 +29,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Find codeql
|
- name: Find codeql
|
||||||
id: find-codeql
|
id: find-codeql
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@main
|
||||||
with:
|
with:
|
||||||
languages: javascript # does not matter
|
languages: javascript # does not matter
|
||||||
- uses: ./.github/actions/os-version
|
- uses: ./.github/actions/os-version
|
||||||
|
|||||||
7
.github/workflows/ql-for-ql-tests.yml
vendored
7
.github/workflows/ql-for-ql-tests.yml
vendored
@@ -17,6 +17,9 @@ on:
|
|||||||
env:
|
env:
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
qltest:
|
qltest:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -24,7 +27,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Find codeql
|
- name: Find codeql
|
||||||
id: find-codeql
|
id: find-codeql
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@main
|
||||||
with:
|
with:
|
||||||
languages: javascript # does not matter
|
languages: javascript # does not matter
|
||||||
- uses: ./.github/actions/os-version
|
- uses: ./.github/actions/os-version
|
||||||
@@ -69,7 +72,7 @@ jobs:
|
|||||||
echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
|
echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
|
||||||
- name: Find codeql
|
- name: Find codeql
|
||||||
id: find-codeql
|
id: find-codeql
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@main
|
||||||
with:
|
with:
|
||||||
languages: javascript # does not matter
|
languages: javascript # does not matter
|
||||||
- uses: ./.github/actions/os-version
|
- uses: ./.github/actions/os-version
|
||||||
|
|||||||
3
.github/workflows/query-list.yml
vendored
3
.github/workflows/query-list.yml
vendored
@@ -13,6 +13,9 @@ on:
|
|||||||
- '.github/actions/fetch-codeql/action.yml'
|
- '.github/actions/fetch-codeql/action.yml'
|
||||||
- 'misc/scripts/generate-code-scanning-query-list.py'
|
- 'misc/scripts/generate-code-scanning-query-list.py'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/ruby-build.yml
vendored
4
.github/workflows/ruby-build.yml
vendored
@@ -32,6 +32,9 @@ defaults:
|
|||||||
run:
|
run:
|
||||||
working-directory: ruby
|
working-directory: ruby
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
@@ -111,6 +114,7 @@ jobs:
|
|||||||
ruby/extractor/target/release/codeql-extractor-ruby.exe
|
ruby/extractor/target/release/codeql-extractor-ruby.exe
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
compile-queries:
|
compile-queries:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|||||||
3
.github/workflows/ruby-dataset-measure.yml
vendored
3
.github/workflows/ruby-dataset-measure.yml
vendored
@@ -17,6 +17,9 @@ on:
|
|||||||
- .github/workflows/ruby-dataset-measure.yml
|
- .github/workflows/ruby-dataset-measure.yml
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
measure:
|
measure:
|
||||||
env:
|
env:
|
||||||
|
|||||||
4
.github/workflows/ruby-qltest.yml
vendored
4
.github/workflows/ruby-qltest.yml
vendored
@@ -29,6 +29,9 @@ defaults:
|
|||||||
run:
|
run:
|
||||||
working-directory: ruby
|
working-directory: ruby
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
qlupgrade:
|
qlupgrade:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -50,6 +53,7 @@ jobs:
|
|||||||
xargs codeql execute upgrades testdb
|
xargs codeql execute upgrades testdb
|
||||||
diff -q testdb/ruby.dbscheme downgrades/initial/ruby.dbscheme
|
diff -q testdb/ruby.dbscheme downgrades/initial/ruby.dbscheme
|
||||||
qltest:
|
qltest:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|||||||
11
.github/workflows/swift.yml
vendored
11
.github/workflows/swift.yml
vendored
@@ -33,40 +33,47 @@ on:
|
|||||||
- rc/*
|
- rc/*
|
||||||
- codeql-cli-*
|
- codeql-cli-*
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks
|
# not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks
|
||||||
# without waiting for the macOS build
|
# without waiting for the macOS build
|
||||||
build-and-test-macos:
|
build-and-test-macos:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
runs-on: macos-12-xl
|
runs-on: macos-12-xl
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./swift/actions/build-and-test
|
- uses: ./swift/actions/build-and-test
|
||||||
build-and-test-linux:
|
build-and-test-linux:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./swift/actions/build-and-test
|
- uses: ./swift/actions/build-and-test
|
||||||
qltests-linux:
|
qltests-linux:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
needs: build-and-test-linux
|
needs: build-and-test-linux
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./swift/actions/run-ql-tests
|
- uses: ./swift/actions/run-ql-tests
|
||||||
qltests-macos:
|
qltests-macos:
|
||||||
if : ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.repository_owner == 'github' && github.event_name == 'pull_request' }}
|
||||||
needs: build-and-test-macos
|
needs: build-and-test-macos
|
||||||
runs-on: macos-12-xl
|
runs-on: macos-12-xl
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./swift/actions/run-ql-tests
|
- uses: ./swift/actions/run-ql-tests
|
||||||
integration-tests-linux:
|
integration-tests-linux:
|
||||||
|
if: github.repository_owner == 'github'
|
||||||
needs: build-and-test-linux
|
needs: build-and-test-linux
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./swift/actions/run-integration-tests
|
- uses: ./swift/actions/run-integration-tests
|
||||||
integration-tests-macos:
|
integration-tests-macos:
|
||||||
if : ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.repository_owner == 'github' && github.event_name == 'pull_request' }}
|
||||||
needs: build-and-test-macos
|
needs: build-and-test-macos
|
||||||
runs-on: macos-12-xl
|
runs-on: macos-12-xl
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
|||||||
3
.github/workflows/sync-files.yml
vendored
3
.github/workflows/sync-files.yml
vendored
@@ -10,6 +10,9 @@ on:
|
|||||||
- main
|
- main
|
||||||
- 'rc/*'
|
- 'rc/*'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
sync:
|
sync:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ defaults:
|
|||||||
run:
|
run:
|
||||||
working-directory: shared/tree-sitter-extractor
|
working-directory: shared/tree-sitter-extractor
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
3
.github/workflows/validate-change-notes.yml
vendored
3
.github/workflows/validate-change-notes.yml
vendored
@@ -15,6 +15,9 @@ on:
|
|||||||
- ".github/workflows/validate-change-notes.yml"
|
- ".github/workflows/validate-change-notes.yml"
|
||||||
- ".github/actions/fetch-codeql/action.yml"
|
- ".github/actions/fetch-codeql/action.yml"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-change-note:
|
check-change-note:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class Element extends @element {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Expr extends @expr {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Stmt extends @stmt {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate isStmtWithInitializer(Stmt stmt) { exists(int kind | stmts(stmt, kind, _) | kind = 29) }
|
||||||
|
|
||||||
|
from Expr child, int index, int index_new, Element parent
|
||||||
|
where
|
||||||
|
exprparents(child, index, parent) and
|
||||||
|
if isStmtWithInitializer(parent) then index_new = index - 1 else index_new = index
|
||||||
|
select child, index_new, parent
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class Stmt extends @stmt {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
from Stmt f, Stmt i
|
||||||
|
where
|
||||||
|
for_initialization(f, i) and
|
||||||
|
f instanceof @stmt_for
|
||||||
|
select f, i
|
||||||
2244
cpp/downgrades/298438feb146335af824002589cd6d4e96e5dbf9/old.dbscheme
Normal file
2244
cpp/downgrades/298438feb146335af824002589cd6d4e96e5dbf9/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
|||||||
|
class Element extends @element {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Stmt extends @stmt {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate isStmtWithInitializer(Stmt stmt) { exists(int kind | stmts(stmt, kind, _) | kind = 29) }
|
||||||
|
|
||||||
|
from Stmt child, int index, int index_new, Element parent
|
||||||
|
where
|
||||||
|
stmtparents(child, index, parent) and
|
||||||
|
(
|
||||||
|
not isStmtWithInitializer(parent)
|
||||||
|
or
|
||||||
|
index > 0
|
||||||
|
) and
|
||||||
|
if isStmtWithInitializer(parent) then index_new = index - 1 else index_new = index
|
||||||
|
select child, index_new, parent
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
description: Support C++20 range-based for initializers
|
||||||
|
compatibility: partial
|
||||||
|
exprparents.rel: run exprparents.qlo
|
||||||
|
stmtparents.rel: run stmtparents.qlo
|
||||||
|
for_initialization.rel: run for_initialization.qlo
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
|
## 0.12.6
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
* A `getInitialization` predicate was added to the `RangeBasedForStmt` class that yields the C++20-style initializer of the range-based `for` statement when it exists.
|
||||||
|
|
||||||
## 0.12.5
|
## 0.12.5
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
|
|||||||
5
cpp/ql/lib/change-notes/released/0.12.6.md
Normal file
5
cpp/ql/lib/change-notes/released/0.12.6.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## 0.12.6
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
* A `getInitialization` predicate was added to the `RangeBasedForStmt` class that yields the C++20-style initializer of the range-based `for` statement when it exists.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.12.5
|
lastReleaseVersion: 0.12.6
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-all
|
name: codeql/cpp-all
|
||||||
version: 0.12.5
|
version: 0.12.6
|
||||||
groups: cpp
|
groups: cpp
|
||||||
dbscheme: semmlecode.cpp.dbscheme
|
dbscheme: semmlecode.cpp.dbscheme
|
||||||
extractor: cpp
|
extractor: cpp
|
||||||
|
|||||||
@@ -735,7 +735,9 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
|
|||||||
or
|
or
|
||||||
s.(ForStmt).getStmt() = e and pred = "getStmt()"
|
s.(ForStmt).getStmt() = e and pred = "getStmt()"
|
||||||
or
|
or
|
||||||
s.(RangeBasedForStmt).getChild(0) = e and pred = "getChild(0)"
|
s.(RangeBasedForStmt).getInitialization() = e and pred = "getInitialization()"
|
||||||
|
or
|
||||||
|
s.(RangeBasedForStmt).getChild(1) = e and pred = "getChild(1)"
|
||||||
or
|
or
|
||||||
s.(RangeBasedForStmt).getBeginEndDeclaration() = e and pred = "getBeginEndDeclaration()"
|
s.(RangeBasedForStmt).getBeginEndDeclaration() = e and pred = "getBeginEndDeclaration()"
|
||||||
or
|
or
|
||||||
@@ -743,7 +745,7 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
|
|||||||
or
|
or
|
||||||
s.(RangeBasedForStmt).getUpdate() = e and pred = "getUpdate()"
|
s.(RangeBasedForStmt).getUpdate() = e and pred = "getUpdate()"
|
||||||
or
|
or
|
||||||
s.(RangeBasedForStmt).getChild(4) = e and pred = "getChild(4)"
|
s.(RangeBasedForStmt).getChild(5) = e and pred = "getChild(5)"
|
||||||
or
|
or
|
||||||
s.(RangeBasedForStmt).getStmt() = e and pred = "getStmt()"
|
s.(RangeBasedForStmt).getStmt() = e and pred = "getStmt()"
|
||||||
or
|
or
|
||||||
@@ -835,7 +837,11 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
|
|||||||
or
|
or
|
||||||
expr.(OverloadedArrayExpr).getArrayOffset() = ele and pred = "getArrayOffset()"
|
expr.(OverloadedArrayExpr).getArrayOffset() = ele and pred = "getArrayOffset()"
|
||||||
or
|
or
|
||||||
expr.(OverloadedPointerDereferenceExpr).getExpr() = ele and pred = "getExpr()"
|
// OverloadedPointerDereferenceExpr::getExpr/0 also considers qualifiers, which are already handled above for all Call classes.
|
||||||
|
not expr.(OverloadedPointerDereferenceExpr).getQualifier() =
|
||||||
|
expr.(OverloadedPointerDereferenceExpr).getExpr() and
|
||||||
|
expr.(OverloadedPointerDereferenceExpr).getExpr() = ele and
|
||||||
|
pred = "getExpr()"
|
||||||
or
|
or
|
||||||
expr.(CommaExpr).getLeftOperand() = ele and pred = "getLeftOperand()"
|
expr.(CommaExpr).getLeftOperand() = ele and pred = "getLeftOperand()"
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -234,7 +234,16 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
|
|||||||
* int f(int y) { return y; }
|
* int f(int y) { return y; }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
override string getName() { var_decls(underlyingElement(this), _, _, result, _) and result != "" }
|
override string getName() {
|
||||||
|
exists(string name |
|
||||||
|
var_decls(underlyingElement(this), _, _, name, _) and
|
||||||
|
(
|
||||||
|
name != "" and result = name
|
||||||
|
or
|
||||||
|
name = "" and result = this.getVariable().(LocalVariable).getName()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type of the variable which is being declared or defined.
|
* Gets the type of the variable which is being declared or defined.
|
||||||
|
|||||||
@@ -203,16 +203,15 @@ private class GuardConditionFromIR extends GuardCondition {
|
|||||||
* `&&` and `||`. See the detailed explanation on predicate `controls`.
|
* `&&` and `||`. See the detailed explanation on predicate `controls`.
|
||||||
*/
|
*/
|
||||||
private predicate controlsBlock(BasicBlock controlled, boolean testIsTrue) {
|
private predicate controlsBlock(BasicBlock controlled, boolean testIsTrue) {
|
||||||
exists(IRBlock irb, Instruction instr |
|
exists(IRBlock irb |
|
||||||
ir.controls(irb, testIsTrue) and
|
ir.controls(irb, testIsTrue) and
|
||||||
instr = irb.getAnInstruction() and
|
nonExcludedIRAndBasicBlock(irb, controlled) and
|
||||||
instr.getAst().(ControlFlowNode).getBasicBlock() = controlled and
|
not isUnreachedBlock(irb)
|
||||||
not isUnreachedBlock(irb) and
|
|
||||||
not this.excludeAsControlledInstruction(instr)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private predicate excludeAsControlledInstruction(Instruction instr) {
|
private predicate excludeAsControlledInstruction(Instruction instr) {
|
||||||
// Exclude the temporaries generated by a ternary expression.
|
// Exclude the temporaries generated by a ternary expression.
|
||||||
exists(TranslatedConditionalExpr tce |
|
exists(TranslatedConditionalExpr tce |
|
||||||
instr = tce.getInstruction(ConditionValueFalseStoreTag())
|
instr = tce.getInstruction(ConditionValueFalseStoreTag())
|
||||||
@@ -226,7 +225,20 @@ private class GuardConditionFromIR extends GuardCondition {
|
|||||||
or
|
or
|
||||||
// Exclude unreached instructions, as their AST is the whole function and not a block.
|
// Exclude unreached instructions, as their AST is the whole function and not a block.
|
||||||
instr instanceof UnreachedInstruction
|
instr instanceof UnreachedInstruction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `irb` is the `IRBlock` corresponding to the AST basic block
|
||||||
|
* `controlled`, and `irb` does not contain any instruction(s) that should make
|
||||||
|
* the `irb` be ignored.
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate nonExcludedIRAndBasicBlock(IRBlock irb, BasicBlock controlled) {
|
||||||
|
exists(Instruction instr |
|
||||||
|
instr = irb.getAnInstruction() and
|
||||||
|
instr.getAst().(ControlFlowNode).getBasicBlock() = controlled and
|
||||||
|
not excludeAsControlledInstruction(instr)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -637,8 +637,10 @@ private predicate straightLineSparse(Node scope, int i, Node ni, Spec spec) {
|
|||||||
any(RangeBasedForStmt for |
|
any(RangeBasedForStmt for |
|
||||||
i = -1 and ni = for and spec.isAt()
|
i = -1 and ni = for and spec.isAt()
|
||||||
or
|
or
|
||||||
|
i = 0 and ni = for.getInitialization() and spec.isAround()
|
||||||
|
or
|
||||||
exists(DeclStmt s | s.getADeclaration() = for.getRangeVariable() |
|
exists(DeclStmt s | s.getADeclaration() = for.getRangeVariable() |
|
||||||
i = 0 and ni = s and spec.isAround()
|
i = 1 and ni = s and spec.isAround()
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(DeclStmt s |
|
exists(DeclStmt s |
|
||||||
@@ -649,22 +651,22 @@ private predicate straightLineSparse(Node scope, int i, Node ni, Spec spec) {
|
|||||||
// DeclStmt in that case.
|
// DeclStmt in that case.
|
||||||
exists(s.getADeclaration())
|
exists(s.getADeclaration())
|
||||||
|
|
|
|
||||||
i = 1 and ni = s and spec.isAround()
|
i = 2 and ni = s and spec.isAround()
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
i = 2 and ni = for.getCondition() and spec.isBefore()
|
i = 3 and ni = for.getCondition() and spec.isBefore()
|
||||||
or
|
or
|
||||||
i = 3 and /* BARRIER */ ni = for and spec.isBarrier()
|
i = 4 and /* BARRIER */ ni = for and spec.isBarrier()
|
||||||
or
|
or
|
||||||
exists(DeclStmt declStmt | declStmt.getADeclaration() = for.getVariable() |
|
exists(DeclStmt declStmt | declStmt.getADeclaration() = for.getVariable() |
|
||||||
i = 4 and ni = declStmt and spec.isAfter()
|
i = 5 and ni = declStmt and spec.isAfter()
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
i = 5 and ni = for.getStmt() and spec.isAround()
|
i = 6 and ni = for.getStmt() and spec.isAround()
|
||||||
or
|
or
|
||||||
i = 6 and ni = for.getUpdate() and spec.isAround()
|
i = 7 and ni = for.getUpdate() and spec.isAround()
|
||||||
or
|
or
|
||||||
i = 7 and ni = for.getCondition() and spec.isBefore()
|
i = 8 and ni = for.getCondition() and spec.isBefore()
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
scope =
|
scope =
|
||||||
|
|||||||
@@ -244,9 +244,15 @@ class ConditionDeclExpr extends Expr, @condition_decl {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the compiler-generated variable access that conceptually occurs after
|
* Gets the compiler-generated variable access that conceptually occurs after
|
||||||
* the initialization of the declared variable.
|
* the initialization of the declared variable, if any.
|
||||||
*/
|
*/
|
||||||
VariableAccess getVariableAccess() { result = this.getChild(0) }
|
VariableAccess getVariableAccess() { result = this.getExpr() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the expression that is evaluated after the initialization of the declared
|
||||||
|
* variable.
|
||||||
|
*/
|
||||||
|
Expr getExpr() { result = this.getChild(0) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the expression that initializes the declared variable. This predicate
|
* Gets the expression that initializes the declared variable. This predicate
|
||||||
|
|||||||
@@ -709,7 +709,7 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
|
|||||||
override DataFlowType getType() {
|
override DataFlowType getType() {
|
||||||
exists(int indirectionIndex |
|
exists(int indirectionIndex |
|
||||||
indirectionIndex = globalUse.getIndirectionIndex() and
|
indirectionIndex = globalUse.getIndirectionIndex() and
|
||||||
result = getTypeImpl(globalUse.getUnspecifiedType(), indirectionIndex - 1)
|
result = getTypeImpl(globalUse.getUnderlyingType(), indirectionIndex - 1)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -740,7 +740,7 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
|
|||||||
|
|
||||||
override DataFlowType getType() {
|
override DataFlowType getType() {
|
||||||
exists(DataFlowType type |
|
exists(DataFlowType type |
|
||||||
type = globalDef.getUnspecifiedType() and
|
type = globalDef.getUnderlyingType() and
|
||||||
if this.isGLValue()
|
if this.isGLValue()
|
||||||
then result = type
|
then result = type
|
||||||
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1)
|
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1)
|
||||||
@@ -943,10 +943,13 @@ private Type getTypeImpl0(Type t, int indirectionIndex) {
|
|||||||
indirectionIndex > 0 and
|
indirectionIndex > 0 and
|
||||||
exists(Type stripped |
|
exists(Type stripped |
|
||||||
stripped = stripPointer(t.stripTopLevelSpecifiers()) and
|
stripped = stripPointer(t.stripTopLevelSpecifiers()) and
|
||||||
// We need to avoid the case where `stripPointer(t) = t` (which can happen on
|
// We need to avoid the case where `stripPointer(t) = t` (which can happen
|
||||||
// iterators that specify a `value_type` that is the iterator itself). Such a type
|
// on iterators that specify a `value_type` that is the iterator itself).
|
||||||
// would create an infinite loop otherwise. For these cases we simply don't produce
|
// Such a type would create an infinite loop otherwise. For these cases we
|
||||||
// a result for `getTypeImpl`.
|
// simply don't produce a result for `getTypeImpl`.
|
||||||
|
// To be on the safe side, we check whether the _unspecified_ type has
|
||||||
|
// changed since this also prevents an infinite loop when `stripped` and
|
||||||
|
// `t` only differ by const'ness or volatile'ness.
|
||||||
stripped.getUnspecifiedType() != t.getUnspecifiedType() and
|
stripped.getUnspecifiedType() != t.getUnspecifiedType() and
|
||||||
result = getTypeImpl0(stripped, indirectionIndex - 1)
|
result = getTypeImpl0(stripped, indirectionIndex - 1)
|
||||||
)
|
)
|
||||||
@@ -996,12 +999,14 @@ private module RawIndirectNodes {
|
|||||||
|
|
||||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||||
|
|
||||||
|
override predicate isGLValue() { this.getOperand().isGLValue() }
|
||||||
|
|
||||||
override DataFlowType getType() {
|
override DataFlowType getType() {
|
||||||
exists(int sub, DataFlowType type, boolean isGLValue |
|
exists(int sub, DataFlowType type, boolean isGLValue |
|
||||||
type = getOperandType(this.getOperand(), isGLValue) and
|
type = getOperandType(this.getOperand(), isGLValue) and
|
||||||
if isGLValue = true then sub = 1 else sub = 0
|
if isGLValue = true then sub = 1 else sub = 0
|
||||||
|
|
|
|
||||||
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
|
result = getTypeImpl(type.getUnderlyingType(), indirectionIndex - sub)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1038,12 +1043,14 @@ private module RawIndirectNodes {
|
|||||||
|
|
||||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||||
|
|
||||||
|
override predicate isGLValue() { this.getInstruction().isGLValue() }
|
||||||
|
|
||||||
override DataFlowType getType() {
|
override DataFlowType getType() {
|
||||||
exists(int sub, DataFlowType type, boolean isGLValue |
|
exists(int sub, DataFlowType type, boolean isGLValue |
|
||||||
type = getInstructionType(this.getInstruction(), isGLValue) and
|
type = getInstructionType(this.getInstruction(), isGLValue) and
|
||||||
if isGLValue = true then sub = 1 else sub = 0
|
if isGLValue = true then sub = 1 else sub = 0
|
||||||
|
|
|
|
||||||
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
|
result = getTypeImpl(type.getUnderlyingType(), indirectionIndex - sub)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1136,7 +1143,7 @@ class FinalParameterNode extends Node, TFinalParameterNode {
|
|||||||
|
|
||||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||||
|
|
||||||
override DataFlowType getType() { result = getTypeImpl(p.getUnspecifiedType(), indirectionIndex) }
|
override DataFlowType getType() { result = getTypeImpl(p.getUnderlyingType(), indirectionIndex) }
|
||||||
|
|
||||||
final override Location getLocationImpl() {
|
final override Location getLocationImpl() {
|
||||||
// Parameters can have multiple locations. When there's a unique location we use
|
// Parameters can have multiple locations. When there's a unique location we use
|
||||||
@@ -1789,7 +1796,7 @@ class VariableNode extends Node, TVariableNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override DataFlowType getType() {
|
override DataFlowType getType() {
|
||||||
result = getTypeImpl(v.getUnspecifiedType(), indirectionIndex - 1)
|
result = getTypeImpl(v.getUnderlyingType(), indirectionIndex - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
final override Location getLocationImpl() {
|
final override Location getLocationImpl() {
|
||||||
|
|||||||
@@ -507,13 +507,13 @@ module ProductFlow {
|
|||||||
private predicate pathSuccPlus(TNodePair n1, TNodePair n2) = fastTC(pathSucc/2)(n1, n2)
|
private predicate pathSuccPlus(TNodePair n1, TNodePair n2) = fastTC(pathSucc/2)(n1, n2)
|
||||||
|
|
||||||
private predicate localPathStep1(Flow1::PathNode pred, Flow1::PathNode succ) {
|
private predicate localPathStep1(Flow1::PathNode pred, Flow1::PathNode succ) {
|
||||||
Flow1::PathGraph::edges(pred, succ) and
|
Flow1::PathGraph::edges(pred, succ, _, _) and
|
||||||
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
|
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
|
||||||
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
|
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localPathStep2(Flow2::PathNode pred, Flow2::PathNode succ) {
|
private predicate localPathStep2(Flow2::PathNode pred, Flow2::PathNode succ) {
|
||||||
Flow2::PathGraph::edges(pred, succ) and
|
Flow2::PathGraph::edges(pred, succ, _, _) and
|
||||||
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
|
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
|
||||||
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
|
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
|
||||||
}
|
}
|
||||||
@@ -530,7 +530,7 @@ module ProductFlow {
|
|||||||
TJump()
|
TJump()
|
||||||
|
|
||||||
private predicate intoImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
|
private predicate intoImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
|
||||||
Flow1::PathGraph::edges(pred1, succ1) and
|
Flow1::PathGraph::edges(pred1, succ1, _, _) and
|
||||||
pred1.getNode().(ArgumentNode).getCall() = call and
|
pred1.getNode().(ArgumentNode).getCall() = call and
|
||||||
succ1.getNode() instanceof ParameterNode
|
succ1.getNode() instanceof ParameterNode
|
||||||
}
|
}
|
||||||
@@ -543,7 +543,7 @@ module ProductFlow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private predicate outImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
|
private predicate outImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
|
||||||
Flow1::PathGraph::edges(pred1, succ1) and
|
Flow1::PathGraph::edges(pred1, succ1, _, _) and
|
||||||
exists(ReturnKindExt returnKind |
|
exists(ReturnKindExt returnKind |
|
||||||
succ1.getNode() = returnKind.getAnOutNode(call) and
|
succ1.getNode() = returnKind.getAnOutNode(call) and
|
||||||
pred1.getNode().(ReturnNodeExt).getKind() = returnKind
|
pred1.getNode().(ReturnNodeExt).getKind() = returnKind
|
||||||
@@ -558,7 +558,7 @@ module ProductFlow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private predicate intoImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
|
private predicate intoImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
|
||||||
Flow2::PathGraph::edges(pred2, succ2) and
|
Flow2::PathGraph::edges(pred2, succ2, _, _) and
|
||||||
pred2.getNode().(ArgumentNode).getCall() = call and
|
pred2.getNode().(ArgumentNode).getCall() = call and
|
||||||
succ2.getNode() instanceof ParameterNode
|
succ2.getNode() instanceof ParameterNode
|
||||||
}
|
}
|
||||||
@@ -571,7 +571,7 @@ module ProductFlow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private predicate outImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
|
private predicate outImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
|
||||||
Flow2::PathGraph::edges(pred2, succ2) and
|
Flow2::PathGraph::edges(pred2, succ2, _, _) and
|
||||||
exists(ReturnKindExt returnKind |
|
exists(ReturnKindExt returnKind |
|
||||||
succ2.getNode() = returnKind.getAnOutNode(call) and
|
succ2.getNode() = returnKind.getAnOutNode(call) and
|
||||||
pred2.getNode().(ReturnNodeExt).getKind() = returnKind
|
pred2.getNode().(ReturnNodeExt).getKind() = returnKind
|
||||||
@@ -590,7 +590,7 @@ module ProductFlow {
|
|||||||
Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1,
|
Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1,
|
||||||
TKind kind
|
TKind kind
|
||||||
) {
|
) {
|
||||||
Flow1::PathGraph::edges(pred1, succ1) and
|
Flow1::PathGraph::edges(pred1, succ1, _, _) and
|
||||||
predDecl != succDecl and
|
predDecl != succDecl and
|
||||||
pred1.getNode().getEnclosingCallable() = predDecl and
|
pred1.getNode().getEnclosingCallable() = predDecl and
|
||||||
succ1.getNode().getEnclosingCallable() = succDecl and
|
succ1.getNode().getEnclosingCallable() = succDecl and
|
||||||
@@ -610,7 +610,7 @@ module ProductFlow {
|
|||||||
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2,
|
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2,
|
||||||
TKind kind
|
TKind kind
|
||||||
) {
|
) {
|
||||||
Flow2::PathGraph::edges(pred2, succ2) and
|
Flow2::PathGraph::edges(pred2, succ2, _, _) and
|
||||||
predDecl != succDecl and
|
predDecl != succDecl and
|
||||||
pred2.getNode().getEnclosingCallable() = predDecl and
|
pred2.getNode().getEnclosingCallable() = predDecl and
|
||||||
succ2.getNode().getEnclosingCallable() = succDecl and
|
succ2.getNode().getEnclosingCallable() = succDecl and
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ private newtype TDefOrUseImpl =
|
|||||||
exists(SsaInternals0::Def def |
|
exists(SsaInternals0::Def def |
|
||||||
def.getSourceVariable().getBaseVariable().(BaseIRVariable).getIRVariable().getAst() = p and
|
def.getSourceVariable().getBaseVariable().(BaseIRVariable).getIRVariable().getAst() = p and
|
||||||
not def.getValue().asInstruction() instanceof InitializeParameterInstruction and
|
not def.getValue().asInstruction() instanceof InitializeParameterInstruction and
|
||||||
unspecifiedTypeIsModifiableAt(p.getUnspecifiedType(), indirectionIndex)
|
underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,11 +172,13 @@ private predicate isGlobalDefImpl(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate unspecifiedTypeIsModifiableAt(Type unspecified, int indirectionIndex) {
|
private predicate underlyingTypeIsModifiableAt(Type underlying, int indirectionIndex) {
|
||||||
indirectionIndex = [1 .. getIndirectionForUnspecifiedType(unspecified).getNumberOfIndirections()] and
|
indirectionIndex =
|
||||||
|
[1 .. getIndirectionForUnspecifiedType(underlying.getUnspecifiedType())
|
||||||
|
.getNumberOfIndirections()] and
|
||||||
exists(CppType cppType |
|
exists(CppType cppType |
|
||||||
cppType.hasUnspecifiedType(unspecified, _) and
|
cppType.hasUnderlyingType(underlying, false) and
|
||||||
isModifiableAt(cppType, indirectionIndex + 1)
|
isModifiableAt(cppType, indirectionIndex)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,6 +547,11 @@ class GlobalUse extends UseImpl, TGlobalUse {
|
|||||||
*/
|
*/
|
||||||
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
|
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of this use, after typedefs have been resolved.
|
||||||
|
*/
|
||||||
|
Type getUnderlyingType() { result = global.getUnderlyingType() }
|
||||||
|
|
||||||
override predicate isCertain() { any() }
|
override predicate isCertain() { any() }
|
||||||
|
|
||||||
override BaseSourceVariableInstruction getBase() { none() }
|
override BaseSourceVariableInstruction getBase() { none() }
|
||||||
@@ -588,11 +595,16 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
|
|||||||
int getIndirection() { result = indirectionIndex }
|
int getIndirection() { result = indirectionIndex }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type of this use after specifiers have been deeply stripped
|
* Gets the type of this definition after specifiers have been deeply
|
||||||
* and typedefs have been resolved.
|
* stripped and typedefs have been resolved.
|
||||||
*/
|
*/
|
||||||
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
|
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of this definition, after typedefs have been resolved.
|
||||||
|
*/
|
||||||
|
Type getUnderlyingType() { result = global.getUnderlyingType() }
|
||||||
|
|
||||||
override string toString() { result = "Def of " + this.getSourceVariable() }
|
override string toString() { result = "Def of " + this.getSourceVariable() }
|
||||||
|
|
||||||
override Location getLocation() { result = f.getLocation() }
|
override Location getLocation() { result = f.getLocation() }
|
||||||
@@ -1092,6 +1104,11 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
|
|||||||
*/
|
*/
|
||||||
DataFlowType getUnspecifiedType() { result = global.getUnspecifiedType() }
|
DataFlowType getUnspecifiedType() { result = global.getUnspecifiedType() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of this definition, after typedefs have been resolved.
|
||||||
|
*/
|
||||||
|
DataFlowType getUnderlyingType() { result = global.getUnderlyingType() }
|
||||||
|
|
||||||
/** Gets the `IRFunction` whose body is evaluated after this definition. */
|
/** Gets the `IRFunction` whose body is evaluated after this definition. */
|
||||||
IRFunction getIRFunction() { result = global.getIRFunction() }
|
IRFunction getIRFunction() { result = global.getIRFunction() }
|
||||||
|
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ private module IsModifiableAtImpl {
|
|||||||
private predicate impl(CppType cppType, int indirectionIndex) {
|
private predicate impl(CppType cppType, int indirectionIndex) {
|
||||||
exists(Type pointerType, Type base |
|
exists(Type pointerType, Type base |
|
||||||
isUnderlyingIndirectionType(pointerType) and
|
isUnderlyingIndirectionType(pointerType) and
|
||||||
cppType.hasUnderlyingType(pointerType, _) and
|
cppType.hasUnderlyingType(pointerType, false) and
|
||||||
base = getTypeImpl(pointerType, indirectionIndex)
|
base = getTypeImpl(pointerType, indirectionIndex)
|
||||||
|
|
|
|
||||||
// The value cannot be modified if it has a const specifier,
|
// The value cannot be modified if it has a const specifier,
|
||||||
|
|||||||
@@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction {
|
|||||||
*/
|
*/
|
||||||
final Instruction getPartial() { result = this.getPartialOperand().getDef() }
|
final Instruction getPartial() { result = this.getPartialOperand().getDef() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
|
|
||||||
*/
|
|
||||||
final predicate getUpdatedInterval(int startBit, int endBit) {
|
|
||||||
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`.
|
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`.
|
||||||
* This means that the `ChiPartialOperand` will not override the entire memory associated with the
|
* This means that the `ChiPartialOperand` will not override the entire memory associated with the
|
||||||
|
|||||||
@@ -233,20 +233,6 @@ private module Cached {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the partial operand of this `ChiInstruction` updates the bit range
|
|
||||||
* `[startBitOffset, endBitOffset)` of the total operand.
|
|
||||||
*/
|
|
||||||
cached
|
|
||||||
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) {
|
|
||||||
exists(Alias::MemoryLocation location, OldInstruction oldInstruction |
|
|
||||||
oldInstruction = getOldInstruction(chi.getPartial()) and
|
|
||||||
location = Alias::getResultMemoryLocation(oldInstruction) and
|
|
||||||
startBitOffset = Alias::getStartBitOffset(location) and
|
|
||||||
endBitOffset = Alias::getEndBitOffset(location)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `operand` totally overlaps with its definition and consumes the bit range
|
* Holds if `operand` totally overlaps with its definition and consumes the bit range
|
||||||
* `[startBitOffset, endBitOffset)`.
|
* `[startBitOffset, endBitOffset)`.
|
||||||
|
|||||||
@@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction {
|
|||||||
*/
|
*/
|
||||||
final Instruction getPartial() { result = this.getPartialOperand().getDef() }
|
final Instruction getPartial() { result = this.getPartialOperand().getDef() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
|
|
||||||
*/
|
|
||||||
final predicate getUpdatedInterval(int startBit, int endBit) {
|
|
||||||
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`.
|
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`.
|
||||||
* This means that the `ChiPartialOperand` will not override the entire memory associated with the
|
* This means that the `ChiPartialOperand` will not override the entire memory associated with the
|
||||||
|
|||||||
@@ -202,12 +202,6 @@ Instruction getMemoryOperandDefinition(
|
|||||||
none()
|
none()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the partial operand of this `ChiInstruction` updates the bit range
|
|
||||||
* `[startBitOffset, endBitOffset)` of the total operand.
|
|
||||||
*/
|
|
||||||
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBit, int endBit) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the operand totally overlaps with its definition and consumes the
|
* Holds if the operand totally overlaps with its definition and consumes the
|
||||||
* bit range `[startBitOffset, endBitOffset)`.
|
* bit range `[startBitOffset, endBitOffset)`.
|
||||||
|
|||||||
@@ -209,6 +209,8 @@ private predicate usedAsCondition(Expr expr) {
|
|||||||
or
|
or
|
||||||
exists(IfStmt ifStmt | ifStmt.getCondition().getFullyConverted() = expr)
|
exists(IfStmt ifStmt | ifStmt.getCondition().getFullyConverted() = expr)
|
||||||
or
|
or
|
||||||
|
exists(ConstexprIfStmt ifStmt | ifStmt.getCondition().getFullyConverted() = expr)
|
||||||
|
or
|
||||||
exists(ConditionalExpr condExpr |
|
exists(ConditionalExpr condExpr |
|
||||||
// The two-operand form of `ConditionalExpr` treats its condition as a value, since it needs to
|
// The two-operand form of `ConditionalExpr` treats its condition as a value, since it needs to
|
||||||
// be reused as a value if the condition is true.
|
// be reused as a value if the condition is true.
|
||||||
@@ -474,7 +476,6 @@ private module IRDeclarationEntries {
|
|||||||
* This class exists to work around the fact that `DeclStmt`s in some cases
|
* This class exists to work around the fact that `DeclStmt`s in some cases
|
||||||
* do not have `DeclarationEntry`s. Currently, this is the case for:
|
* do not have `DeclarationEntry`s. Currently, this is the case for:
|
||||||
* - `DeclStmt`s in template instantiations.
|
* - `DeclStmt`s in template instantiations.
|
||||||
* - `DeclStmt`s that are generated by the desugaring of range-based for-loops.
|
|
||||||
*
|
*
|
||||||
* So instead, the IR works with `IRDeclarationEntry`s that synthesize missing
|
* So instead, the IR works with `IRDeclarationEntry`s that synthesize missing
|
||||||
* `DeclarationEntry`s when there is no result for `DeclStmt::getDeclarationEntry`.
|
* `DeclarationEntry`s when there is no result for `DeclStmt::getDeclarationEntry`.
|
||||||
|
|||||||
@@ -3173,7 +3173,7 @@ class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr {
|
|||||||
private TranslatedConditionDecl getDecl() { result = getTranslatedConditionDecl(expr) }
|
private TranslatedConditionDecl getDecl() { result = getTranslatedConditionDecl(expr) }
|
||||||
|
|
||||||
private TranslatedExpr getConditionExpr() {
|
private TranslatedExpr getConditionExpr() {
|
||||||
result = getTranslatedExpr(expr.getVariableAccess().getFullyConverted())
|
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -774,6 +774,72 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
|
||||||
|
override ConstexprIfStmt stmt;
|
||||||
|
|
||||||
|
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||||
|
if this.hasInitialization()
|
||||||
|
then result = this.getInitialization().getFirstInstruction(kind)
|
||||||
|
else result = this.getFirstConditionInstruction(kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
override TranslatedElement getChild(int id) {
|
||||||
|
id = 0 and result = this.getInitialization()
|
||||||
|
or
|
||||||
|
id = 1 and result = this.getCondition()
|
||||||
|
or
|
||||||
|
id = 2 and result = this.getThen()
|
||||||
|
or
|
||||||
|
id = 3 and result = this.getElse()
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate hasInitialization() { exists(stmt.getInitialization()) }
|
||||||
|
|
||||||
|
private TranslatedStmt getInitialization() {
|
||||||
|
result = getTranslatedStmt(stmt.getInitialization())
|
||||||
|
}
|
||||||
|
|
||||||
|
private TranslatedCondition getCondition() {
|
||||||
|
result = getTranslatedCondition(stmt.getCondition().getFullyConverted())
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction getFirstConditionInstruction(EdgeKind kind) {
|
||||||
|
result = this.getCondition().getFirstInstruction(kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
private TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
|
||||||
|
|
||||||
|
private TranslatedStmt getElse() { result = getTranslatedStmt(stmt.getElse()) }
|
||||||
|
|
||||||
|
private predicate hasElse() { exists(stmt.getElse()) }
|
||||||
|
|
||||||
|
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||||
|
|
||||||
|
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||||
|
child = this.getCondition() and
|
||||||
|
result = this.getThen().getFirstInstruction(kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||||
|
child = this.getCondition() and
|
||||||
|
if this.hasElse()
|
||||||
|
then result = this.getElse().getFirstInstruction(kind)
|
||||||
|
else result = this.getParent().getChildSuccessor(this, kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||||
|
child = this.getInitialization() and
|
||||||
|
result = this.getFirstConditionInstruction(kind)
|
||||||
|
or
|
||||||
|
(child = this.getThen() or child = this.getElse()) and
|
||||||
|
result = this.getParent().getChildSuccessor(this, kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||||
override Loop stmt;
|
override Loop stmt;
|
||||||
|
|
||||||
@@ -894,25 +960,38 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
|
|||||||
override RangeBasedForStmt stmt;
|
override RangeBasedForStmt stmt;
|
||||||
|
|
||||||
override TranslatedElement getChild(int id) {
|
override TranslatedElement getChild(int id) {
|
||||||
id = 0 and result = this.getRangeVariableDeclStmt()
|
id = 0 and result = this.getInitialization()
|
||||||
|
or
|
||||||
|
id = 1 and result = this.getRangeVariableDeclStmt()
|
||||||
or
|
or
|
||||||
// Note: `__begin` and `__end` are declared by the same `DeclStmt`
|
// Note: `__begin` and `__end` are declared by the same `DeclStmt`
|
||||||
id = 1 and result = this.getBeginEndVariableDeclStmt()
|
id = 2 and result = this.getBeginEndVariableDeclStmt()
|
||||||
or
|
or
|
||||||
id = 2 and result = this.getCondition()
|
id = 3 and result = this.getCondition()
|
||||||
or
|
or
|
||||||
id = 3 and result = this.getUpdate()
|
id = 4 and result = this.getUpdate()
|
||||||
or
|
or
|
||||||
id = 4 and result = this.getVariableDeclStmt()
|
id = 5 and result = this.getVariableDeclStmt()
|
||||||
or
|
or
|
||||||
id = 5 and result = this.getBody()
|
id = 6 and result = this.getBody()
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate hasInitialization() { exists(stmt.getInitialization()) }
|
||||||
|
|
||||||
|
private TranslatedStmt getInitialization() {
|
||||||
|
result = getTranslatedStmt(stmt.getInitialization())
|
||||||
}
|
}
|
||||||
|
|
||||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||||
result = this.getRangeVariableDeclStmt().getFirstInstruction(kind)
|
if this.hasInitialization()
|
||||||
|
then result = this.getInitialization().getFirstInstruction(kind)
|
||||||
|
else result = this.getFirstRangeVariableDeclStmtInstruction(kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||||
|
child = this.getInitialization() and
|
||||||
|
result = this.getFirstRangeVariableDeclStmtInstruction(kind)
|
||||||
|
or
|
||||||
child = this.getRangeVariableDeclStmt() and
|
child = this.getRangeVariableDeclStmt() and
|
||||||
result = this.getBeginEndVariableDeclStmt().getFirstInstruction(kind)
|
result = this.getBeginEndVariableDeclStmt().getFirstInstruction(kind)
|
||||||
or
|
or
|
||||||
@@ -952,6 +1031,10 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Instruction getFirstRangeVariableDeclStmtInstruction(EdgeKind kind) {
|
||||||
|
result = this.getRangeVariableDeclStmt().getFirstInstruction(kind)
|
||||||
|
}
|
||||||
|
|
||||||
private TranslatedDeclStmt getBeginEndVariableDeclStmt() {
|
private TranslatedDeclStmt getBeginEndVariableDeclStmt() {
|
||||||
exists(IRVariableDeclarationEntry entry |
|
exists(IRVariableDeclarationEntry entry |
|
||||||
entry.getStmt() = stmt.getBeginEndDeclaration() and
|
entry.getStmt() = stmt.getBeginEndDeclaration() and
|
||||||
|
|||||||
@@ -2125,13 +2125,6 @@ class ChiInstruction extends Instruction {
|
|||||||
*/
|
*/
|
||||||
final Instruction getPartial() { result = this.getPartialOperand().getDef() }
|
final Instruction getPartial() { result = this.getPartialOperand().getDef() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
|
|
||||||
*/
|
|
||||||
final predicate getUpdatedInterval(int startBit, int endBit) {
|
|
||||||
Construction::getIntervalUpdatedByChi(this, startBit, endBit)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`.
|
* Holds if the `ChiPartialOperand` totally, but not exactly, overlaps with the `ChiTotalOperand`.
|
||||||
* This means that the `ChiPartialOperand` will not override the entire memory associated with the
|
* This means that the `ChiPartialOperand` will not override the entire memory associated with the
|
||||||
|
|||||||
@@ -233,20 +233,6 @@ private module Cached {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the partial operand of this `ChiInstruction` updates the bit range
|
|
||||||
* `[startBitOffset, endBitOffset)` of the total operand.
|
|
||||||
*/
|
|
||||||
cached
|
|
||||||
predicate getIntervalUpdatedByChi(ChiInstruction chi, int startBitOffset, int endBitOffset) {
|
|
||||||
exists(Alias::MemoryLocation location, OldInstruction oldInstruction |
|
|
||||||
oldInstruction = getOldInstruction(chi.getPartial()) and
|
|
||||||
location = Alias::getResultMemoryLocation(oldInstruction) and
|
|
||||||
startBitOffset = Alias::getStartBitOffset(location) and
|
|
||||||
endBitOffset = Alias::getEndBitOffset(location)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `operand` totally overlaps with its definition and consumes the bit range
|
* Holds if `operand` totally overlaps with its definition and consumes the bit range
|
||||||
* `[startBitOffset, endBitOffset)`.
|
* `[startBitOffset, endBitOffset)`.
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ private import implementations.Deallocation
|
|||||||
private import implementations.Fread
|
private import implementations.Fread
|
||||||
private import implementations.Getenv
|
private import implementations.Getenv
|
||||||
private import implementations.Gets
|
private import implementations.Gets
|
||||||
|
private import implementations.GetText
|
||||||
private import implementations.IdentityFunction
|
private import implementations.IdentityFunction
|
||||||
private import implementations.Inet
|
private import implementations.Inet
|
||||||
private import implementations.Iterator
|
private import implementations.Iterator
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import semmle.code.cpp.models.interfaces.DataFlow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the transated text index for a given gettext function `f`
|
||||||
|
*/
|
||||||
|
private int getTextArg(Function f) {
|
||||||
|
// basic variations of gettext
|
||||||
|
f.hasGlobalOrStdName("gettext") and result = 0
|
||||||
|
or
|
||||||
|
f.hasGlobalOrStdName("dgettext") and result = 1
|
||||||
|
or
|
||||||
|
f.hasGlobalOrStdName("dcgettext") and result = 1
|
||||||
|
or
|
||||||
|
// plural variations of gettext that take one format string for singular and another for plural form
|
||||||
|
f.hasGlobalOrStdName("ngettext") and
|
||||||
|
(result = 0 or result = 1)
|
||||||
|
or
|
||||||
|
f.hasGlobalOrStdName("dngettext") and
|
||||||
|
(result = 1 or result = 2)
|
||||||
|
or
|
||||||
|
f.hasGlobalOrStdName("dcngettext") and
|
||||||
|
(result = 1 or result = 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
class GetTextFunction extends DataFlowFunction {
|
||||||
|
int argInd;
|
||||||
|
|
||||||
|
GetTextFunction() { argInd = getTextArg(this) }
|
||||||
|
|
||||||
|
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||||
|
input.isParameterDeref(argInd) and output.isReturnValueDeref()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,11 +22,28 @@ private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, Alias
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index of the parameter that specifies the fill character to insert, if any.
|
||||||
|
*/
|
||||||
|
private int getFillCharParameterIndex() {
|
||||||
|
(
|
||||||
|
this.hasGlobalOrStdOrBslName("memset")
|
||||||
|
or
|
||||||
|
this.hasGlobalOrStdName("wmemset")
|
||||||
|
or
|
||||||
|
this.hasGlobalName(["__builtin_memset", "__builtin_memset_chk"])
|
||||||
|
) and
|
||||||
|
result = 1
|
||||||
|
}
|
||||||
|
|
||||||
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
|
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
|
||||||
|
|
||||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||||
input.isParameter(0) and
|
input.isParameter(0) and
|
||||||
output.isReturnValue()
|
output.isReturnValue()
|
||||||
|
or
|
||||||
|
input.isParameter(this.getFillCharParameterIndex()) and
|
||||||
|
(output.isParameterDeref(0) or output.isReturnValueDeref())
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
|
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
|
||||||
|
|||||||
@@ -892,6 +892,26 @@ class DoStmt extends Loop, @stmt_end_test_while {
|
|||||||
class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
||||||
override string getAPrimaryQlClass() { result = "RangeBasedForStmt" }
|
override string getAPrimaryQlClass() { result = "RangeBasedForStmt" }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the initialization statement of this 'for' statement, if any.
|
||||||
|
*
|
||||||
|
* For example, for
|
||||||
|
* ```
|
||||||
|
* for (int x = y; auto z : ... ) { }
|
||||||
|
* ```
|
||||||
|
* the result is `int x = y;`.
|
||||||
|
*
|
||||||
|
* Does not hold if the initialization statement is missing or an empty statement, as in
|
||||||
|
* ```
|
||||||
|
* for (auto z : ...) { }
|
||||||
|
* ```
|
||||||
|
* or
|
||||||
|
* ```
|
||||||
|
* for (; auto z : ) { }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
Stmt getInitialization() { for_initialization(underlyingElement(this), unresolveElement(result)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the 'body' statement of this range-based 'for' statement.
|
* Gets the 'body' statement of this range-based 'for' statement.
|
||||||
*
|
*
|
||||||
@@ -901,7 +921,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
|||||||
* ```
|
* ```
|
||||||
* the result is the `BlockStmt` `{ y += x; }`.
|
* the result is the `BlockStmt` `{ y += x; }`.
|
||||||
*/
|
*/
|
||||||
override Stmt getStmt() { result = this.getChild(5) }
|
override Stmt getStmt() { result = this.getChild(6) }
|
||||||
|
|
||||||
override string toString() { result = "for(...:...) ..." }
|
override string toString() { result = "for(...:...) ..." }
|
||||||
|
|
||||||
@@ -914,7 +934,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
|||||||
* ```
|
* ```
|
||||||
* the result is `int x`.
|
* the result is `int x`.
|
||||||
*/
|
*/
|
||||||
LocalVariable getVariable() { result = this.getChild(4).(DeclStmt).getADeclaration() }
|
LocalVariable getVariable() { result = this.getChild(5).(DeclStmt).getADeclaration() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the expression giving the range to iterate over.
|
* Gets the expression giving the range to iterate over.
|
||||||
@@ -928,7 +948,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
|||||||
Expr getRange() { result = this.getRangeVariable().getInitializer().getExpr() }
|
Expr getRange() { result = this.getRangeVariable().getInitializer().getExpr() }
|
||||||
|
|
||||||
/** Gets the compiler-generated `__range` variable after desugaring. */
|
/** Gets the compiler-generated `__range` variable after desugaring. */
|
||||||
LocalVariable getRangeVariable() { result = this.getChild(0).(DeclStmt).getADeclaration() }
|
LocalVariable getRangeVariable() { result = this.getChild(1).(DeclStmt).getADeclaration() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the compiler-generated `__begin != __end` which is the
|
* Gets the compiler-generated `__begin != __end` which is the
|
||||||
@@ -936,7 +956,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
|||||||
* It will be either an `NEExpr` or a call to a user-defined
|
* It will be either an `NEExpr` or a call to a user-defined
|
||||||
* `operator!=`.
|
* `operator!=`.
|
||||||
*/
|
*/
|
||||||
override Expr getCondition() { result = this.getChild(2) }
|
override Expr getCondition() { result = this.getChild(3) }
|
||||||
|
|
||||||
override Expr getControllingExpr() { result = this.getCondition() }
|
override Expr getControllingExpr() { result = this.getCondition() }
|
||||||
|
|
||||||
@@ -945,7 +965,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
|||||||
* `__end`, initializing them to the values they have before entering the
|
* `__end`, initializing them to the values they have before entering the
|
||||||
* desugared loop.
|
* desugared loop.
|
||||||
*/
|
*/
|
||||||
DeclStmt getBeginEndDeclaration() { result = this.getChild(1) }
|
DeclStmt getBeginEndDeclaration() { result = this.getChild(2) }
|
||||||
|
|
||||||
/** Gets the compiler-generated `__begin` variable after desugaring. */
|
/** Gets the compiler-generated `__begin` variable after desugaring. */
|
||||||
LocalVariable getBeginVariable() { result = this.getBeginEndDeclaration().getDeclaration(0) }
|
LocalVariable getBeginVariable() { result = this.getBeginEndDeclaration().getDeclaration(0) }
|
||||||
@@ -959,7 +979,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
|
|||||||
* be either a `PrefixIncrExpr` or a call to a user-defined
|
* be either a `PrefixIncrExpr` or a call to a user-defined
|
||||||
* `operator++`.
|
* `operator++`.
|
||||||
*/
|
*/
|
||||||
Expr getUpdate() { result = this.getChild(3) }
|
Expr getUpdate() { result = this.getChild(4) }
|
||||||
|
|
||||||
/** Gets the compiler-generated `__begin` variable after desugaring. */
|
/** Gets the compiler-generated `__begin` variable after desugaring. */
|
||||||
LocalVariable getAnIterationVariable() { result = this.getBeginVariable() }
|
LocalVariable getAnIterationVariable() { result = this.getBeginVariable() }
|
||||||
|
|||||||
@@ -2050,8 +2050,11 @@ switch_body(
|
|||||||
int body_id: @stmt ref
|
int body_id: @stmt ref
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@stmt_for_or_range_based_for = @stmt_for
|
||||||
|
| @stmt_range_based_for;
|
||||||
|
|
||||||
for_initialization(
|
for_initialization(
|
||||||
unique int for_stmt: @stmt_for ref,
|
unique int for_stmt: @stmt_for_or_range_based_for ref,
|
||||||
int init_id: @stmt ref
|
int init_id: @stmt ref
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class Element extends @element {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Expr extends @expr {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Stmt extends @stmt {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate isStmtWithInitializer(Stmt stmt) { exists(int kind | stmts(stmt, kind, _) | kind = 29) }
|
||||||
|
|
||||||
|
from Expr child, int index, int index_new, Element parent
|
||||||
|
where
|
||||||
|
exprparents(child, index, parent) and
|
||||||
|
if isStmtWithInitializer(parent) then index_new = index + 1 else index_new = index
|
||||||
|
select child, index_new, parent
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,15 @@
|
|||||||
|
class Element extends @element {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Stmt extends @stmt {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate isStmtWithInitializer(Stmt stmt) { exists(int kind | stmts(stmt, kind, _) | kind = 29) }
|
||||||
|
|
||||||
|
from Stmt child, int index, int index_new, Element parent
|
||||||
|
where
|
||||||
|
stmtparents(child, index, parent) and
|
||||||
|
if isStmtWithInitializer(parent) then index_new = index + 1 else index_new = index
|
||||||
|
select child, index_new, parent
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
description: Support C++20 range-based for initializers
|
||||||
|
compatibility: partial
|
||||||
|
exprparents.rel: run exprparents.qlo
|
||||||
|
stmtparents.rel: run stmtparents.qlo
|
||||||
@@ -1,3 +1,10 @@
|
|||||||
|
## 0.9.5
|
||||||
|
|
||||||
|
### Minor Analysis Improvements
|
||||||
|
|
||||||
|
* The "non-constant format string" query (`cpp/non-constant-format`) has been updated to produce fewer false positives.
|
||||||
|
* Added dataflow models for the `gettext` function variants.
|
||||||
|
|
||||||
## 0.9.4
|
## 0.9.4
|
||||||
|
|
||||||
### Minor Analysis Improvements
|
### Minor Analysis Improvements
|
||||||
@@ -6,7 +13,6 @@
|
|||||||
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) no longer reports an alert when an explicit check for EOF is added.
|
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) no longer reports an alert when an explicit check for EOF is added.
|
||||||
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) now recognizes more EOF checks.
|
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) now recognizes more EOF checks.
|
||||||
* The "Potentially uninitialized local variable" query (`cpp/uninitialized-local`) no longer reports an alert when the local variable is used as a qualifier to a static member function call.
|
* The "Potentially uninitialized local variable" query (`cpp/uninitialized-local`) no longer reports an alert when the local variable is used as a qualifier to a static member function call.
|
||||||
* ```
|
|
||||||
* The diagnostic query `cpp/diagnostics/successfully-extracted-files` now considers any C/C++ file seen during extraction, even one with some errors, to be extracted / scanned. This affects the Code Scanning UI measure of scanned C/C++ files.
|
* The diagnostic query `cpp/diagnostics/successfully-extracted-files` now considers any C/C++ file seen during extraction, even one with some errors, to be extracted / scanned. This affects the Code Scanning UI measure of scanned C/C++ files.
|
||||||
|
|
||||||
## 0.9.3
|
## 0.9.3
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* @name Non-constant format string
|
* @name Non-constant format string
|
||||||
* @description Passing a non-constant 'format' string to a printf-like function can lead
|
* @description Passing a value that is not a string literal 'format' string to a printf-like function can lead
|
||||||
* to a mismatch between the number of arguments defined by the 'format' and the number
|
* to a mismatch between the number of arguments defined by the 'format' and the number
|
||||||
* of arguments actually passed to the function. If the format string ultimately stems
|
* of arguments actually passed to the function. If the format string ultimately stems
|
||||||
* from an untrusted source, this can be used for exploits.
|
* from an untrusted source, this can be used for exploits.
|
||||||
|
* This query finds format strings coming from non-literal sources. Note that format strings of
|
||||||
|
* type `const char*` it is still considered non-constant if the value is not coming from a string
|
||||||
|
* literal. For example, for a parameter with type `const char*` of an exported function that is
|
||||||
|
* used as a format string, there is no way to ensure the originating value was a string literal.
|
||||||
* @kind problem
|
* @kind problem
|
||||||
* @problem.severity recommendation
|
* @problem.severity recommendation
|
||||||
* @security-severity 9.3
|
* @security-severity 9.3
|
||||||
@@ -17,142 +21,117 @@
|
|||||||
|
|
||||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||||
import semmle.code.cpp.commons.Printf
|
import semmle.code.cpp.commons.Printf
|
||||||
|
import semmle.code.cpp.security.FlowSources
|
||||||
|
import semmle.code.cpp.ir.dataflow.internal.ModelUtil
|
||||||
|
import semmle.code.cpp.models.interfaces.DataFlow
|
||||||
|
import semmle.code.cpp.models.interfaces.Taint
|
||||||
|
import semmle.code.cpp.ir.IR
|
||||||
|
|
||||||
// For the following `...gettext` functions, we assume that
|
class UncalledFunction extends Function {
|
||||||
// all translations preserve the type and order of `%` specifiers
|
UncalledFunction() {
|
||||||
// (and hence are safe to use as format strings). This
|
not exists(Call c | c.getTarget() = this) and
|
||||||
// assumption is hard-coded into the query.
|
// Ignore functions that appear to be function pointers
|
||||||
predicate whitelistFunction(Function f, int arg) {
|
// function pointers may be seen as uncalled statically
|
||||||
// basic variations of gettext
|
not exists(FunctionAccess fa | fa.getTarget() = this)
|
||||||
f.getName() = "_" and arg = 0
|
}
|
||||||
or
|
|
||||||
f.getName() = "gettext" and arg = 0
|
|
||||||
or
|
|
||||||
f.getName() = "dgettext" and arg = 1
|
|
||||||
or
|
|
||||||
f.getName() = "dcgettext" and arg = 1
|
|
||||||
or
|
|
||||||
// plural variations of gettext that take one format string for singular and another for plural form
|
|
||||||
f.getName() = "ngettext" and
|
|
||||||
(arg = 0 or arg = 1)
|
|
||||||
or
|
|
||||||
f.getName() = "dngettext" and
|
|
||||||
(arg = 1 or arg = 2)
|
|
||||||
or
|
|
||||||
f.getName() = "dcngettext" and
|
|
||||||
(arg = 1 or arg = 2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we assume that ALL uses of the `_` macro
|
/**
|
||||||
// return constant string literals
|
* Holds if `node` is a non-constant source of data flow for non-const format string detection.
|
||||||
predicate underscoreMacro(Expr e) {
|
* This is defined as either:
|
||||||
exists(MacroInvocation mi |
|
* 1) a `FlowSource`
|
||||||
mi.getMacroName() = "_" and
|
* 2) a parameter of an 'uncalled' function
|
||||||
mi.getExpr() = e
|
* 3) an argument to a function with no definition that is not known to define the output through its input
|
||||||
|
* 4) an out arg of a function with no definition that is not known to define the output through its input
|
||||||
|
*
|
||||||
|
* The latter two cases address identifying standard string manipulation libraries as input sources
|
||||||
|
* e.g., strcpy. More simply, functions without definitions that are known to manipulate the
|
||||||
|
* input to produce an output are not sources. Instead the ultimate source of input to these functions
|
||||||
|
* should be considered as the source.
|
||||||
|
*
|
||||||
|
* False Negative Implication: This approach has false negatives (fails to identify non-const sources)
|
||||||
|
* when the source is a field of a struct or object and the initialization is not observed statically.
|
||||||
|
* There are 3 general cases where this can occur:
|
||||||
|
* 1) Parameters of uncalled functions that are structs/objects and a field is accessed for a format string.
|
||||||
|
* 2) A local variable that is a struct/object and initialization of the field occurs in code that is unseen statically.
|
||||||
|
* e.g., an object constructor isn't known statically, or a function sets fields
|
||||||
|
* of a struct, but the function is not known statically.
|
||||||
|
* 3) A function meeting cases (3) and (4) above returns (through an out argument or return value)
|
||||||
|
* a struct or object where a field containing a format string has been initialized.
|
||||||
|
*
|
||||||
|
* Note, uninitialized variables used as format strings are never detected by design.
|
||||||
|
* Uninitialized variables are a separate vulnerability concern and should be addressed by a separate query.
|
||||||
|
*/
|
||||||
|
predicate isNonConst(DataFlow::Node node) {
|
||||||
|
node instanceof FlowSource
|
||||||
|
or
|
||||||
|
// Parameters of uncalled functions that aren't const
|
||||||
|
exists(UncalledFunction f, Parameter p |
|
||||||
|
f.getAParameter() = p and
|
||||||
|
p = node.asParameter()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// Consider as an input any out arg of a function or a function's return where the function is not:
|
||||||
|
// 1. a function with a known dataflow or taintflow from input to output and the `node` is the output
|
||||||
|
// 2. a function where there is a known definition
|
||||||
|
// i.e., functions that with unknown bodies and are not known to define the output through its input
|
||||||
|
// are considered as possible non-const sources
|
||||||
|
// The function's output must also not be const to be considered a non-const source
|
||||||
|
exists(Function func, CallInstruction call |
|
||||||
|
// NOTE: could use `Call` getAnArgument() instead of `CallInstruction` but requires two
|
||||||
|
// variables representing the same call in ordoer to use `callOutput` below.
|
||||||
|
exists(Expr arg |
|
||||||
|
call.getPositionalArgumentOperand(_).getDef().getUnconvertedResultExpression() = arg and
|
||||||
|
arg = node.asDefiningArgument()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
call.getUnconvertedResultExpression() = node.asIndirectExpr()
|
||||||
|
|
|
||||||
|
func = call.getStaticCallTarget() and
|
||||||
|
not exists(FunctionOutput output |
|
||||||
|
// NOTE: we must include dataflow and taintflow. e.g., including only dataflow we will find sprintf
|
||||||
|
// variant function's output are now possible non-const sources
|
||||||
|
pragma[only_bind_out](func).(DataFlowFunction).hasDataFlow(_, output) or
|
||||||
|
pragma[only_bind_out](func).(TaintFunction).hasTaintFlow(_, output)
|
||||||
|
|
|
||||||
|
node = callOutput(call, output)
|
||||||
|
)
|
||||||
|
) and
|
||||||
|
not exists(Call c |
|
||||||
|
c.getTarget().hasDefinition() and
|
||||||
|
if node instanceof DataFlow::DefinitionByReferenceNode
|
||||||
|
then c.getAnArgument() = node.asDefiningArgument()
|
||||||
|
else c = [node.asExpr(), node.asIndirectExpr()]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `t` cannot hold a character array, directly or indirectly.
|
* Holds if `sink` is a sink is a format string of any
|
||||||
|
* `FormattingFunctionCall`.
|
||||||
*/
|
*/
|
||||||
predicate cannotContainString(Type t, boolean isIndirect) {
|
|
||||||
isIndirect = false and
|
|
||||||
exists(Type unspecified |
|
|
||||||
unspecified = t.getUnspecifiedType() and
|
|
||||||
not unspecified instanceof UnknownType
|
|
||||||
|
|
|
||||||
unspecified instanceof BuiltInType or
|
|
||||||
unspecified instanceof IntegralOrEnumType
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isNonConst(DataFlow::Node node, boolean isIndirect) {
|
|
||||||
exists(Expr e |
|
|
||||||
e = node.asExpr() and isIndirect = false
|
|
||||||
or
|
|
||||||
e = node.asIndirectExpr() and isIndirect = true
|
|
||||||
|
|
|
||||||
exists(FunctionCall fc | fc = e |
|
|
||||||
not (
|
|
||||||
whitelistFunction(fc.getTarget(), _) or
|
|
||||||
fc.getTarget().hasDefinition()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(Parameter p | p = e.(VariableAccess).getTarget() |
|
|
||||||
p.getFunction().getName() = "main" and p.getType() instanceof PointerType
|
|
||||||
)
|
|
||||||
or
|
|
||||||
e instanceof CrementOperation
|
|
||||||
or
|
|
||||||
e instanceof AddressOfExpr
|
|
||||||
or
|
|
||||||
e instanceof ReferenceToExpr
|
|
||||||
or
|
|
||||||
e instanceof AssignPointerAddExpr
|
|
||||||
or
|
|
||||||
e instanceof AssignPointerSubExpr
|
|
||||||
or
|
|
||||||
e instanceof PointerArithmeticOperation
|
|
||||||
or
|
|
||||||
e instanceof FieldAccess
|
|
||||||
or
|
|
||||||
e instanceof PointerDereferenceExpr
|
|
||||||
or
|
|
||||||
e instanceof AddressOfExpr
|
|
||||||
or
|
|
||||||
e instanceof ExprCall
|
|
||||||
or
|
|
||||||
e instanceof NewArrayExpr
|
|
||||||
or
|
|
||||||
exists(Variable v | v = e.(VariableAccess).getTarget() |
|
|
||||||
v.getType().(ArrayType).getBaseType() instanceof CharType and
|
|
||||||
exists(AssignExpr ae |
|
|
||||||
ae.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() = v
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
node instanceof DataFlow::DefinitionByReferenceNode and
|
|
||||||
isIndirect = true
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[noinline]
|
|
||||||
predicate isBarrierNode(DataFlow::Node node) {
|
|
||||||
underscoreMacro([node.asExpr(), node.asIndirectExpr()])
|
|
||||||
or
|
|
||||||
exists(node.asExpr()) and
|
|
||||||
cannotContainString(node.getType(), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isSinkImpl(DataFlow::Node sink, Expr formatString) {
|
predicate isSinkImpl(DataFlow::Node sink, Expr formatString) {
|
||||||
[sink.asExpr(), sink.asIndirectExpr()] = formatString and
|
[sink.asExpr(), sink.asIndirectExpr()] = formatString and
|
||||||
exists(FormattingFunctionCall fc | formatString = fc.getArgument(fc.getFormatParameterIndex()))
|
exists(FormattingFunctionCall fc | formatString = fc.getArgument(fc.getFormatParameterIndex()))
|
||||||
}
|
}
|
||||||
|
|
||||||
module NonConstFlowConfig implements DataFlow::ConfigSig {
|
module NonConstFlowConfig implements DataFlow::ConfigSig {
|
||||||
predicate isSource(DataFlow::Node source) {
|
predicate isSource(DataFlow::Node source) { isNonConst(source) }
|
||||||
exists(boolean isIndirect, Type t |
|
|
||||||
isNonConst(source, isIndirect) and
|
|
||||||
t = source.getType() and
|
|
||||||
not cannotContainString(t, isIndirect)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _) }
|
predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _) }
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node node) { isBarrierNode(node) }
|
predicate isBarrier(DataFlow::Node node) {
|
||||||
|
// Ignore tracing non-const through array indices
|
||||||
|
exists(ArrayExpr a | a.getArrayOffset() = node.asExpr())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module NonConstFlow = TaintTracking::Global<NonConstFlowConfig>;
|
module NonConstFlow = TaintTracking::Global<NonConstFlowConfig>;
|
||||||
|
|
||||||
from FormattingFunctionCall call, Expr formatString
|
from FormattingFunctionCall call, Expr formatString, DataFlow::Node sink
|
||||||
where
|
where
|
||||||
call.getArgument(call.getFormatParameterIndex()) = formatString and
|
call.getArgument(call.getFormatParameterIndex()) = formatString and
|
||||||
exists(DataFlow::Node sink |
|
|
||||||
NonConstFlow::flowTo(sink) and
|
NonConstFlow::flowTo(sink) and
|
||||||
isSinkImpl(sink, formatString)
|
isSinkImpl(sink, formatString)
|
||||||
)
|
|
||||||
select formatString,
|
select formatString,
|
||||||
"The format string argument to " + call.getTarget().getName() +
|
"The format string argument to " + call.getTarget().getName() +
|
||||||
" should be constant to prevent security issues and other potential errors."
|
" should be constant to prevent security issues and other potential errors."
|
||||||
|
|||||||
@@ -6,5 +6,4 @@
|
|||||||
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) no longer reports an alert when an explicit check for EOF is added.
|
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) no longer reports an alert when an explicit check for EOF is added.
|
||||||
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) now recognizes more EOF checks.
|
* The "Incorrect return-value check for a 'scanf'-like function" query (`cpp/incorrectly-checked-scanf`) now recognizes more EOF checks.
|
||||||
* The "Potentially uninitialized local variable" query (`cpp/uninitialized-local`) no longer reports an alert when the local variable is used as a qualifier to a static member function call.
|
* The "Potentially uninitialized local variable" query (`cpp/uninitialized-local`) no longer reports an alert when the local variable is used as a qualifier to a static member function call.
|
||||||
* ```
|
|
||||||
* The diagnostic query `cpp/diagnostics/successfully-extracted-files` now considers any C/C++ file seen during extraction, even one with some errors, to be extracted / scanned. This affects the Code Scanning UI measure of scanned C/C++ files.
|
* The diagnostic query `cpp/diagnostics/successfully-extracted-files` now considers any C/C++ file seen during extraction, even one with some errors, to be extracted / scanned. This affects the Code Scanning UI measure of scanned C/C++ files.
|
||||||
|
|||||||
6
cpp/ql/src/change-notes/released/0.9.5.md
Normal file
6
cpp/ql/src/change-notes/released/0.9.5.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
## 0.9.5
|
||||||
|
|
||||||
|
### Minor Analysis Improvements
|
||||||
|
|
||||||
|
* The "non-constant format string" query (`cpp/non-constant-format`) has been updated to produce fewer false positives.
|
||||||
|
* Added dataflow models for the `gettext` function variants.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.9.4
|
lastReleaseVersion: 0.9.5
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-queries
|
name: codeql/cpp-queries
|
||||||
version: 0.9.4
|
version: 0.9.5
|
||||||
groups:
|
groups:
|
||||||
- cpp
|
- cpp
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:22:27:22:30 | **argv | test.cpp:29:13:29:20 | *filePath |
|
| test.cpp:22:27:22:30 | **argv | test.cpp:29:13:29:20 | *filePath | provenance | |
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:22:27:22:30 | **argv | semmle.label | **argv |
|
| test.cpp:22:27:22:30 | **argv | semmle.label | **argv |
|
||||||
| test.cpp:29:13:29:20 | *filePath | semmle.label | *filePath |
|
| test.cpp:29:13:29:20 | *filePath | semmle.label | *filePath |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:22:17:22:21 | ... * ... | test.cpp:23:33:23:37 | size1 |
|
| test.cpp:22:17:22:21 | ... * ... | test.cpp:23:33:23:37 | size1 | provenance | |
|
||||||
| test.cpp:37:24:37:27 | size | test.cpp:37:46:37:49 | size |
|
| test.cpp:37:24:37:27 | size | test.cpp:37:46:37:49 | size | provenance | |
|
||||||
| test.cpp:45:36:45:40 | ... * ... | test.cpp:37:24:37:27 | size |
|
| test.cpp:45:36:45:40 | ... * ... | test.cpp:37:24:37:27 | size | provenance | |
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:13:33:13:37 | ... * ... | semmle.label | ... * ... |
|
| test.cpp:13:33:13:37 | ... * ... | semmle.label | ... * ... |
|
||||||
| test.cpp:15:31:15:35 | ... * ... | semmle.label | ... * ... |
|
| test.cpp:15:31:15:35 | ... * ... | semmle.label | ... * ... |
|
||||||
|
|||||||
@@ -1,43 +1,43 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:4:17:4:22 | call to malloc | test.cpp:6:9:6:11 | arr |
|
| test.cpp:4:17:4:22 | call to malloc | test.cpp:6:9:6:11 | arr | provenance | |
|
||||||
| test.cpp:4:17:4:22 | call to malloc | test.cpp:10:9:10:11 | arr |
|
| test.cpp:4:17:4:22 | call to malloc | test.cpp:10:9:10:11 | arr | provenance | |
|
||||||
| test.cpp:19:9:19:16 | *mk_array [p] | test.cpp:28:19:28:26 | call to mk_array [p] |
|
| test.cpp:19:9:19:16 | *mk_array [p] | test.cpp:28:19:28:26 | call to mk_array [p] | provenance | |
|
||||||
| test.cpp:19:9:19:16 | *mk_array [p] | test.cpp:50:18:50:25 | call to mk_array [p] |
|
| test.cpp:19:9:19:16 | *mk_array [p] | test.cpp:50:18:50:25 | call to mk_array [p] | provenance | |
|
||||||
| test.cpp:21:5:21:7 | *arr [post update] [p] | test.cpp:22:5:22:7 | *arr [p] |
|
| test.cpp:21:5:21:7 | *arr [post update] [p] | test.cpp:22:5:22:7 | *arr [p] | provenance | |
|
||||||
| test.cpp:21:5:21:24 | ... = ... | test.cpp:21:5:21:7 | *arr [post update] [p] |
|
| test.cpp:21:5:21:24 | ... = ... | test.cpp:21:5:21:7 | *arr [post update] [p] | provenance | |
|
||||||
| test.cpp:21:13:21:18 | call to malloc | test.cpp:21:5:21:24 | ... = ... |
|
| test.cpp:21:13:21:18 | call to malloc | test.cpp:21:5:21:24 | ... = ... | provenance | |
|
||||||
| test.cpp:22:5:22:7 | *arr [p] | test.cpp:19:9:19:16 | *mk_array [p] |
|
| test.cpp:22:5:22:7 | *arr [p] | test.cpp:19:9:19:16 | *mk_array [p] | provenance | |
|
||||||
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:31:9:31:11 | *arr [p] |
|
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:31:9:31:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:35:9:35:11 | *arr [p] |
|
| test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:35:9:35:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:31:9:31:11 | *arr [p] | test.cpp:31:13:31:13 | p |
|
| test.cpp:31:9:31:11 | *arr [p] | test.cpp:31:13:31:13 | p | provenance | |
|
||||||
| test.cpp:35:9:35:11 | *arr [p] | test.cpp:35:13:35:13 | p |
|
| test.cpp:35:9:35:11 | *arr [p] | test.cpp:35:13:35:13 | p | provenance | |
|
||||||
| test.cpp:39:27:39:29 | arr [p] | test.cpp:41:9:41:11 | *arr [p] |
|
| test.cpp:39:27:39:29 | arr [p] | test.cpp:41:9:41:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:39:27:39:29 | arr [p] | test.cpp:45:9:45:11 | *arr [p] |
|
| test.cpp:39:27:39:29 | arr [p] | test.cpp:45:9:45:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:41:9:41:11 | *arr [p] | test.cpp:41:13:41:13 | p |
|
| test.cpp:41:9:41:11 | *arr [p] | test.cpp:41:13:41:13 | p | provenance | |
|
||||||
| test.cpp:45:9:45:11 | *arr [p] | test.cpp:45:13:45:13 | p |
|
| test.cpp:45:9:45:11 | *arr [p] | test.cpp:45:13:45:13 | p | provenance | |
|
||||||
| test.cpp:50:18:50:25 | call to mk_array [p] | test.cpp:39:27:39:29 | arr [p] |
|
| test.cpp:50:18:50:25 | call to mk_array [p] | test.cpp:39:27:39:29 | arr [p] | provenance | |
|
||||||
| test.cpp:55:5:55:7 | *arr [post update] [p] | test.cpp:56:5:56:7 | *arr [p] |
|
| test.cpp:55:5:55:7 | *arr [post update] [p] | test.cpp:56:5:56:7 | *arr [p] | provenance | |
|
||||||
| test.cpp:55:5:55:24 | ... = ... | test.cpp:55:5:55:7 | *arr [post update] [p] |
|
| test.cpp:55:5:55:24 | ... = ... | test.cpp:55:5:55:7 | *arr [post update] [p] | provenance | |
|
||||||
| test.cpp:55:13:55:18 | call to malloc | test.cpp:55:5:55:24 | ... = ... |
|
| test.cpp:55:13:55:18 | call to malloc | test.cpp:55:5:55:24 | ... = ... | provenance | |
|
||||||
| test.cpp:56:5:56:7 | *arr [p] | test.cpp:59:9:59:11 | *arr [p] |
|
| test.cpp:56:5:56:7 | *arr [p] | test.cpp:59:9:59:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:56:5:56:7 | *arr [p] | test.cpp:63:9:63:11 | *arr [p] |
|
| test.cpp:56:5:56:7 | *arr [p] | test.cpp:63:9:63:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:59:9:59:11 | *arr [p] | test.cpp:59:13:59:13 | p |
|
| test.cpp:59:9:59:11 | *arr [p] | test.cpp:59:13:59:13 | p | provenance | |
|
||||||
| test.cpp:63:9:63:11 | *arr [p] | test.cpp:63:13:63:13 | p |
|
| test.cpp:63:9:63:11 | *arr [p] | test.cpp:63:13:63:13 | p | provenance | |
|
||||||
| test.cpp:67:10:67:19 | **mk_array_p [p] | test.cpp:76:20:76:29 | *call to mk_array_p [p] |
|
| test.cpp:67:10:67:19 | **mk_array_p [p] | test.cpp:76:20:76:29 | *call to mk_array_p [p] | provenance | |
|
||||||
| test.cpp:67:10:67:19 | **mk_array_p [p] | test.cpp:98:18:98:27 | *call to mk_array_p [p] |
|
| test.cpp:67:10:67:19 | **mk_array_p [p] | test.cpp:98:18:98:27 | *call to mk_array_p [p] | provenance | |
|
||||||
| test.cpp:69:5:69:7 | *arr [post update] [p] | test.cpp:70:5:70:7 | *arr [p] |
|
| test.cpp:69:5:69:7 | *arr [post update] [p] | test.cpp:70:5:70:7 | *arr [p] | provenance | |
|
||||||
| test.cpp:69:5:69:25 | ... = ... | test.cpp:69:5:69:7 | *arr [post update] [p] |
|
| test.cpp:69:5:69:25 | ... = ... | test.cpp:69:5:69:7 | *arr [post update] [p] | provenance | |
|
||||||
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... |
|
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... | provenance | |
|
||||||
| test.cpp:70:5:70:7 | *arr [p] | test.cpp:67:10:67:19 | **mk_array_p [p] |
|
| test.cpp:70:5:70:7 | *arr [p] | test.cpp:67:10:67:19 | **mk_array_p [p] | provenance | |
|
||||||
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:79:9:79:11 | *arr [p] |
|
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:79:9:79:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:83:9:83:11 | *arr [p] |
|
| test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:83:9:83:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:79:9:79:11 | *arr [p] | test.cpp:79:14:79:14 | p |
|
| test.cpp:79:9:79:11 | *arr [p] | test.cpp:79:14:79:14 | p | provenance | |
|
||||||
| test.cpp:83:9:83:11 | *arr [p] | test.cpp:83:14:83:14 | p |
|
| test.cpp:83:9:83:11 | *arr [p] | test.cpp:83:14:83:14 | p | provenance | |
|
||||||
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:89:9:89:11 | *arr [p] |
|
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:89:9:89:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:93:9:93:11 | *arr [p] |
|
| test.cpp:87:28:87:30 | *arr [p] | test.cpp:93:9:93:11 | *arr [p] | provenance | |
|
||||||
| test.cpp:89:9:89:11 | *arr [p] | test.cpp:89:14:89:14 | p |
|
| test.cpp:89:9:89:11 | *arr [p] | test.cpp:89:14:89:14 | p | provenance | |
|
||||||
| test.cpp:93:9:93:11 | *arr [p] | test.cpp:93:14:93:14 | p |
|
| test.cpp:93:9:93:11 | *arr [p] | test.cpp:93:14:93:14 | p | provenance | |
|
||||||
| test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:87:28:87:30 | *arr [p] |
|
| test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:87:28:87:30 | *arr [p] | provenance | |
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc |
|
| test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc |
|
||||||
| test.cpp:6:9:6:11 | arr | semmle.label | arr |
|
| test.cpp:6:9:6:11 | arr | semmle.label | arr |
|
||||||
|
|||||||
@@ -1,74 +1,74 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:34:10:34:12 | buf | test.cpp:34:5:34:24 | access to array |
|
| test.cpp:34:10:34:12 | buf | test.cpp:34:5:34:24 | access to array | provenance | |
|
||||||
| test.cpp:35:10:35:12 | buf | test.cpp:35:5:35:22 | access to array |
|
| test.cpp:35:10:35:12 | buf | test.cpp:35:5:35:22 | access to array | provenance | |
|
||||||
| test.cpp:36:10:36:12 | buf | test.cpp:36:5:36:24 | access to array |
|
| test.cpp:36:10:36:12 | buf | test.cpp:36:5:36:24 | access to array | provenance | |
|
||||||
| test.cpp:39:14:39:16 | buf | test.cpp:39:9:39:19 | access to array |
|
| test.cpp:39:14:39:16 | buf | test.cpp:39:9:39:19 | access to array | provenance | |
|
||||||
| test.cpp:43:14:43:16 | buf | test.cpp:43:9:43:19 | access to array |
|
| test.cpp:43:14:43:16 | buf | test.cpp:43:9:43:19 | access to array | provenance | |
|
||||||
| test.cpp:48:10:48:12 | buf | test.cpp:48:5:48:24 | access to array |
|
| test.cpp:48:10:48:12 | buf | test.cpp:48:5:48:24 | access to array | provenance | |
|
||||||
| test.cpp:49:10:49:12 | buf | test.cpp:49:5:49:22 | access to array |
|
| test.cpp:49:10:49:12 | buf | test.cpp:49:5:49:22 | access to array | provenance | |
|
||||||
| test.cpp:50:10:50:12 | buf | test.cpp:50:5:50:24 | access to array |
|
| test.cpp:50:10:50:12 | buf | test.cpp:50:5:50:24 | access to array | provenance | |
|
||||||
| test.cpp:53:14:53:16 | buf | test.cpp:53:9:53:19 | access to array |
|
| test.cpp:53:14:53:16 | buf | test.cpp:53:9:53:19 | access to array | provenance | |
|
||||||
| test.cpp:57:14:57:16 | buf | test.cpp:57:9:57:19 | access to array |
|
| test.cpp:57:14:57:16 | buf | test.cpp:57:9:57:19 | access to array | provenance | |
|
||||||
| test.cpp:61:14:61:16 | buf | test.cpp:61:9:61:19 | access to array |
|
| test.cpp:61:14:61:16 | buf | test.cpp:61:9:61:19 | access to array | provenance | |
|
||||||
| test.cpp:70:33:70:33 | p | test.cpp:71:5:71:17 | access to array |
|
| test.cpp:70:33:70:33 | p | test.cpp:71:5:71:17 | access to array | provenance | |
|
||||||
| test.cpp:70:33:70:33 | p | test.cpp:72:5:72:15 | access to array |
|
| test.cpp:70:33:70:33 | p | test.cpp:72:5:72:15 | access to array | provenance | |
|
||||||
| test.cpp:76:26:76:46 | & ... | test.cpp:66:32:66:32 | p |
|
| test.cpp:76:26:76:46 | & ... | test.cpp:66:32:66:32 | p | provenance | |
|
||||||
| test.cpp:76:32:76:34 | buf | test.cpp:76:26:76:46 | & ... |
|
| test.cpp:76:32:76:34 | buf | test.cpp:76:26:76:46 | & ... | provenance | |
|
||||||
| test.cpp:77:26:77:44 | & ... | test.cpp:66:32:66:32 | p |
|
| test.cpp:77:26:77:44 | & ... | test.cpp:66:32:66:32 | p | provenance | |
|
||||||
| test.cpp:77:32:77:34 | buf | test.cpp:77:26:77:44 | & ... |
|
| test.cpp:77:32:77:34 | buf | test.cpp:77:26:77:44 | & ... | provenance | |
|
||||||
| test.cpp:79:27:79:34 | buf | test.cpp:70:33:70:33 | p |
|
| test.cpp:79:27:79:34 | buf | test.cpp:70:33:70:33 | p | provenance | |
|
||||||
| test.cpp:79:32:79:34 | buf | test.cpp:79:27:79:34 | buf |
|
| test.cpp:79:32:79:34 | buf | test.cpp:79:27:79:34 | buf | provenance | |
|
||||||
| test.cpp:85:34:85:36 | buf | test.cpp:87:5:87:31 | access to array |
|
| test.cpp:85:34:85:36 | buf | test.cpp:87:5:87:31 | access to array | provenance | |
|
||||||
| test.cpp:85:34:85:36 | buf | test.cpp:88:5:88:27 | access to array |
|
| test.cpp:85:34:85:36 | buf | test.cpp:88:5:88:27 | access to array | provenance | |
|
||||||
| test.cpp:96:13:96:15 | arr | test.cpp:96:13:96:18 | access to array |
|
| test.cpp:96:13:96:15 | arr | test.cpp:96:13:96:18 | access to array | provenance | |
|
||||||
| test.cpp:111:17:111:19 | arr | test.cpp:111:17:111:22 | access to array |
|
| test.cpp:111:17:111:19 | arr | test.cpp:111:17:111:22 | access to array | provenance | |
|
||||||
| test.cpp:111:17:111:19 | arr | test.cpp:115:35:115:40 | access to array |
|
| test.cpp:111:17:111:19 | arr | test.cpp:115:35:115:40 | access to array | provenance | |
|
||||||
| test.cpp:111:17:111:19 | arr | test.cpp:119:17:119:22 | access to array |
|
| test.cpp:111:17:111:19 | arr | test.cpp:119:17:119:22 | access to array | provenance | |
|
||||||
| test.cpp:115:35:115:37 | arr | test.cpp:111:17:111:22 | access to array |
|
| test.cpp:115:35:115:37 | arr | test.cpp:111:17:111:22 | access to array | provenance | |
|
||||||
| test.cpp:115:35:115:37 | arr | test.cpp:115:35:115:40 | access to array |
|
| test.cpp:115:35:115:37 | arr | test.cpp:115:35:115:40 | access to array | provenance | |
|
||||||
| test.cpp:115:35:115:37 | arr | test.cpp:119:17:119:22 | access to array |
|
| test.cpp:115:35:115:37 | arr | test.cpp:119:17:119:22 | access to array | provenance | |
|
||||||
| test.cpp:119:17:119:19 | arr | test.cpp:111:17:111:22 | access to array |
|
| test.cpp:119:17:119:19 | arr | test.cpp:111:17:111:22 | access to array | provenance | |
|
||||||
| test.cpp:119:17:119:19 | arr | test.cpp:115:35:115:40 | access to array |
|
| test.cpp:119:17:119:19 | arr | test.cpp:115:35:115:40 | access to array | provenance | |
|
||||||
| test.cpp:119:17:119:19 | arr | test.cpp:119:17:119:22 | access to array |
|
| test.cpp:119:17:119:19 | arr | test.cpp:119:17:119:22 | access to array | provenance | |
|
||||||
| test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array |
|
| test.cpp:128:9:128:11 | arr | test.cpp:128:9:128:14 | access to array | provenance | |
|
||||||
| test.cpp:134:25:134:27 | arr | test.cpp:136:9:136:16 | ... += ... |
|
| test.cpp:134:25:134:27 | arr | test.cpp:136:9:136:16 | ... += ... | provenance | |
|
||||||
| test.cpp:136:9:136:16 | ... += ... | test.cpp:138:13:138:15 | arr |
|
| test.cpp:136:9:136:16 | ... += ... | test.cpp:138:13:138:15 | arr | provenance | |
|
||||||
| test.cpp:143:18:143:21 | asdf | test.cpp:134:25:134:27 | arr |
|
| test.cpp:143:18:143:21 | asdf | test.cpp:134:25:134:27 | arr | provenance | |
|
||||||
| test.cpp:143:18:143:21 | asdf | test.cpp:143:18:143:21 | asdf |
|
| test.cpp:143:18:143:21 | asdf | test.cpp:143:18:143:21 | asdf | provenance | |
|
||||||
| test.cpp:146:26:146:26 | *p | test.cpp:147:4:147:9 | -- ... |
|
| test.cpp:146:26:146:26 | *p | test.cpp:147:4:147:9 | -- ... | provenance | |
|
||||||
| test.cpp:156:12:156:14 | buf | test.cpp:156:12:156:18 | ... + ... |
|
| test.cpp:156:12:156:14 | buf | test.cpp:156:12:156:18 | ... + ... | provenance | |
|
||||||
| test.cpp:156:12:156:18 | ... + ... | test.cpp:158:17:158:18 | *& ... |
|
| test.cpp:156:12:156:18 | ... + ... | test.cpp:158:17:158:18 | *& ... | provenance | |
|
||||||
| test.cpp:158:17:158:18 | *& ... | test.cpp:146:26:146:26 | *p |
|
| test.cpp:158:17:158:18 | *& ... | test.cpp:146:26:146:26 | *p | provenance | |
|
||||||
| test.cpp:218:23:218:28 | buffer | test.cpp:220:5:220:11 | access to array |
|
| test.cpp:218:23:218:28 | buffer | test.cpp:220:5:220:11 | access to array | provenance | |
|
||||||
| test.cpp:218:23:218:28 | buffer | test.cpp:221:5:221:11 | access to array |
|
| test.cpp:218:23:218:28 | buffer | test.cpp:221:5:221:11 | access to array | provenance | |
|
||||||
| test.cpp:229:25:229:29 | array | test.cpp:231:5:231:10 | access to array |
|
| test.cpp:229:25:229:29 | array | test.cpp:231:5:231:10 | access to array | provenance | |
|
||||||
| test.cpp:229:25:229:29 | array | test.cpp:232:5:232:10 | access to array |
|
| test.cpp:229:25:229:29 | array | test.cpp:232:5:232:10 | access to array | provenance | |
|
||||||
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array |
|
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array | provenance | |
|
||||||
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array |
|
| test.cpp:245:30:245:30 | p | test.cpp:261:27:261:30 | access to array | provenance | |
|
||||||
| test.cpp:274:14:274:20 | buffer3 | test.cpp:245:30:245:30 | p |
|
| test.cpp:274:14:274:20 | buffer3 | test.cpp:245:30:245:30 | p | provenance | |
|
||||||
| test.cpp:274:14:274:20 | buffer3 | test.cpp:274:14:274:20 | buffer3 |
|
| test.cpp:274:14:274:20 | buffer3 | test.cpp:274:14:274:20 | buffer3 | provenance | |
|
||||||
| test.cpp:277:35:277:35 | p | test.cpp:278:14:278:14 | p |
|
| test.cpp:277:35:277:35 | p | test.cpp:278:14:278:14 | p | provenance | |
|
||||||
| test.cpp:278:14:278:14 | p | test.cpp:245:30:245:30 | p |
|
| test.cpp:278:14:278:14 | p | test.cpp:245:30:245:30 | p | provenance | |
|
||||||
| test.cpp:283:19:283:25 | buffer1 | test.cpp:277:35:277:35 | p |
|
| test.cpp:283:19:283:25 | buffer1 | test.cpp:277:35:277:35 | p | provenance | |
|
||||||
| test.cpp:283:19:283:25 | buffer1 | test.cpp:283:19:283:25 | buffer1 |
|
| test.cpp:283:19:283:25 | buffer1 | test.cpp:283:19:283:25 | buffer1 | provenance | |
|
||||||
| test.cpp:286:19:286:25 | buffer2 | test.cpp:277:35:277:35 | p |
|
| test.cpp:286:19:286:25 | buffer2 | test.cpp:277:35:277:35 | p | provenance | |
|
||||||
| test.cpp:286:19:286:25 | buffer2 | test.cpp:286:19:286:25 | buffer2 |
|
| test.cpp:286:19:286:25 | buffer2 | test.cpp:286:19:286:25 | buffer2 | provenance | |
|
||||||
| test.cpp:289:19:289:25 | buffer3 | test.cpp:277:35:277:35 | p |
|
| test.cpp:289:19:289:25 | buffer3 | test.cpp:277:35:277:35 | p | provenance | |
|
||||||
| test.cpp:289:19:289:25 | buffer3 | test.cpp:289:19:289:25 | buffer3 |
|
| test.cpp:289:19:289:25 | buffer3 | test.cpp:289:19:289:25 | buffer3 | provenance | |
|
||||||
| test.cpp:292:25:292:27 | arr | test.cpp:299:16:299:21 | access to array |
|
| test.cpp:292:25:292:27 | arr | test.cpp:299:16:299:21 | access to array | provenance | |
|
||||||
| test.cpp:292:25:292:27 | arr | test.cpp:299:16:299:21 | access to array |
|
| test.cpp:292:25:292:27 | arr | test.cpp:299:16:299:21 | access to array | provenance | |
|
||||||
| test.cpp:306:20:306:23 | arr1 | test.cpp:292:25:292:27 | arr |
|
| test.cpp:306:20:306:23 | arr1 | test.cpp:292:25:292:27 | arr | provenance | |
|
||||||
| test.cpp:306:20:306:23 | arr1 | test.cpp:306:20:306:23 | arr1 |
|
| test.cpp:306:20:306:23 | arr1 | test.cpp:306:20:306:23 | arr1 | provenance | |
|
||||||
| test.cpp:309:20:309:23 | arr2 | test.cpp:292:25:292:27 | arr |
|
| test.cpp:309:20:309:23 | arr2 | test.cpp:292:25:292:27 | arr | provenance | |
|
||||||
| test.cpp:309:20:309:23 | arr2 | test.cpp:309:20:309:23 | arr2 |
|
| test.cpp:309:20:309:23 | arr2 | test.cpp:309:20:309:23 | arr2 | provenance | |
|
||||||
| test.cpp:319:19:319:22 | temp | test.cpp:319:19:319:27 | ... + ... |
|
| test.cpp:319:19:319:22 | temp | test.cpp:319:19:319:27 | ... + ... | provenance | |
|
||||||
| test.cpp:319:19:319:22 | temp | test.cpp:324:23:324:32 | ... + ... |
|
| test.cpp:319:19:319:22 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | |
|
||||||
| test.cpp:319:19:319:27 | ... + ... | test.cpp:325:24:325:26 | end |
|
| test.cpp:319:19:319:27 | ... + ... | test.cpp:325:24:325:26 | end | provenance | |
|
||||||
| test.cpp:322:19:322:22 | temp | test.cpp:322:19:322:27 | ... + ... |
|
| test.cpp:322:19:322:22 | temp | test.cpp:322:19:322:27 | ... + ... | provenance | |
|
||||||
| test.cpp:322:19:322:22 | temp | test.cpp:324:23:324:32 | ... + ... |
|
| test.cpp:322:19:322:22 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | |
|
||||||
| test.cpp:322:19:322:27 | ... + ... | test.cpp:325:24:325:26 | end |
|
| test.cpp:322:19:322:27 | ... + ... | test.cpp:325:24:325:26 | end | provenance | |
|
||||||
| test.cpp:324:23:324:26 | temp | test.cpp:324:23:324:32 | ... + ... |
|
| test.cpp:324:23:324:26 | temp | test.cpp:324:23:324:32 | ... + ... | provenance | |
|
||||||
| test.cpp:324:23:324:32 | ... + ... | test.cpp:325:15:325:19 | temp2 |
|
| test.cpp:324:23:324:32 | ... + ... | test.cpp:325:15:325:19 | temp2 | provenance | |
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:34:5:34:24 | access to array | semmle.label | access to array |
|
| test.cpp:34:5:34:24 | access to array | semmle.label | access to array |
|
||||||
| test.cpp:34:10:34:12 | buf | semmle.label | buf |
|
| test.cpp:34:10:34:12 | buf | semmle.label | buf |
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:45:18:45:23 | buffer | test.cpp:45:7:45:10 | *func |
|
| test.cpp:45:18:45:23 | buffer | test.cpp:45:7:45:10 | *func | provenance | |
|
||||||
| test.cpp:74:24:74:30 | medical | test.cpp:78:24:78:27 | temp |
|
| test.cpp:74:24:74:30 | medical | test.cpp:78:24:78:27 | temp | provenance | |
|
||||||
| test.cpp:74:24:74:30 | medical | test.cpp:81:22:81:28 | medical |
|
| test.cpp:74:24:74:30 | medical | test.cpp:81:22:81:28 | medical | provenance | |
|
||||||
| test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp |
|
| test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp | provenance | |
|
||||||
| test.cpp:77:16:77:22 | medical | test.cpp:81:22:81:28 | medical |
|
| test.cpp:77:16:77:22 | medical | test.cpp:81:22:81:28 | medical | provenance | |
|
||||||
| test.cpp:81:17:81:20 | call to func | test.cpp:82:24:82:28 | buff5 |
|
| test.cpp:81:17:81:20 | call to func | test.cpp:82:24:82:28 | buff5 | provenance | |
|
||||||
| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer |
|
| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer | provenance | |
|
||||||
| test.cpp:81:22:81:28 | medical | test.cpp:81:17:81:20 | call to func |
|
| test.cpp:81:22:81:28 | medical | test.cpp:81:17:81:20 | call to func | provenance | |
|
||||||
| test.cpp:96:37:96:46 | theZipcode | test.cpp:99:42:99:51 | theZipcode |
|
| test.cpp:96:37:96:46 | theZipcode | test.cpp:99:42:99:51 | theZipcode | provenance | |
|
||||||
| test.cpp:99:61:99:70 | theZipcode | test.cpp:99:42:99:51 | theZipcode |
|
| test.cpp:99:61:99:70 | theZipcode | test.cpp:99:42:99:51 | theZipcode | provenance | |
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:45:7:45:10 | *func | semmle.label | *func |
|
| test.cpp:45:7:45:10 | *func | semmle.label | *func |
|
||||||
| test.cpp:45:18:45:23 | buffer | semmle.label | buffer |
|
| test.cpp:45:18:45:23 | buffer | semmle.label | buffer |
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ postWithInFlow
|
|||||||
| test.cpp:931:5:931:18 | global_pointer [post update] | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:931:5:931:18 | global_pointer [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| test.cpp:932:5:932:19 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:932:5:932:19 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| test.cpp:932:6:932:19 | global_pointer [inner post update] | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:932:6:932:19 | global_pointer [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
|
| test.cpp:1045:9:1045:11 | ref arg buf | PostUpdateNode should not be the target of local flow. |
|
||||||
viableImplInCallContextTooLarge
|
viableImplInCallContextTooLarge
|
||||||
uniqueParameterNodeAtPosition
|
uniqueParameterNodeAtPosition
|
||||||
uniqueParameterNodePosition
|
uniqueParameterNodePosition
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ postWithInFlow
|
|||||||
| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
||||||
| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
||||||
| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
|
||||||
|
| test.cpp:1045:9:1045:11 | memset output argument | PostUpdateNode should not be the target of local flow. |
|
||||||
viableImplInCallContextTooLarge
|
viableImplInCallContextTooLarge
|
||||||
uniqueParameterNodeAtPosition
|
uniqueParameterNodeAtPosition
|
||||||
uniqueParameterNodePosition
|
uniqueParameterNodePosition
|
||||||
|
|||||||
@@ -303,6 +303,13 @@ irFlow
|
|||||||
| test.cpp:914:46:914:53 | source | test.cpp:919:10:919:30 | global_pointer_static |
|
| test.cpp:914:46:914:53 | source | test.cpp:919:10:919:30 | global_pointer_static |
|
||||||
| test.cpp:915:57:915:76 | *indirect_source(1) | test.cpp:921:19:921:50 | *global_pointer_static_indirect_1 |
|
| test.cpp:915:57:915:76 | *indirect_source(1) | test.cpp:921:19:921:50 | *global_pointer_static_indirect_1 |
|
||||||
| test.cpp:932:23:932:28 | call to source | test.cpp:937:10:937:24 | * ... |
|
| test.cpp:932:23:932:28 | call to source | test.cpp:937:10:937:24 | * ... |
|
||||||
|
| test.cpp:958:18:958:32 | *call to indirect_source | test.cpp:961:19:961:28 | *translated |
|
||||||
|
| test.cpp:973:18:973:32 | *call to indirect_source | test.cpp:977:19:977:28 | *translated |
|
||||||
|
| test.cpp:994:18:994:32 | *call to indirect_source | test.cpp:999:19:999:28 | *translated |
|
||||||
|
| test.cpp:994:18:994:32 | *call to indirect_source | test.cpp:1003:19:1003:28 | *translated |
|
||||||
|
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1027:19:1027:28 | *translated |
|
||||||
|
| test.cpp:1021:18:1021:32 | *call to indirect_source | test.cpp:1031:19:1031:28 | *translated |
|
||||||
|
| test.cpp:1045:14:1045:19 | call to source | test.cpp:1046:7:1046:10 | * ... |
|
||||||
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
|
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
|
||||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||||
|
|||||||
@@ -937,3 +937,111 @@ namespace global_variable_conflation_test {
|
|||||||
sink(*global_pointer); // $ ir MISSING: ast
|
sink(*global_pointer); // $ ir MISSING: ast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* gettext(const char*);
|
||||||
|
char* dgettext(const char*, const char*);
|
||||||
|
char* ngettext(const char*, const char*, unsigned long int);
|
||||||
|
char* dngettext (const char*, const char *, const char *, unsigned long int);
|
||||||
|
|
||||||
|
namespace test_gettext {
|
||||||
|
char* source();
|
||||||
|
char* indirect_source();
|
||||||
|
|
||||||
|
void test_gettext() {
|
||||||
|
char* data = source();
|
||||||
|
char* translated = gettext(data);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // clean
|
||||||
|
}
|
||||||
|
|
||||||
|
void indirect_test_dgettext() {
|
||||||
|
char* data = indirect_source();
|
||||||
|
char* translated = gettext(data);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // $ ir MISSING: ast
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_dgettext() {
|
||||||
|
char* data = source();
|
||||||
|
char* domain = source(); // Should not trace from this source
|
||||||
|
char* translated = dgettext(domain, data);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // clean
|
||||||
|
}
|
||||||
|
|
||||||
|
void indirect_test_gettext() {
|
||||||
|
char* data = indirect_source();
|
||||||
|
char* domain = indirect_source(); // Should not trace from this source
|
||||||
|
char* translated = dgettext(domain, data);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // $ ir MISSING: ast
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_ngettext() {
|
||||||
|
char* data = source();
|
||||||
|
char* np = nullptr; // Don't coun't as a source
|
||||||
|
|
||||||
|
char* translated = ngettext(data, np, 0);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // clean
|
||||||
|
|
||||||
|
translated = ngettext(np, data, 0);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // clean
|
||||||
|
}
|
||||||
|
|
||||||
|
void indirect_test_ngettext() {
|
||||||
|
char* data = indirect_source();
|
||||||
|
char* np = nullptr; // Don't coun't as a source
|
||||||
|
|
||||||
|
char* translated = ngettext(data, np, 0);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // $ ir MISSING: ast
|
||||||
|
|
||||||
|
translated = ngettext(np, data, 0);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // $ ir MISSING: ast
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_dngettext() {
|
||||||
|
char* data = source();
|
||||||
|
char* np = nullptr; // Don't coun't as a source
|
||||||
|
char* domain = source(); // Should not trace from this source
|
||||||
|
|
||||||
|
char* translated = dngettext(domain, data, np, 0);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // clean
|
||||||
|
|
||||||
|
translated = dngettext(domain, np, data, 0);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // clean
|
||||||
|
}
|
||||||
|
|
||||||
|
void indirect_test_dngettext() {
|
||||||
|
char* data = indirect_source();
|
||||||
|
char* np = nullptr; // Don't coun't as a source
|
||||||
|
char* domain = indirect_source(); // Should not trace from this source
|
||||||
|
|
||||||
|
char* translated = dngettext(domain, data, np, 0);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // $ ir MISSING: ast
|
||||||
|
|
||||||
|
translated = dngettext(domain, np, data, 0);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // $ ir MISSING: ast
|
||||||
|
}
|
||||||
|
|
||||||
|
void indirect_test_gettext_no_flow_from_domain() {
|
||||||
|
char* domain = source(); // Should not trace from this source
|
||||||
|
char* translated = dgettext(domain, nullptr);
|
||||||
|
sink(translated); // clean
|
||||||
|
indirect_sink(translated); // clean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset(void*, int, size_t);
|
||||||
|
|
||||||
|
void memset_test(char* buf) { // $ ast-def=buf
|
||||||
|
memset(buf, source(), 10);
|
||||||
|
sink(*buf); // $ ir MISSING: ast
|
||||||
|
}
|
||||||
@@ -1,3 +1,18 @@
|
|||||||
astTypeBugs
|
astTypeBugs
|
||||||
irTypeBugs
|
irTypeBugs
|
||||||
|
incorrectBaseType
|
||||||
|
| clang.cpp:22:8:22:20 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
|
||||||
|
| clang.cpp:23:17:23:29 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
|
||||||
|
| flowOut.cpp:50:14:50:15 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
|
||||||
|
| flowOut.cpp:84:9:84:10 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
|
||||||
|
| flowOut.cpp:101:13:101:14 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
|
||||||
|
| self_parameter_flow.cpp:8:8:8:9 | *& ... | Expected 'Node.getType()' to be unsigned char, but it was unsigned char * |
|
||||||
|
| test.cpp:67:28:67:37 | (reference dereference) | Expected 'Node.getType()' to be const int, but it was int * |
|
||||||
|
| test.cpp:531:39:531:40 | *& ... | Expected 'Node.getType()' to be int, but it was const int * |
|
||||||
|
| test.cpp:615:13:615:21 | *& ... | Expected 'Node.getType()' to be int, but it was void |
|
||||||
|
| test.cpp:704:22:704:25 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
|
||||||
|
| test.cpp:715:24:715:25 | *& ... | Expected 'Node.getType()' to be unsigned char, but it was unsigned char * |
|
||||||
|
| test.cpp:848:23:848:25 | (reference dereference) | Expected 'Node.getType()' to be int, but it was int * |
|
||||||
|
| test.cpp:854:10:854:36 | * ... | Expected 'Node.getType()' to be const int, but it was int |
|
||||||
|
| test.cpp:867:10:867:30 | * ... | Expected 'Node.getType()' to be const int, but it was int |
|
||||||
failures
|
failures
|
||||||
|
|||||||
@@ -25,6 +25,17 @@ module IrTest {
|
|||||||
n != 1
|
n != 1
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query predicate incorrectBaseType(Node n, string msg) {
|
||||||
|
exists(PointerType pointerType, Type nodeType, Type baseType |
|
||||||
|
not n.isGLValue() and
|
||||||
|
pointerType = n.asIndirectExpr(1).getActualType() and
|
||||||
|
baseType = pointerType.getBaseType() and
|
||||||
|
nodeType = n.getType() and
|
||||||
|
nodeType != baseType and
|
||||||
|
msg = "Expected 'Node.getType()' to be " + baseType + ", but it was " + nodeType
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import IrTest
|
import IrTest
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
|
|||||||
memoryOperandDefinitionIsUnmodeled
|
memoryOperandDefinitionIsUnmodeled
|
||||||
operandAcrossFunctions
|
operandAcrossFunctions
|
||||||
instructionWithoutUniqueBlock
|
instructionWithoutUniqueBlock
|
||||||
|
missingCanonicalLanguageType
|
||||||
|
multipleCanonicalLanguageTypes
|
||||||
containsLoopOfForwardEdges
|
containsLoopOfForwardEdges
|
||||||
|
missingIRType
|
||||||
|
multipleIRTypes
|
||||||
lostReachability
|
lostReachability
|
||||||
backEdgeCountMismatch
|
backEdgeCountMismatch
|
||||||
useNotDominatedByDefinition
|
useNotDominatedByDefinition
|
||||||
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
|
|||||||
fieldAddressOnNonPointer
|
fieldAddressOnNonPointer
|
||||||
thisArgumentIsNonPointer
|
thisArgumentIsNonPointer
|
||||||
nonUniqueIRVariable
|
nonUniqueIRVariable
|
||||||
missingCanonicalLanguageType
|
|
||||||
multipleCanonicalLanguageTypes
|
|
||||||
missingIRType
|
|
||||||
multipleIRTypes
|
|
||||||
missingCppType
|
missingCppType
|
||||||
|
|||||||
@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
|
|||||||
memoryOperandDefinitionIsUnmodeled
|
memoryOperandDefinitionIsUnmodeled
|
||||||
operandAcrossFunctions
|
operandAcrossFunctions
|
||||||
instructionWithoutUniqueBlock
|
instructionWithoutUniqueBlock
|
||||||
|
missingCanonicalLanguageType
|
||||||
|
multipleCanonicalLanguageTypes
|
||||||
containsLoopOfForwardEdges
|
containsLoopOfForwardEdges
|
||||||
|
missingIRType
|
||||||
|
multipleIRTypes
|
||||||
lostReachability
|
lostReachability
|
||||||
backEdgeCountMismatch
|
backEdgeCountMismatch
|
||||||
useNotDominatedByDefinition
|
useNotDominatedByDefinition
|
||||||
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
|
|||||||
fieldAddressOnNonPointer
|
fieldAddressOnNonPointer
|
||||||
thisArgumentIsNonPointer
|
thisArgumentIsNonPointer
|
||||||
nonUniqueIRVariable
|
nonUniqueIRVariable
|
||||||
missingCanonicalLanguageType
|
|
||||||
multipleCanonicalLanguageTypes
|
|
||||||
missingIRType
|
|
||||||
multipleIRTypes
|
|
||||||
missingCppType
|
missingCppType
|
||||||
|
|||||||
@@ -1065,6 +1065,8 @@ struct vector {
|
|||||||
bool operator!=(iterator right) const;
|
bool operator!=(iterator right) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vector(T);
|
||||||
|
~vector();
|
||||||
iterator begin() const;
|
iterator begin() const;
|
||||||
iterator end() const;
|
iterator end() const;
|
||||||
};
|
};
|
||||||
@@ -2112,4 +2114,56 @@ char* test_strtod(char *s) {
|
|||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// semmle-extractor-options: -std=c++17 --clang
|
struct HasOperatorBool {
|
||||||
|
operator bool();
|
||||||
|
};
|
||||||
|
|
||||||
|
void call_as_child_of_ConditionDeclExpr() {
|
||||||
|
if(HasOperatorBool b = HasOperatorBool()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassWithDestructor {
|
||||||
|
char *x;
|
||||||
|
public:
|
||||||
|
ClassWithDestructor() { x = new char; }
|
||||||
|
~ClassWithDestructor() { delete x; }
|
||||||
|
|
||||||
|
void set_x(char y) { *x = y; }
|
||||||
|
char get_x() { return *x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr bool initialization_with_destructor_bool = true;
|
||||||
|
|
||||||
|
void initialization_with_destructor(bool b, char c) {
|
||||||
|
if (ClassWithDestructor x; b)
|
||||||
|
x.set_x('a');
|
||||||
|
|
||||||
|
if constexpr (ClassWithDestructor x; initialization_with_destructor_bool)
|
||||||
|
x.set_x('a');
|
||||||
|
|
||||||
|
switch(ClassWithDestructor x; c) {
|
||||||
|
case 'a':
|
||||||
|
x.set_x('a');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
x.set_x('b');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassWithDestructor x;
|
||||||
|
for(vector<ClassWithDestructor> ys(x); ClassWithDestructor y : ys)
|
||||||
|
y.set_x('a');
|
||||||
|
|
||||||
|
for(vector<ClassWithDestructor> ys(x); ClassWithDestructor y : ys) {
|
||||||
|
y.set_x('a');
|
||||||
|
if (y.get_x() == 'b')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(vector<int> ys(1); int y : ys) {
|
||||||
|
if (y == 1)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// semmle-extractor-options: -std=c++20 --clang
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ multipleIRTypes
|
|||||||
lostReachability
|
lostReachability
|
||||||
backEdgeCountMismatch
|
backEdgeCountMismatch
|
||||||
useNotDominatedByDefinition
|
useNotDominatedByDefinition
|
||||||
| ir.cpp:1486:8:1486:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1486:8:1486:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() |
|
| ir.cpp:1488:8:1488:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1488:8:1488:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() |
|
||||||
| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() |
|
| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() |
|
||||||
| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() |
|
| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() |
|
||||||
| try_except.c:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:32:6:32:6 | void h(int) | void h(int) |
|
| try_except.c:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:32:6:32:6 | void h(int) | void h(int) |
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
|
|||||||
memoryOperandDefinitionIsUnmodeled
|
memoryOperandDefinitionIsUnmodeled
|
||||||
operandAcrossFunctions
|
operandAcrossFunctions
|
||||||
instructionWithoutUniqueBlock
|
instructionWithoutUniqueBlock
|
||||||
|
missingCanonicalLanguageType
|
||||||
|
multipleCanonicalLanguageTypes
|
||||||
containsLoopOfForwardEdges
|
containsLoopOfForwardEdges
|
||||||
|
missingIRType
|
||||||
|
multipleIRTypes
|
||||||
lostReachability
|
lostReachability
|
||||||
backEdgeCountMismatch
|
backEdgeCountMismatch
|
||||||
useNotDominatedByDefinition
|
useNotDominatedByDefinition
|
||||||
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
|
|||||||
fieldAddressOnNonPointer
|
fieldAddressOnNonPointer
|
||||||
thisArgumentIsNonPointer
|
thisArgumentIsNonPointer
|
||||||
nonUniqueIRVariable
|
nonUniqueIRVariable
|
||||||
missingCanonicalLanguageType
|
|
||||||
multipleCanonicalLanguageTypes
|
|
||||||
missingIRType
|
|
||||||
multipleIRTypes
|
|
||||||
missingCppType
|
missingCppType
|
||||||
|
|||||||
@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
|
|||||||
memoryOperandDefinitionIsUnmodeled
|
memoryOperandDefinitionIsUnmodeled
|
||||||
operandAcrossFunctions
|
operandAcrossFunctions
|
||||||
instructionWithoutUniqueBlock
|
instructionWithoutUniqueBlock
|
||||||
|
missingCanonicalLanguageType
|
||||||
|
multipleCanonicalLanguageTypes
|
||||||
containsLoopOfForwardEdges
|
containsLoopOfForwardEdges
|
||||||
|
missingIRType
|
||||||
|
multipleIRTypes
|
||||||
lostReachability
|
lostReachability
|
||||||
backEdgeCountMismatch
|
backEdgeCountMismatch
|
||||||
useNotDominatedByDefinition
|
useNotDominatedByDefinition
|
||||||
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
|
|||||||
fieldAddressOnNonPointer
|
fieldAddressOnNonPointer
|
||||||
thisArgumentIsNonPointer
|
thisArgumentIsNonPointer
|
||||||
nonUniqueIRVariable
|
nonUniqueIRVariable
|
||||||
missingCanonicalLanguageType
|
|
||||||
multipleCanonicalLanguageTypes
|
|
||||||
missingIRType
|
|
||||||
multipleIRTypes
|
|
||||||
missingCppType
|
missingCppType
|
||||||
|
|||||||
@@ -8,10 +8,6 @@ duplicateChiOperand
|
|||||||
sideEffectWithoutPrimary
|
sideEffectWithoutPrimary
|
||||||
instructionWithoutSuccessor
|
instructionWithoutSuccessor
|
||||||
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||||
| condition_decls.cpp:16:19:16:20 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:26:23:26:24 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:41:22:41:23 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:48:52:48:53 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
|
|
||||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||||
@@ -21,7 +17,11 @@ unnecessaryPhiInstruction
|
|||||||
memoryOperandDefinitionIsUnmodeled
|
memoryOperandDefinitionIsUnmodeled
|
||||||
operandAcrossFunctions
|
operandAcrossFunctions
|
||||||
instructionWithoutUniqueBlock
|
instructionWithoutUniqueBlock
|
||||||
|
missingCanonicalLanguageType
|
||||||
|
multipleCanonicalLanguageTypes
|
||||||
containsLoopOfForwardEdges
|
containsLoopOfForwardEdges
|
||||||
|
missingIRType
|
||||||
|
multipleIRTypes
|
||||||
lostReachability
|
lostReachability
|
||||||
backEdgeCountMismatch
|
backEdgeCountMismatch
|
||||||
useNotDominatedByDefinition
|
useNotDominatedByDefinition
|
||||||
@@ -36,8 +36,4 @@ thisArgumentIsNonPointer
|
|||||||
| pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
|
| pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
|
||||||
| pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
|
| pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
|
||||||
nonUniqueIRVariable
|
nonUniqueIRVariable
|
||||||
missingCanonicalLanguageType
|
|
||||||
multipleCanonicalLanguageTypes
|
|
||||||
missingIRType
|
|
||||||
multipleIRTypes
|
|
||||||
missingCppType
|
missingCppType
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
missingOperand
|
missingOperand
|
||||||
| condition_decls.cpp:16:6:16:20 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:26:10:26:24 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:41:9:41:23 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:48:39:48:53 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
|
|
||||||
| misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | void misc3() | void misc3() |
|
| misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | void misc3() | void misc3() |
|
||||||
| try_catch.cpp:23:5:23:18 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) |
|
| try_catch.cpp:23:5:23:18 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) |
|
||||||
unexpectedOperand
|
unexpectedOperand
|
||||||
@@ -15,14 +11,6 @@ instructionWithoutSuccessor
|
|||||||
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||||
| VacuousDestructorCall.cpp:3:3:3:3 | VariableAddress: x | Instruction 'VariableAddress: x' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
| VacuousDestructorCall.cpp:3:3:3:3 | VariableAddress: x | Instruction 'VariableAddress: x' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||||
| VacuousDestructorCall.cpp:4:3:4:3 | Load: y | Instruction 'Load: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
| VacuousDestructorCall.cpp:4:3:4:3 | Load: y | Instruction 'Load: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||||
| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:26:19:26:20 | IndirectMayWriteSideEffect: bi | Instruction 'IndirectMayWriteSideEffect: bi' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
|
|
||||||
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
|
|
||||||
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
|
|
||||||
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
|
|
||||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||||
|
|||||||
@@ -8,10 +8,6 @@ duplicateChiOperand
|
|||||||
sideEffectWithoutPrimary
|
sideEffectWithoutPrimary
|
||||||
instructionWithoutSuccessor
|
instructionWithoutSuccessor
|
||||||
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||||
| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
|
|
||||||
| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
|
|
||||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||||
@@ -21,7 +17,11 @@ unnecessaryPhiInstruction
|
|||||||
memoryOperandDefinitionIsUnmodeled
|
memoryOperandDefinitionIsUnmodeled
|
||||||
operandAcrossFunctions
|
operandAcrossFunctions
|
||||||
instructionWithoutUniqueBlock
|
instructionWithoutUniqueBlock
|
||||||
|
missingCanonicalLanguageType
|
||||||
|
multipleCanonicalLanguageTypes
|
||||||
containsLoopOfForwardEdges
|
containsLoopOfForwardEdges
|
||||||
|
missingIRType
|
||||||
|
multipleIRTypes
|
||||||
lostReachability
|
lostReachability
|
||||||
backEdgeCountMismatch
|
backEdgeCountMismatch
|
||||||
useNotDominatedByDefinition
|
useNotDominatedByDefinition
|
||||||
@@ -36,8 +36,4 @@ thisArgumentIsNonPointer
|
|||||||
| pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
|
| pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
|
||||||
| pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
|
| pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
|
||||||
nonUniqueIRVariable
|
nonUniqueIRVariable
|
||||||
missingCanonicalLanguageType
|
|
||||||
multipleCanonicalLanguageTypes
|
|
||||||
missingIRType
|
|
||||||
multipleIRTypes
|
|
||||||
missingCppType
|
missingCppType
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user