mirror of
https://github.com/github/codeql.git
synced 2026-05-26 09:01:22 +02:00
Compare commits
17 Commits
hackathon/
...
sidshank/t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de9e11ca6f | ||
|
|
92b20c212f | ||
|
|
5447b65d88 | ||
|
|
839469ba5a | ||
|
|
385123cba1 | ||
|
|
9a3d129d48 | ||
|
|
1ee6df188f | ||
|
|
11658ad000 | ||
|
|
ac90ad01d0 | ||
|
|
1f2def0efa | ||
|
|
67880a2798 | ||
|
|
2f0958e59d | ||
|
|
35b73c6a48 | ||
|
|
18ee392fa1 | ||
|
|
3fd06b02b6 | ||
|
|
4c29ea9cf6 | ||
|
|
f19681fa12 |
1
.bazelrc
1
.bazelrc
@@ -1,4 +1,5 @@
|
||||
common --enable_platform_specific_config
|
||||
common --enable_bzlmod
|
||||
# because we use --override_module with `%workspace%`, the lock file is not stable
|
||||
common --lockfile_mode=off
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.0.0rc1
|
||||
5f5d70b6c4d2fb1a889479569107f1692239e8a7
|
||||
|
||||
2
.github/codeql/codeql-config.yml
vendored
2
.github/codeql/codeql-config.yml
vendored
@@ -9,5 +9,3 @@ paths-ignore:
|
||||
- '/python/'
|
||||
- '/javascript/ql/test'
|
||||
- '/javascript/extractor/tests'
|
||||
- '/rust/ql/test'
|
||||
- '/rust/ql/integration-tests'
|
||||
|
||||
8
.github/labeler.yml
vendored
8
.github/labeler.yml
vendored
@@ -30,18 +30,10 @@ Ruby:
|
||||
- ruby/**/*
|
||||
- change-notes/**/*ruby*
|
||||
|
||||
Rust:
|
||||
- rust/**/*
|
||||
- change-notes/**/*rust*
|
||||
|
||||
Swift:
|
||||
- swift/**/*
|
||||
- change-notes/**/*swift*
|
||||
|
||||
Actions:
|
||||
- actions/**/*
|
||||
- change-notes/**/*actions*
|
||||
|
||||
documentation:
|
||||
- "**/*.qhelp"
|
||||
- "**/*.md"
|
||||
|
||||
1
.github/pull_request_template.md
vendored
1
.github/pull_request_template.md
vendored
@@ -11,4 +11,3 @@
|
||||
|
||||
- [ ] Autofixes generated based on these changes are valid, only needed if this PR makes significant changes to `.ql`, `.qll`, or `.qhelp` files. See [the documentation](https://github.com/github/codeql-team/blob/main/docs/best-practices/validating-autofix-for-query-changes.md) (internal access required).
|
||||
- [ ] Changes are validated [at scale](https://github.com/github/codeql-dca/) (internal access required).
|
||||
- [ ] Adding a new query? Consider also [adding the query to autofix](https://github.com/github/codeml-autofix/blob/main/docs/updating-query-support.md#adding-a-new-query-to-the-query-suite).
|
||||
|
||||
2
.github/workflows/build-ripunzip.yml
vendored
2
.github/workflows/build-ripunzip.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-13, windows-2019]
|
||||
os: [ubuntu-20.04, macos-12, windows-2019]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
5
.github/workflows/check-change-note.yml
vendored
5
.github/workflows/check-change-note.yml
vendored
@@ -16,12 +16,11 @@ on:
|
||||
- "shared/**/*.qll"
|
||||
- "!**/experimental/**"
|
||||
- "!ql/**"
|
||||
- "!rust/**"
|
||||
- ".github/workflows/check-change-note.yml"
|
||||
|
||||
jobs:
|
||||
check-change-note:
|
||||
env:
|
||||
env:
|
||||
REPO: ${{ github.repository }}
|
||||
PULL_REQUEST_NUMBER: ${{ github.event.number }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -34,7 +33,7 @@ jobs:
|
||||
!contains(github.event.pull_request.labels.*.name, 'no-change-note-required')
|
||||
run: |
|
||||
change_note_files=$(gh api "repos/$REPO/pulls/$PULL_REQUEST_NUMBER/files" --paginate --jq '.[].filename | select(test("/change-notes/.*[.]md$"))')
|
||||
|
||||
|
||||
if [ -z "$change_note_files" ]; then
|
||||
echo "No change note found. Either add one, or add the 'no-change-note-required' label."
|
||||
exit 1
|
||||
|
||||
4
.github/workflows/csv-coverage-metrics.yml
vendored
4
.github/workflows/csv-coverage-metrics.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
run: |
|
||||
DATABASE="${{ runner.temp }}/java-database"
|
||||
codeql database analyze --format=sarif-latest --output=metrics-java.sarif -- "$DATABASE" ./java/ql/src/Metrics/Summaries/FrameworkCoverage.ql
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: metrics-java.sarif
|
||||
path: metrics-java.sarif
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
run: |
|
||||
DATABASE="${{ runner.temp }}/csharp-database"
|
||||
codeql database analyze --format=sarif-latest --output=metrics-csharp.sarif -- "$DATABASE" ./csharp/ql/src/Metrics/Summaries/FrameworkCoverage.ql
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: metrics-csharp.sarif
|
||||
path: metrics-csharp.sarif
|
||||
|
||||
10
.github/workflows/csv-coverage-pr-artifacts.yml
vendored
10
.github/workflows/csv-coverage-pr-artifacts.yml
vendored
@@ -71,21 +71,21 @@ jobs:
|
||||
run: |
|
||||
python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md
|
||||
- name: Upload CSV package list
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: csv-framework-coverage-merge
|
||||
path: |
|
||||
out_merge/framework-coverage-*.csv
|
||||
out_merge/framework-coverage-*.rst
|
||||
- name: Upload CSV package list
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: csv-framework-coverage-base
|
||||
path: |
|
||||
out_base/framework-coverage-*.csv
|
||||
out_base/framework-coverage-*.rst
|
||||
- name: Upload comparison results
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: comparison
|
||||
path: |
|
||||
@@ -97,7 +97,7 @@ jobs:
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
- name: Upload PR number
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: pr
|
||||
path: pr/
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
- name: Upload comment ID (if it exists)
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: comment
|
||||
path: comment/
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
run: |
|
||||
python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels
|
||||
- name: Upload timeseries CSV
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: framework-coverage-timeseries
|
||||
path: framework-coverage-timeseries-*.csv
|
||||
|
||||
4
.github/workflows/csv-coverage.yml
vendored
4
.github/workflows/csv-coverage.yml
vendored
@@ -34,12 +34,12 @@ jobs:
|
||||
run: |
|
||||
python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script
|
||||
- name: Upload CSV package list
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: framework-coverage-csv
|
||||
path: framework-coverage-*.csv
|
||||
- name: Upload RST package list
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: framework-coverage-rst
|
||||
path: framework-coverage-*.rst
|
||||
|
||||
2
.github/workflows/go-tests.yml
vendored
2
.github/workflows/go-tests.yml
vendored
@@ -3,7 +3,6 @@ on:
|
||||
push:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
@@ -13,7 +12,6 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
|
||||
16
.github/workflows/mad_modelDiff.yml
vendored
16
.github/workflows/mad_modelDiff.yml
vendored
@@ -38,20 +38,14 @@ jobs:
|
||||
path: codeql-main
|
||||
ref: main
|
||||
- uses: ./codeql-main/.github/actions/fetch-codeql
|
||||
# compute the shortname of the project that does not contain any special (disk) characters
|
||||
- run: |
|
||||
echo "SHORTNAME=${SLUG//[^a-zA-Z0-9_]/}" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
SLUG: ${{ matrix.slug }}
|
||||
id: shortname
|
||||
- name: Download database
|
||||
env:
|
||||
SLUG: ${{ matrix.slug }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
SHORTNAME: ${{ steps.shortname.outputs.SHORTNAME }}
|
||||
run: |
|
||||
set -x
|
||||
mkdir lib-dbs
|
||||
SHORTNAME=${SLUG//[^a-zA-Z0-9_]/}
|
||||
gh api -H "Accept: application/zip" "/repos/${SLUG}/code-scanning/codeql/databases/java" > "$SHORTNAME.zip"
|
||||
unzip -q -d "${SHORTNAME}-db" "${SHORTNAME}.zip"
|
||||
mkdir "lib-dbs/$SHORTNAME/"
|
||||
@@ -99,14 +93,14 @@ jobs:
|
||||
name="diff_${basename/.model.yml/""}"
|
||||
(diff -w -u $m $t | diff2html -i stdin -F $MODELS/$name.html) || true
|
||||
done
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: models-${{ steps.shortname.outputs.SHORTNAME }}
|
||||
name: models
|
||||
path: tmp-models/**/**/*.model.yml
|
||||
retention-days: 20
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: diffs-${{ steps.shortname.outputs.SHORTNAME }}
|
||||
name: diffs
|
||||
path: tmp-models/*.html
|
||||
# An html file is only produced if the generated models differ.
|
||||
if-no-files-found: ignore
|
||||
|
||||
2
.github/workflows/mad_regenerate-models.yml
vendored
2
.github/workflows/mad_regenerate-models.yml
vendored
@@ -59,7 +59,7 @@ jobs:
|
||||
find java -name "*.model.yml" -print0 | xargs -0 git add
|
||||
git status
|
||||
git diff --cached > models.patch
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: patch
|
||||
path: models.patch
|
||||
|
||||
7
.github/workflows/post-pr-comment.yml
vendored
7
.github/workflows/post-pr-comment.yml
vendored
@@ -17,11 +17,8 @@ jobs:
|
||||
post_comment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
run: |
|
||||
gh run download "${WORKFLOW_RUN_ID}" --repo "${GITHUB_REPOSITORY}" --name "comment-pr-number"
|
||||
gh run download "${WORKFLOW_RUN_ID}" --repo "${GITHUB_REPOSITORY}" --name "comment-body"
|
||||
gh run download "${WORKFLOW_RUN_ID}" --repo "${GITHUB_REPOSITORY}" --name "comment-id"
|
||||
- name: Download artifact
|
||||
run: gh run download "${WORKFLOW_RUN_ID}" --repo "${GITHUB_REPOSITORY}" --name "comment"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
|
||||
12
.github/workflows/qhelp-pr-preview.yml
vendored
12
.github/workflows/qhelp-pr-preview.yml
vendored
@@ -36,9 +36,9 @@ jobs:
|
||||
- run: echo "${PR_NUMBER}" > pr_number.txt
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.number }}
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: comment-pr-number
|
||||
name: comment
|
||||
path: pr_number.txt
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
@@ -78,9 +78,9 @@ jobs:
|
||||
exit "${EXIT_CODE}"
|
||||
|
||||
- if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: comment-body
|
||||
name: comment
|
||||
path: comment_body.txt
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
@@ -94,9 +94,9 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
PR_NUMBER: ${{ github.event.number }}
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: comment-id
|
||||
name: comment
|
||||
path: comment_id.txt
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
4
.github/workflows/ql-for-ql-build.yml
vendored
4
.github/workflows/ql-for-ql-build.yml
vendored
@@ -75,7 +75,7 @@ jobs:
|
||||
sarif_file: ql-for-ql.sarif
|
||||
category: ql-for-ql
|
||||
- name: Sarif as artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ql-for-ql.sarif
|
||||
path: ql-for-ql.sarif
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
mkdir split-sarif
|
||||
node ./ql/scripts/split-sarif.js ql-for-ql.sarif split-sarif
|
||||
- name: Upload langs as artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ql-for-ql-langs
|
||||
path: split-sarif
|
||||
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
"${CODEQL}" dataset measure --threads 4 --output "stats/${{ matrix.repo }}/stats.xml" "${{ runner.temp }}/database/db-ql"
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: measurements
|
||||
path: stats
|
||||
@@ -76,14 +76,14 @@ jobs:
|
||||
needs: measure
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: measurements
|
||||
path: stats
|
||||
- run: |
|
||||
python -m pip install --user lxml
|
||||
find stats -name 'stats.xml' -print0 | sort -z | xargs -0 python ruby/scripts/merge_stats.py --output ql/ql/src/ql.dbscheme.stats --normalise ql_tokeninfo
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ql.dbscheme.stats
|
||||
path: ql/ql/src/ql.dbscheme.stats
|
||||
|
||||
2
.github/workflows/query-list.yml
vendored
2
.github/workflows/query-list.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
run: |
|
||||
python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv
|
||||
- name: Upload code scanning query list
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: code-scanning-query-list
|
||||
path: code-scanning-query-list.csv
|
||||
|
||||
36
.github/workflows/ruby-build.yml
vendored
36
.github/workflows/ruby-build.yml
vendored
@@ -65,8 +65,8 @@ jobs:
|
||||
id: cache-extractor
|
||||
with:
|
||||
path: |
|
||||
target/release/codeql-extractor-ruby
|
||||
target/release/codeql-extractor-ruby.exe
|
||||
ruby/extractor/target/release/codeql-extractor-ruby
|
||||
ruby/extractor/target/release/codeql-extractor-ruby.exe
|
||||
ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
|
||||
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ruby/extractor/**/*.rs') }}
|
||||
- uses: actions/cache@v3
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
ruby/target
|
||||
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-rust-cargo-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/**/Cargo.lock') }}
|
||||
- name: Check formatting
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
@@ -91,23 +91,23 @@ jobs:
|
||||
run: cd extractor && cargo build --release
|
||||
- name: Generate dbscheme
|
||||
if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}}
|
||||
run: ../target/release/codeql-extractor-ruby generate --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
|
||||
- uses: actions/upload-artifact@v4
|
||||
run: extractor/target/release/codeql-extractor-ruby generate --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
with:
|
||||
name: ruby.dbscheme
|
||||
path: ruby/ql/lib/ruby.dbscheme
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
with:
|
||||
name: TreeSitter.qll
|
||||
path: ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: extractor-${{ matrix.os }}
|
||||
path: |
|
||||
target/release/codeql-extractor-ruby
|
||||
target/release/codeql-extractor-ruby.exe
|
||||
ruby/extractor/target/release/codeql-extractor-ruby
|
||||
ruby/extractor/target/release/codeql-extractor-ruby.exe
|
||||
retention-days: 1
|
||||
compile-queries:
|
||||
if: github.repository_owner == 'github'
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
PACK_FOLDER=$(readlink -f "$PACKS"/codeql/ruby-queries/*)
|
||||
codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
|
||||
(cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;)
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: codeql-ruby-queries
|
||||
path: |
|
||||
@@ -147,19 +147,19 @@ jobs:
|
||||
needs: [build, compile-queries]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ruby.dbscheme
|
||||
path: ruby/ruby
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: extractor-ubuntu-latest
|
||||
path: ruby/linux64
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: extractor-windows-latest
|
||||
path: ruby/win64
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: extractor-macos-latest
|
||||
path: ruby/osx64
|
||||
@@ -172,13 +172,13 @@ jobs:
|
||||
cp win64/codeql-extractor-ruby.exe ruby/tools/win64/extractor.exe
|
||||
chmod +x ruby/tools/{linux64,osx64}/extractor
|
||||
zip -rq codeql-ruby.zip ruby
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: codeql-ruby-pack
|
||||
path: ruby/codeql-ruby.zip
|
||||
retention-days: 1
|
||||
include-hidden-files: true
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: codeql-ruby-queries
|
||||
path: ruby/qlpacks
|
||||
@@ -190,7 +190,7 @@ jobs:
|
||||
]
|
||||
}' > .codeqlmanifest.json
|
||||
zip -rq codeql-ruby-bundle.zip .codeqlmanifest.json ruby qlpacks
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: codeql-ruby-bundle
|
||||
path: ruby/codeql-ruby-bundle.zip
|
||||
@@ -214,7 +214,7 @@ jobs:
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
|
||||
- name: Download Ruby bundle
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: codeql-ruby-bundle
|
||||
path: ${{ runner.temp }}
|
||||
|
||||
9
.github/workflows/ruby-dataset-measure.yml
vendored
9
.github/workflows/ruby-dataset-measure.yml
vendored
@@ -52,9 +52,9 @@ jobs:
|
||||
run: |
|
||||
mkdir -p "stats/${{ matrix.repo }}"
|
||||
codeql dataset measure --threads 4 --output "stats/${{ matrix.repo }}/stats.xml" "${{ runner.temp }}/database/db-ruby"
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: measurements-${{ hashFiles('stats/**') }}
|
||||
name: measurements
|
||||
path: stats
|
||||
retention-days: 1
|
||||
|
||||
@@ -63,13 +63,14 @@ jobs:
|
||||
needs: measure
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: measurements
|
||||
path: stats
|
||||
- run: |
|
||||
python -m pip install --user lxml
|
||||
find stats -name 'stats.xml' | sort | xargs python ruby/scripts/merge_stats.py --output ruby/ql/lib/ruby.dbscheme.stats --normalise ruby_tokeninfo
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ruby.dbscheme.stats
|
||||
path: ruby/ql/lib/ruby.dbscheme.stats
|
||||
|
||||
64
.github/workflows/rust-analysis.yml
vendored
64
.github/workflows/rust-analysis.yml
vendored
@@ -1,64 +0,0 @@
|
||||
name: "Code scanning - Rust"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- 'rc/*'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- 'rc/*'
|
||||
paths:
|
||||
- '**/*.rs'
|
||||
- '**/Cargo.toml'
|
||||
- '.github/codeql/codeql-config.yml'
|
||||
- '.github/workflows/rust-analysis.yml'
|
||||
schedule:
|
||||
- cron: '0 9 * * 1'
|
||||
|
||||
env:
|
||||
CODEQL_ENABLE_EXPERIMENTAL_FEATURES: "true"
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
strategy:
|
||||
matrix:
|
||||
language: [ 'rust' ]
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
pull-requests: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Query latest nightly CodeQL bundle
|
||||
shell: bash
|
||||
id: codeql
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
REPO=dsp-testing/codeql-cli-nightlies
|
||||
TAG=$(
|
||||
gh release list -R $REPO -L1 --exclude-drafts --json tagName -q ".[] | .tagName"
|
||||
)
|
||||
echo "nightly_bundle=https://github.com/$REPO/releases/download/$TAG/codeql-bundle-linux64.tar.zst" \
|
||||
| tee -a "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@main
|
||||
with:
|
||||
tools: ${{ steps.codeql.outputs.nightly_bundle }}
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@main
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@main
|
||||
58
.github/workflows/rust.yml
vendored
58
.github/workflows/rust.yml
vendored
@@ -1,58 +0,0 @@
|
||||
name: "Rust"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "rust/**"
|
||||
- "misc/bazel/**"
|
||||
- "misc/codegen/**"
|
||||
- "shared/**"
|
||||
- "MODULE.bazel"
|
||||
- .github/workflows/rust.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
- "!**/*.md"
|
||||
- "!**/*.qhelp"
|
||||
branches:
|
||||
- rust-experiment
|
||||
- main
|
||||
- rc/*
|
||||
- codeql-cli-*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
rust-code:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Format
|
||||
working-directory: rust/extractor
|
||||
shell: bash
|
||||
run: |
|
||||
cargo fmt --check
|
||||
- name: Compilation
|
||||
working-directory: rust/extractor
|
||||
shell: bash
|
||||
run: cargo check
|
||||
- name: Clippy
|
||||
working-directory: rust/extractor
|
||||
shell: bash
|
||||
run: |
|
||||
cargo clippy --fix
|
||||
git diff --exit-code
|
||||
rust-codegen:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install CodeQL
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
- name: Code generation
|
||||
shell: bash
|
||||
run: |
|
||||
bazel run //rust/codegen
|
||||
git add .
|
||||
git diff --exit-code HEAD
|
||||
6
.github/workflows/swift.yml
vendored
6
.github/workflows/swift.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
# without waiting for the macOS build
|
||||
build-and-test-macos:
|
||||
if: github.repository_owner == 'github'
|
||||
runs-on: macos-13-xlarge
|
||||
runs-on: macos-12-xl
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./swift/actions/build-and-test
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
qltests-macos:
|
||||
if: ${{ github.repository_owner == 'github' && github.event_name == 'pull_request' }}
|
||||
needs: build-and-test-macos
|
||||
runs-on: macos-13-xlarge
|
||||
runs-on: macos-12-xl
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./swift/actions/run-ql-tests
|
||||
@@ -98,7 +98,7 @@ jobs:
|
||||
- name: Generate C++ files
|
||||
run: |
|
||||
bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/generated-cpp-files
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: swift-generated-cpp-files
|
||||
path: generated-cpp-files/**
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -65,9 +65,3 @@ node_modules/
|
||||
|
||||
# bazel-built in-tree extractor packs
|
||||
/*/extractor-pack
|
||||
|
||||
# Jetbrains IDE files
|
||||
.idea
|
||||
|
||||
# cargo build directory
|
||||
/target
|
||||
|
||||
@@ -5,9 +5,9 @@ repos:
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
|
||||
exclude: /test/.*$(?<!\.ql)(?<!\.qll)(?<!\.qlref)|.*\.patch
|
||||
- id: end-of-file-fixer
|
||||
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
|
||||
exclude: /test/.*$(?<!\.ql)(?<!\.qll)(?<!\.qlref)|.*\.patch
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v17.0.6
|
||||
@@ -15,7 +15,7 @@ repos:
|
||||
- id: clang-format
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-autopep8
|
||||
rev: v2.0.4
|
||||
rev: v1.6.0
|
||||
hooks:
|
||||
- id: autopep8
|
||||
files: ^misc/codegen/.*\.py
|
||||
@@ -45,7 +45,7 @@ repos:
|
||||
|
||||
- id: sync-files
|
||||
name: Fix files required to be identical
|
||||
files: \.(qll?|qhelp|swift|toml)$|^config/identical-files\.json$
|
||||
files: \.(qll?|qhelp|swift)$|^config/identical-files\.json$
|
||||
language: system
|
||||
entry: python3 config/sync-files.py --latest
|
||||
pass_filenames: false
|
||||
@@ -58,7 +58,7 @@ repos:
|
||||
|
||||
- id: swift-codegen
|
||||
name: Run Swift checked in code generation
|
||||
files: ^misc/codegen/|^swift/(schema.py$|codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)|ql/\.generated.list)
|
||||
files: ^swift/(schema.py$|codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)|ql/\.generated.list)
|
||||
language: system
|
||||
entry: bazel run //swift/codegen -- --quiet
|
||||
pass_filenames: false
|
||||
@@ -69,17 +69,3 @@ repos:
|
||||
language: system
|
||||
entry: bazel test //misc/codegen/test
|
||||
pass_filenames: false
|
||||
|
||||
- id: rust-codegen
|
||||
name: Run Rust checked in code generation
|
||||
files: ^misc/codegen/|^rust/(schema.py$|codegen/|.*/generated/|ql/lib/(rust\.dbscheme$|codeql/rust/elements)|\.generated.list)
|
||||
language: system
|
||||
entry: bazel run //rust/codegen -- --quiet
|
||||
pass_filenames: false
|
||||
|
||||
- id: rust-lint
|
||||
name: Run fmt and clippy on Rust code
|
||||
files: ^rust/extractor/(.*rs|Cargo.toml)$
|
||||
language: system
|
||||
entry: python3 rust/lint.py
|
||||
pass_filenames: false
|
||||
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"omnisharp.autoStart": false,
|
||||
"cmake.sourceDirectory": "${workspaceFolder}/swift",
|
||||
"cmake.buildDirectory": "${workspaceFolder}/bazel-cmake-build",
|
||||
"editor.suggest.matchOnWordStartOnly": false
|
||||
"cmake.buildDirectory": "${workspaceFolder}/bazel-cmake-build"
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
/ql/ @github/codeql-ql-for-ql-reviewers
|
||||
|
||||
# Bazel (excluding BUILD.bazel files)
|
||||
WORKSPACE.bazel @github/codeql-ci-reviewers
|
||||
MODULE.bazel @github/codeql-ci-reviewers
|
||||
.bazelversion @github/codeql-ci-reviewers
|
||||
.bazelrc @github/codeql-ci-reviewers
|
||||
|
||||
2730
Cargo.lock
generated
2730
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
16
Cargo.toml
16
Cargo.toml
@@ -1,16 +0,0 @@
|
||||
# This is the shared workspace file for extractor using shared/tree-sitter/extractor
|
||||
[workspace]
|
||||
|
||||
resolver = "2"
|
||||
members = [
|
||||
"shared/tree-sitter-extractor",
|
||||
"ruby/extractor",
|
||||
"rust/extractor",
|
||||
"rust/extractor/macros",
|
||||
"rust/ast-generator",
|
||||
]
|
||||
|
||||
[patch.crates-io]
|
||||
# patch for build script bug preventing bazel build
|
||||
# see https://github.com/rust-lang/rustc_apfloat/pull/17
|
||||
rustc_apfloat = { git = "https://github.com/redsun82/rustc_apfloat.git", rev = "096d585100636bc2e9f09d7eefec38c5b334d47b" }
|
||||
29
MODULE.bazel
29
MODULE.bazel
@@ -18,16 +18,16 @@ bazel_dep(name = "platforms", version = "0.0.10")
|
||||
bazel_dep(name = "rules_go", version = "0.50.0")
|
||||
bazel_dep(name = "rules_pkg", version = "1.0.1")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
|
||||
bazel_dep(name = "rules_python", version = "0.36.0")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.7.1")
|
||||
bazel_dep(name = "rules_python", version = "0.35.0")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.6.1")
|
||||
bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl")
|
||||
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
|
||||
bazel_dep(name = "fmt", version = "10.0.0")
|
||||
bazel_dep(name = "rules_kotlin", version = "2.0.0-codeql.1")
|
||||
bazel_dep(name = "rules_kotlin", version = "1.9.4-codeql.1")
|
||||
bazel_dep(name = "gazelle", version = "0.38.0")
|
||||
bazel_dep(name = "rules_dotnet", version = "0.16.1")
|
||||
bazel_dep(name = "rules_dotnet", version = "0.15.1")
|
||||
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
|
||||
bazel_dep(name = "rules_rust", version = "0.52.2")
|
||||
bazel_dep(name = "rules_rust", version = "0.49.3")
|
||||
|
||||
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
|
||||
|
||||
@@ -47,25 +47,21 @@ cp.from_cargo(
|
||||
)
|
||||
use_repo(cp, "py_deps")
|
||||
|
||||
# deps for ruby+rust, but shortened due to windows file paths
|
||||
# crate_ruby, but shortened due to windows file paths
|
||||
r = use_extension(
|
||||
"@rules_rust//crate_universe:extension.bzl",
|
||||
"crate",
|
||||
isolate = True,
|
||||
)
|
||||
r.from_cargo(
|
||||
name = "r",
|
||||
cargo_lockfile = "//:Cargo.lock",
|
||||
name = "rd",
|
||||
cargo_lockfile = "//ruby/extractor:Cargo.lock",
|
||||
manifests = [
|
||||
"//:Cargo.toml",
|
||||
"//ruby/extractor:Cargo.toml",
|
||||
"//rust/extractor:Cargo.toml",
|
||||
"//rust/extractor/macros:Cargo.toml",
|
||||
"//rust/ast-generator:Cargo.toml",
|
||||
"//shared/tree-sitter-extractor:Cargo.toml",
|
||||
"//ruby/extractor/codeql-extractor-fake-crate:Cargo.toml",
|
||||
],
|
||||
)
|
||||
use_repo(r, tree_sitter_extractors_deps = "r")
|
||||
use_repo(r, ruby_deps = "rd")
|
||||
|
||||
dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet")
|
||||
dotnet.toolchain(dotnet_version = "8.0.101")
|
||||
@@ -128,7 +124,6 @@ use_repo(
|
||||
"kotlin-compiler-1.9.20-Beta",
|
||||
"kotlin-compiler-2.0.0-RC1",
|
||||
"kotlin-compiler-2.0.20-Beta2",
|
||||
"kotlin-compiler-2.1.0-Beta1",
|
||||
"kotlin-compiler-embeddable-1.5.0",
|
||||
"kotlin-compiler-embeddable-1.5.10",
|
||||
"kotlin-compiler-embeddable-1.5.20",
|
||||
@@ -142,7 +137,6 @@ use_repo(
|
||||
"kotlin-compiler-embeddable-1.9.20-Beta",
|
||||
"kotlin-compiler-embeddable-2.0.0-RC1",
|
||||
"kotlin-compiler-embeddable-2.0.20-Beta2",
|
||||
"kotlin-compiler-embeddable-2.1.0-Beta1",
|
||||
"kotlin-stdlib-1.5.0",
|
||||
"kotlin-stdlib-1.5.10",
|
||||
"kotlin-stdlib-1.5.20",
|
||||
@@ -156,11 +150,10 @@ use_repo(
|
||||
"kotlin-stdlib-1.9.20-Beta",
|
||||
"kotlin-stdlib-2.0.0-RC1",
|
||||
"kotlin-stdlib-2.0.20-Beta2",
|
||||
"kotlin-stdlib-2.1.0-Beta1",
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.23.1")
|
||||
go_sdk.download(version = "1.22.2")
|
||||
|
||||
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//go/extractor:go.mod")
|
||||
|
||||
2
WORKSPACE.bazel
Normal file
2
WORKSPACE.bazel
Normal file
@@ -0,0 +1,2 @@
|
||||
# please use MODULE.bazel to add dependencies
|
||||
# this empty file is required by internal repositories, don't remove it
|
||||
@@ -1,20 +0,0 @@
|
||||
load("//misc/bazel:pkg.bzl", "codeql_pack")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
[
|
||||
codeql_pack(
|
||||
name = "-".join(parts),
|
||||
srcs = [
|
||||
"//actions/extractor",
|
||||
],
|
||||
pack_prefix = "/".join(parts),
|
||||
)
|
||||
for parts in (
|
||||
[
|
||||
"experimental",
|
||||
"actions",
|
||||
],
|
||||
["actions"],
|
||||
)
|
||||
]
|
||||
@@ -1,10 +0,0 @@
|
||||
load("//misc/bazel:pkg.bzl", "codeql_pkg_files", "strip_prefix")
|
||||
|
||||
codeql_pkg_files(
|
||||
name = "extractor",
|
||||
srcs = [
|
||||
"codeql-extractor.yml",
|
||||
] + glob(["tools/**"]),
|
||||
strip_prefix = strip_prefix.from_pkg(),
|
||||
visibility = ["//actions:__pkg__"],
|
||||
)
|
||||
@@ -1,44 +0,0 @@
|
||||
name: "actions"
|
||||
aliases: []
|
||||
display_name: "GitHub Actions"
|
||||
version: 0.0.1
|
||||
column_kind: "utf16"
|
||||
unicode_newlines: true
|
||||
build_modes:
|
||||
- none
|
||||
file_coverage_languages: []
|
||||
github_api_languages: []
|
||||
scc_languages: []
|
||||
file_types:
|
||||
- name: workflow
|
||||
display_name: GitHub Actions workflow files
|
||||
extensions:
|
||||
- .yml
|
||||
- .yaml
|
||||
forwarded_extractor_name: javascript
|
||||
options:
|
||||
trap:
|
||||
title: TRAP options
|
||||
description: Options about how the extractor handles TRAP files
|
||||
type: object
|
||||
visibility: 3
|
||||
properties:
|
||||
cache:
|
||||
title: TRAP cache options
|
||||
description: Options about how the extractor handles its TRAP cache
|
||||
type: object
|
||||
properties:
|
||||
dir:
|
||||
title: TRAP cache directory
|
||||
description: The directory of the TRAP cache to use
|
||||
type: string
|
||||
bound:
|
||||
title: TRAP cache bound
|
||||
description: A soft limit (in MB) on the size of the TRAP cache
|
||||
type: string
|
||||
pattern: "[0-9]+"
|
||||
write:
|
||||
title: TRAP cache writeable
|
||||
description: Whether to write to the TRAP cache as well as reading it
|
||||
type: string
|
||||
pattern: "(true|TRUE|false|FALSE)"
|
||||
@@ -1,40 +0,0 @@
|
||||
if (($null -ne $env:LGTM_INDEX_INCLUDE) -or ($null -ne $env:LGTM_INDEX_EXCLUDE) -or ($null -ne $env:LGTM_INDEX_FILTERS)) {
|
||||
Write-Output 'Path filters set. Passing them through to the JavaScript extractor.'
|
||||
} else {
|
||||
Write-Output 'No path filters set. Using the default filters.'
|
||||
$DefaultPathFilters = @(
|
||||
'exclude:**/*',
|
||||
'include:.github/workflows/**/*.yml',
|
||||
'include:.github/workflows/**/*.yaml',
|
||||
'include:**/action.yml',
|
||||
'include:**/action.yaml'
|
||||
)
|
||||
|
||||
$env:LGTM_INDEX_FILTERS = $DefaultPathFilters -join "`n"
|
||||
}
|
||||
|
||||
# Find the JavaScript extractor directory via `codeql resolve extractor`.
|
||||
$CodeQL = Join-Path $env:CODEQL_DIST 'codeql.exe'
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = &$CodeQL resolve extractor --language javascript
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw 'Failed to resolve JavaScript extractor.'
|
||||
}
|
||||
|
||||
Write-Output "Found JavaScript extractor at '${env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}'."
|
||||
|
||||
# Run the JavaScript autobuilder.
|
||||
$JavaScriptAutoBuild = Join-Path $env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT 'tools\autobuild.cmd'
|
||||
Write-Output "Running JavaScript autobuilder at '${JavaScriptAutoBuild}'."
|
||||
|
||||
# Copy the values of the Actions extractor environment variables to the JavaScript extractor environment variables.
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_DIAGNOSTIC_DIR
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_LOG_DIR
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_SCRATCH_DIR
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_SOURCE_ARCHIVE_DIR
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = $env:CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE
|
||||
|
||||
&$JavaScriptAutoBuild
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "JavaScript autobuilder failed."
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
@echo off
|
||||
rem All of the work is done in the PowerShell script
|
||||
powershell.exe %~dp0autobuild-impl.ps1
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
DEFAULT_PATH_FILTERS=$(cat << END
|
||||
exclude:**/*
|
||||
include:.github/workflows/**/*.yml
|
||||
include:.github/workflows/**/*.yaml
|
||||
include:**/action.yml
|
||||
include:**/action.yaml
|
||||
END
|
||||
)
|
||||
|
||||
if [ -n "${LGTM_INDEX_INCLUDE:-}" ] || [ -n "${LGTM_INDEX_EXCLUDE:-}" ] || [ -n "${LGTM_INDEX_FILTERS:-}" ] ; then
|
||||
echo "Path filters set. Passing them through to the JavaScript extractor."
|
||||
else
|
||||
echo "No path filters set. Using the default filters."
|
||||
LGTM_INDEX_FILTERS="${DEFAULT_PATH_FILTERS}"
|
||||
export LGTM_INDEX_FILTERS
|
||||
fi
|
||||
|
||||
# Find the JavaScript extractor directory via `codeql resolve extractor`.
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$($CODEQL_DIST/codeql resolve extractor --language javascript)"
|
||||
export CODEQL_EXTRACTOR_JAVASCRIPT_ROOT
|
||||
|
||||
echo "Found JavaScript extractor at '${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}'."
|
||||
|
||||
# Run the JavaScript autobuilder
|
||||
JAVASCRIPT_AUTO_BUILD="${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}/tools/autobuild.sh"
|
||||
echo "Running JavaScript autobuilder at '${JAVASCRIPT_AUTO_BUILD}'."
|
||||
|
||||
# Copy the values of the Actions extractor environment variables to the JavaScript extractor environment variables.
|
||||
env CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR="${CODEQL_EXTRACTOR_ACTIONS_DIAGNOSTIC_DIR}" \
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR="${CODEQL_EXTRACTOR_ACTIONS_LOG_DIR}" \
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR="${CODEQL_EXTRACTOR_ACTIONS_SCRATCH_DIR}" \
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR="${CODEQL_EXTRACTOR_ACTIONS_SOURCE_ARCHIVE_DIR}" \
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR="${CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR}" \
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE="${CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE}" \
|
||||
${JAVASCRIPT_AUTO_BUILD}
|
||||
@@ -1 +0,0 @@
|
||||
predicate placeholder(int x) { x = 0 }
|
||||
@@ -1,12 +0,0 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.0.1-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
codeql/util: ${workspace}
|
||||
codeql/yaml: ${workspace}
|
||||
codeql/controlflow: ${workspace}
|
||||
codeql/dataflow: ${workspace}
|
||||
codeql/javascript-all: ${workspace}
|
||||
extractor: actions
|
||||
groups: actions
|
||||
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* @name Placeholder Query
|
||||
* @description Placeholder
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 9.3
|
||||
* @precision high
|
||||
* @id actions/placeholder
|
||||
* @tags actions security
|
||||
*/
|
||||
|
||||
import actions
|
||||
import javascript
|
||||
|
||||
from File f
|
||||
select f, "Analyzed a file."
|
||||
@@ -1,8 +0,0 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.0.1-dev
|
||||
library: false
|
||||
groups: [actions, queries]
|
||||
extractor: actions
|
||||
dependencies:
|
||||
codeql/actions-all: ${workspace}
|
||||
warnOnImplicitThis: true
|
||||
@@ -1,23 +0,0 @@
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
job1:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- shell: pwsh
|
||||
run: Write-Output "foo"
|
||||
job2:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "foo"
|
||||
|
||||
job3:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- shell: bash
|
||||
run: echo "foo"
|
||||
job4:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- run: Write-Output "foo"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
| 1 |
|
||||
@@ -1 +0,0 @@
|
||||
select 1
|
||||
@@ -1,8 +0,0 @@
|
||||
name: codeql/actions-tests
|
||||
groups: [codeql, test]
|
||||
dependencies:
|
||||
codeql/actions-all: ${workspace}
|
||||
codeql/actions-queries: ${workspace}
|
||||
extractor: actions
|
||||
tests: .
|
||||
warnOnImplicitThis: true
|
||||
@@ -1,23 +0,0 @@
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
job1:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- shell: pwsh
|
||||
run: Write-Output "foo"
|
||||
job2:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "foo"
|
||||
|
||||
job3:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- shell: bash
|
||||
run: echo "foo"
|
||||
job4:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- run: Write-Output "foo"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
| .github/workflows/shell.yml:0:0:0:0 | .github/workflows/shell.yml | Analyzed a file. |
|
||||
@@ -1 +0,0 @@
|
||||
Placeholder.ql
|
||||
@@ -57,6 +57,10 @@
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
|
||||
],
|
||||
"Model as Data Generation Java/C# - CaptureModels": [
|
||||
"java/ql/src/utils/modelgenerator/internal/CaptureModels.qll",
|
||||
"csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll"
|
||||
],
|
||||
"Sign Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
|
||||
@@ -351,5 +355,9 @@
|
||||
"Python model summaries test extension": [
|
||||
"python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml",
|
||||
"python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml"
|
||||
],
|
||||
"shared tree-sitter extractor cargo.toml": [
|
||||
"shared/tree-sitter-extractor/Cargo.toml",
|
||||
"ruby/extractor/codeql-extractor-fake-crate/Cargo.toml"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
predicate isExprRequires(Expr expr) { exists(int kind | exprs(expr, kind, _) | kind = 390) }
|
||||
|
||||
from Expr expr, int kind, int kind_new, Location location
|
||||
where
|
||||
exprs(expr, kind, location) and
|
||||
if isExprRequires(expr) then kind_new = 1 else kind_new = kind
|
||||
select expr, kind_new, location
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
description: Add requires expr
|
||||
compatibility: partial
|
||||
exprs.rel: run exprs.qlo
|
||||
@@ -1,17 +0,0 @@
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
predicate isExprRequirement(Expr expr) {
|
||||
exists(int kind | exprs(expr, kind, _) | kind = [391, 392, 393])
|
||||
}
|
||||
|
||||
from Expr expr, int kind, int kind_new, Location location
|
||||
where
|
||||
exprs(expr, kind, location) and
|
||||
if isExprRequirement(expr) then kind_new = 1 else kind_new = kind
|
||||
select expr, kind_new, location
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
class Parameter extends @parameter {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class ParameterizedElement extends @parameterized_element {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Type extends @type {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Parameter param, ParameterizedElement pe, int index, Type type
|
||||
where
|
||||
params(param, pe, index, type) and
|
||||
not pe instanceof @requires_expr
|
||||
select param, pe, index, type
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
||||
description: Support C++20 requires expressions
|
||||
compatibility: partial
|
||||
compound_requirement_is_noexcept.rel: delete
|
||||
exprs.rel: run exprs.qlo
|
||||
params.rel: run params.qlo
|
||||
@@ -1,55 +1,3 @@
|
||||
## 2.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a new predicate `DataFlow::getARuntimeTarget` for getting a function that may be invoked by a `Call` expression. Unlike `Call.getTarget` this new predicate may also resolve function pointers.
|
||||
* Added the predicate `mayBeFromImplicitlyDeclaredFunction()` to the `Call` class to represent calls that may be the return value of an implicitly declared C function.
|
||||
* Added the predicate `getAnExplicitDeclarationEntry()` to the `Function` class to get a `FunctionDeclarationEntry` that is not implicit.
|
||||
* Added classes `RequiresExpr`, `SimpleRequirementExpr`, `TypeRequirementExpr`, `CompoundRequirementExpr`, and `NestedRequirementExpr` to represent C++20 requires expressions and the simple, type, compound, and nested requirements that can occur in `requires` expressions.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The function call target resolution algorithm has been improved to resolve more calls through function pointers. As a result, dataflow queries may have more results.
|
||||
|
||||
## 2.0.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added taint flow model for `fopen` and related functions.
|
||||
* The `SimpleRangeAnalysis` library (`semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis`) now generates more precise ranges for calls to `fgetc` and `getc`.
|
||||
|
||||
## 2.0.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 2.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Deleted many deprecated taint-tracking configurations based on `TaintTracking::Configuration`.
|
||||
* Deleted many deprecated dataflow configurations based on `DataFlow::Configuration`.
|
||||
* Deleted the deprecated `hasQualifiedName` and `isDefined` predicates from the `Declaration` class, use `hasGlobalName` and `hasDefinition` respectively instead.
|
||||
* Deleted the `getFullSignature` predicate from the `Function` class, use `getIdentityString(Declaration)` from `semmle.code.cpp.Print` instead.
|
||||
* Deleted the deprecated `freeCall` predicate from `Alloc.qll`. Use `DeallocationExpr` instead.
|
||||
* Deleted the deprecated `explorationLimit` predicate from `DataFlow::Configuration`, use `FlowExploration<explorationLimit>` instead.
|
||||
* Deleted the deprecated `getFieldExpr` predicate from `ClassAggregateLiteral`, use `getAFieldExpr` instead.
|
||||
* Deleted the deprecated `getElementExpr` predicate from `ArrayOrVectorAggregateLiteral`, use `getAnElementExpr` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a class `C11GenericExpr` to represent C11 generic selection expressions. The generic selection is represented as a `Conversion` on the expression that will be selected.
|
||||
* Added subclasses of `BuiltInOperations` for the `__is_scoped_enum`, `__is_trivially_equality_comparable`, and `__is_trivially_relocatable` builtin operations.
|
||||
* Added a subclass of `Expr` for `__datasizeof` expressions.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added a data flow model for `swap` member functions, which were previously modeled as taint tracking functions. This change improves the precision of queries where flow through `swap` member functions might affect the results.
|
||||
* Added a data flow model for `realloc`-like functions, which were previously modeled as a taint tracking functions. This change improves the precision of queries where flow through `realloc`-like functions might affect the results.
|
||||
|
||||
## 1.4.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.4.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added subclasses of `BuiltInOperations` for the `__is_scoped_enum`, `__is_trivially_equality_comparable`, and `__is_trivially_relocatable` builtin operations.
|
||||
* Added a subclass of `Expr` for `__datasizeof` expressions.
|
||||
4
cpp/ql/lib/change-notes/2024-08-30-c11-generics.md
Normal file
4
cpp/ql/lib/change-notes/2024-08-30-c11-generics.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a class `C11GenericExpr` to represent C11 generic selection expressions. The generic selection is represented as a `Conversion` on the expression that will be selected.
|
||||
@@ -1,7 +1,6 @@
|
||||
## 2.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* Deleted many deprecated taint-tracking configurations based on `TaintTracking::Configuration`.
|
||||
* Deleted many deprecated dataflow configurations based on `DataFlow::Configuration`.
|
||||
* Deleted the deprecated `hasQualifiedName` and `isDefined` predicates from the `Declaration` class, use `hasGlobalName` and `hasDefinition` respectively instead.
|
||||
@@ -10,14 +9,3 @@
|
||||
* Deleted the deprecated `explorationLimit` predicate from `DataFlow::Configuration`, use `FlowExploration<explorationLimit>` instead.
|
||||
* Deleted the deprecated `getFieldExpr` predicate from `ClassAggregateLiteral`, use `getAFieldExpr` instead.
|
||||
* Deleted the deprecated `getElementExpr` predicate from `ArrayOrVectorAggregateLiteral`, use `getAnElementExpr` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a class `C11GenericExpr` to represent C11 generic selection expressions. The generic selection is represented as a `Conversion` on the expression that will be selected.
|
||||
* Added subclasses of `BuiltInOperations` for the `__is_scoped_enum`, `__is_trivially_equality_comparable`, and `__is_trivially_relocatable` builtin operations.
|
||||
* Added a subclass of `Expr` for `__datasizeof` expressions.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added a data flow model for `swap` member functions, which were previously modeled as taint tracking functions. This change improves the precision of queries where flow through `swap` member functions might affect the results.
|
||||
* Added a data flow model for `realloc`-like functions, which were previously modeled as a taint tracking functions. This change improves the precision of queries where flow through `realloc`-like functions might affect the results.
|
||||
4
cpp/ql/lib/change-notes/2024-09-03-realloc-data-flow.md
Normal file
4
cpp/ql/lib/change-notes/2024-09-03-realloc-data-flow.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added a data flow model for `realloc`-like functions, which were previously modeled as a taint tracking functions. This change improves the precision of queries where flow through `realloc`-like functions might affect the results.
|
||||
4
cpp/ql/lib/change-notes/2024-09-04-swap-data-flow.md
Normal file
4
cpp/ql/lib/change-notes/2024-09-04-swap-data-flow.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added a data flow model for `swap` member functions, which were previously modeled as taint tracking functions. This change improves the precision of queries where flow through `swap` member functions might affect the results.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.4.2
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 2.0.1
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,6 +0,0 @@
|
||||
## 2.0.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added taint flow model for `fopen` and related functions.
|
||||
* The `SimpleRangeAnalysis` library (`semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis`) now generates more precise ranges for calls to `fgetc` and `getc`.
|
||||
@@ -1,12 +0,0 @@
|
||||
## 2.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a new predicate `DataFlow::getARuntimeTarget` for getting a function that may be invoked by a `Call` expression. Unlike `Call.getTarget` this new predicate may also resolve function pointers.
|
||||
* Added the predicate `mayBeFromImplicitlyDeclaredFunction()` to the `Call` class to represent calls that may be the return value of an implicitly declared C function.
|
||||
* Added the predicate `getAnExplicitDeclarationEntry()` to the `Function` class to get a `FunctionDeclarationEntry` that is not implicit.
|
||||
* Added classes `RequiresExpr`, `SimpleRequirementExpr`, `TypeRequirementExpr`, `CompoundRequirementExpr`, and `NestedRequirementExpr` to represent C++20 requires expressions and the simple, type, compound, and nested requirements that can occur in `requires` expressions.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The function call target resolution algorithm has been improved to resolve more calls through function pointers. As a result, dataflow queries may have more results.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 2.1.0
|
||||
lastReleaseVersion: 1.4.1
|
||||
|
||||
@@ -17,7 +17,6 @@ import semmle.code.cpp.File
|
||||
import semmle.code.cpp.Linkage
|
||||
import semmle.code.cpp.Location
|
||||
import semmle.code.cpp.Compilation
|
||||
import semmle.code.cpp.Concept
|
||||
import semmle.code.cpp.Element
|
||||
import semmle.code.cpp.Namespace
|
||||
import semmle.code.cpp.Specifier
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 2.1.1-dev
|
||||
version: 1.4.2-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
/**
|
||||
* Provides classes for working with C++ concepts.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.exprs.Expr
|
||||
|
||||
/**
|
||||
* A C++ requires expression.
|
||||
*
|
||||
* For example, with `T` and `U` template parameters:
|
||||
* ```cpp
|
||||
* requires (T x, U y) { x + y; };
|
||||
* ```
|
||||
*/
|
||||
class RequiresExpr extends Expr, @requires_expr {
|
||||
override string toString() {
|
||||
if exists(this.getAParameter())
|
||||
then result = "requires(...) { ... }"
|
||||
else result = "requires { ... }"
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "RequiresExpr" }
|
||||
|
||||
/**
|
||||
* Gets a requirement in this requires expression.
|
||||
*/
|
||||
RequirementExpr getARequirement() { result = this.getAChild() }
|
||||
|
||||
/**
|
||||
* Gets the nth requirement in this requires expression.
|
||||
*/
|
||||
RequirementExpr getRequirement(int n) { result = this.getChild(n) }
|
||||
|
||||
/**
|
||||
* Gets the number of requirements in this requires expression.
|
||||
*/
|
||||
int getNumberOfRequirements() { result = count(this.getARequirement()) }
|
||||
|
||||
/**
|
||||
* Gets a parameter of this requires expression, if any.
|
||||
*/
|
||||
Parameter getAParameter() { result.getRequiresExpr() = underlyingElement(this) }
|
||||
|
||||
/**
|
||||
* Gets the the nth parameter of this requires expression.
|
||||
*/
|
||||
Parameter getParameter(int n) {
|
||||
result.getRequiresExpr() = underlyingElement(this) and result.getIndex() = n
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of parameters of this requires expression.
|
||||
*/
|
||||
int getNumberOfParameters() { result = count(this.getAParameter()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ requirement in a requires expression.
|
||||
*/
|
||||
class RequirementExpr extends Expr { }
|
||||
|
||||
/**
|
||||
* A C++ simple requirement in a requires expression.
|
||||
*
|
||||
* For example, if:
|
||||
* ```cpp
|
||||
* requires(T x, U y) { x + y; };
|
||||
* ```
|
||||
* with `T` and `U` template parameters, then `x + y;` is a simple requirement.
|
||||
*/
|
||||
class SimpleRequirementExpr extends RequirementExpr {
|
||||
SimpleRequirementExpr() {
|
||||
this.getParent() instanceof RequiresExpr and
|
||||
not this instanceof TypeRequirementExpr and
|
||||
not this instanceof CompoundRequirementExpr and
|
||||
not this instanceof NestedRequirementExpr
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "SimpleRequirementExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ type requirement in a requires expression.
|
||||
*
|
||||
* For example, if:
|
||||
* ```cpp
|
||||
* requires { typename T::a_field; };
|
||||
* ```
|
||||
* with `T` a template parameter, then `typename T::a_field;` is a type requirement.
|
||||
*/
|
||||
class TypeRequirementExpr extends RequirementExpr, TypeName {
|
||||
TypeRequirementExpr() { this.getParent() instanceof RequiresExpr }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TypeRequirementExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ compound requirement in a requires expression.
|
||||
*
|
||||
* For example, if:
|
||||
* ```cpp
|
||||
* requires(T x) { { x } noexcept -> std::same_as<int>; };
|
||||
* ```
|
||||
* with `T` a template parameter, then `{ x } noexcept -> std::same_as<int>;` is
|
||||
* a compound requirement.
|
||||
*/
|
||||
class CompoundRequirementExpr extends RequirementExpr, @compound_requirement {
|
||||
override string toString() {
|
||||
if exists(this.getReturnTypeRequirement())
|
||||
then result = "{ ... } -> ..."
|
||||
else result = "{ ... }"
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "CompoundRequirementExpr" }
|
||||
|
||||
/**
|
||||
* Gets the expression from the compound requirement.
|
||||
*/
|
||||
Expr getExpr() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets the return type requirement from the compound requirement, if any.
|
||||
*/
|
||||
Expr getReturnTypeRequirement() { result = this.getChild(1) }
|
||||
|
||||
/**
|
||||
* Holds if the expression from the compound requirement must not be
|
||||
* potentially throwing.
|
||||
*/
|
||||
predicate isNoExcept() { compound_requirement_is_noexcept(underlyingElement(this)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ nested requirement in a requires expression.
|
||||
*
|
||||
* For example, if:
|
||||
* ```cpp
|
||||
* requires { requires std::is_same<T, int>::value; };
|
||||
* ```
|
||||
* with `T` a template parameter, then `requires std::is_same<T, int>::value;` is
|
||||
* a nested requirement.
|
||||
*/
|
||||
class NestedRequirementExpr extends Expr, @nested_requirement {
|
||||
override string toString() { result = "requires ..." }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "NestedRequirementExpr" }
|
||||
|
||||
/**
|
||||
* Gets the constraint from the nested requirement.
|
||||
*/
|
||||
Expr getConstraint() { result = this.getChild(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ concept id expression.
|
||||
*/
|
||||
class ConceptIdExpr extends RequirementExpr, @concept_id {
|
||||
override string toString() { result = "concept<...>" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ConceptIdExpr" }
|
||||
}
|
||||
@@ -129,7 +129,7 @@ class Element extends ElementBase {
|
||||
* or certain kinds of `Statement`.
|
||||
*/
|
||||
Element getParentScope() {
|
||||
// result instanceof Class
|
||||
// result instanceof class
|
||||
exists(Declaration m |
|
||||
m = this and
|
||||
result = m.getDeclaringType() and
|
||||
@@ -138,40 +138,31 @@ class Element extends ElementBase {
|
||||
or
|
||||
exists(TemplateClass tc | this = tc.getATemplateArgument() and result = tc)
|
||||
or
|
||||
// result instanceof Namespace
|
||||
// result instanceof namespace
|
||||
exists(Namespace n | result = n and n.getADeclaration() = this)
|
||||
or
|
||||
exists(FriendDecl d, Namespace n | this = d and n.getADeclaration() = d and result = n)
|
||||
or
|
||||
exists(Namespace n | this = n and result = n.getParentNamespace())
|
||||
or
|
||||
// result instanceof Stmt
|
||||
// result instanceof stmt
|
||||
exists(LocalVariable v |
|
||||
this = v and
|
||||
exists(DeclStmt ds | ds.getADeclaration() = v and result = ds.getParent())
|
||||
)
|
||||
or
|
||||
exists(Parameter p |
|
||||
this = p and
|
||||
(
|
||||
result = p.getFunction() or
|
||||
result = p.getCatchBlock().getParent().(Handler).getParent().(TryStmt).getParent() or
|
||||
result = p.getRequiresExpr().getEnclosingStmt().getParent()
|
||||
)
|
||||
)
|
||||
exists(Parameter p | this = p and result = p.getFunction())
|
||||
or
|
||||
exists(GlobalVariable g, Namespace n | this = g and n.getADeclaration() = g and result = n)
|
||||
or
|
||||
exists(TemplateVariable tv | this = tv.getATemplateArgument() and result = tv)
|
||||
or
|
||||
exists(EnumConstant e | this = e and result = e.getDeclaringEnum())
|
||||
or
|
||||
// result instanceof Block|Function
|
||||
// result instanceof block|function
|
||||
exists(BlockStmt b | this = b and blockscope(unresolveElement(b), unresolveElement(result)))
|
||||
or
|
||||
exists(TemplateFunction tf | this = tf.getATemplateArgument() and result = tf)
|
||||
or
|
||||
// result instanceof Stmt
|
||||
// result instanceof stmt
|
||||
exists(ControlStructure s | this = s and result = s.getParent())
|
||||
or
|
||||
using_container(unresolveElement(result), underlyingElement(this))
|
||||
|
||||
@@ -230,14 +230,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a non-implicit function declaration entry.
|
||||
*/
|
||||
FunctionDeclarationEntry getAnExplicitDeclarationEntry() {
|
||||
result = this.getADeclarationEntry() and
|
||||
not result.isImplicit()
|
||||
}
|
||||
|
||||
private predicate declEntry(FunctionDeclarationEntry fde) {
|
||||
fun_decls(unresolveElement(fde), underlyingElement(this), _, _, _) and
|
||||
// If one .cpp file specializes a function, and another calls the
|
||||
@@ -508,17 +500,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* Gets the nearest enclosing AccessHolder.
|
||||
*/
|
||||
override AccessHolder getEnclosingAccessHolder() { result = this.getDeclaringType() }
|
||||
|
||||
/**
|
||||
* Holds if this function has extraction errors that create an `ErrorExpr`.
|
||||
*/
|
||||
predicate hasErrors() {
|
||||
exists(ErrorExpr e |
|
||||
e.getEnclosingFunction() = this and
|
||||
// Exclude the first allocator call argument because it is always extracted as `ErrorExpr`.
|
||||
not exists(NewOrNewArrayExpr new | e = new.getAllocatorCall().getArgument(0))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
@@ -670,8 +651,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
|
||||
|
||||
/**
|
||||
* Holds if this declaration is an implicit function declaration, that is,
|
||||
* where a function is used before it is declared (under older C standards,
|
||||
* or when there were parse errors).
|
||||
* where a function is used before it is declared (under older C standards).
|
||||
*/
|
||||
predicate isImplicit() { fun_implicit(underlyingElement(this)) }
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import semmle.code.cpp.Declaration
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
* A C/C++ function parameter, catch block parameter, or requires expression parameter.
|
||||
* For example the function parameter `p` and the catch block parameter `e` in the following
|
||||
* A C/C++ function parameter or catch block parameter. For example the
|
||||
* function parameter `p` and the catch block parameter `e` in the following
|
||||
* code:
|
||||
* ```
|
||||
* void myFunction(int p) {
|
||||
@@ -20,8 +20,8 @@ private import semmle.code.cpp.internal.ResolveClass
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* For catch block parameters and expression , there is a one-to-one
|
||||
* correspondence between the `Parameter` and its `VariableDeclarationEntry`.
|
||||
* For catch block parameters, there is a one-to-one correspondence between
|
||||
* the `Parameter` and its `ParameterDeclarationEntry`.
|
||||
*
|
||||
* For function parameters, there is a one-to-many relationship between
|
||||
* `Parameter` and `ParameterDeclarationEntry`, because one function can
|
||||
@@ -73,8 +73,7 @@ class Parameter extends LocalScopeVariable, @parameter {
|
||||
}
|
||||
|
||||
private VariableDeclarationEntry getANamedDeclarationEntry() {
|
||||
result = this.getAnEffectiveDeclarationEntry() and
|
||||
exists(string name | var_decls(unresolveElement(result), _, _, name, _) | name != "")
|
||||
result = this.getAnEffectiveDeclarationEntry() and result.getName() != ""
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,12 +118,6 @@ class Parameter extends LocalScopeVariable, @parameter {
|
||||
*/
|
||||
BlockStmt getCatchBlock() { params(underlyingElement(this), unresolveElement(result), _, _) }
|
||||
|
||||
/**
|
||||
* Gets the requires expression to which the parameter belongs, if it is a
|
||||
* requires expression parameter.
|
||||
*/
|
||||
RequiresExpr getRequiresExpr() { params(underlyingElement(this), unresolveElement(result), _, _) }
|
||||
|
||||
/**
|
||||
* Gets the zero-based index of this parameter.
|
||||
*
|
||||
|
||||
@@ -80,10 +80,6 @@ private Declaration getAnEnclosingDeclaration(Locatable ast) {
|
||||
or
|
||||
result = ast.(Parameter).getFunction()
|
||||
or
|
||||
result = ast.(Parameter).getCatchBlock().getEnclosingFunction()
|
||||
or
|
||||
result = ast.(Parameter).getRequiresExpr().getEnclosingFunction()
|
||||
or
|
||||
result = ast.(Expr).getEnclosingDeclaration()
|
||||
or
|
||||
result = ast.(Initializer).getDeclaration()
|
||||
@@ -103,10 +99,7 @@ private newtype TPrintAstNode =
|
||||
stmt.getADeclarationEntry() = entry and
|
||||
shouldPrintDeclaration(stmt.getEnclosingFunction())
|
||||
} or
|
||||
TFunctionParametersNode(Function func) { shouldPrintDeclaration(func) } or
|
||||
TRequiresExprParametersNode(RequiresExpr req) {
|
||||
shouldPrintDeclaration(getAnEnclosingDeclaration(req))
|
||||
} or
|
||||
TParametersNode(Function func) { shouldPrintDeclaration(func) } or
|
||||
TConstructorInitializersNode(Constructor ctor) {
|
||||
ctor.hasEntryPoint() and
|
||||
shouldPrintDeclaration(ctor)
|
||||
@@ -310,14 +303,14 @@ class ExprNode extends AstNode {
|
||||
|
||||
ExprNode() { expr = ast }
|
||||
|
||||
override PrintAstNode getChildInternal(int childIndex) {
|
||||
result.(AstNode).getAst() = expr.getChild(childIndex)
|
||||
override AstNode getChildInternal(int childIndex) {
|
||||
result.getAst() = expr.getChild(childIndex)
|
||||
or
|
||||
childIndex = max(int index | exists(expr.getChild(index)) or index = 0) + 1 and
|
||||
result.(AstNode).getAst() = expr.(ConditionDeclExpr).getInitializingExpr()
|
||||
result.getAst() = expr.(ConditionDeclExpr).getInitializingExpr()
|
||||
or
|
||||
exists(int destructorIndex |
|
||||
result.(AstNode).getAst() = expr.getImplicitDestructorCall(destructorIndex) and
|
||||
result.getAst() = expr.getImplicitDestructorCall(destructorIndex) and
|
||||
childIndex = destructorIndex + max(int index | exists(expr.getChild(index)) or index = 0) + 2
|
||||
)
|
||||
}
|
||||
@@ -336,8 +329,7 @@ class ExprNode extends AstNode {
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
result =
|
||||
getChildAccessorWithoutConversions(ast, this.getChildInternal(childIndex).(AstNode).getAst())
|
||||
result = getChildAccessorWithoutConversions(ast, this.getChildInternal(childIndex).getAst())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,26 +409,6 @@ class StmtExprNode extends ExprNode {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing a `RequiresExpr`
|
||||
*/
|
||||
class RequiresExprNode extends ExprNode {
|
||||
override RequiresExpr expr;
|
||||
|
||||
override PrintAstNode getChildInternal(int childIndex) {
|
||||
result = super.getChildInternal(childIndex)
|
||||
or
|
||||
childIndex = -1 and
|
||||
result.(RequiresExprParametersNode).getRequiresExpr() = expr
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
result = super.getChildAccessorPredicateInternal(childIndex)
|
||||
or
|
||||
childIndex = -1 and result = "<params>"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing a `DeclarationEntry`.
|
||||
*/
|
||||
@@ -538,22 +510,6 @@ class DeclStmtNode extends StmtNode {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing a `Handler`.
|
||||
*/
|
||||
class HandlerNode extends ChildStmtNode {
|
||||
Handler handler;
|
||||
|
||||
HandlerNode() { handler = stmt }
|
||||
|
||||
override BaseAstNode getChildInternal(int childIndex) {
|
||||
result = super.getChildInternal(childIndex)
|
||||
or
|
||||
childIndex = -1 and
|
||||
result.getAst() = handler.getParameter()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing a `Parameter`.
|
||||
*/
|
||||
@@ -596,10 +552,10 @@ class InitializerNode extends AstNode {
|
||||
/**
|
||||
* A node representing the parameters of a `Function`.
|
||||
*/
|
||||
class FunctionParametersNode extends PrintAstNode, TFunctionParametersNode {
|
||||
class ParametersNode extends PrintAstNode, TParametersNode {
|
||||
Function func;
|
||||
|
||||
FunctionParametersNode() { this = TFunctionParametersNode(func) }
|
||||
ParametersNode() { this = TParametersNode(func) }
|
||||
|
||||
final override string toString() { result = "" }
|
||||
|
||||
@@ -620,33 +576,6 @@ class FunctionParametersNode extends PrintAstNode, TFunctionParametersNode {
|
||||
final Function getFunction() { result = func }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing the parameters of a `RequiresExpr`.
|
||||
*/
|
||||
class RequiresExprParametersNode extends PrintAstNode, TRequiresExprParametersNode {
|
||||
RequiresExpr req;
|
||||
|
||||
RequiresExprParametersNode() { this = TRequiresExprParametersNode(req) }
|
||||
|
||||
final override string toString() { result = "" }
|
||||
|
||||
final override Location getLocation() { result = getRepresentativeLocation(req) }
|
||||
|
||||
override AstNode getChildInternal(int childIndex) {
|
||||
result.getAst() = req.getParameter(childIndex)
|
||||
}
|
||||
|
||||
override string getChildAccessorPredicateInternal(int childIndex) {
|
||||
exists(this.getChildInternal(childIndex)) and
|
||||
result = "getParameter(" + childIndex.toString() + ")"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `RequiresExpr` for which this node represents the parameters.
|
||||
*/
|
||||
final RequiresExpr getRequiresExpr() { result = req }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing the initializer list of a `Constructor`.
|
||||
*/
|
||||
@@ -750,7 +679,7 @@ class FunctionNode extends FunctionOrGlobalOrNamespaceVariableNode {
|
||||
|
||||
override PrintAstNode getChildInternal(int childIndex) {
|
||||
childIndex = 0 and
|
||||
result.(FunctionParametersNode).getFunction() = func
|
||||
result.(ParametersNode).getFunction() = func
|
||||
or
|
||||
childIndex = 1 and
|
||||
result.(ConstructorInitializersNode).getConstructor() = func
|
||||
@@ -825,8 +754,6 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
|
||||
or
|
||||
s.(ConstexprIfStmt).getElse() = e and pred = "getElse()"
|
||||
or
|
||||
s.(Handler).getParameter() = e and pred = "getParameter()"
|
||||
or
|
||||
s.(IfStmt).getInitialization() = e and pred = "getInitialization()"
|
||||
or
|
||||
s.(IfStmt).getCondition() = e and pred = "getCondition()"
|
||||
@@ -974,11 +901,6 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
|
||||
or
|
||||
expr.(CommaExpr).getRightOperand() = ele and pred = "getRightOperand()"
|
||||
or
|
||||
expr.(CompoundRequirementExpr).getExpr() = ele and pred = "getExpr()"
|
||||
or
|
||||
expr.(CompoundRequirementExpr).getReturnTypeRequirement() = ele and
|
||||
pred = "getReturnTypeRequirement()"
|
||||
or
|
||||
expr.(ConditionDeclExpr).getVariableAccess() = ele and pred = "getVariableAccess()"
|
||||
or
|
||||
expr.(ConstructorFieldInit).getExpr() = ele and pred = "getExpr()"
|
||||
@@ -999,8 +921,6 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
|
||||
or
|
||||
expr.(LambdaExpression).getInitializer() = ele and pred = "getInitializer()"
|
||||
or
|
||||
expr.(NestedRequirementExpr).getConstraint() = ele and pred = "getConstraint()"
|
||||
or
|
||||
expr.(NewOrNewArrayExpr).getAllocatorCall() = ele and pred = "getAllocatorCall()"
|
||||
or
|
||||
expr.(NewOrNewArrayExpr).getAlignmentArgument() = ele and pred = "getAlignmentArgument()"
|
||||
@@ -1040,11 +960,6 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
|
||||
or
|
||||
expr.(UnaryOperation).getOperand() = ele and pred = "getOperand()"
|
||||
or
|
||||
exists(int n |
|
||||
expr.(RequiresExpr).getRequirement(n) = ele and
|
||||
pred = "getRequirement(" + n + ")"
|
||||
)
|
||||
or
|
||||
expr.(SizeofExprOperator).getExprOperand() = ele and pred = "getExprOperand()"
|
||||
or
|
||||
expr.(StmtExpr).getStmt() = ele and pred = "getStmt()"
|
||||
|
||||
@@ -39,8 +39,8 @@ class Type extends Locatable, @type {
|
||||
|
||||
/**
|
||||
* Gets a specifier of this type, recursively looking through `typedef` and
|
||||
* `decltype`. For example, in the context of `typedef const int *restrict t`,
|
||||
* the type `volatile t` has specifiers `volatile` and `restrict` but not
|
||||
* `decltype`. For example, in the context of `typedef const int *restrict
|
||||
* t`, the type `volatile t` has specifiers `volatile` and `restrict` but not
|
||||
* `const` since the `const` is attached to the type being pointed to rather
|
||||
* than the pointer itself.
|
||||
*/
|
||||
|
||||
@@ -241,10 +241,6 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
|
||||
name != "" and result = name
|
||||
or
|
||||
name = "" and result = this.getVariable().(LocalVariable).getName()
|
||||
or
|
||||
name = "" and
|
||||
not this instanceof ParameterDeclarationEntry and
|
||||
result = this.getVariable().(Parameter).getName()
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -299,11 +295,19 @@ class ParameterDeclarationEntry extends VariableDeclarationEntry {
|
||||
|
||||
private string getAnonymousParameterDescription() {
|
||||
not exists(this.getName()) and
|
||||
exists(string anon |
|
||||
anon = "(unnamed parameter " + this.getIndex().toString() + ")" and
|
||||
exists(string idx |
|
||||
idx =
|
||||
((this.getIndex() + 1).toString() + "th")
|
||||
.replaceAll("1th", "1st")
|
||||
.replaceAll("2th", "2nd")
|
||||
.replaceAll("3th", "3rd")
|
||||
.replaceAll("11st", "11th")
|
||||
.replaceAll("12nd", "12th")
|
||||
.replaceAll("13rd", "13th") and
|
||||
if exists(this.getCanonicalName())
|
||||
then result = "declaration of " + this.getCanonicalName() + " as " + anon
|
||||
else result = "declaration of " + anon
|
||||
then
|
||||
result = "declaration of " + this.getCanonicalName() + " as anonymous " + idx + " parameter"
|
||||
else result = "declaration of " + idx + " parameter"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ private int isSource(Expr bufferExpr, Element why) {
|
||||
exists(Type bufferType |
|
||||
// buffer is the address of a variable
|
||||
why = bufferExpr.(AddressOfExpr).getAddressable() and
|
||||
bufferType = why.(Variable).getUnspecifiedType() and
|
||||
bufferType = why.(Variable).getType() and
|
||||
result = bufferType.getSize() and
|
||||
not bufferType instanceof ReferenceType and
|
||||
not any(Union u).getAMemberVariable() = why
|
||||
|
||||
@@ -261,17 +261,13 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
model = ""
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
Node node1, FlowState state1, Node node2, FlowState state2, string model
|
||||
) {
|
||||
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1) and
|
||||
model = ""
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1 and
|
||||
model = ""
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(Node node, ContentSet c) {
|
||||
@@ -287,8 +283,6 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||
|
||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { none() }
|
||||
}
|
||||
|
||||
deprecated private import Impl<Config> as I
|
||||
|
||||
@@ -261,17 +261,13 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
model = ""
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
Node node1, FlowState state1, Node node2, FlowState state2, string model
|
||||
) {
|
||||
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1) and
|
||||
model = ""
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1 and
|
||||
model = ""
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(Node node, ContentSet c) {
|
||||
@@ -287,8 +283,6 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||
|
||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { none() }
|
||||
}
|
||||
|
||||
deprecated private import Impl<Config> as I
|
||||
|
||||
@@ -261,17 +261,13 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
model = ""
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
Node node1, FlowState state1, Node node2, FlowState state2, string model
|
||||
) {
|
||||
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1) and
|
||||
model = ""
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1 and
|
||||
model = ""
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(Node node, ContentSet c) {
|
||||
@@ -287,8 +283,6 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||
|
||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { none() }
|
||||
}
|
||||
|
||||
deprecated private import Impl<Config> as I
|
||||
|
||||
@@ -261,17 +261,13 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
model = ""
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
Node node1, FlowState state1, Node node2, FlowState state2, string model
|
||||
) {
|
||||
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1) and
|
||||
model = ""
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1 and
|
||||
model = ""
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(Node node, ContentSet c) {
|
||||
@@ -287,8 +283,6 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||
|
||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { none() }
|
||||
}
|
||||
|
||||
deprecated private import Impl<Config> as I
|
||||
|
||||
@@ -261,17 +261,13 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
model = ""
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
Node node1, FlowState state1, Node node2, FlowState state2, string model
|
||||
) {
|
||||
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1) and
|
||||
model = ""
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1 and
|
||||
model = ""
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(Node node, ContentSet c) {
|
||||
@@ -287,8 +283,6 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||
|
||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { none() }
|
||||
}
|
||||
|
||||
deprecated private import Impl<Config> as I
|
||||
|
||||
@@ -281,9 +281,3 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
|
||||
}
|
||||
|
||||
private predicate iteratorDereference(Call c) { c.getTarget() instanceof IteratorReferenceFunction }
|
||||
|
||||
/**
|
||||
* Holds if the additional step from `src` to `sink` should be considered in
|
||||
* speculative taint flow exploration.
|
||||
*/
|
||||
predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { none() }
|
||||
|
||||
@@ -149,11 +149,6 @@ class Call extends Expr, NameQualifiableElement, TCall {
|
||||
variableAddressEscapesTreeNonConst(va, this.getQualifier().getFullyConverted()) and
|
||||
i = -1
|
||||
}
|
||||
|
||||
/** Holds if this expression could be the return value of an implicitly declared function. */
|
||||
predicate mayBeFromImplicitlyDeclaredFunction() {
|
||||
this.getTarget().getADeclarationEntry().isImplicit()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -181,7 +181,12 @@ class VariableDeclarationEntry extends @var_decl {
|
||||
string getName() { var_decls(this, _, _, result, _) and result != "" }
|
||||
}
|
||||
|
||||
class Parameter extends LocalScopeVariable, @parameter { }
|
||||
class Parameter extends LocalScopeVariable, @parameter {
|
||||
@functionorblock function;
|
||||
int index;
|
||||
|
||||
Parameter() { params(this, function, index, _) }
|
||||
}
|
||||
|
||||
class GlobalOrNamespaceVariable extends Variable, @globalvariable { }
|
||||
|
||||
|
||||
@@ -261,17 +261,13 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
model = ""
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
Node node1, FlowState state1, Node node2, FlowState state2, string model
|
||||
) {
|
||||
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1) and
|
||||
model = ""
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1 and
|
||||
model = ""
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(Node node, ContentSet c) {
|
||||
@@ -287,8 +283,6 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||
|
||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { none() }
|
||||
}
|
||||
|
||||
deprecated private import Impl<Config> as I
|
||||
|
||||
@@ -261,17 +261,13 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
model = ""
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
Node node1, FlowState state1, Node node2, FlowState state2, string model
|
||||
) {
|
||||
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1) and
|
||||
model = ""
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1 and
|
||||
model = ""
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(Node node, ContentSet c) {
|
||||
@@ -287,8 +283,6 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||
|
||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { none() }
|
||||
}
|
||||
|
||||
deprecated private import Impl<Config> as I
|
||||
|
||||
@@ -261,17 +261,13 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
model = ""
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
Node node1, FlowState state1, Node node2, FlowState state2, string model
|
||||
) {
|
||||
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1) and
|
||||
model = ""
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1 and
|
||||
model = ""
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(Node node, ContentSet c) {
|
||||
@@ -287,8 +283,6 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||
|
||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { none() }
|
||||
}
|
||||
|
||||
deprecated private import Impl<Config> as I
|
||||
|
||||
@@ -261,17 +261,13 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
model = ""
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
Node node1, FlowState state1, Node node2, FlowState state2, string model
|
||||
) {
|
||||
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {
|
||||
getConfig(state1).isAdditionalFlowStep(node1, getState(state1), node2, getState(state2)) and
|
||||
getConfig(state2) = getConfig(state1) and
|
||||
model = ""
|
||||
getConfig(state2) = getConfig(state1)
|
||||
or
|
||||
not singleConfiguration() and
|
||||
getConfig(state1).isAdditionalFlowStep(node1, node2) and
|
||||
state2 = state1 and
|
||||
model = ""
|
||||
state2 = state1
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(Node node, ContentSet c) {
|
||||
@@ -287,8 +283,6 @@ deprecated private module Config implements FullStateConfigSig {
|
||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||
|
||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { none() }
|
||||
}
|
||||
|
||||
deprecated private import Impl<Config> as I
|
||||
|
||||
@@ -1328,10 +1328,7 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
|
||||
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
(
|
||||
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() or
|
||||
call.asCallInstruction().getCallTargetOperand() = receiver.asOperand()
|
||||
) and
|
||||
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode() and
|
||||
exists(kind)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ private import SsaInternals as Ssa
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import codeql.util.Unit
|
||||
private import Node0ToString
|
||||
private import DataFlowDispatch as DataFlowDispatch
|
||||
import ExprNodes
|
||||
|
||||
/**
|
||||
@@ -2498,16 +2497,3 @@ class AdditionalCallTarget extends Unit {
|
||||
*/
|
||||
abstract Declaration viableTarget(Call call);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a function that may be called by `call`.
|
||||
*
|
||||
* Note that `call` may be a call to a function pointer expression.
|
||||
*/
|
||||
Function getARuntimeTarget(Call call) {
|
||||
exists(DataFlowCall dfCall | dfCall.asCallInstruction().getUnconvertedResultExpression() = call |
|
||||
result = DataFlowDispatch::viableCallable(dfCall).asSourceCallable()
|
||||
or
|
||||
result = DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -546,7 +546,7 @@ module ProductFlow {
|
||||
Flow1::PathGraph::edges(pred1, succ1, _, _) and
|
||||
exists(ReturnKindExt returnKind |
|
||||
succ1.getNode() = returnKind.getAnOutNode(call) and
|
||||
returnKind = getParamReturnPosition(_, pred1.asParameterReturnNode()).getKind()
|
||||
paramReturnNode(_, pred1.asParameterReturnNode(), _, returnKind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ module ProductFlow {
|
||||
Flow2::PathGraph::edges(pred2, succ2, _, _) and
|
||||
exists(ReturnKindExt returnKind |
|
||||
succ2.getNode() = returnKind.getAnOutNode(call) and
|
||||
returnKind = getParamReturnPosition(_, pred2.asParameterReturnNode()).getKind()
|
||||
paramReturnNode(_, pred2.asParameterReturnNode(), _, returnKind)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -212,30 +212,3 @@ predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut, string
|
||||
nodeOut = callOutput(call, modelOut)
|
||||
)
|
||||
}
|
||||
|
||||
import SpeculativeTaintFlow
|
||||
|
||||
private module SpeculativeTaintFlow {
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as DataFlowDispatch
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||
|
||||
/**
|
||||
* Holds if the additional step from `src` to `sink` should be considered in
|
||||
* speculative taint flow exploration.
|
||||
*/
|
||||
predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
exists(DataFlowCall call, ArgumentPosition argpos |
|
||||
// TODO: exclude neutrals and anything that has QL modeling.
|
||||
not exists(DataFlowDispatch::viableCallable(call)) and
|
||||
src.(DataFlowPrivate::ArgumentNode).argumentOf(call, argpos)
|
||||
|
|
||||
not argpos.(DirectPosition).getIndex() = -1 and
|
||||
sink.(PostUpdateNode)
|
||||
.getPreUpdateNode()
|
||||
.(DataFlowPrivate::ArgumentNode)
|
||||
.argumentOf(call, any(DirectPosition qualpos | qualpos.getIndex() = -1))
|
||||
or
|
||||
sink.(DataFlowPrivate::OutNode).getCall() = call
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ private module Input implements TypeFlowInput<Location> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate step(TypeFlowNode n1, TypeFlowNode n2) {
|
||||
predicate joinStep(TypeFlowNode n1, TypeFlowNode n2) {
|
||||
// instruction -> phi
|
||||
getAnUltimateLocalDefinition(n2.asInstruction()) = n1.asInstruction()
|
||||
or
|
||||
@@ -179,8 +179,6 @@ private module Input implements TypeFlowInput<Location> {
|
||||
n1.asInstruction() = arg and
|
||||
n2.asInstruction() = p
|
||||
)
|
||||
or
|
||||
instructionStep(n1.asInstruction(), n2.asInstruction())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,6 +199,10 @@ private module Input implements TypeFlowInput<Location> {
|
||||
i2.(PointerArithmeticInstruction).getLeft() = i1
|
||||
}
|
||||
|
||||
predicate step(TypeFlowNode n1, TypeFlowNode n2) {
|
||||
instructionStep(n1.asInstruction(), n2.asInstruction())
|
||||
}
|
||||
|
||||
predicate isNullValue(TypeFlowNode n) { n.isNullValue() }
|
||||
|
||||
private newtype TType =
|
||||
@@ -243,7 +245,11 @@ private module Input implements TypeFlowInput<Location> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate upcastCand(TypeFlowNode n, Type t1, Type t2) {
|
||||
exists(TypeFlowNode next | step(n, next) |
|
||||
exists(TypeFlowNode next |
|
||||
step(n, next)
|
||||
or
|
||||
joinStep(n, next)
|
||||
|
|
||||
n.getType() = t1 and
|
||||
next.getType() = t2 and
|
||||
t1 != t2
|
||||
|
||||
@@ -6,112 +6,6 @@
|
||||
* uses, however, it is better to write a query that imports `PrintIR.qll`, extends
|
||||
* `PrintIRConfiguration`, and overrides `shouldPrintDeclaration()` to select a subset of declarations
|
||||
* to dump.
|
||||
*
|
||||
* Anatomy of a printed IR instruction
|
||||
*
|
||||
* An instruction:
|
||||
*
|
||||
* ```
|
||||
* # 2281| v2281_19(void) = Call[~String] : func:r2281_18, this:r2281_17
|
||||
* ```
|
||||
*
|
||||
* The prefix `# 2281|` specifies that this instruction was generated by the C++ source code on line 2281.
|
||||
* Scrolling up in the printed output, one will eventually find the name of the file to which the line
|
||||
* belongs.
|
||||
*
|
||||
* `v2281_19(void)` is the result of the instruction. Here, `v` means this is a void result or operand (so
|
||||
* there should be no later uses of the result; see below for other possible values). The `2281_19` is a
|
||||
* unique ID for the result. This is usually just the line number plus a small integer suffix to make it
|
||||
* unique within the function. The type of the result is `void`. In this case, it is `void`, because
|
||||
* `~String` returns `void`. The type of the result is usually just the name of the appropriate C++ type,
|
||||
* but it will sometimes be a type like `glval<int>`, which means result holds a glvalue, which at the
|
||||
* IR level works like a pointer. In other words, in the source code the type was `int`, but it is really
|
||||
* more like an `int*`. We see this, for example, in `x = y;`, where `x` is a glvalue.
|
||||
*
|
||||
* `Call` is the opcode of the instruction. Common opcodes include:
|
||||
*
|
||||
* * Arithmetic operations: `Add`, `Sub`, `Mul`, etc.
|
||||
* * Memory access operations: `Load`, `Store`.
|
||||
* * Function calls: `Call`.
|
||||
* * Literals: `Constant`.
|
||||
* * Variable addresses: `VariableAddress`.
|
||||
* * Function entry points: `EnterFunction`.
|
||||
* * Return from a function: `Return`, `ReturnVoid`. Note that the value being returned is set separately by a
|
||||
* `Store` to a special `#return` variable.
|
||||
* * Stack unwinding for C++ function that throw and where the exception escapes the function: `Unwind`.
|
||||
* * Common exit point for `Unwind` and `Return`: `ExitFunction`.
|
||||
* * SSA-related opcodes: `Phi`, `Chi`.
|
||||
*
|
||||
* `[~String]` denotes additional information. The information might be present earlier in the IR, as is the case
|
||||
* for `Call`, where it is the name of the called function. This is also the case for `Load` and `Store`, where it
|
||||
* is the name of the variable that loaded or stored (if known). In the case of `Constant`, `FieldAddress`, and
|
||||
* `VariableAddress`, the information between brackets does not occur earlier.
|
||||
*
|
||||
* `func:r2281_18` and `this:r28281_17` are the operands of the instruction. The `func:` prefix denotes the operand
|
||||
* that holds the address of the called function. The `this:` prefix denotes the argument to the special `this`
|
||||
* parameter of an instance member function. `r2281_18`, `r2281_17` are the unique IDs of the operands. Each of these
|
||||
* matches the ID of a previously seen result, showing where that value came from. The `r` means that these are
|
||||
* "register" operands (see below).
|
||||
*
|
||||
* Result and operand kinds:
|
||||
*
|
||||
* Every result and operand is one of these three kinds:
|
||||
*
|
||||
* * `r` "register". These operands are not stored in any particular memory location. We can think of them as
|
||||
* temporary values created during the evaluation of an expression. A register operand almost always has one
|
||||
* use, often in the same block as its definition.
|
||||
* * `m` "memory". These operands represents accesses to a specific memory location. The location could be a
|
||||
* local variable, a global variable, a field of an object, an element of an array, or any memory that we happen
|
||||
* to have a pointer to. These only occur as the result of a `Store`, the source operand of a `Load` or on the
|
||||
* SSA instructions (`Phi`, `Chi`).
|
||||
* * `v` "void". Really just a register operand, but we mark register operands of type void with this special prefix
|
||||
* so we know that there is no actual value there.
|
||||
*
|
||||
* Branches in the IR:
|
||||
*
|
||||
* The IR is divided into basic blocks. At the end of each block, there are one or more edges showing the possible
|
||||
* control flow successors of the block.
|
||||
*
|
||||
* ```
|
||||
* # 44| v44_3(void) = ConditionalBranch : r44_2
|
||||
* #-----| False -> Block 4
|
||||
* #-----| True -> Block 3
|
||||
* ```
|
||||
* Here we have a block that ends with a conditional branch. The two edges show where the control flows to depending
|
||||
* on whether the condition is true or false.
|
||||
*
|
||||
* SSA instructions:
|
||||
*
|
||||
* We use `Phi` instructions in SSA to create a single definition for a variable that might be assigned on multiple
|
||||
* control flow paths. The `Phi` instruction merges the potential values of that variable from each predecessor edge,
|
||||
* and the resulting definition is then used wherever that variable is accessed later on.
|
||||
*
|
||||
* When dealing with aliased memory, we use the `Chi` instruction to create a single definition for memory that might
|
||||
* or might not have been updated by a store, depending on the actual address that was written to. For example, take:
|
||||
*
|
||||
* ```cpp
|
||||
* int x = 5;
|
||||
* int y = 7;
|
||||
* int* p = condition ? &x : &y;
|
||||
* *p = 6;
|
||||
* return x;
|
||||
* ```
|
||||
*
|
||||
* At the point where we store to `*p`, we do not know whether `p` points to `x` or `y`. Thus, we do not know whether
|
||||
* `return x;` is going to return the value that `x` was originally initialized to (5), or whether it will return 6,
|
||||
* because it was overwritten by `*p = 6;`. We insert a `Chi` instruction immediately after the store to `*p`:
|
||||
*
|
||||
* ```
|
||||
* r2(int) = Constant[6]
|
||||
* r3(int*) = <<value of p>>
|
||||
* m4(int) = Store : &r3, r2 // Stores the constant 6 to *p
|
||||
* m5(unknown) = Chi : total:m1, partial:m4
|
||||
* ```
|
||||
* The `partial:` operand represents the memory that was just stored. The `total:` operand represents the previous
|
||||
* contents of all of the memory that `p` might have pointed to (in this case, both `x` and `y`). The result of the
|
||||
* `Chi` represents the new contents of whatever memory the `total:` operand referred to. We usually do not know exactly
|
||||
* which parts of that memory were overwritten, but it does model that any of that memory could have been modified, so
|
||||
* that later instructions do not assume that the memory was unchanged.
|
||||
*/
|
||||
|
||||
private import internal.IRInternal
|
||||
|
||||
@@ -683,13 +683,8 @@ private Overlap getExtentOverlap(MemoryLocation0 def, MemoryLocation0 use) {
|
||||
def.getVirtualVariable() = use.getVirtualVariable() and
|
||||
def instanceof EntireAllocationMemoryLocation and
|
||||
(
|
||||
// EntireAllocationMemoryLocation exactly overlaps any EntireAllocationMemoryLocation for the
|
||||
// same allocation. Checking the allocation, rather than the memory location itself, ensures
|
||||
// that we get the right relationship between the "must" and "may" memory locations for that
|
||||
// allocation.
|
||||
// Note that if one of the locations is a "may" access, the overlap will be downgraded to
|
||||
// `MustTotallyOverlap` or `MayPartialOverlap` in `getOverlap()`.
|
||||
use.(EntireAllocationMemoryLocation).getAnAllocation() = def.getAnAllocation() and
|
||||
// EntireAllocationMemoryLocation exactly overlaps itself.
|
||||
use instanceof EntireAllocationMemoryLocation and
|
||||
result instanceof MustExactlyOverlap
|
||||
or
|
||||
not use instanceof EntireAllocationMemoryLocation and
|
||||
|
||||
@@ -6,112 +6,6 @@
|
||||
* uses, however, it is better to write a query that imports `PrintIR.qll`, extends
|
||||
* `PrintIRConfiguration`, and overrides `shouldPrintDeclaration()` to select a subset of declarations
|
||||
* to dump.
|
||||
*
|
||||
* Anatomy of a printed IR instruction
|
||||
*
|
||||
* An instruction:
|
||||
*
|
||||
* ```
|
||||
* # 2281| v2281_19(void) = Call[~String] : func:r2281_18, this:r2281_17
|
||||
* ```
|
||||
*
|
||||
* The prefix `# 2281|` specifies that this instruction was generated by the C++ source code on line 2281.
|
||||
* Scrolling up in the printed output, one will eventually find the name of the file to which the line
|
||||
* belongs.
|
||||
*
|
||||
* `v2281_19(void)` is the result of the instruction. Here, `v` means this is a void result or operand (so
|
||||
* there should be no later uses of the result; see below for other possible values). The `2281_19` is a
|
||||
* unique ID for the result. This is usually just the line number plus a small integer suffix to make it
|
||||
* unique within the function. The type of the result is `void`. In this case, it is `void`, because
|
||||
* `~String` returns `void`. The type of the result is usually just the name of the appropriate C++ type,
|
||||
* but it will sometimes be a type like `glval<int>`, which means result holds a glvalue, which at the
|
||||
* IR level works like a pointer. In other words, in the source code the type was `int`, but it is really
|
||||
* more like an `int*`. We see this, for example, in `x = y;`, where `x` is a glvalue.
|
||||
*
|
||||
* `Call` is the opcode of the instruction. Common opcodes include:
|
||||
*
|
||||
* * Arithmetic operations: `Add`, `Sub`, `Mul`, etc.
|
||||
* * Memory access operations: `Load`, `Store`.
|
||||
* * Function calls: `Call`.
|
||||
* * Literals: `Constant`.
|
||||
* * Variable addresses: `VariableAddress`.
|
||||
* * Function entry points: `EnterFunction`.
|
||||
* * Return from a function: `Return`, `ReturnVoid`. Note that the value being returned is set separately by a
|
||||
* `Store` to a special `#return` variable.
|
||||
* * Stack unwinding for C++ function that throw and where the exception escapes the function: `Unwind`.
|
||||
* * Common exit point for `Unwind` and `Return`: `ExitFunction`.
|
||||
* * SSA-related opcodes: `Phi`, `Chi`.
|
||||
*
|
||||
* `[~String]` denotes additional information. The information might be present earlier in the IR, as is the case
|
||||
* for `Call`, where it is the name of the called function. This is also the case for `Load` and `Store`, where it
|
||||
* is the name of the variable that loaded or stored (if known). In the case of `Constant`, `FieldAddress`, and
|
||||
* `VariableAddress`, the information between brackets does not occur earlier.
|
||||
*
|
||||
* `func:r2281_18` and `this:r28281_17` are the operands of the instruction. The `func:` prefix denotes the operand
|
||||
* that holds the address of the called function. The `this:` prefix denotes the argument to the special `this`
|
||||
* parameter of an instance member function. `r2281_18`, `r2281_17` are the unique IDs of the operands. Each of these
|
||||
* matches the ID of a previously seen result, showing where that value came from. The `r` means that these are
|
||||
* "register" operands (see below).
|
||||
*
|
||||
* Result and operand kinds:
|
||||
*
|
||||
* Every result and operand is one of these three kinds:
|
||||
*
|
||||
* * `r` "register". These operands are not stored in any particular memory location. We can think of them as
|
||||
* temporary values created during the evaluation of an expression. A register operand almost always has one
|
||||
* use, often in the same block as its definition.
|
||||
* * `m` "memory". These operands represents accesses to a specific memory location. The location could be a
|
||||
* local variable, a global variable, a field of an object, an element of an array, or any memory that we happen
|
||||
* to have a pointer to. These only occur as the result of a `Store`, the source operand of a `Load` or on the
|
||||
* SSA instructions (`Phi`, `Chi`).
|
||||
* * `v` "void". Really just a register operand, but we mark register operands of type void with this special prefix
|
||||
* so we know that there is no actual value there.
|
||||
*
|
||||
* Branches in the IR:
|
||||
*
|
||||
* The IR is divided into basic blocks. At the end of each block, there are one or more edges showing the possible
|
||||
* control flow successors of the block.
|
||||
*
|
||||
* ```
|
||||
* # 44| v44_3(void) = ConditionalBranch : r44_2
|
||||
* #-----| False -> Block 4
|
||||
* #-----| True -> Block 3
|
||||
* ```
|
||||
* Here we have a block that ends with a conditional branch. The two edges show where the control flows to depending
|
||||
* on whether the condition is true or false.
|
||||
*
|
||||
* SSA instructions:
|
||||
*
|
||||
* We use `Phi` instructions in SSA to create a single definition for a variable that might be assigned on multiple
|
||||
* control flow paths. The `Phi` instruction merges the potential values of that variable from each predecessor edge,
|
||||
* and the resulting definition is then used wherever that variable is accessed later on.
|
||||
*
|
||||
* When dealing with aliased memory, we use the `Chi` instruction to create a single definition for memory that might
|
||||
* or might not have been updated by a store, depending on the actual address that was written to. For example, take:
|
||||
*
|
||||
* ```cpp
|
||||
* int x = 5;
|
||||
* int y = 7;
|
||||
* int* p = condition ? &x : &y;
|
||||
* *p = 6;
|
||||
* return x;
|
||||
* ```
|
||||
*
|
||||
* At the point where we store to `*p`, we do not know whether `p` points to `x` or `y`. Thus, we do not know whether
|
||||
* `return x;` is going to return the value that `x` was originally initialized to (5), or whether it will return 6,
|
||||
* because it was overwritten by `*p = 6;`. We insert a `Chi` instruction immediately after the store to `*p`:
|
||||
*
|
||||
* ```
|
||||
* r2(int) = Constant[6]
|
||||
* r3(int*) = <<value of p>>
|
||||
* m4(int) = Store : &r3, r2 // Stores the constant 6 to *p
|
||||
* m5(unknown) = Chi : total:m1, partial:m4
|
||||
* ```
|
||||
* The `partial:` operand represents the memory that was just stored. The `total:` operand represents the previous
|
||||
* contents of all of the memory that `p` might have pointed to (in this case, both `x` and `y`). The result of the
|
||||
* `Chi` represents the new contents of whatever memory the `total:` operand referred to. We usually do not know exactly
|
||||
* which parts of that memory were overwritten, but it does model that any of that memory could have been modified, so
|
||||
* that later instructions do not assume that the memory was unchanged.
|
||||
*/
|
||||
|
||||
private import internal.IRInternal
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user