diff --git a/.codeqlmanifest.json b/.codeqlmanifest.json
index 4efe12f6d2b..c4d4260a2cc 100644
--- a/.codeqlmanifest.json
+++ b/.codeqlmanifest.json
@@ -1,8 +1,11 @@
-{ "provide": [ "*/ql/src/qlpack.yml",
+{ "provide": [ "ruby/.codeqlmanifest.json",
+ "*/ql/src/qlpack.yml",
"*/ql/lib/qlpack.yml",
"*/ql/test/qlpack.yml",
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
"*/ql/examples/qlpack.yml",
"*/upgrades/qlpack.yml",
+ "javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
+ "javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
"misc/legacy-support/*/qlpack.yml",
"misc/suite-helpers/qlpack.yml" ] }
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 8f9ffdde4de..ff73bcb4e7b 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,9 +1,14 @@
{
"extensions": [
+ "rust-lang.rust",
+ "bungcip.better-toml",
"github.vscode-codeql",
"slevesque.vscode-zipexplorer"
],
"settings": {
+ "files.watcherExclude": {
+ "**/target/**": true
+ },
"codeQL.runningQueries.memory": 2048
}
}
diff --git a/.github/actions/fetch-codeql/action.yml b/.github/actions/fetch-codeql/action.yml
new file mode 100644
index 00000000000..de6d50dc12f
--- /dev/null
+++ b/.github/actions/fetch-codeql/action.yml
@@ -0,0 +1,14 @@
+name: Fetch CodeQL
+description: Fetches the latest version of CodeQL
+runs:
+ using: composite
+ steps:
+ - name: Fetch CodeQL
+ shell: bash
+ run: |
+ LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1)
+ gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST"
+ unzip -q codeql-linux64.zip
+ echo "${{ github.workspace }}/codeql" >> $GITHUB_PATH
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000000..613f9287146
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,18 @@
+version: 2
+updates:
+ - package-ecosystem: "cargo"
+ directory: "ruby/node-types"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "cargo"
+ directory: "ruby/generator"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "cargo"
+ directory: "ruby/extractor"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "cargo"
+ directory: "ruby/autobuilder"
+ schedule:
+ interval: "daily"
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 17fac6dc765..87b97436ad9 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -18,6 +18,10 @@ Python:
- python/**/*
- change-notes/**/*python*
+Ruby:
+ - ruby/**/*
+ - change-notes/**/*ruby*
+
documentation:
- "**/*.qhelp"
- "**/*.md"
diff --git a/.github/workflows/csv-coverage-pr-artifacts.yml b/.github/workflows/csv-coverage-pr-artifacts.yml
index 201eea5c073..8b89b9b22c1 100644
--- a/.github/workflows/csv-coverage-pr-artifacts.yml
+++ b/.github/workflows/csv-coverage-pr-artifacts.yml
@@ -6,6 +6,8 @@ on:
- '.github/workflows/csv-coverage-pr-comment.yml'
- '*/ql/src/**/*.ql'
- '*/ql/src/**/*.qll'
+ - '*/ql/lib/**/*.ql'
+ - '*/ql/lib/**/*.qll'
- 'misc/scripts/library-coverage/*.py'
# input data files
- '*/documentation/library-coverage/cwe-sink.csv'
diff --git a/.github/workflows/qhelp-pr-preview.yml b/.github/workflows/qhelp-pr-preview.yml
new file mode 100644
index 00000000000..7e2ea6a10f8
--- /dev/null
+++ b/.github/workflows/qhelp-pr-preview.yml
@@ -0,0 +1,39 @@
+name: Query help preview
+
+on:
+ pull_request:
+ branches:
+ - main
+ - 'rc/*'
+ paths:
+ - "ruby/**/*.qhelp"
+
+jobs:
+ qhelp:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 2
+ - name: Determine changed files
+ id: changes
+ run: |
+ echo -n "::set-output name=qhelp_files::"
+ (git diff --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep .qhelp$ | grep -v .inc.qhelp;
+ git diff --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep .inc.qhelp$ | xargs -d '\n' -rn1 basename | xargs -d '\n' -rn1 git grep -l) |
+ sort -u | xargs -d '\n' -n1 printf "'%s' "
+
+ - uses: ./.github/actions/fetch-codeql
+
+ - name: QHelp preview
+ if: ${{ steps.changes.outputs.qhelp_files }}
+ run: |
+ ( echo "QHelp previews:";
+ for path in ${{ steps.changes.outputs.qhelp_files }} ; do
+ echo "${path}"
+ echo
+ codeql generate query-help --format=markdown ${path}
+ echo ""
+ done) | gh pr comment "${{ github.event.pull_request.number }}" -F -
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml
new file mode 100644
index 00000000000..4361ce5a1cc
--- /dev/null
+++ b/.github/workflows/ruby-build.yml
@@ -0,0 +1,232 @@
+name: "Ruby: Build"
+
+on:
+ push:
+ paths:
+ - 'ruby/**'
+ branches:
+ - main
+ - 'rc/*'
+ pull_request:
+ paths:
+ - 'ruby/**'
+ branches:
+ - main
+ - 'rc/*'
+ workflow_dispatch:
+ inputs:
+ tag:
+ description: "Version tag to create"
+ required: false
+
+env:
+ CARGO_TERM_COLOR: always
+
+defaults:
+ run:
+ working-directory: ruby
+
+jobs:
+ build:
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install GNU tar
+ if: runner.os == 'macOS'
+ run: |
+ brew install gnu-tar
+ echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.cargo/registry
+ ~/.cargo/git
+ ruby/target
+ key: ${{ runner.os }}-rust-cargo-${{ hashFiles('**/Cargo.lock') }}
+ - name: Check formatting
+ run: cargo fmt --all -- --check
+ - name: Build
+ run: cargo build --verbose
+ - name: Run tests
+ run: cargo test --verbose
+ - name: Release build
+ run: cargo build --release
+ - name: Generate dbscheme
+ if: ${{ matrix.os == 'ubuntu-latest' }}
+ run: target/release/ruby-generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
+ - uses: actions/upload-artifact@v2
+ if: ${{ matrix.os == 'ubuntu-latest' }}
+ with:
+ name: ruby.dbscheme
+ path: ruby/ql/lib/ruby.dbscheme
+ - uses: actions/upload-artifact@v2
+ if: ${{ matrix.os == 'ubuntu-latest' }}
+ with:
+ name: TreeSitter.qll
+ path: ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
+ - uses: actions/upload-artifact@v2
+ with:
+ name: extractor-${{ matrix.os }}
+ path: |
+ ruby/target/release/ruby-autobuilder
+ ruby/target/release/ruby-autobuilder.exe
+ ruby/target/release/ruby-extractor
+ ruby/target/release/ruby-extractor.exe
+ retention-days: 1
+ compile-queries:
+ runs-on: ubuntu-latest
+ env:
+ CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI
+ steps:
+ - uses: actions/checkout@v2
+ - name: Fetch CodeQL
+ run: |
+ LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1)
+ gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST"
+ unzip -q codeql-linux64.zip
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ - name: Build Query Pack
+ run: |
+ codeql/codeql pack create ql/lib --output target/packs
+ codeql/codeql pack install ql/src
+ codeql/codeql pack create ql/src --output target/packs
+ PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
+ codeql/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}/{}" \;)
+ - name: Compile with previous CodeQL versions
+ run: |
+ for version in $(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | tail -3 | head -2); do
+ rm -f codeql-linux64.zip
+ gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$version"
+ rm -rf codeql; unzip -q codeql-linux64.zip
+ codeql/codeql query compile target/packs/*
+ done
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ - uses: actions/upload-artifact@v2
+ with:
+ name: codeql-ruby-queries
+ path: |
+ ruby/target/packs/*
+ retention-days: 1
+
+ package:
+ runs-on: ubuntu-latest
+ needs: [build, compile-queries]
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/download-artifact@v2
+ with:
+ name: ruby.dbscheme
+ path: ruby/ruby
+ - uses: actions/download-artifact@v2
+ with:
+ name: extractor-ubuntu-latest
+ path: ruby/linux64
+ - uses: actions/download-artifact@v2
+ with:
+ name: extractor-windows-latest
+ path: ruby/win64
+ - uses: actions/download-artifact@v2
+ with:
+ name: extractor-macos-latest
+ path: ruby/osx64
+ - run: |
+ mkdir -p ruby
+ cp -r codeql-extractor.yml tools ql/lib/ruby.dbscheme.stats ruby/
+ mkdir -p ruby/tools/{linux64,osx64,win64}
+ cp linux64/ruby-autobuilder ruby/tools/linux64/autobuilder
+ cp osx64/ruby-autobuilder ruby/tools/osx64/autobuilder
+ cp win64/ruby-autobuilder.exe ruby/tools/win64/autobuilder.exe
+ cp linux64/ruby-extractor ruby/tools/linux64/extractor
+ cp osx64/ruby-extractor ruby/tools/osx64/extractor
+ cp win64/ruby-extractor.exe ruby/tools/win64/extractor.exe
+ chmod +x ruby/tools/{linux64,osx64}/{autobuilder,extractor}
+ zip -rq codeql-ruby.zip ruby
+ - uses: actions/upload-artifact@v2
+ with:
+ name: codeql-ruby-pack
+ path: ruby/codeql-ruby.zip
+ retention-days: 1
+ - uses: actions/download-artifact@v2
+ with:
+ name: codeql-ruby-queries
+ path: ruby/qlpacks
+ - run: |
+ echo '{
+ "provide": [
+ "ruby/codeql-extractor.yml",
+ "qlpacks/*/*/*/qlpack.yml"
+ ]
+ }' > .codeqlmanifest.json
+ zip -rq codeql-ruby-bundle.zip .codeqlmanifest.json ruby qlpacks
+ - uses: actions/upload-artifact@v2
+ with:
+ name: codeql-ruby-bundle
+ path: ruby/codeql-ruby-bundle.zip
+ retention-days: 1
+
+ test:
+ defaults:
+ run:
+ working-directory: ${{ github.workspace }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+
+ runs-on: ${{ matrix.os }}
+ needs: [package]
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ repository: Shopify/example-ruby-app
+ ref: 67a0decc5eb550f3a9228eda53925c3afd40dfe9
+ - name: Fetch CodeQL
+ shell: bash
+ run: |
+ LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1)
+ gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql.zip "$LATEST"
+ unzip -q codeql.zip
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ working-directory: ${{ runner.temp }}
+ - name: Download Ruby bundle
+ uses: actions/download-artifact@v2
+ with:
+ name: codeql-ruby-bundle
+ path: ${{ runner.temp }}
+ - name: Unzip Ruby bundle
+ shell: bash
+ run: unzip -q -d "${{ runner.temp }}/ruby-bundle" "${{ runner.temp }}/codeql-ruby-bundle.zip"
+ - name: Prepare test files
+ shell: bash
+ run: |
+ echo "import ruby select count(File f)" > "test.ql"
+ echo "| 4 |" > "test.expected"
+ echo 'name: sample-tests
+ version: 0.0.0
+ dependencies:
+ codeql/ruby-all: 0.0.1
+ extractor: ruby
+ tests: .
+ ' > qlpack.yml
+ - name: Run QL test
+ shell: bash
+ run: |
+ "${{ runner.temp }}/codeql/codeql" test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" .
+ - name: Create database
+ shell: bash
+ run: |
+ "${{ runner.temp }}/codeql/codeql" database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root . ../database
+ - name: Analyze database
+ shell: bash
+ run: |
+ "${{ runner.temp }}/codeql/codeql" database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls
diff --git a/.github/workflows/ruby-dataset-measure.yml b/.github/workflows/ruby-dataset-measure.yml
new file mode 100644
index 00000000000..39e5a8486d6
--- /dev/null
+++ b/.github/workflows/ruby-dataset-measure.yml
@@ -0,0 +1,71 @@
+name: "Ruby: Collect database stats"
+
+on:
+ push:
+ branches:
+ - main
+ - 'rc/*'
+ paths:
+ - ruby/ql/lib/ruby.dbscheme
+ pull_request:
+ branches:
+ - main
+ - 'rc/*'
+ paths:
+ - ruby/ql/lib/ruby.dbscheme
+ workflow_dispatch:
+
+jobs:
+ measure:
+ env:
+ CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI
+ strategy:
+ fail-fast: false
+ matrix:
+ repo: [rails/rails, discourse/discourse, spree/spree]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+
+ - uses: ./.github/actions/fetch-codeql
+
+ - uses: ./ruby/actions/create-extractor-pack
+
+ - name: Checkout ${{ matrix.repo }}
+ uses: actions/checkout@v2
+ with:
+ repository: ${{ matrix.repo }}
+ path: ${{ github.workspace }}/repo
+ - name: Create database
+ run: |
+ codeql database create \
+ --search-path "${{ github.workspace }}/ruby" \
+ --threads 4 \
+ --language ruby --source-root "${{ github.workspace }}/repo" \
+ "${{ runner.temp }}/database"
+ - name: Measure database
+ 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@v2
+ with:
+ name: measurements
+ path: stats
+ retention-days: 1
+
+ merge:
+ runs-on: ubuntu-latest
+ needs: measure
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/download-artifact@v2
+ 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@v2
+ with:
+ name: ruby.dbscheme.stats
+ path: ruby/ql/lib/ruby.dbscheme.stats
diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml
new file mode 100644
index 00000000000..fad38bf689e
--- /dev/null
+++ b/.github/workflows/ruby-qltest.yml
@@ -0,0 +1,48 @@
+name: "Ruby: Run QL Tests"
+
+on:
+ push:
+ paths:
+ - 'ruby/**'
+ branches:
+ - main
+ - 'rc/*'
+ pull_request:
+ paths:
+ - 'ruby/**'
+ branches:
+ - main
+ - 'rc/*'
+
+env:
+ CARGO_TERM_COLOR: always
+
+defaults:
+ run:
+ working-directory: ruby
+
+jobs:
+ qltest:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: ./.github/actions/fetch-codeql
+ - uses: ./ruby/actions/create-extractor-pack
+ - name: Run QL tests
+ run: |
+ codeql test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ruby" --additional-packs "${{ github.workspace }}" --consistency-queries ql/consistency-queries ql/test
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ - name: Check QL formatting
+ run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
+ - name: Check QL compilation
+ run: |
+ codeql query compile --check-only --threads=4 --warnings=error --search-path "${{ github.workspace }}/ruby" --additional-packs "${{ github.workspace }}" "ql/src" "ql/examples"
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ - name: Check DB upgrade scripts
+ run: |
+ echo >empty.trap
+ codeql dataset import -S ql/lib/upgrades/initial/ruby.dbscheme testdb empty.trap
+ codeql dataset upgrade testdb --additional-packs ql/lib/upgrades
+ diff -q testdb/ruby.dbscheme ql/lib/ruby.dbscheme
diff --git a/.github/workflows/sync-files.yml b/.github/workflows/sync-files.yml
new file mode 100644
index 00000000000..e41f4b75dc6
--- /dev/null
+++ b/.github/workflows/sync-files.yml
@@ -0,0 +1,20 @@
+name: Check synchronized files
+
+on:
+ push:
+ branches:
+ - main
+ - 'rc/*'
+ pull_request:
+ branches:
+ - main
+ - 'rc/*'
+
+jobs:
+ sync:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Check synchronized files
+ run: python config/sync-files.py
+
diff --git a/.gitignore b/.gitignore
index 0951496d45c..bf37ce08333 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,6 @@
/codeql/
csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
+
+# Avoid committing cached package components
+.codeql
diff --git a/CODEOWNERS b/CODEOWNERS
index 89529f95924..d5f3362a7ca 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -3,6 +3,7 @@
/java/ @github/codeql-java
/javascript/ @github/codeql-javascript
/python/ @github/codeql-python
+/ruby/ @github/codeql-ruby
# Make @xcorail (GitHub Security Lab) a code owner for experimental queries so he gets pinged when we promote a query out of experimental
/cpp/**/experimental/**/* @github/codeql-c-analysis @xcorail
@@ -10,6 +11,7 @@
/java/**/experimental/**/* @github/codeql-java @xcorail
/javascript/**/experimental/**/* @github/codeql-javascript @xcorail
/python/**/experimental/**/* @github/codeql-python @xcorail
+/ruby/**/experimental/**/* @github/codeql-ruby @xcorail
# Notify members of codeql-go about PRs to the shared data-flow library files
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @github/codeql-java @github/codeql-go
@@ -22,4 +24,4 @@
/docs/codeql-cli/ @github/codeql-cli-reviewers
/docs/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
/docs/ql-language-reference/ @github/codeql-frontend-reviewers
-/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
\ No newline at end of file
+/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
diff --git a/config/identical-files.json b/config/identical-files.json
index 74ef7b82323..a60bd919028 100644
--- a/config/identical-files.json
+++ b/config/identical-files.json
@@ -24,14 +24,17 @@
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
- "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll"
+ "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll",
+ "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll",
+ "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll"
],
"DataFlow Java/C++/C#/Python Common": [
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll",
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll",
- "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll"
+ "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll",
+ "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll"
],
"TaintTracking::Configuration Java/C++/C#/Python": [
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
@@ -49,18 +52,21 @@
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTrackingImpl.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll",
- "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll"
+ "python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll",
+ "ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll"
],
"DataFlow Java/C++/C#/Python Consistency checks": [
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll",
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll",
- "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll"
+ "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll",
+ "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll"
],
"DataFlow Java/C# Flow Summaries": [
"java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
- "csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll"
+ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll",
+ "ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll"
],
"SsaReadPosition Java/C#": [
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
@@ -367,8 +373,10 @@
],
"Inline Test Expectations": [
"cpp/ql/test/TestUtilities/InlineExpectationsTest.qll",
+ "csharp/ql/test/TestUtilities/InlineExpectationsTest.qll",
"java/ql/test/TestUtilities/InlineExpectationsTest.qll",
- "python/ql/test/TestUtilities/InlineExpectationsTest.qll"
+ "python/ql/test/TestUtilities/InlineExpectationsTest.qll",
+ "ruby/ql/test/TestUtilities/InlineExpectationsTest.qll"
],
"C++ ExternalAPIs": [
"cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll",
@@ -440,7 +448,8 @@
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
- "csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll"
+ "csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll",
+ "ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImplCommon.qll"
],
"CryptoAlgorithms Python/JS": [
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
@@ -460,6 +469,23 @@
],
"ReDoS Polynomial Python/JS": [
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
- "python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll"
+ "python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll",
+ "ruby/ql/lib/codeql/ruby/regexp/SuperlinearBackTracking.qll"
+ ],
+ "CFG": [
+ "csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
+ "ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll"
+ ],
+ "TypeTracker": [
+ "python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll",
+ "ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll"
+ ],
+ "CodeQL Tutorial": [
+ "cpp/ql/lib/tutorial.qll",
+ "csharp/ql/lib/tutorial.qll",
+ "java/ql/lib/tutorial.qll",
+ "javascript/ql/lib/tutorial.qll",
+ "python/ql/lib/tutorial.qll",
+ "ruby/ql/lib/tutorial.qll"
]
-}
\ No newline at end of file
+}
diff --git a/cpp/change-notes/2021-06-10-cleartext-transmission.md b/cpp/change-notes/2021-06-10-cleartext-transmission.md
new file mode 100644
index 00000000000..ce6debf1407
--- /dev/null
+++ b/cpp/change-notes/2021-06-10-cleartext-transmission.md
@@ -0,0 +1,2 @@
+lgtm,codescanning
+* A new query (`cpp/cleartext-transmission`) has been added. This is similar to the `cpp/cleartext-storage-file`, `cpp/cleartext-storage-buffer` and `cpp/cleartext-storage-database` queries but looks for cases where sensitive information is most likely transmitted over a network.
diff --git a/cpp/change-notes/2021-09-27-command-line-injection.md b/cpp/change-notes/2021-09-27-command-line-injection.md
new file mode 100644
index 00000000000..53ce1fd1dbe
--- /dev/null
+++ b/cpp/change-notes/2021-09-27-command-line-injection.md
@@ -0,0 +1,2 @@
+lgtm,codescanning
+* The "Uncontrolled data used in OS command" (`cpp/command-line-injection`) query has been enhanced to reduce false positive results and its `@precision` increased to `high`
\ No newline at end of file
diff --git a/cpp/change-notes/2021-09-27-overflow-static.md b/cpp/change-notes/2021-09-27-overflow-static.md
new file mode 100644
index 00000000000..e28ba4970ce
--- /dev/null
+++ b/cpp/change-notes/2021-09-27-overflow-static.md
@@ -0,0 +1,3 @@
+lgtm,codescanning
+* Increase precision to high for the "Static buffer overflow" query
+ (`cpp/static-buffer-overflow`). This means the query is run and displayed by default on Code Scanning and LGTM.
diff --git a/cpp/change-notes/2021-10-01-improper-null-termination.md b/cpp/change-notes/2021-10-01-improper-null-termination.md
new file mode 100644
index 00000000000..fc569913ccf
--- /dev/null
+++ b/cpp/change-notes/2021-10-01-improper-null-termination.md
@@ -0,0 +1,2 @@
+lgtm,codescanning
+* Several improvements made to the `NullTermination.qll` library and the 'Potential improper null termination' (cpp/improper-null-termination). These changes reduce the number of false positive results for this query and related query 'User-controlled data may not be null terminated' (cpp/user-controlled-null-termination-tainted).
diff --git a/cpp/change-notes/2021-10-07-extraction-errors.md b/cpp/change-notes/2021-10-07-extraction-errors.md
new file mode 100644
index 00000000000..d4d00afb77a
--- /dev/null
+++ b/cpp/change-notes/2021-10-07-extraction-errors.md
@@ -0,0 +1,3 @@
+codescanning
+* Problems with extraction that in most cases won't break the analysis in a significant way are now reported as warnings rather than errors.
+* The failed extractor invocations query now has severity `error`.
diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateCleartextWrite.qll b/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateCleartextWrite.qll
index 922dadaa20e..5438722fd08 100644
--- a/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateCleartextWrite.qll
+++ b/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateCleartextWrite.qll
@@ -52,11 +52,8 @@ module PrivateCleartextWrite {
class WriteSink extends Sink {
WriteSink() {
- exists(FileWrite f, BufferWrite b |
- this.asExpr() = f.getASource()
- or
- this.asExpr() = b.getAChild()
- )
+ this.asExpr() = any(FileWrite f).getASource() or
+ this.asExpr() = any(BufferWrite b).getAChild()
}
}
}
diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateData.qll b/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateData.qll
index 621e8aad707..ec37e8ce86c 100644
--- a/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateData.qll
+++ b/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateData.qll
@@ -13,26 +13,25 @@ import cpp
/** A string for `match` that identifies strings that look like they represent private data. */
private string privateNames() {
- // Inspired by the list on https://cwe.mitre.org/data/definitions/359.html
- // Government identifiers, such as Social Security Numbers
- result = "%social%security%number%" or
- // Contact information, such as home addresses and telephone numbers
- result = "%postcode%" or
- result = "%zipcode%" or
- // result = "%telephone%" or
- // Geographic location - where the user is (or was)
- result = "%latitude%" or
- result = "%longitude%" or
- // Financial data - such as credit card numbers, salary, bank accounts, and debts
- result = "%creditcard%" or
- result = "%salary%" or
- result = "%bankaccount%" or
- // Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc.
- // result = "%email%" or
- // result = "%mobile%" or
- result = "%employer%" or
- // Health - medical conditions, insurance status, prescription records
- result = "%medical%"
+ result =
+ [
+ // Inspired by the list on https://cwe.mitre.org/data/definitions/359.html
+ // Government identifiers, such as Social Security Numbers
+ "%social%security%number%",
+ // Contact information, such as home addresses and telephone numbers
+ "%postcode%", "%zipcode%",
+ // result = "%telephone%" or
+ // Geographic location - where the user is (or was)
+ "%latitude%", "%longitude%",
+ // Financial data - such as credit card numbers, salary, bank accounts, and debts
+ "%creditcard%", "%salary%", "%bankaccount%",
+ // Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc.
+ // result = "%email%" or
+ // result = "%mobile%" or
+ "%employer%",
+ // Health - medical conditions, insurance status, prescription records
+ "%medical%"
+ ]
}
/** An expression that might contain private data. */
diff --git a/cpp/ql/lib/external/ExternalArtifact.qll b/cpp/ql/lib/external/ExternalArtifact.qll
index abbc96a7b47..1034f1c9ecc 100644
--- a/cpp/ql/lib/external/ExternalArtifact.qll
+++ b/cpp/ql/lib/external/ExternalArtifact.qll
@@ -15,7 +15,7 @@ class ExternalData extends @externalDataElement {
* Gets the path of the file this data was loaded from, with its
* extension replaced by `.ql`.
*/
- string getQueryPath() { result = getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") }
+ string getQueryPath() { result = this.getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") }
/** Gets the number of fields in this data item. */
int getNumFields() { result = 1 + max(int i | externalData(this, _, i, _) | i) }
@@ -24,22 +24,22 @@ class ExternalData extends @externalDataElement {
string getField(int i) { externalData(this, _, i, result) }
/** Gets the integer value of the `i`th field of this data item. */
- int getFieldAsInt(int i) { result = getField(i).toInt() }
+ int getFieldAsInt(int i) { result = this.getField(i).toInt() }
/** Gets the floating-point value of the `i`th field of this data item. */
- float getFieldAsFloat(int i) { result = getField(i).toFloat() }
+ float getFieldAsFloat(int i) { result = this.getField(i).toFloat() }
/** Gets the value of the `i`th field of this data item, interpreted as a date. */
- date getFieldAsDate(int i) { result = getField(i).toDate() }
+ date getFieldAsDate(int i) { result = this.getField(i).toDate() }
/** Gets a textual representation of this data item. */
- string toString() { result = getQueryPath() + ": " + buildTupleString(0) }
+ string toString() { result = this.getQueryPath() + ": " + this.buildTupleString(0) }
/** Gets a textual representation of this data item, starting with the `n`th field. */
private string buildTupleString(int n) {
- n = getNumFields() - 1 and result = getField(n)
+ n = this.getNumFields() - 1 and result = this.getField(n)
or
- n < getNumFields() - 1 and result = getField(n) + "," + buildTupleString(n + 1)
+ n < this.getNumFields() - 1 and result = this.getField(n) + "," + this.buildTupleString(n + 1)
}
}
@@ -53,8 +53,8 @@ class DefectExternalData extends ExternalData {
}
/** Gets the URL associated with this data item. */
- string getURL() { result = getField(0) }
+ string getURL() { result = this.getField(0) }
/** Gets the message associated with this data item. */
- string getMessage() { result = getField(1) }
+ string getMessage() { result = this.getField(1) }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/Class.qll b/cpp/ql/lib/semmle/code/cpp/Class.qll
index 987ec7ffa3d..c4fdbfb40f6 100644
--- a/cpp/ql/lib/semmle/code/cpp/Class.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Class.qll
@@ -269,13 +269,13 @@ class Class extends UserType {
* DEPRECATED: name changed to `hasImplicitCopyConstructor` to reflect that
* `= default` members are no longer included.
*/
- deprecated predicate hasGeneratedCopyConstructor() { hasImplicitCopyConstructor() }
+ deprecated predicate hasGeneratedCopyConstructor() { this.hasImplicitCopyConstructor() }
/**
* DEPRECATED: name changed to `hasImplicitCopyAssignmentOperator` to
* reflect that `= default` members are no longer included.
*/
- deprecated predicate hasGeneratedCopyAssignmentOperator() { hasImplicitCopyConstructor() }
+ deprecated predicate hasGeneratedCopyAssignmentOperator() { this.hasImplicitCopyConstructor() }
/**
* Holds if this class, struct or union has an implicitly-declared copy
@@ -487,7 +487,7 @@ class Class extends UserType {
exists(ClassDerivation cd |
// Add the offset of the direct base class and the offset of `baseClass`
// within that direct base class.
- cd = getADerivation() and
+ cd = this.getADerivation() and
result = cd.getBaseClass().getANonVirtualBaseClassByteOffset(baseClass) + cd.getByteOffset()
)
}
@@ -502,12 +502,12 @@ class Class extends UserType {
*/
int getABaseClassByteOffset(Class baseClass) {
// Handle the non-virtual case.
- result = getANonVirtualBaseClassByteOffset(baseClass)
+ result = this.getANonVirtualBaseClassByteOffset(baseClass)
or
exists(Class virtualBaseClass, int virtualBaseOffset, int offsetFromVirtualBase |
// Look for the base class as a non-virtual base of a direct or indirect
// virtual base, adding the two offsets.
- getVirtualBaseClassByteOffset(virtualBaseClass) = virtualBaseOffset and
+ this.getVirtualBaseClassByteOffset(virtualBaseClass) = virtualBaseOffset and
offsetFromVirtualBase = virtualBaseClass.getANonVirtualBaseClassByteOffset(baseClass) and
result = virtualBaseOffset + offsetFromVirtualBase
)
@@ -623,11 +623,11 @@ class Class extends UserType {
* inherits one).
*/
predicate isPolymorphic() {
- exists(MemberFunction f | f.getDeclaringType() = getABaseClass*() and f.isVirtual())
+ exists(MemberFunction f | f.getDeclaringType() = this.getABaseClass*() and f.isVirtual())
}
override predicate involvesTemplateParameter() {
- getATemplateArgument().(Type).involvesTemplateParameter()
+ this.getATemplateArgument().(Type).involvesTemplateParameter()
}
/** Holds if this class, struct or union was declared 'final'. */
@@ -765,7 +765,7 @@ class ClassDerivation extends Locatable, @derivation {
* };
* ```
*/
- Class getBaseClass() { result = getBaseType().getUnderlyingType() }
+ Class getBaseClass() { result = this.getBaseType().getUnderlyingType() }
override string getAPrimaryQlClass() { result = "ClassDerivation" }
@@ -818,7 +818,7 @@ class ClassDerivation extends Locatable, @derivation {
predicate hasSpecifier(string s) { this.getASpecifier().hasName(s) }
/** Holds if the derivation is for a virtual base class. */
- predicate isVirtual() { hasSpecifier("virtual") }
+ predicate isVirtual() { this.hasSpecifier("virtual") }
/** Gets the location of the derivation. */
override Location getLocation() { derivations(underlyingElement(this), _, _, _, result) }
@@ -846,7 +846,7 @@ class ClassDerivation extends Locatable, @derivation {
* ```
*/
class LocalClass extends Class {
- LocalClass() { isLocal() }
+ LocalClass() { this.isLocal() }
override string getAPrimaryQlClass() { not this instanceof LocalStruct and result = "LocalClass" }
@@ -989,9 +989,9 @@ class ClassTemplateSpecialization extends Class {
TemplateClass getPrimaryTemplate() {
// Ignoring template arguments, the primary template has the same name
// as each of its specializations.
- result.getSimpleName() = getSimpleName() and
+ result.getSimpleName() = this.getSimpleName() and
// It is in the same namespace as its specializations.
- result.getNamespace() = getNamespace() and
+ result.getNamespace() = this.getNamespace() and
// It is distinguished by the fact that each of its template arguments
// is a distinct template parameter.
count(TemplateParameter tp | tp = result.getATemplateArgument()) =
@@ -1108,7 +1108,7 @@ deprecated class Interface extends Class {
* ```
*/
class VirtualClassDerivation extends ClassDerivation {
- VirtualClassDerivation() { hasSpecifier("virtual") }
+ VirtualClassDerivation() { this.hasSpecifier("virtual") }
override string getAPrimaryQlClass() { result = "VirtualClassDerivation" }
}
@@ -1136,7 +1136,7 @@ class VirtualBaseClass extends Class {
VirtualClassDerivation getAVirtualDerivation() { result.getBaseClass() = this }
/** A class/struct that is derived from this one using virtual inheritance. */
- Class getAVirtuallyDerivedClass() { result = getAVirtualDerivation().getDerivedClass() }
+ Class getAVirtuallyDerivedClass() { result = this.getAVirtualDerivation().getDerivedClass() }
}
/**
@@ -1155,7 +1155,7 @@ class ProxyClass extends UserType {
override string getAPrimaryQlClass() { result = "ProxyClass" }
/** Gets the location of the proxy class. */
- override Location getLocation() { result = getTemplateParameter().getDefinitionLocation() }
+ override Location getLocation() { result = this.getTemplateParameter().getDefinitionLocation() }
/** Gets the template parameter for which this is the proxy class. */
TemplateParameter getTemplateParameter() {
diff --git a/cpp/ql/lib/semmle/code/cpp/Declaration.qll b/cpp/ql/lib/semmle/code/cpp/Declaration.qll
index 7ac79fd99c1..0433be1f120 100644
--- a/cpp/ql/lib/semmle/code/cpp/Declaration.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Declaration.qll
@@ -184,7 +184,7 @@ class Declaration extends Locatable, @declaration {
predicate hasDefinition() { exists(this.getDefinition()) }
/** DEPRECATED: Use `hasDefinition` instead. */
- predicate isDefined() { hasDefinition() }
+ predicate isDefined() { this.hasDefinition() }
/** Gets the preferred location of this declaration, if any. */
override Location getLocation() { none() }
@@ -209,7 +209,7 @@ class Declaration extends Locatable, @declaration {
predicate isStatic() { this.hasSpecifier("static") }
/** Holds if this declaration is a member of a class/struct/union. */
- predicate isMember() { hasDeclaringType() }
+ predicate isMember() { this.hasDeclaringType() }
/** Holds if this declaration is a member of a class/struct/union. */
predicate hasDeclaringType() { exists(this.getDeclaringType()) }
@@ -226,14 +226,14 @@ class Declaration extends Locatable, @declaration {
* When called on a template, this will return a template parameter type for
* both typed and non-typed parameters.
*/
- final Locatable getATemplateArgument() { result = getTemplateArgument(_) }
+ final Locatable getATemplateArgument() { result = this.getTemplateArgument(_) }
/**
* Gets a template argument used to instantiate this declaration from a template.
* When called on a template, this will return a non-typed template
* parameter value.
*/
- final Locatable getATemplateArgumentKind() { result = getTemplateArgumentKind(_) }
+ final Locatable getATemplateArgumentKind() { result = this.getTemplateArgumentKind(_) }
/**
* Gets the `i`th template argument used to instantiate this declaration from a
@@ -252,9 +252,9 @@ class Declaration extends Locatable, @declaration {
* `getTemplateArgument(1)` return `1`.
*/
final Locatable getTemplateArgument(int index) {
- if exists(getTemplateArgumentValue(index))
- then result = getTemplateArgumentValue(index)
- else result = getTemplateArgumentType(index)
+ if exists(this.getTemplateArgumentValue(index))
+ then result = this.getTemplateArgumentValue(index)
+ else result = this.getTemplateArgumentType(index)
}
/**
@@ -275,14 +275,13 @@ class Declaration extends Locatable, @declaration {
* `getTemplateArgumentKind(0)`.
*/
final Locatable getTemplateArgumentKind(int index) {
- if exists(getTemplateArgumentValue(index))
- then result = getTemplateArgumentType(index)
- else none()
+ exists(this.getTemplateArgumentValue(index)) and
+ result = this.getTemplateArgumentType(index)
}
/** Gets the number of template arguments for this declaration. */
final int getNumberOfTemplateArguments() {
- result = count(int i | exists(getTemplateArgument(i)))
+ result = count(int i | exists(this.getTemplateArgument(i)))
}
private Type getTemplateArgumentType(int index) {
@@ -328,9 +327,9 @@ class DeclarationEntry extends Locatable, TDeclarationEntry {
* available), or the name declared by this entry otherwise.
*/
string getCanonicalName() {
- if getDeclaration().hasDefinition()
- then result = getDeclaration().getDefinition().getName()
- else result = getName()
+ if this.getDeclaration().hasDefinition()
+ then result = this.getDeclaration().getDefinition().getName()
+ else result = this.getName()
}
/**
@@ -371,18 +370,18 @@ class DeclarationEntry extends Locatable, TDeclarationEntry {
/**
* Holds if this declaration entry has a specifier with the given name.
*/
- predicate hasSpecifier(string specifier) { getASpecifier() = specifier }
+ predicate hasSpecifier(string specifier) { this.getASpecifier() = specifier }
/** Holds if this declaration entry is a definition. */
predicate isDefinition() { none() } // overridden in subclasses
override string toString() {
- if isDefinition()
- then result = "definition of " + getName()
+ if this.isDefinition()
+ then result = "definition of " + this.getName()
else
- if getName() = getCanonicalName()
- then result = "declaration of " + getName()
- else result = "declaration of " + getCanonicalName() + " as " + getName()
+ if this.getName() = this.getCanonicalName()
+ then result = "declaration of " + this.getName()
+ else result = "declaration of " + this.getCanonicalName() + " as " + this.getName()
}
}
@@ -581,7 +580,7 @@ private class DirectAccessHolder extends Element {
// transitive closure with a restricted base case.
this.thisCanAccessClassStep(base, derived)
or
- exists(Class between | thisCanAccessClassTrans(base, between) |
+ exists(Class between | this.thisCanAccessClassTrans(base, between) |
isDirectPublicBaseOf(between, derived) or
this.thisCanAccessClassStep(between, derived)
)
diff --git a/cpp/ql/lib/semmle/code/cpp/Element.qll b/cpp/ql/lib/semmle/code/cpp/Element.qll
index 1f547adccaa..9273d1b31bf 100644
--- a/cpp/ql/lib/semmle/code/cpp/Element.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Element.qll
@@ -61,7 +61,7 @@ class ElementBase extends @element {
/**
* Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
*/
- final string getPrimaryQlClasses() { result = concat(getAPrimaryQlClass(), ",") }
+ final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") }
/**
* Gets the name of a primary CodeQL class to which this element belongs.
@@ -206,9 +206,9 @@ class Element extends ElementBase {
/** Gets the closest `Element` enclosing this one. */
cached
Element getEnclosingElement() {
- result = getEnclosingElementPref()
+ result = this.getEnclosingElementPref()
or
- not exists(getEnclosingElementPref()) and
+ not exists(this.getEnclosingElementPref()) and
(
this = result.(Class).getAMember()
or
@@ -281,7 +281,7 @@ private predicate isFromUninstantiatedTemplateRec(Element e, Element template) {
* ```
*/
class StaticAssert extends Locatable, @static_assert {
- override string toString() { result = "static_assert(..., \"" + getMessage() + "\")" }
+ override string toString() { result = "static_assert(..., \"" + this.getMessage() + "\")" }
/**
* Gets the expression which this static assertion ensures is true.
diff --git a/cpp/ql/lib/semmle/code/cpp/Enum.qll b/cpp/ql/lib/semmle/code/cpp/Enum.qll
index 9cddeb78f9b..38263dacf7a 100644
--- a/cpp/ql/lib/semmle/code/cpp/Enum.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Enum.qll
@@ -85,7 +85,7 @@ class Enum extends UserType, IntegralOrEnumType {
* ```
*/
class LocalEnum extends Enum {
- LocalEnum() { isLocal() }
+ LocalEnum() { this.isLocal() }
override string getAPrimaryQlClass() { result = "LocalEnum" }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll
index 853b34ecfd9..3b72533b4f4 100644
--- a/cpp/ql/lib/semmle/code/cpp/File.qll
+++ b/cpp/ql/lib/semmle/code/cpp/File.qll
@@ -38,7 +38,7 @@ class Container extends Locatable, @container {
* DEPRECATED: Use `getLocation` instead.
* Gets a URL representing the location of this container.
*
- * For more information see [Providing URLs](https://help.semmle.com/QL/learn-ql/ql/locations.html#providing-urls).
+ * For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls).
*/
deprecated string getURL() { none() } // overridden by subclasses
@@ -52,7 +52,7 @@ class Container extends Locatable, @container {
*/
string getRelativePath() {
exists(string absPath, string pref |
- absPath = getAbsolutePath() and sourceLocationPrefix(pref)
+ absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
|
absPath = pref and result = ""
or
@@ -79,7 +79,7 @@ class Container extends Locatable, @container {
*
*/
string getBaseName() {
- result = getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
+ result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
}
/**
@@ -105,7 +105,9 @@ class Container extends Locatable, @container {
*
"/tmp/x.tar.gz"
"gz"
*
*/
- string getExtension() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3) }
+ string getExtension() {
+ result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
+ }
/**
* Gets the stem of this container, that is, the prefix of its base name up to
@@ -124,7 +126,9 @@ class Container extends Locatable, @container {
*
"/tmp/x.tar.gz"
"x.tar"
*
*/
- string getStem() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1) }
+ string getStem() {
+ result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
+ }
/** Gets the parent container of this file or folder, if any. */
Container getParentContainer() {
@@ -135,20 +139,20 @@ class Container extends Locatable, @container {
Container getAChildContainer() { this = result.getParentContainer() }
/** Gets a file in this container. */
- File getAFile() { result = getAChildContainer() }
+ File getAFile() { result = this.getAChildContainer() }
/** Gets the file in this container that has the given `baseName`, if any. */
File getFile(string baseName) {
- result = getAFile() and
+ result = this.getAFile() and
result.getBaseName() = baseName
}
/** Gets a sub-folder in this container. */
- Folder getAFolder() { result = getAChildContainer() }
+ Folder getAFolder() { result = this.getAChildContainer() }
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
Folder getFolder(string baseName) {
- result = getAFolder() and
+ result = this.getAFolder() and
result.getBaseName() = baseName
}
@@ -157,7 +161,7 @@ class Container extends Locatable, @container {
*
* This is the absolute path of the container.
*/
- override string toString() { result = getAbsolutePath() }
+ override string toString() { result = this.getAbsolutePath() }
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/Function.qll b/cpp/ql/lib/semmle/code/cpp/Function.qll
index 6cae134645f..0f1de2b512c 100644
--- a/cpp/ql/lib/semmle/code/cpp/Function.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Function.qll
@@ -43,26 +43,26 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
*/
string getFullSignature() {
exists(string name, string templateArgs, string args |
- result = name + templateArgs + args + " -> " + getType().toString() and
- name = getQualifiedName() and
+ result = name + templateArgs + args + " -> " + this.getType().toString() and
+ name = this.getQualifiedName() and
(
- if exists(getATemplateArgument())
+ if exists(this.getATemplateArgument())
then
templateArgs =
"<" +
concat(int i |
- exists(getTemplateArgument(i))
+ exists(this.getTemplateArgument(i))
|
- getTemplateArgument(i).toString(), ", " order by i
+ this.getTemplateArgument(i).toString(), ", " order by i
) + ">"
else templateArgs = ""
) and
args =
"(" +
concat(int i |
- exists(getParameter(i))
+ exists(this.getParameter(i))
|
- getParameter(i).getType().toString(), ", " order by i
+ this.getParameter(i).getType().toString(), ", " order by i
) + ")"
)
}
@@ -70,7 +70,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
/** Gets a specifier of this function. */
override Specifier getASpecifier() {
funspecifiers(underlyingElement(this), unresolveElement(result)) or
- result.hasName(getADeclarationEntry().getASpecifier())
+ result.hasName(this.getADeclarationEntry().getASpecifier())
}
/** Gets an attribute of this function. */
@@ -149,7 +149,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* Holds if this function is declared with `__attribute__((naked))` or
* `__declspec(naked)`.
*/
- predicate isNaked() { getAnAttribute().hasName("naked") }
+ predicate isNaked() { this.getAnAttribute().hasName("naked") }
/**
* Holds if this function has a trailing return type.
@@ -172,7 +172,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* Gets the return type of this function after specifiers have been deeply
* stripped and typedefs have been resolved.
*/
- Type getUnspecifiedType() { result = getType().getUnspecifiedType() }
+ Type getUnspecifiedType() { result = this.getType().getUnspecifiedType() }
/**
* Gets the nth parameter of this function. There is no result for the
@@ -206,7 +206,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
int getEffectiveNumberOfParameters() {
// This method is overridden in `MemberFunction`, where the result is
// adjusted to account for the implicit `this` parameter.
- result = getNumberOfParameters()
+ result = this.getNumberOfParameters()
}
/**
@@ -216,7 +216,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* return `int p1, int p2`.
*/
string getParameterString() {
- result = concat(int i | | min(getParameter(i).getTypedName()), ", " order by i)
+ result = concat(int i | | min(this.getParameter(i).getTypedName()), ", " order by i)
}
/** Gets a call to this function. */
@@ -229,7 +229,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
*/
override FunctionDeclarationEntry getADeclarationEntry() {
if fun_decls(_, underlyingElement(this), _, _, _)
- then declEntry(result)
+ then this.declEntry(result)
else
exists(Function f |
this.isConstructedFrom(f) and
@@ -250,7 +250,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* Gets the location of a `FunctionDeclarationEntry` corresponding to this
* declaration.
*/
- override Location getADeclarationLocation() { result = getADeclarationEntry().getLocation() }
+ override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
/** Holds if this Function is a Template specialization. */
predicate isSpecialization() {
@@ -265,14 +265,14 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* definition, if any.
*/
override FunctionDeclarationEntry getDefinition() {
- result = getADeclarationEntry() and
+ result = this.getADeclarationEntry() and
result.isDefinition()
}
/** Gets the location of the definition, if any. */
override Location getDefinitionLocation() {
- if exists(getDefinition())
- then result = getDefinition().getLocation()
+ if exists(this.getDefinition())
+ then result = this.getDefinition().getLocation()
else exists(Function f | this.isConstructedFrom(f) and result = f.getDefinition().getLocation())
}
@@ -281,7 +281,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* definition, if possible.)
*/
override Location getLocation() {
- if exists(getDefinition())
+ if exists(this.getDefinition())
then result = this.getDefinitionLocation()
else result = this.getADeclarationLocation()
}
@@ -299,7 +299,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
BlockStmt getBlock() { result.getParentScope() = this }
/** Holds if this function has an entry point. */
- predicate hasEntryPoint() { exists(getEntryPoint()) }
+ predicate hasEntryPoint() { exists(this.getEntryPoint()) }
/**
* Gets the first node in this function's control flow graph.
@@ -392,7 +392,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* Holds if this function has C linkage, as specified by one of its
* declaration entries. For example: `extern "C" void foo();`.
*/
- predicate hasCLinkage() { getADeclarationEntry().hasCLinkage() }
+ predicate hasCLinkage() { this.getADeclarationEntry().hasCLinkage() }
/**
* Holds if this function is constructed from `f` as a result
@@ -409,27 +409,27 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* several functions that are not linked together have been compiled. An
* example would be a project with many 'main' functions.
*/
- predicate isMultiplyDefined() { strictcount(getFile()) > 1 }
+ predicate isMultiplyDefined() { strictcount(this.getFile()) > 1 }
/** Holds if this function is a varargs function. */
- predicate isVarargs() { hasSpecifier("varargs") }
+ predicate isVarargs() { this.hasSpecifier("varargs") }
/** Gets a type that is specified to be thrown by the function. */
- Type getAThrownType() { result = getADeclarationEntry().getAThrownType() }
+ Type getAThrownType() { result = this.getADeclarationEntry().getAThrownType() }
/**
* Gets the `i`th type specified to be thrown by the function.
*/
- Type getThrownType(int i) { result = getADeclarationEntry().getThrownType(i) }
+ Type getThrownType(int i) { result = this.getADeclarationEntry().getThrownType(i) }
/** Holds if the function has an exception specification. */
- predicate hasExceptionSpecification() { getADeclarationEntry().hasExceptionSpecification() }
+ predicate hasExceptionSpecification() { this.getADeclarationEntry().hasExceptionSpecification() }
/** Holds if this function has a `throw()` exception specification. */
- predicate isNoThrow() { getADeclarationEntry().isNoThrow() }
+ predicate isNoThrow() { this.getADeclarationEntry().isNoThrow() }
/** Holds if this function has a `noexcept` exception specification. */
- predicate isNoExcept() { getADeclarationEntry().isNoExcept() }
+ predicate isNoExcept() { this.getADeclarationEntry().isNoExcept() }
/**
* Gets a function that overloads this one.
@@ -539,7 +539,7 @@ private predicate candGetAnOverloadNonMember(string name, Namespace namespace, F
*/
class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
/** Gets the function which is being declared or defined. */
- override Function getDeclaration() { result = getFunction() }
+ override Function getDeclaration() { result = this.getFunction() }
override string getAPrimaryQlClass() { result = "FunctionDeclarationEntry" }
@@ -586,7 +586,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* case, catch) plus the number of branching expressions (`?`, `&&`,
* `||`) plus one.
*/
- int getCyclomaticComplexity() { result = 1 + cyclomaticComplexityBranches(getBlock()) }
+ int getCyclomaticComplexity() { result = 1 + cyclomaticComplexityBranches(this.getBlock()) }
/**
* If this is a function definition, get the block containing the
@@ -594,7 +594,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
*/
BlockStmt getBlock() {
this.isDefinition() and
- result = getFunction().getBlock() and
+ result = this.getFunction().getBlock() and
result.getFile() = this.getFile()
}
@@ -604,7 +604,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
*/
pragma[noopt]
int getNumberOfLines() {
- exists(BlockStmt b, Location l, int start, int end, int diff | b = getBlock() |
+ exists(BlockStmt b, Location l, int start, int end, int diff | b = this.getBlock() |
l = b.getLocation() and
start = l.getStartLine() and
end = l.getEndLine() and
@@ -618,7 +618,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* declaration.
*/
ParameterDeclarationEntry getAParameterDeclarationEntry() {
- result = getParameterDeclarationEntry(_)
+ result = this.getParameterDeclarationEntry(_)
}
/**
@@ -639,7 +639,8 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* return 'int p1, int p2'.
*/
string getParameterString() {
- result = concat(int i | | min(getParameterDeclarationEntry(i).getTypedName()), ", " order by i)
+ result =
+ concat(int i | | min(this.getParameterDeclarationEntry(i).getTypedName()), ", " order by i)
}
/**
@@ -647,10 +648,10 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
*
* `extern "C" void foo();`
*/
- predicate hasCLinkage() { getASpecifier() = "c_linkage" }
+ predicate hasCLinkage() { this.getASpecifier() = "c_linkage" }
/** Holds if this declaration entry has a void parameter list. */
- predicate hasVoidParamList() { getASpecifier() = "void_param_list" }
+ predicate hasVoidParamList() { this.getASpecifier() = "void_param_list" }
/** Holds if this declaration is also a definition of its function. */
override predicate isDefinition() { fun_def(underlyingElement(this)) }
@@ -665,7 +666,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
predicate isImplicit() { fun_implicit(underlyingElement(this)) }
/** Gets a type that is specified to be thrown by the declared function. */
- Type getAThrownType() { result = getThrownType(_) }
+ Type getAThrownType() { result = this.getThrownType(_) }
/**
* Gets the `i`th type specified to be thrown by the declared function
@@ -690,8 +691,8 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
predicate hasExceptionSpecification() {
fun_decl_throws(underlyingElement(this), _, _) or
fun_decl_noexcept(underlyingElement(this), _) or
- isNoThrow() or
- isNoExcept()
+ this.isNoThrow() or
+ this.isNoExcept()
}
/**
@@ -763,7 +764,7 @@ class Operator extends Function {
*/
class TemplateFunction extends Function {
TemplateFunction() {
- is_function_template(underlyingElement(this)) and exists(getATemplateArgument())
+ is_function_template(underlyingElement(this)) and exists(this.getATemplateArgument())
}
override string getAPrimaryQlClass() { result = "TemplateFunction" }
diff --git a/cpp/ql/lib/semmle/code/cpp/Include.qll b/cpp/ql/lib/semmle/code/cpp/Include.qll
index f21edb2651d..9a120b1013c 100644
--- a/cpp/ql/lib/semmle/code/cpp/Include.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Include.qll
@@ -23,7 +23,7 @@ class Include extends PreprocessorDirective, @ppd_include {
* Gets the token which occurs after `#include`, for example `"filename"`
* or ``.
*/
- string getIncludeText() { result = getHead() }
+ string getIncludeText() { result = this.getHead() }
/** Gets the file directly included by this `#include`. */
File getIncludedFile() { includes(underlyingElement(this), unresolveElement(result)) }
@@ -53,7 +53,7 @@ class Include extends PreprocessorDirective, @ppd_include {
* ```
*/
class IncludeNext extends Include, @ppd_include_next {
- override string toString() { result = "#include_next " + getIncludeText() }
+ override string toString() { result = "#include_next " + this.getIncludeText() }
}
/**
@@ -65,5 +65,5 @@ class IncludeNext extends Include, @ppd_include_next {
* ```
*/
class Import extends Include, @ppd_objc_import {
- override string toString() { result = "#import " + getIncludeText() }
+ override string toString() { result = "#import " + this.getIncludeText() }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/Initializer.qll b/cpp/ql/lib/semmle/code/cpp/Initializer.qll
index 64607af3393..62af72c1803 100644
--- a/cpp/ql/lib/semmle/code/cpp/Initializer.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Initializer.qll
@@ -34,8 +34,8 @@ class Initializer extends ControlFlowNode, @initialiser {
override predicate fromSource() { not this.getLocation() instanceof UnknownLocation }
override string toString() {
- if exists(getDeclaration())
- then result = "initializer for " + max(getDeclaration().getName())
+ if exists(this.getDeclaration())
+ then result = "initializer for " + max(this.getDeclaration().getName())
else result = "initializer"
}
diff --git a/cpp/ql/lib/semmle/code/cpp/Location.qll b/cpp/ql/lib/semmle/code/cpp/Location.qll
index 2a730ea5768..92b358d474c 100644
--- a/cpp/ql/lib/semmle/code/cpp/Location.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Location.qll
@@ -61,7 +61,7 @@ class Location extends @location {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -79,8 +79,8 @@ class Location extends @location {
/** Holds if location `l` is completely contained within this one. */
predicate subsumes(Location l) {
- exists(File f | f = getFile() |
- exists(int thisStart, int thisEnd | charLoc(f, thisStart, thisEnd) |
+ exists(File f | f = this.getFile() |
+ exists(int thisStart, int thisEnd | this.charLoc(f, thisStart, thisEnd) |
exists(int lStart, int lEnd | l.charLoc(f, lStart, lEnd) |
thisStart <= lStart and lEnd <= thisEnd
)
@@ -97,10 +97,10 @@ class Location extends @location {
* see `subsumes`.
*/
predicate charLoc(File f, int start, int end) {
- f = getFile() and
+ f = this.getFile() and
exists(int maxCols | maxCols = maxCols(f) |
- start = getStartLine() * maxCols + getStartColumn() and
- end = getEndLine() * maxCols + getEndColumn()
+ start = this.getStartLine() * maxCols + this.getStartColumn() and
+ end = this.getEndLine() * maxCols + this.getEndColumn()
)
}
}
@@ -144,7 +144,7 @@ class Locatable extends Element { }
* expressions, one for statements and one for other program elements.
*/
class UnknownLocation extends Location {
- UnknownLocation() { getFile().getAbsolutePath() = "" }
+ UnknownLocation() { this.getFile().getAbsolutePath() = "" }
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/Macro.qll b/cpp/ql/lib/semmle/code/cpp/Macro.qll
index aa4b8d41999..6d61ae7be7c 100644
--- a/cpp/ql/lib/semmle/code/cpp/Macro.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Macro.qll
@@ -44,10 +44,10 @@ class Macro extends PreprocessorDirective, @ppd_define {
* Gets the name of the macro. For example, `MAX` in
* `#define MAX(x,y) (((x)>(y))?(x):(y))`.
*/
- string getName() { result = getHead().splitAt("(", 0) }
+ string getName() { result = this.getHead().splitAt("(", 0) }
/** Holds if the macro has name `name`. */
- predicate hasName(string name) { getName() = name }
+ predicate hasName(string name) { this.getName() = name }
}
/**
@@ -130,7 +130,7 @@ class MacroAccess extends Locatable, @macroinvocation {
override string toString() { result = this.getMacro().getHead() }
/** Gets the name of the accessed macro. */
- string getMacroName() { result = getMacro().getName() }
+ string getMacroName() { result = this.getMacro().getName() }
}
/**
@@ -197,8 +197,8 @@ class MacroInvocation extends MacroAccess {
* expression. In other cases, it may have multiple results or no results.
*/
Expr getExpr() {
- result = getAnExpandedElement() and
- not result.getParent() = getAnExpandedElement() and
+ result = this.getAnExpandedElement() and
+ not result.getParent() = this.getAnExpandedElement() and
not result instanceof Conversion
}
@@ -208,8 +208,8 @@ class MacroInvocation extends MacroAccess {
* element is not a statement (for example if it is an expression).
*/
Stmt getStmt() {
- result = getAnExpandedElement() and
- not result.getParent() = getAnExpandedElement()
+ result = this.getAnExpandedElement() and
+ not result.getParent() = this.getAnExpandedElement()
}
/**
@@ -278,7 +278,7 @@ deprecated class MacroInvocationExpr extends Expr {
MacroInvocation getInvocation() { result.getExpr() = this }
/** Gets the name of the invoked macro. */
- string getMacroName() { result = getInvocation().getMacroName() }
+ string getMacroName() { result = this.getInvocation().getMacroName() }
}
/**
@@ -298,7 +298,7 @@ deprecated class MacroInvocationStmt extends Stmt {
MacroInvocation getInvocation() { result.getStmt() = this }
/** Gets the name of the invoked macro. */
- string getMacroName() { result = getInvocation().getMacroName() }
+ string getMacroName() { result = this.getInvocation().getMacroName() }
}
/** Holds if `l` is the location of a macro. */
diff --git a/cpp/ql/lib/semmle/code/cpp/MemberFunction.qll b/cpp/ql/lib/semmle/code/cpp/MemberFunction.qll
index 63c1406d8a5..03b1704549f 100644
--- a/cpp/ql/lib/semmle/code/cpp/MemberFunction.qll
+++ b/cpp/ql/lib/semmle/code/cpp/MemberFunction.qll
@@ -36,7 +36,9 @@ class MemberFunction extends Function {
* `this` parameter.
*/
override int getEffectiveNumberOfParameters() {
- if isStatic() then result = getNumberOfParameters() else result = getNumberOfParameters() + 1
+ if this.isStatic()
+ then result = this.getNumberOfParameters()
+ else result = this.getNumberOfParameters() + 1
}
/** Holds if this member is private. */
@@ -49,13 +51,13 @@ class MemberFunction extends Function {
predicate isPublic() { this.hasSpecifier("public") }
/** Holds if this declaration has the lvalue ref-qualifier */
- predicate isLValueRefQualified() { hasSpecifier("&") }
+ predicate isLValueRefQualified() { this.hasSpecifier("&") }
/** Holds if this declaration has the rvalue ref-qualifier */
- predicate isRValueRefQualified() { hasSpecifier("&&") }
+ predicate isRValueRefQualified() { this.hasSpecifier("&&") }
/** Holds if this declaration has a ref-qualifier */
- predicate isRefQualified() { isLValueRefQualified() or isRValueRefQualified() }
+ predicate isRefQualified() { this.isLValueRefQualified() or this.isRValueRefQualified() }
/** Holds if this function overrides that function. */
predicate overrides(MemberFunction that) {
@@ -73,10 +75,10 @@ class MemberFunction extends Function {
* class body.
*/
FunctionDeclarationEntry getClassBodyDeclarationEntry() {
- if strictcount(getADeclarationEntry()) = 1
- then result = getDefinition()
+ if strictcount(this.getADeclarationEntry()) = 1
+ then result = this.getDefinition()
else (
- result = getADeclarationEntry() and result != getDefinition()
+ result = this.getADeclarationEntry() and result != this.getDefinition()
)
}
@@ -198,7 +200,7 @@ class Constructor extends MemberFunction {
* compiler-generated action which initializes a base class or member
* variable.
*/
- ConstructorInit getAnInitializer() { result = getInitializer(_) }
+ ConstructorInit getAnInitializer() { result = this.getInitializer(_) }
/**
* Gets an entry in the constructor's initializer list, or a
@@ -220,8 +222,8 @@ class ImplicitConversionFunction extends MemberFunction {
functions(underlyingElement(this), _, 4)
or
// ConversionConstructor (deprecated)
- strictcount(Parameter p | p = getAParameter() and not p.hasInitializer()) = 1 and
- not hasSpecifier("explicit")
+ strictcount(Parameter p | p = this.getAParameter() and not p.hasInitializer()) = 1 and
+ not this.hasSpecifier("explicit")
}
/** Gets the type this `ImplicitConversionFunction` takes as input. */
@@ -248,8 +250,8 @@ class ImplicitConversionFunction extends MemberFunction {
*/
deprecated class ConversionConstructor extends Constructor, ImplicitConversionFunction {
ConversionConstructor() {
- strictcount(Parameter p | p = getAParameter() and not p.hasInitializer()) = 1 and
- not hasSpecifier("explicit")
+ strictcount(Parameter p | p = this.getAParameter() and not p.hasInitializer()) = 1 and
+ not this.hasSpecifier("explicit")
}
override string getAPrimaryQlClass() {
@@ -301,15 +303,15 @@ class CopyConstructor extends Constructor {
hasCopySignature(this) and
(
// The rest of the parameters all have default values
- forall(int i | i > 0 and exists(getParameter(i)) | getParameter(i).hasInitializer())
+ forall(int i | i > 0 and exists(this.getParameter(i)) | this.getParameter(i).hasInitializer())
or
// or this is a template class, in which case the default values have
// not been extracted even if they exist. In that case, we assume that
// there are default values present since that is the most common case
// in real-world code.
- getDeclaringType() instanceof TemplateClass
+ this.getDeclaringType() instanceof TemplateClass
) and
- not exists(getATemplateArgument())
+ not exists(this.getATemplateArgument())
}
override string getAPrimaryQlClass() { result = "CopyConstructor" }
@@ -325,8 +327,8 @@ class CopyConstructor extends Constructor {
// type-checked for each template instantiation; if an argument in an
// instantiation fails to type-check then the corresponding parameter has
// no default argument in the instantiation.
- getDeclaringType() instanceof TemplateClass and
- getNumberOfParameters() > 1
+ this.getDeclaringType() instanceof TemplateClass and
+ this.getNumberOfParameters() > 1
}
}
@@ -358,15 +360,15 @@ class MoveConstructor extends Constructor {
hasMoveSignature(this) and
(
// The rest of the parameters all have default values
- forall(int i | i > 0 and exists(getParameter(i)) | getParameter(i).hasInitializer())
+ forall(int i | i > 0 and exists(this.getParameter(i)) | this.getParameter(i).hasInitializer())
or
// or this is a template class, in which case the default values have
// not been extracted even if they exist. In that case, we assume that
// there are default values present since that is the most common case
// in real-world code.
- getDeclaringType() instanceof TemplateClass
+ this.getDeclaringType() instanceof TemplateClass
) and
- not exists(getATemplateArgument())
+ not exists(this.getATemplateArgument())
}
override string getAPrimaryQlClass() { result = "MoveConstructor" }
@@ -382,8 +384,8 @@ class MoveConstructor extends Constructor {
// type-checked for each template instantiation; if an argument in an
// instantiation fails to type-check then the corresponding parameter has
// no default argument in the instantiation.
- getDeclaringType() instanceof TemplateClass and
- getNumberOfParameters() > 1
+ this.getDeclaringType() instanceof TemplateClass and
+ this.getNumberOfParameters() > 1
}
}
@@ -426,7 +428,7 @@ class Destructor extends MemberFunction {
* Gets a compiler-generated action which destructs a base class or member
* variable.
*/
- DestructorDestruction getADestruction() { result = getDestruction(_) }
+ DestructorDestruction getADestruction() { result = this.getDestruction(_) }
/**
* Gets a compiler-generated action which destructs a base class or member
@@ -475,16 +477,16 @@ class ConversionOperator extends MemberFunction, ImplicitConversionFunction {
*/
class CopyAssignmentOperator extends Operator {
CopyAssignmentOperator() {
- hasName("operator=") and
+ this.hasName("operator=") and
(
hasCopySignature(this)
or
// Unlike CopyConstructor, this member allows a non-reference
// parameter.
- getParameter(0).getUnspecifiedType() = getDeclaringType()
+ this.getParameter(0).getUnspecifiedType() = this.getDeclaringType()
) and
not exists(this.getParameter(1)) and
- not exists(getATemplateArgument())
+ not exists(this.getATemplateArgument())
}
override string getAPrimaryQlClass() { result = "CopyAssignmentOperator" }
@@ -507,10 +509,10 @@ class CopyAssignmentOperator extends Operator {
*/
class MoveAssignmentOperator extends Operator {
MoveAssignmentOperator() {
- hasName("operator=") and
+ this.hasName("operator=") and
hasMoveSignature(this) and
not exists(this.getParameter(1)) and
- not exists(getATemplateArgument())
+ not exists(this.getATemplateArgument())
}
override string getAPrimaryQlClass() { result = "MoveAssignmentOperator" }
diff --git a/cpp/ql/lib/semmle/code/cpp/Namespace.qll b/cpp/ql/lib/semmle/code/cpp/Namespace.qll
index d46abc6b4db..47ebc9d35c5 100644
--- a/cpp/ql/lib/semmle/code/cpp/Namespace.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Namespace.qll
@@ -38,8 +38,8 @@ class Namespace extends NameQualifyingElement, @namespace {
* unless the namespace has exactly one declaration entry.
*/
override Location getLocation() {
- if strictcount(getADeclarationEntry()) = 1
- then result = getADeclarationEntry().getLocation()
+ if strictcount(this.getADeclarationEntry()) = 1
+ then result = this.getADeclarationEntry().getLocation()
else result instanceof UnknownDefaultLocation
}
@@ -50,7 +50,7 @@ class Namespace extends NameQualifyingElement, @namespace {
predicate hasName(string name) { name = this.getName() }
/** Holds if this namespace is anonymous. */
- predicate isAnonymous() { hasName("(unnamed namespace)") }
+ predicate isAnonymous() { this.hasName("(unnamed namespace)") }
/** Gets the name of the parent namespace, if it exists. */
private string getParentName() {
@@ -60,9 +60,9 @@ class Namespace extends NameQualifyingElement, @namespace {
/** Gets the qualified name of this namespace. For example: `a::b`. */
string getQualifiedName() {
- if exists(getParentName())
- then result = getParentNamespace().getQualifiedName() + "::" + getName()
- else result = getName()
+ if exists(this.getParentName())
+ then result = this.getParentNamespace().getQualifiedName() + "::" + this.getName()
+ else result = this.getName()
}
/** Gets the parent namespace, if any. */
@@ -99,7 +99,7 @@ class Namespace extends NameQualifyingElement, @namespace {
/** Gets a version of the `QualifiedName` that is more suitable for display purposes. */
string getFriendlyName() { result = this.getQualifiedName() }
- final override string toString() { result = getFriendlyName() }
+ final override string toString() { result = this.getFriendlyName() }
/** Gets a declaration of (part of) this namespace. */
NamespaceDeclarationEntry getADeclarationEntry() { result.getNamespace() = this }
diff --git a/cpp/ql/lib/semmle/code/cpp/Parameter.qll b/cpp/ql/lib/semmle/code/cpp/Parameter.qll
index b87bfe6a4c7..47b77b542c1 100644
--- a/cpp/ql/lib/semmle/code/cpp/Parameter.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Parameter.qll
@@ -40,12 +40,12 @@ class Parameter extends LocalScopeVariable, @parameter {
*/
override string getName() {
exists(VariableDeclarationEntry vde |
- vde = getANamedDeclarationEntry() and result = vde.getName()
+ vde = this.getANamedDeclarationEntry() and result = vde.getName()
|
- vde.isDefinition() or not getANamedDeclarationEntry().isDefinition()
+ vde.isDefinition() or not this.getANamedDeclarationEntry().isDefinition()
)
or
- not exists(getANamedDeclarationEntry()) and
+ not exists(this.getANamedDeclarationEntry()) and
result = "(unnamed parameter " + this.getIndex().toString() + ")"
}
@@ -58,8 +58,12 @@ class Parameter extends LocalScopeVariable, @parameter {
*/
string getTypedName() {
exists(string typeString, string nameString |
- (if exists(getType().getName()) then typeString = getType().getName() else typeString = "") and
- (if exists(getName()) then nameString = getName() else nameString = "") and
+ (
+ if exists(this.getType().getName())
+ then typeString = this.getType().getName()
+ else typeString = ""
+ ) and
+ (if exists(this.getName()) then nameString = this.getName() else nameString = "") and
(
if typeString != "" and nameString != ""
then result = typeString + " " + nameString
@@ -69,7 +73,7 @@ class Parameter extends LocalScopeVariable, @parameter {
}
private VariableDeclarationEntry getANamedDeclarationEntry() {
- result = getAnEffectiveDeclarationEntry() and result.getName() != ""
+ result = this.getAnEffectiveDeclarationEntry() and result.getName() != ""
}
/**
@@ -82,13 +86,13 @@ class Parameter extends LocalScopeVariable, @parameter {
* own).
*/
private VariableDeclarationEntry getAnEffectiveDeclarationEntry() {
- if getFunction().isConstructedFrom(_)
+ if this.getFunction().isConstructedFrom(_)
then
exists(Function prototypeInstantiation |
- prototypeInstantiation.getParameter(getIndex()) = result.getVariable() and
- getFunction().isConstructedFrom(prototypeInstantiation)
+ prototypeInstantiation.getParameter(this.getIndex()) = result.getVariable() and
+ this.getFunction().isConstructedFrom(prototypeInstantiation)
)
- else result = getADeclarationEntry()
+ else result = this.getADeclarationEntry()
}
/**
@@ -114,7 +118,7 @@ class Parameter extends LocalScopeVariable, @parameter {
* `getName()` is not "(unnamed parameter i)" (where `i` is the index
* of the parameter).
*/
- predicate isNamed() { exists(getANamedDeclarationEntry()) }
+ predicate isNamed() { exists(this.getANamedDeclarationEntry()) }
/**
* Gets the function to which this parameter belongs, if it is a function
@@ -157,9 +161,9 @@ class Parameter extends LocalScopeVariable, @parameter {
*/
override Location getLocation() {
exists(VariableDeclarationEntry vde |
- vde = getAnEffectiveDeclarationEntry() and result = vde.getLocation()
+ vde = this.getAnEffectiveDeclarationEntry() and result = vde.getLocation()
|
- vde.isDefinition() or not getAnEffectiveDeclarationEntry().isDefinition()
+ vde.isDefinition() or not this.getAnEffectiveDeclarationEntry().isDefinition()
)
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/Preprocessor.qll b/cpp/ql/lib/semmle/code/cpp/Preprocessor.qll
index 2389db07f2a..91b7aa1aab9 100644
--- a/cpp/ql/lib/semmle/code/cpp/Preprocessor.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Preprocessor.qll
@@ -29,8 +29,8 @@ class PreprocessorDirective extends Locatable, @preprocdirect {
PreprocessorBranch getAGuard() {
exists(PreprocessorEndif e, int line |
result.getEndIf() = e and
- e.getFile() = getFile() and
- result.getFile() = getFile() and
+ e.getFile() = this.getFile() and
+ result.getFile() = this.getFile() and
line = this.getLocation().getStartLine() and
result.getLocation().getStartLine() < line and
line < e.getLocation().getEndLine()
@@ -69,7 +69,9 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
* directives in different translation units, then there can be more than
* one result.
*/
- PreprocessorEndif getEndIf() { preprocpair(unresolveElement(getIf()), unresolveElement(result)) }
+ PreprocessorEndif getEndIf() {
+ preprocpair(unresolveElement(this.getIf()), unresolveElement(result))
+ }
/**
* Gets the next `#elif`, `#else` or `#endif` matching this branching
@@ -137,7 +139,7 @@ class PreprocessorBranch extends PreprocessorBranchDirective, @ppd_branch {
* which evaluated it, or was not taken by any translation unit which
* evaluated it.
*/
- predicate wasPredictable() { not (wasTaken() and wasNotTaken()) }
+ predicate wasPredictable() { not (this.wasTaken() and this.wasNotTaken()) }
}
/**
@@ -268,7 +270,7 @@ class PreprocessorUndef extends PreprocessorDirective, @ppd_undef {
/**
* Gets the name of the macro that is undefined.
*/
- string getName() { result = getHead() }
+ string getName() { result = this.getHead() }
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/Print.qll b/cpp/ql/lib/semmle/code/cpp/Print.qll
index f8d30f55a88..64ae5b960d1 100644
--- a/cpp/ql/lib/semmle/code/cpp/Print.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Print.qll
@@ -105,8 +105,8 @@ private class DumpType extends Type {
// for a `SpecifiedType`, insert the qualifiers after
// `getDeclaratorSuffixBeforeQualifiers()`.
result =
- getTypeSpecifier() + getDeclaratorPrefix() + getDeclaratorSuffixBeforeQualifiers() +
- getDeclaratorSuffix()
+ this.getTypeSpecifier() + this.getDeclaratorPrefix() +
+ this.getDeclaratorSuffixBeforeQualifiers() + this.getDeclaratorSuffix()
}
/**
@@ -147,29 +147,35 @@ private class DumpType extends Type {
}
private class BuiltInDumpType extends DumpType, BuiltInType {
- override string getTypeSpecifier() { result = toString() }
+ override string getTypeSpecifier() { result = this.toString() }
}
private class IntegralDumpType extends BuiltInDumpType, IntegralType {
- override string getTypeSpecifier() { result = getCanonicalArithmeticType().toString() }
+ override string getTypeSpecifier() { result = this.getCanonicalArithmeticType().toString() }
}
private class DerivedDumpType extends DumpType, DerivedType {
- override string getTypeSpecifier() { result = getBaseType().(DumpType).getTypeSpecifier() }
+ override string getTypeSpecifier() { result = this.getBaseType().(DumpType).getTypeSpecifier() }
override string getDeclaratorSuffixBeforeQualifiers() {
- result = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
+ result = this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
}
- override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
+ override string getDeclaratorSuffix() {
+ result = this.getBaseType().(DumpType).getDeclaratorSuffix()
+ }
}
private class DecltypeDumpType extends DumpType, Decltype {
- override string getTypeSpecifier() { result = getBaseType().(DumpType).getTypeSpecifier() }
+ override string getTypeSpecifier() { result = this.getBaseType().(DumpType).getTypeSpecifier() }
- override string getDeclaratorPrefix() { result = getBaseType().(DumpType).getDeclaratorPrefix() }
+ override string getDeclaratorPrefix() {
+ result = this.getBaseType().(DumpType).getDeclaratorPrefix()
+ }
- override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
+ override string getDeclaratorSuffix() {
+ result = this.getBaseType().(DumpType).getDeclaratorSuffix()
+ }
}
private class PointerIshDumpType extends DerivedDumpType {
@@ -180,10 +186,10 @@ private class PointerIshDumpType extends DerivedDumpType {
override string getDeclaratorPrefix() {
exists(string declarator |
- result = getBaseType().(DumpType).getDeclaratorPrefix() + declarator and
- if getBaseType().getUnspecifiedType() instanceof ArrayType
- then declarator = "(" + getDeclaratorToken() + ")"
- else declarator = getDeclaratorToken()
+ result = this.getBaseType().(DumpType).getDeclaratorPrefix() + declarator and
+ if this.getBaseType().getUnspecifiedType() instanceof ArrayType
+ then declarator = "(" + this.getDeclaratorToken() + ")"
+ else declarator = this.getDeclaratorToken()
)
}
@@ -206,13 +212,13 @@ private class RValueReferenceDumpType extends PointerIshDumpType, RValueReferenc
}
private class PointerToMemberDumpType extends DumpType, PointerToMemberType {
- override string getTypeSpecifier() { result = getBaseType().(DumpType).getTypeSpecifier() }
+ override string getTypeSpecifier() { result = this.getBaseType().(DumpType).getTypeSpecifier() }
override string getDeclaratorPrefix() {
exists(string declarator, string parenDeclarator, Type baseType |
- declarator = getClass().(DumpType).getTypeIdentityString() + "::*" and
- result = getBaseType().(DumpType).getDeclaratorPrefix() + " " + parenDeclarator and
- baseType = getBaseType().getUnspecifiedType() and
+ declarator = this.getClass().(DumpType).getTypeIdentityString() + "::*" and
+ result = this.getBaseType().(DumpType).getDeclaratorPrefix() + " " + parenDeclarator and
+ baseType = this.getBaseType().getUnspecifiedType() and
if baseType instanceof ArrayType or baseType instanceof RoutineType
then parenDeclarator = "(" + declarator
else parenDeclarator = declarator
@@ -221,38 +227,44 @@ private class PointerToMemberDumpType extends DumpType, PointerToMemberType {
override string getDeclaratorSuffixBeforeQualifiers() {
exists(Type baseType |
- baseType = getBaseType().getUnspecifiedType() and
+ baseType = this.getBaseType().getUnspecifiedType() and
if baseType instanceof ArrayType or baseType instanceof RoutineType
- then result = ")" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
- else result = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
+ then result = ")" + this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
+ else result = this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
)
}
- override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
+ override string getDeclaratorSuffix() {
+ result = this.getBaseType().(DumpType).getDeclaratorSuffix()
+ }
}
private class ArrayDumpType extends DerivedDumpType, ArrayType {
- override string getDeclaratorPrefix() { result = getBaseType().(DumpType).getDeclaratorPrefix() }
+ override string getDeclaratorPrefix() {
+ result = this.getBaseType().(DumpType).getDeclaratorPrefix()
+ }
override string getDeclaratorSuffixBeforeQualifiers() {
- if exists(getArraySize())
+ if exists(this.getArraySize())
then
result =
- "[" + getArraySize().toString() + "]" +
- getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
- else result = "[]" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
+ "[" + this.getArraySize().toString() + "]" +
+ this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
+ else result = "[]" + this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
}
}
private class FunctionPointerIshDumpType extends DerivedDumpType, FunctionPointerIshType {
override string getDeclaratorSuffixBeforeQualifiers() {
- result = ")" + getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
+ result = ")" + this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers()
}
- override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
+ override string getDeclaratorSuffix() {
+ result = this.getBaseType().(DumpType).getDeclaratorSuffix()
+ }
override string getDeclaratorPrefix() {
- result = getBaseType().(DumpType).getDeclaratorPrefix() + "(" + getDeclaratorToken()
+ result = this.getBaseType().(DumpType).getDeclaratorPrefix() + "(" + this.getDeclaratorToken()
}
/**
@@ -274,10 +286,10 @@ private class BlockDumpType extends FunctionPointerIshDumpType, BlockType {
}
private class RoutineDumpType extends DumpType, RoutineType {
- override string getTypeSpecifier() { result = getReturnType().(DumpType).getTypeSpecifier() }
+ override string getTypeSpecifier() { result = this.getReturnType().(DumpType).getTypeSpecifier() }
override string getDeclaratorPrefix() {
- result = getReturnType().(DumpType).getDeclaratorPrefix()
+ result = this.getReturnType().(DumpType).getDeclaratorPrefix()
}
language[monotonicAggregates]
@@ -285,39 +297,41 @@ private class RoutineDumpType extends DumpType, RoutineType {
result =
"(" +
concat(int i |
- exists(getParameterType(i))
+ exists(this.getParameterType(i))
|
- getParameterTypeString(getParameterType(i)), ", " order by i
+ getParameterTypeString(this.getParameterType(i)), ", " order by i
) + ")"
}
override string getDeclaratorSuffix() {
result =
- getReturnType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
- getReturnType().(DumpType).getDeclaratorSuffix()
+ this.getReturnType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
+ this.getReturnType().(DumpType).getDeclaratorSuffix()
}
}
private class SpecifiedDumpType extends DerivedDumpType, SpecifiedType {
override string getDeclaratorPrefix() {
exists(string basePrefix |
- basePrefix = getBaseType().(DumpType).getDeclaratorPrefix() and
- if getBaseType().getUnspecifiedType() instanceof RoutineType
+ basePrefix = this.getBaseType().(DumpType).getDeclaratorPrefix() and
+ if this.getBaseType().getUnspecifiedType() instanceof RoutineType
then result = basePrefix
- else result = basePrefix + " " + getSpecifierString()
+ else result = basePrefix + " " + this.getSpecifierString()
)
}
override string getDeclaratorSuffixBeforeQualifiers() {
exists(string baseSuffix |
- baseSuffix = getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() and
- if getBaseType().getUnspecifiedType() instanceof RoutineType
- then result = baseSuffix + " " + getSpecifierString()
+ baseSuffix = this.getBaseType().(DumpType).getDeclaratorSuffixBeforeQualifiers() and
+ if this.getBaseType().getUnspecifiedType() instanceof RoutineType
+ then result = baseSuffix + " " + this.getSpecifierString()
else result = baseSuffix
)
}
- override string getDeclaratorSuffix() { result = getBaseType().(DumpType).getDeclaratorSuffix() }
+ override string getDeclaratorSuffix() {
+ result = this.getBaseType().(DumpType).getDeclaratorSuffix()
+ }
}
private class UserDumpType extends DumpType, DumpDeclaration, UserType {
@@ -330,18 +344,18 @@ private class UserDumpType extends DumpType, DumpDeclaration, UserType {
// "lambda [] type at line 12, col. 40"
// Use `min(getSimpleName())` to work around an extractor bug where a lambda can have different names
// from different compilation units.
- simpleName = "(" + min(getSimpleName()) + ")"
- else simpleName = getSimpleName()
+ simpleName = "(" + min(this.getSimpleName()) + ")"
+ else simpleName = this.getSimpleName()
) and
- result = getScopePrefix(this) + simpleName + getTemplateArgumentsString()
+ result = getScopePrefix(this) + simpleName + this.getTemplateArgumentsString()
)
}
- override string getTypeSpecifier() { result = getIdentityString() }
+ override string getTypeSpecifier() { result = this.getIdentityString() }
}
private class DumpProxyClass extends UserDumpType, ProxyClass {
- override string getIdentityString() { result = getName() }
+ override string getIdentityString() { result = this.getName() }
}
private class DumpVariable extends DumpDeclaration, Variable {
@@ -360,9 +374,9 @@ private class DumpVariable extends DumpDeclaration, Variable {
private class DumpFunction extends DumpDeclaration, Function {
override string getIdentityString() {
result =
- getType().(DumpType).getTypeSpecifier() + getType().(DumpType).getDeclaratorPrefix() + " " +
- getScopePrefix(this) + getName() + getTemplateArgumentsString() +
- getDeclaratorSuffixBeforeQualifiers() + getDeclaratorSuffix()
+ this.getType().(DumpType).getTypeSpecifier() + this.getType().(DumpType).getDeclaratorPrefix()
+ + " " + getScopePrefix(this) + this.getName() + this.getTemplateArgumentsString() +
+ this.getDeclaratorSuffixBeforeQualifiers() + this.getDeclaratorSuffix()
}
language[monotonicAggregates]
@@ -370,28 +384,29 @@ private class DumpFunction extends DumpDeclaration, Function {
result =
"(" +
concat(int i |
- exists(getParameter(i).getType())
+ exists(this.getParameter(i).getType())
|
- getParameterTypeString(getParameter(i).getType()), ", " order by i
- ) + ")" + getQualifierString()
+ getParameterTypeString(this.getParameter(i).getType()), ", " order by i
+ ) + ")" + this.getQualifierString()
}
private string getQualifierString() {
- if exists(getACVQualifier())
+ if exists(this.getACVQualifier())
then
- result = " " + strictconcat(string qualifier | qualifier = getACVQualifier() | qualifier, " ")
+ result =
+ " " + strictconcat(string qualifier | qualifier = this.getACVQualifier() | qualifier, " ")
else result = ""
}
private string getACVQualifier() {
- result = getASpecifier().getName() and
+ result = this.getASpecifier().getName() and
result = ["const", "volatile"]
}
private string getDeclaratorSuffix() {
result =
- getType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
- getType().(DumpType).getDeclaratorSuffix()
+ this.getType().(DumpType).getDeclaratorSuffixBeforeQualifiers() +
+ this.getType().(DumpType).getDeclaratorSuffix()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/Specifier.qll b/cpp/ql/lib/semmle/code/cpp/Specifier.qll
index 4a425b690f4..fe2919c3ed6 100644
--- a/cpp/ql/lib/semmle/code/cpp/Specifier.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Specifier.qll
@@ -31,11 +31,7 @@ class Specifier extends Element, @specifier {
* A C/C++ function specifier: `inline`, `virtual`, or `explicit`.
*/
class FunctionSpecifier extends Specifier {
- FunctionSpecifier() {
- this.hasName("inline") or
- this.hasName("virtual") or
- this.hasName("explicit")
- }
+ FunctionSpecifier() { this.hasName(["inline", "virtual", "explicit"]) }
override string getAPrimaryQlClass() { result = "FunctionSpecifier" }
}
@@ -45,13 +41,7 @@ class FunctionSpecifier extends Specifier {
* or `mutable".
*/
class StorageClassSpecifier extends Specifier {
- StorageClassSpecifier() {
- this.hasName("auto") or
- this.hasName("register") or
- this.hasName("static") or
- this.hasName("extern") or
- this.hasName("mutable")
- }
+ StorageClassSpecifier() { this.hasName(["auto", "register", "static", "extern", "mutable"]) }
override string getAPrimaryQlClass() { result = "StorageClassSpecifier" }
}
@@ -60,11 +50,7 @@ class StorageClassSpecifier extends Specifier {
* A C++ access specifier: `public`, `protected`, or `private`.
*/
class AccessSpecifier extends Specifier {
- AccessSpecifier() {
- this.hasName("public") or
- this.hasName("protected") or
- this.hasName("private")
- }
+ AccessSpecifier() { this.hasName(["public", "protected", "private"]) }
/**
* Gets the visibility of a field with access specifier `this` if it is
@@ -140,7 +126,7 @@ class Attribute extends Element, @attribute {
AttributeArgument getArgument(int i) { result.getAttribute() = this and result.getIndex() = i }
/** Gets an argument of the attribute. */
- AttributeArgument getAnArgument() { result = getArgument(_) }
+ AttributeArgument getAnArgument() { result = this.getArgument(_) }
}
/**
@@ -166,7 +152,7 @@ class StdAttribute extends Attribute, @stdattribute {
* Holds if this attribute has the given namespace and name.
*/
predicate hasQualifiedName(string namespace, string name) {
- namespace = getNamespace() and hasName(name)
+ namespace = this.getNamespace() and this.hasName(name)
}
}
@@ -184,7 +170,7 @@ class Declspec extends Attribute, @declspec { }
*/
class MicrosoftAttribute extends Attribute, @msattribute {
AttributeArgument getNamedArgument(string name) {
- result = getAnArgument() and result.getName() = name
+ result = this.getAnArgument() and result.getName() = name
}
}
@@ -212,13 +198,13 @@ class AlignAs extends Attribute, @alignas {
* ```
*/
class FormatAttribute extends GnuAttribute {
- FormatAttribute() { getName() = "format" }
+ FormatAttribute() { this.getName() = "format" }
/**
* Gets the archetype of this format attribute, for example
* `"printf"`.
*/
- string getArchetype() { result = getArgument(0).getValueText() }
+ string getArchetype() { result = this.getArgument(0).getValueText() }
/**
* Gets the index in (1-based) format attribute notation associated
@@ -236,7 +222,7 @@ class FormatAttribute extends GnuAttribute {
* Gets the (0-based) index of the format string,
* according to this attribute.
*/
- int getFormatIndex() { result = getArgument(1).getValueInt() - firstArgumentNumber() }
+ int getFormatIndex() { result = this.getArgument(1).getValueInt() - this.firstArgumentNumber() }
/**
* Gets the (0-based) index of the first format argument (if any),
@@ -244,8 +230,8 @@ class FormatAttribute extends GnuAttribute {
*/
int getFirstFormatArgIndex() {
exists(int val |
- val = getArgument(2).getValueInt() and
- result = val - firstArgumentNumber() and
+ val = this.getArgument(2).getValueInt() and
+ result = val - this.firstArgumentNumber() and
not val = 0 // indicates a `vprintf` style format function with arguments not directly available.
)
}
@@ -277,7 +263,7 @@ class AttributeArgument extends Element, @attribute_arg {
/**
* Gets the value of this argument, if its value is integral.
*/
- int getValueInt() { result = getValueText().toInt() }
+ int getValueInt() { result = this.getValueText().toInt() }
/**
* Gets the value of this argument, if its value is a type.
@@ -304,11 +290,11 @@ class AttributeArgument extends Element, @attribute_arg {
then result = "empty argument"
else
exists(string prefix, string tail |
- (if exists(getName()) then prefix = getName() + "=" else prefix = "") and
+ (if exists(this.getName()) then prefix = this.getName() + "=" else prefix = "") and
(
if exists(@attribute_arg_type self | self = underlyingElement(this))
- then tail = getValueType().getName()
- else tail = getValueText()
+ then tail = this.getValueType().getName()
+ else tail = this.getValueText()
) and
result = prefix + tail
)
diff --git a/cpp/ql/lib/semmle/code/cpp/Struct.qll b/cpp/ql/lib/semmle/code/cpp/Struct.qll
index 50a208894b4..5465472374f 100644
--- a/cpp/ql/lib/semmle/code/cpp/Struct.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Struct.qll
@@ -41,7 +41,7 @@ class Struct extends Class {
* ```
*/
class LocalStruct extends Struct {
- LocalStruct() { isLocal() }
+ LocalStruct() { this.isLocal() }
override string getAPrimaryQlClass() { not this instanceof LocalUnion and result = "LocalStruct" }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/TestFile.qll b/cpp/ql/lib/semmle/code/cpp/TestFile.qll
index b9e3fe3a614..a2e496ab019 100644
--- a/cpp/ql/lib/semmle/code/cpp/TestFile.qll
+++ b/cpp/ql/lib/semmle/code/cpp/TestFile.qll
@@ -10,8 +10,8 @@ import semmle.code.cpp.File
*/
private class GoogleTestHeader extends File {
GoogleTestHeader() {
- getBaseName() = "gtest.h" and
- getParentContainer().getBaseName() = "gtest"
+ this.getBaseName() = "gtest.h" and
+ this.getParentContainer().getBaseName() = "gtest"
}
}
@@ -30,8 +30,8 @@ private class GoogleTest extends MacroInvocation {
*/
private class BoostTestFolder extends Folder {
BoostTestFolder() {
- getBaseName() = "test" and
- getParentContainer().getBaseName() = "boost"
+ this.getBaseName() = "test" and
+ this.getParentContainer().getBaseName() = "boost"
}
}
@@ -49,7 +49,7 @@ private class BoostTest extends MacroInvocation {
* The `cppunit` directory.
*/
private class CppUnitFolder extends Folder {
- CppUnitFolder() { getBaseName() = "cppunit" }
+ CppUnitFolder() { this.getBaseName() = "cppunit" }
}
/**
@@ -57,8 +57,8 @@ private class CppUnitFolder extends Folder {
*/
private class CppUnitClass extends Class {
CppUnitClass() {
- getFile().getParentContainer+() instanceof CppUnitFolder and
- getNamespace().getParentNamespace*().getName() = "CppUnit"
+ this.getFile().getParentContainer+() instanceof CppUnitFolder and
+ this.getNamespace().getParentNamespace*().getName() = "CppUnit"
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/Type.qll b/cpp/ql/lib/semmle/code/cpp/Type.qll
index bf3defd4f40..f8552144ea8 100644
--- a/cpp/ql/lib/semmle/code/cpp/Type.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Type.qll
@@ -81,7 +81,7 @@ class Type extends Locatable, @type {
* Holds if this type refers to type `t` (by default,
* a type always refers to itself).
*/
- predicate refersTo(Type t) { refersToDirectly*(t) }
+ predicate refersTo(Type t) { this.refersToDirectly*(t) }
/**
* Holds if this type refers to type `t` directly.
@@ -1080,11 +1080,11 @@ class DerivedType extends Type, @derivedtype {
override predicate refersToDirectly(Type t) { t = this.getBaseType() }
- override predicate involvesReference() { getBaseType().involvesReference() }
+ override predicate involvesReference() { this.getBaseType().involvesReference() }
- override predicate involvesTemplateParameter() { getBaseType().involvesTemplateParameter() }
+ override predicate involvesTemplateParameter() { this.getBaseType().involvesTemplateParameter() }
- override Type stripType() { result = getBaseType().stripType() }
+ override Type stripType() { result = this.getBaseType().stripType() }
/**
* Holds if this type has the `__autoreleasing` specifier or if it points to
@@ -1165,33 +1165,35 @@ class Decltype extends Type, @decltype {
*/
predicate parenthesesWouldChangeMeaning() { decltypes(underlyingElement(this), _, _, true) }
- override Type getUnderlyingType() { result = getBaseType().getUnderlyingType() }
+ override Type getUnderlyingType() { result = this.getBaseType().getUnderlyingType() }
- override Type stripTopLevelSpecifiers() { result = getBaseType().stripTopLevelSpecifiers() }
+ override Type stripTopLevelSpecifiers() { result = this.getBaseType().stripTopLevelSpecifiers() }
- override Type stripType() { result = getBaseType().stripType() }
+ override Type stripType() { result = this.getBaseType().stripType() }
- override Type resolveTypedefs() { result = getBaseType().resolveTypedefs() }
+ override Type resolveTypedefs() { result = this.getBaseType().resolveTypedefs() }
- override Location getLocation() { result = getExpr().getLocation() }
+ override Location getLocation() { result = this.getExpr().getLocation() }
override string toString() { result = "decltype(...)" }
override string getName() { none() }
- override int getSize() { result = getBaseType().getSize() }
+ override int getSize() { result = this.getBaseType().getSize() }
- override int getAlignment() { result = getBaseType().getAlignment() }
+ override int getAlignment() { result = this.getBaseType().getAlignment() }
- override int getPointerIndirectionLevel() { result = getBaseType().getPointerIndirectionLevel() }
+ override int getPointerIndirectionLevel() {
+ result = this.getBaseType().getPointerIndirectionLevel()
+ }
override string explain() {
result = "decltype resulting in {" + this.getBaseType().explain() + "}"
}
- override predicate involvesReference() { getBaseType().involvesReference() }
+ override predicate involvesReference() { this.getBaseType().involvesReference() }
- override predicate involvesTemplateParameter() { getBaseType().involvesTemplateParameter() }
+ override predicate involvesTemplateParameter() { this.getBaseType().involvesTemplateParameter() }
override predicate isDeeplyConst() { this.getBaseType().isDeeplyConst() }
@@ -1223,7 +1225,7 @@ class PointerType extends DerivedType {
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
override Type resolveTypedefs() {
- result.(PointerType).getBaseType() = getBaseType().resolveTypedefs()
+ result.(PointerType).getBaseType() = this.getBaseType().resolveTypedefs()
}
}
@@ -1240,7 +1242,9 @@ class ReferenceType extends DerivedType {
override string getAPrimaryQlClass() { result = "ReferenceType" }
- override int getPointerIndirectionLevel() { result = getBaseType().getPointerIndirectionLevel() }
+ override int getPointerIndirectionLevel() {
+ result = this.getBaseType().getPointerIndirectionLevel()
+ }
override string explain() { result = "reference to {" + this.getBaseType().explain() + "}" }
@@ -1251,7 +1255,7 @@ class ReferenceType extends DerivedType {
override predicate involvesReference() { any() }
override Type resolveTypedefs() {
- result.(ReferenceType).getBaseType() = getBaseType().resolveTypedefs()
+ result.(ReferenceType).getBaseType() = this.getBaseType().resolveTypedefs()
}
}
@@ -1330,11 +1334,11 @@ class SpecifiedType extends DerivedType {
}
override Type resolveTypedefs() {
- result.(SpecifiedType).getBaseType() = getBaseType().resolveTypedefs() and
- result.getASpecifier() = getASpecifier()
+ result.(SpecifiedType).getBaseType() = this.getBaseType().resolveTypedefs() and
+ result.getASpecifier() = this.getASpecifier()
}
- override Type stripTopLevelSpecifiers() { result = getBaseType().stripTopLevelSpecifiers() }
+ override Type stripTopLevelSpecifiers() { result = this.getBaseType().stripTopLevelSpecifiers() }
}
/**
@@ -1433,7 +1437,8 @@ class GNUVectorType extends DerivedType {
override int getAlignment() { arraysizes(underlyingElement(this), _, _, result) }
override string explain() {
- result = "GNU " + getNumElements() + " element vector of {" + this.getBaseType().explain() + "}"
+ result =
+ "GNU " + this.getNumElements() + " element vector of {" + this.getBaseType().explain() + "}"
}
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
@@ -1468,7 +1473,9 @@ class FunctionReferenceType extends FunctionPointerIshType {
override string getAPrimaryQlClass() { result = "FunctionReferenceType" }
- override int getPointerIndirectionLevel() { result = getBaseType().getPointerIndirectionLevel() }
+ override int getPointerIndirectionLevel() {
+ result = this.getBaseType().getPointerIndirectionLevel()
+ }
override string explain() {
result = "reference to {" + this.getBaseType().(RoutineType).explain() + "}"
@@ -1535,8 +1542,8 @@ class FunctionPointerIshType extends DerivedType {
int getNumberOfParameters() { result = count(int i | exists(this.getParameterType(i))) }
override predicate involvesTemplateParameter() {
- getReturnType().involvesTemplateParameter() or
- getAParameterType().involvesTemplateParameter()
+ this.getReturnType().involvesTemplateParameter() or
+ this.getAParameterType().involvesTemplateParameter()
}
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
@@ -1581,7 +1588,7 @@ class PointerToMemberType extends Type, @ptrtomember {
this.getBaseType().explain() + "}"
}
- override predicate involvesTemplateParameter() { getBaseType().involvesTemplateParameter() }
+ override predicate involvesTemplateParameter() { this.getBaseType().involvesTemplateParameter() }
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
}
@@ -1650,7 +1657,6 @@ class RoutineType extends Type, @routinetype {
i = 0 and result = "" and not exists(this.getAParameterType())
or
(
- exists(this.getParameterType(i)) and
if i < max(int j | exists(this.getParameterType(j)))
then
// Not the last one
@@ -1671,8 +1677,8 @@ class RoutineType extends Type, @routinetype {
override predicate isDeeplyConstBelow() { none() } // Current limitation: no such thing as a const routine type
override predicate involvesTemplateParameter() {
- getReturnType().involvesTemplateParameter() or
- getAParameterType().involvesTemplateParameter()
+ this.getReturnType().involvesTemplateParameter() or
+ this.getAParameterType().involvesTemplateParameter()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/TypedefType.qll b/cpp/ql/lib/semmle/code/cpp/TypedefType.qll
index aaf452ce4bb..51bcf6f6127 100644
--- a/cpp/ql/lib/semmle/code/cpp/TypedefType.qll
+++ b/cpp/ql/lib/semmle/code/cpp/TypedefType.qll
@@ -25,7 +25,7 @@ class TypedefType extends UserType {
override Type getUnderlyingType() { result = this.getBaseType().getUnderlyingType() }
- override Type stripTopLevelSpecifiers() { result = getBaseType().stripTopLevelSpecifiers() }
+ override Type stripTopLevelSpecifiers() { result = this.getBaseType().stripTopLevelSpecifiers() }
override int getSize() { result = this.getBaseType().getSize() }
@@ -43,11 +43,11 @@ class TypedefType extends UserType {
result = this.getBaseType().getASpecifier()
}
- override predicate involvesReference() { getBaseType().involvesReference() }
+ override predicate involvesReference() { this.getBaseType().involvesReference() }
- override Type resolveTypedefs() { result = getBaseType().resolveTypedefs() }
+ override Type resolveTypedefs() { result = this.getBaseType().resolveTypedefs() }
- override Type stripType() { result = getBaseType().stripType() }
+ override Type stripType() { result = this.getBaseType().stripType() }
}
/**
@@ -90,7 +90,7 @@ class UsingAliasTypedefType extends TypedefType {
* ```
*/
class LocalTypedefType extends TypedefType {
- LocalTypedefType() { isLocal() }
+ LocalTypedefType() { this.isLocal() }
override string getAPrimaryQlClass() { result = "LocalTypedefType" }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/Union.qll b/cpp/ql/lib/semmle/code/cpp/Union.qll
index 6dcb2f0796c..2f1b5b07b25 100644
--- a/cpp/ql/lib/semmle/code/cpp/Union.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Union.qll
@@ -37,7 +37,7 @@ class Union extends Struct {
* ```
*/
class LocalUnion extends Union {
- LocalUnion() { isLocal() }
+ LocalUnion() { this.isLocal() }
override string getAPrimaryQlClass() { result = "LocalUnion" }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/UserType.qll b/cpp/ql/lib/semmle/code/cpp/UserType.qll
index 2ab0603f06c..13697722190 100644
--- a/cpp/ql/lib/semmle/code/cpp/UserType.qll
+++ b/cpp/ql/lib/semmle/code/cpp/UserType.qll
@@ -30,19 +30,19 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
* Gets the simple name of this type, without any template parameters. For example
* if the name of the type is `"myType"`, the simple name is just `"myType"`.
*/
- string getSimpleName() { result = getName().regexpReplaceAll("<.*", "") }
+ string getSimpleName() { result = this.getName().regexpReplaceAll("<.*", "") }
override predicate hasName(string name) { usertypes(underlyingElement(this), name, _) }
/** Holds if this type is anonymous. */
- predicate isAnonymous() { getName().matches("(unnamed%") }
+ predicate isAnonymous() { this.getName().matches("(unnamed%") }
override predicate hasSpecifier(string s) { Type.super.hasSpecifier(s) }
override Specifier getASpecifier() { result = Type.super.getASpecifier() }
override Location getLocation() {
- if hasDefinition()
+ if this.hasDefinition()
then result = this.getDefinitionLocation()
else result = this.getADeclarationLocation()
}
@@ -53,16 +53,16 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
else exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry())
}
- override Location getADeclarationLocation() { result = getADeclarationEntry().getLocation() }
+ override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
override TypeDeclarationEntry getDefinition() {
- result = getADeclarationEntry() and
+ result = this.getADeclarationEntry() and
result.isDefinition()
}
override Location getDefinitionLocation() {
- if exists(getDefinition())
- then result = getDefinition().getLocation()
+ if exists(this.getDefinition())
+ then result = this.getDefinition().getLocation()
else
exists(Class t |
this.(Class).isConstructedFrom(t) and result = t.getDefinition().getLocation()
@@ -80,7 +80,7 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
* Holds if this is a local type (that is, a type that has a directly-enclosing
* function).
*/
- predicate isLocal() { exists(getEnclosingFunction()) }
+ predicate isLocal() { exists(this.getEnclosingFunction()) }
/*
* Dummy implementations of inherited methods. This class must not be
@@ -107,9 +107,9 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
* ```
*/
class TypeDeclarationEntry extends DeclarationEntry, @type_decl {
- override UserType getDeclaration() { result = getType() }
+ override UserType getDeclaration() { result = this.getType() }
- override string getName() { result = getType().getName() }
+ override string getName() { result = this.getType().getName() }
override string getAPrimaryQlClass() { result = "TypeDeclarationEntry" }
diff --git a/cpp/ql/lib/semmle/code/cpp/Variable.qll b/cpp/ql/lib/semmle/code/cpp/Variable.qll
index 12e25f33afe..b0c9bac7f66 100644
--- a/cpp/ql/lib/semmle/code/cpp/Variable.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Variable.qll
@@ -104,17 +104,17 @@ class Variable extends Declaration, @variable {
override VariableDeclarationEntry getADeclarationEntry() { result.getDeclaration() = this }
- override Location getADeclarationLocation() { result = getADeclarationEntry().getLocation() }
+ override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
override VariableDeclarationEntry getDefinition() {
- result = getADeclarationEntry() and
+ result = this.getADeclarationEntry() and
result.isDefinition()
}
- override Location getDefinitionLocation() { result = getDefinition().getLocation() }
+ override Location getDefinitionLocation() { result = this.getDefinition().getLocation() }
override Location getLocation() {
- if exists(getDefinition())
+ if exists(this.getDefinition())
then result = this.getDefinitionLocation()
else result = this.getADeclarationLocation()
}
@@ -199,7 +199,7 @@ class Variable extends Declaration, @variable {
* ```
*/
class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
- override Variable getDeclaration() { result = getVariable() }
+ override Variable getDeclaration() { result = this.getVariable() }
override string getAPrimaryQlClass() { result = "VariableDeclarationEntry" }
@@ -276,32 +276,33 @@ class ParameterDeclarationEntry extends VariableDeclarationEntry {
int getIndex() { param_decl_bind(underlyingElement(this), result, _) }
private string getAnonymousParameterDescription() {
- not exists(getName()) and
+ not exists(this.getName()) and
exists(string idx |
idx =
- ((getIndex() + 1).toString() + "th")
+ ((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(getCanonicalName())
- then result = "declaration of " + getCanonicalName() + " as anonymous " + idx + " parameter"
+ if exists(this.getCanonicalName())
+ then
+ result = "declaration of " + this.getCanonicalName() + " as anonymous " + idx + " parameter"
else result = "declaration of " + idx + " parameter"
)
}
override string toString() {
- isDefinition() and
- result = "definition of " + getName()
+ this.isDefinition() and
+ result = "definition of " + this.getName()
or
- not isDefinition() and
- if getName() = getCanonicalName()
- then result = "declaration of " + getName()
- else result = "declaration of " + getCanonicalName() + " as " + getName()
+ not this.isDefinition() and
+ if this.getName() = this.getCanonicalName()
+ then result = "declaration of " + this.getName()
+ else result = "declaration of " + this.getCanonicalName() + " as " + this.getName()
or
- result = getAnonymousParameterDescription()
+ result = this.getAnonymousParameterDescription()
}
/**
@@ -311,8 +312,12 @@ class ParameterDeclarationEntry extends VariableDeclarationEntry {
*/
string getTypedName() {
exists(string typeString, string nameString |
- (if exists(getType().getName()) then typeString = getType().getName() else typeString = "") and
- (if exists(getName()) then nameString = getName() else nameString = "") and
+ (
+ if exists(this.getType().getName())
+ then typeString = this.getType().getName()
+ else typeString = ""
+ ) and
+ (if exists(this.getName()) then nameString = this.getName() else nameString = "") and
if typeString != "" and nameString != ""
then result = typeString + " " + nameString
else result = typeString + nameString
@@ -540,7 +545,7 @@ class MemberVariable extends Variable, @membervariable {
}
/** Holds if this member is mutable. */
- predicate isMutable() { getADeclarationEntry().hasSpecifier("mutable") }
+ predicate isMutable() { this.getADeclarationEntry().hasSpecifier("mutable") }
private Type getAType() { membervariables(underlyingElement(this), unresolveElement(result), _) }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/XML.qll b/cpp/ql/lib/semmle/code/cpp/XML.qll
index 5871fed0ddd..76f3b3cb022 100755
--- a/cpp/ql/lib/semmle/code/cpp/XML.qll
+++ b/cpp/ql/lib/semmle/code/cpp/XML.qll
@@ -24,7 +24,7 @@ class XMLLocatable extends @xmllocatable, TXMLLocatable {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -108,7 +108,7 @@ class XMLParent extends @xmlparent {
}
/** Gets the text value contained in this XML parent. */
- string getTextValue() { result = allCharactersString() }
+ string getTextValue() { result = this.allCharactersString() }
/** Gets a printable representation of this XML parent. */
string toString() { result = this.getName() }
@@ -119,7 +119,7 @@ class XMLFile extends XMLParent, File {
XMLFile() { xmlEncoding(this, _) }
/** Gets a printable representation of this XML file. */
- override string toString() { result = getName() }
+ override string toString() { result = this.getName() }
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
@@ -129,14 +129,14 @@ class XMLFile extends XMLParent, File {
*
* Gets the path of this XML file.
*/
- deprecated string getPath() { result = getAbsolutePath() }
+ deprecated string getPath() { result = this.getAbsolutePath() }
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
- deprecated string getFolder() { result = getParentContainer().getAbsolutePath() }
+ deprecated string getFolder() { result = this.getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }
@@ -200,7 +200,7 @@ class XMLDTD extends XMLLocatable, @xmldtd {
*/
class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
/** Holds if this XML element has the given `name`. */
- predicate hasName(string name) { name = getName() }
+ predicate hasName(string name) { name = this.getName() }
/** Gets the name of this XML element. */
override string getName() { xmlElements(this, result, _, _, _) }
@@ -239,7 +239,7 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
/** Gets a printable representation of this XML element. */
- override string toString() { result = getName() }
+ override string toString() { result = this.getName() }
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll b/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll
index 5778ee7dfb1..2328476d525 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/Buffer.qll
@@ -10,44 +10,11 @@ import semmle.code.cpp.dataflow.DataFlow
* char data[1]; // v
* };
* ```
- * This requires that `v` is an array of size 0 or 1, and `v` is the last member of `c`.
- * In addition, if the size of the structure is taken, there must be at least one instance
- * where a `c` pointer is allocated with additional space.
- * For example, holds for `c` if it occurs as
- * ```
- * malloc(sizeof(c) + 100 * sizeof(char))
- * ```
- * but not if it only ever occurs as
- * ```
- * malloc(sizeof(c))
- * ```
+ * This requires that `v` is an array of size 0 or 1.
*/
predicate memberMayBeVarSize(Class c, MemberVariable v) {
- exists(int i |
- // `v` is the last field in `c`
- i = max(int j | c.getCanonicalMember(j) instanceof Field | j) and
- v = c.getCanonicalMember(i) and
- // v is an array of size at most 1
- v.getUnspecifiedType().(ArrayType).getArraySize() <= 1 and
- not c instanceof Union
- ) and
- // If the size is taken, then arithmetic is performed on the result at least once
- (
- // `sizeof(c)` is not taken
- not exists(SizeofOperator so |
- so.(SizeofTypeOperator).getTypeOperand().getUnspecifiedType() = c or
- so.(SizeofExprOperator).getExprOperand().getUnspecifiedType() = c
- )
- or
- // or `sizeof(c)` is taken
- exists(SizeofOperator so |
- so.(SizeofTypeOperator).getTypeOperand().getUnspecifiedType() = c or
- so.(SizeofExprOperator).getExprOperand().getUnspecifiedType() = c
- |
- // and arithmetic is performed on the result
- so.getParent*() instanceof AddExpr
- )
- )
+ c = v.getDeclaringType() and
+ v.getUnspecifiedType().(ArrayType).getArraySize() <= 1
}
/**
@@ -60,10 +27,6 @@ int getBufferSize(Expr bufferExpr, Element why) {
result = bufferVar.getUnspecifiedType().(ArrayType).getSize() and
why = bufferVar and
not memberMayBeVarSize(_, bufferVar) and
- not exists(Union bufferType |
- bufferType.getAMemberVariable() = why and
- bufferVar.getUnspecifiedType().(ArrayType).getSize() <= 1
- ) and
not result = 0 // zero sized arrays are likely to have special usage, for example
or
// behaving a bit like a 'union' overlapping other fields.
@@ -85,13 +48,6 @@ int getBufferSize(Expr bufferExpr, Element why) {
parentPtr.getTarget().getUnspecifiedType().(PointerType).getBaseType() = parentClass and
result = getBufferSize(parentPtr, _) + bufferVar.getType().getSize() - parentClass.getSize()
)
- or
- exists(Union bufferType |
- bufferType.getAMemberVariable() = why and
- why = bufferVar and
- bufferVar.getUnspecifiedType().(ArrayType).getSize() <= 1 and
- result = bufferType.getSize()
- )
)
or
// buffer is a fixed size dynamic allocation
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/CommonType.qll b/cpp/ql/lib/semmle/code/cpp/commons/CommonType.qll
index 5d6c64630a6..26e60538ec6 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/CommonType.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/CommonType.qll
@@ -375,8 +375,8 @@ class Wchar_t extends Type {
class MicrosoftInt8Type extends IntegralType {
MicrosoftInt8Type() {
this instanceof CharType and
- not isExplicitlyUnsigned() and
- not isExplicitlySigned()
+ not this.isExplicitlyUnsigned() and
+ not this.isExplicitlySigned()
}
}
@@ -391,8 +391,8 @@ class MicrosoftInt8Type extends IntegralType {
class MicrosoftInt16Type extends IntegralType {
MicrosoftInt16Type() {
this instanceof ShortType and
- not isExplicitlyUnsigned() and
- not isExplicitlySigned()
+ not this.isExplicitlyUnsigned() and
+ not this.isExplicitlySigned()
}
}
@@ -407,8 +407,8 @@ class MicrosoftInt16Type extends IntegralType {
class MicrosoftInt32Type extends IntegralType {
MicrosoftInt32Type() {
this instanceof IntType and
- not isExplicitlyUnsigned() and
- not isExplicitlySigned()
+ not this.isExplicitlyUnsigned() and
+ not this.isExplicitlySigned()
}
}
@@ -423,8 +423,8 @@ class MicrosoftInt32Type extends IntegralType {
class MicrosoftInt64Type extends IntegralType {
MicrosoftInt64Type() {
this instanceof LongLongType and
- not isExplicitlyUnsigned() and
- not isExplicitlySigned()
+ not this.isExplicitlyUnsigned() and
+ not this.isExplicitlySigned()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Dependency.qll b/cpp/ql/lib/semmle/code/cpp/commons/Dependency.qll
index 1b885fb8f5f..59776d5b87a 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/Dependency.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/Dependency.qll
@@ -33,7 +33,7 @@ DependencyOptions getDependencyOptions() { any() }
class DependsSource extends Element {
DependsSource() {
// not inside a template instantiation
- not exists(Element other | isFromTemplateInstantiation(other)) or
+ not exists(Element other | this.isFromTemplateInstantiation(other)) or
// allow DeclarationEntrys of template specializations
this.(DeclarationEntry).getDeclaration().(Function).isConstructedFrom(_) or
this.(DeclarationEntry).getDeclaration().(Class).isConstructedFrom(_)
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll b/cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll
index ee072fb0ed3..2f811ab83a0 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/NullTermination.qll
@@ -1,6 +1,7 @@
import cpp
private import semmle.code.cpp.models.interfaces.ArrayFunction
private import semmle.code.cpp.models.implementations.Strcat
+import semmle.code.cpp.dataflow.DataFlow
private predicate mayAddNullTerminatorHelper(Expr e, VariableAccess va, Expr e0) {
exists(StackVariable v0, Expr val |
@@ -45,22 +46,28 @@ predicate mayAddNullTerminator(Expr e, VariableAccess va) {
ae.getRValue().getAChild*() = va
)
or
- // Function call: library function, varargs function, function
- // containing assembler code, or function where the relevant
- // parameter is potentially added a null terminator.
+ // Function calls...
exists(Call c, Function f, int i |
e = c and
f = c.getTarget() and
not functionArgumentMustBeNullTerminated(f, i) and
c.getAnArgumentSubExpr(i) = va
|
- not f.hasEntryPoint() and not functionArgumentMustBeNullTerminated(f, i)
+ // library function
+ not f.hasEntryPoint()
or
+ // function where the relevant parameter is potentially added a null terminator
mayAddNullTerminator(_, f.getParameter(i).getAnAccess())
or
+ // varargs function
f.isVarargs() and i >= f.getNumberOfParameters()
or
+ // function containing assembler code
exists(AsmStmt s | s.getEnclosingFunction() = f)
+ or
+ // function where the relevant parameter is returned (leaking it to be potentially null terminated elsewhere)
+ DataFlow::localFlow(DataFlow::parameterNode(f.getParameter(i)),
+ DataFlow::exprNode(any(ReturnStmt rs).getExpr()))
)
or
// Call without target (e.g., function pointer call)
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
index ef5f5511f6d..a7c72a5db8d 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
@@ -8,7 +8,7 @@ import semmle.code.cpp.commons.StringAnalysis
import semmle.code.cpp.models.interfaces.FormattingFunction
class PrintfFormatAttribute extends FormatAttribute {
- PrintfFormatAttribute() { getArchetype() = ["printf", "__printf__"] }
+ PrintfFormatAttribute() { this.getArchetype() = ["printf", "__printf__"] }
}
/**
@@ -20,13 +20,13 @@ class AttributeFormattingFunction extends FormattingFunction {
AttributeFormattingFunction() {
exists(PrintfFormatAttribute printf_attrib |
- printf_attrib = getAnAttribute() and
+ printf_attrib = this.getAnAttribute() and
exists(printf_attrib.getFirstFormatArgIndex()) // exclude `vprintf` style format functions
)
}
override int getFormatParameterIndex() {
- forex(PrintfFormatAttribute printf_attrib | printf_attrib = getAnAttribute() |
+ forex(PrintfFormatAttribute printf_attrib | printf_attrib = this.getAnAttribute() |
result = printf_attrib.getFormatIndex()
)
}
@@ -132,7 +132,7 @@ deprecated predicate variadicFormatter(Function f, int formatParamIndex) {
class UserDefinedFormattingFunction extends FormattingFunction {
override string getAPrimaryQlClass() { result = "UserDefinedFormattingFunction" }
- UserDefinedFormattingFunction() { isVarargs() and callsVariadicFormatter(this, _, _, _) }
+ UserDefinedFormattingFunction() { this.isVarargs() and callsVariadicFormatter(this, _, _, _) }
override int getFormatParameterIndex() { callsVariadicFormatter(this, _, result, _) }
@@ -191,7 +191,7 @@ class FormattingFunctionCall extends Expr {
exists(int i |
result = this.getArgument(i) and
n >= 0 and
- n = i - getTarget().(FormattingFunction).getFirstFormatArgumentIndex()
+ n = i - this.getTarget().(FormattingFunction).getFirstFormatArgumentIndex()
)
}
@@ -251,7 +251,22 @@ class FormattingFunctionCall extends Expr {
int getNumFormatArgument() {
result = count(this.getFormatArgument(_)) and
// format arguments must be known
- exists(getTarget().(FormattingFunction).getFirstFormatArgumentIndex())
+ exists(this.getTarget().(FormattingFunction).getFirstFormatArgumentIndex())
+ }
+
+ /**
+ * Gets the argument, if any, to which the output is written. If `isStream` is
+ * `true`, the output argument is a stream (that is, this call behaves like
+ * `fprintf`). If `isStream` is `false`, the output argument is a buffer (that
+ * is, this call behaves like `sprintf`)
+ */
+ Expr getOutputArgument(boolean isStream) {
+ result =
+ this.(Call)
+ .getArgument(this.(Call)
+ .getTarget()
+ .(FormattingFunction)
+ .getOutputParameterIndex(isStream))
}
}
@@ -275,7 +290,7 @@ class FormatLiteral extends Literal {
* DEPRECATED: Use getDefaultCharType() instead.
*/
deprecated predicate isWideCharDefault() {
- getUse().getTarget().(FormattingFunction).isWideCharDefault()
+ this.getUse().getTarget().(FormattingFunction).isWideCharDefault()
}
/**
@@ -283,7 +298,7 @@ class FormatLiteral extends Literal {
* `char` or `wchar_t`.
*/
Type getDefaultCharType() {
- result = getUse().getTarget().(FormattingFunction).getDefaultCharType()
+ result = this.getUse().getTarget().(FormattingFunction).getDefaultCharType()
}
/**
@@ -292,7 +307,7 @@ class FormatLiteral extends Literal {
* which is correct for a particular function.
*/
Type getNonDefaultCharType() {
- result = getUse().getTarget().(FormattingFunction).getNonDefaultCharType()
+ result = this.getUse().getTarget().(FormattingFunction).getNonDefaultCharType()
}
/**
@@ -300,7 +315,9 @@ class FormatLiteral extends Literal {
* snapshots there may be multiple results where we can't tell which is correct for a
* particular function.
*/
- Type getWideCharType() { result = getUse().getTarget().(FormattingFunction).getWideCharType() }
+ Type getWideCharType() {
+ result = this.getUse().getTarget().(FormattingFunction).getWideCharType()
+ }
/**
* Holds if this `FormatLiteral` is in a context that supports
@@ -338,7 +355,7 @@ class FormatLiteral extends Literal {
}
private string getFlagRegexp() {
- if isMicrosoft() then result = "[-+ #0']*" else result = "[-+ #0'I]*"
+ if this.isMicrosoft() then result = "[-+ #0']*" else result = "[-+ #0'I]*"
}
private string getFieldWidthRegexp() { result = "(?:[1-9][0-9]*|\\*|\\*[0-9]+\\$)?" }
@@ -346,13 +363,13 @@ class FormatLiteral extends Literal {
private string getPrecRegexp() { result = "(?:\\.(?:[0-9]*|\\*|\\*[0-9]+\\$))?" }
private string getLengthRegexp() {
- if isMicrosoft()
+ if this.isMicrosoft()
then result = "(?:hh?|ll?|L|q|j|z|t|w|I32|I64|I)?"
else result = "(?:hh?|ll?|L|q|j|z|Z|t)?"
}
private string getConvCharRegexp() {
- if isMicrosoft()
+ if this.isMicrosoft()
then result = "[aAcCdeEfFgGimnopsSuxXZ@]"
else result = "[aAcCdeEfFgGimnopsSuxX@]"
}
@@ -732,16 +749,16 @@ class FormatLiteral extends Literal {
* Gets the argument type required by the nth conversion specifier.
*/
Type getConversionType(int n) {
- result = getConversionType1(n) or
- result = getConversionType1b(n) or
- result = getConversionType2(n) or
- result = getConversionType3(n) or
- result = getConversionType4(n) or
- result = getConversionType6(n) or
- result = getConversionType7(n) or
- result = getConversionType8(n) or
- result = getConversionType9(n) or
- result = getConversionType10(n)
+ result = this.getConversionType1(n) or
+ result = this.getConversionType1b(n) or
+ result = this.getConversionType2(n) or
+ result = this.getConversionType3(n) or
+ result = this.getConversionType4(n) or
+ result = this.getConversionType6(n) or
+ result = this.getConversionType7(n) or
+ result = this.getConversionType8(n) or
+ result = this.getConversionType9(n) or
+ result = this.getConversionType10(n)
}
private Type getConversionType1(int n) {
@@ -771,15 +788,15 @@ class FormatLiteral extends Literal {
or
conv = ["c", "C"] and
len = ["l", "w"] and
- result = getWideCharType()
+ result = this.getWideCharType()
or
conv = "c" and
(len != "l" and len != "w" and len != "h") and
- result = getDefaultCharType()
+ result = this.getDefaultCharType()
or
conv = "C" and
(len != "l" and len != "w" and len != "h") and
- result = getNonDefaultCharType()
+ result = this.getNonDefaultCharType()
)
)
}
@@ -816,15 +833,15 @@ class FormatLiteral extends Literal {
or
conv = ["s", "S"] and
len = ["l", "w"] and
- result.(PointerType).getBaseType() = getWideCharType()
+ result.(PointerType).getBaseType() = this.getWideCharType()
or
conv = "s" and
(len != "l" and len != "w" and len != "h") and
- result.(PointerType).getBaseType() = getDefaultCharType()
+ result.(PointerType).getBaseType() = this.getDefaultCharType()
or
conv = "S" and
(len != "l" and len != "w" and len != "h") and
- result.(PointerType).getBaseType() = getNonDefaultCharType()
+ result.(PointerType).getBaseType() = this.getNonDefaultCharType()
)
)
}
@@ -879,19 +896,19 @@ class FormatLiteral extends Literal {
exists(string len, string conv |
this.parseConvSpec(n, _, _, _, _, _, len, conv) and
(len != "l" and len != "w" and len != "h") and
- getUse().getTarget().(FormattingFunction).getFormatCharType().getSize() > 1 and // wide function
+ this.getUse().getTarget().(FormattingFunction).getFormatCharType().getSize() > 1 and // wide function
(
conv = "c" and
- result = getNonDefaultCharType()
+ result = this.getNonDefaultCharType()
or
conv = "C" and
- result = getDefaultCharType()
+ result = this.getDefaultCharType()
or
conv = "s" and
- result.(PointerType).getBaseType() = getNonDefaultCharType()
+ result.(PointerType).getBaseType() = this.getNonDefaultCharType()
or
conv = "S" and
- result.(PointerType).getBaseType() = getDefaultCharType()
+ result.(PointerType).getBaseType() = this.getDefaultCharType()
)
)
}
@@ -924,9 +941,13 @@ class FormatLiteral extends Literal {
* not account for positional arguments (`$`).
*/
int getFormatArgumentIndexFor(int n, int mode) {
- hasFormatArgumentIndexFor(n, mode) and
+ this.hasFormatArgumentIndexFor(n, mode) and
(3 * n) + mode =
- rank[result + 1](int n2, int mode2 | hasFormatArgumentIndexFor(n2, mode2) | (3 * n2) + mode2)
+ rank[result + 1](int n2, int mode2 |
+ this.hasFormatArgumentIndexFor(n2, mode2)
+ |
+ (3 * n2) + mode2
+ )
}
/**
@@ -936,7 +957,7 @@ class FormatLiteral extends Literal {
int getNumArgNeeded(int n) {
exists(this.getConvSpecOffset(n)) and
exists(this.getConversionChar(n)) and
- result = count(int mode | hasFormatArgumentIndexFor(n, mode))
+ result = count(int mode | this.hasFormatArgumentIndexFor(n, mode))
}
/**
@@ -948,7 +969,7 @@ class FormatLiteral extends Literal {
// At least one conversion specifier has a parameter field, in which case,
// they all should have.
result = max(string s | this.getParameterField(_) = s + "$" | s.toInt())
- else result = count(int n, int mode | hasFormatArgumentIndexFor(n, mode))
+ else result = count(int n, int mode | this.hasFormatArgumentIndexFor(n, mode))
}
/**
@@ -1038,10 +1059,10 @@ class FormatLiteral extends Literal {
exists(int sizeBits |
sizeBits =
min(int bits |
- bits = getIntegralDisplayType(n).getSize() * 8
+ bits = this.getIntegralDisplayType(n).getSize() * 8
or
exists(IntegralType t |
- t = getUse().getConversionArgument(n).getType().getUnderlyingType()
+ t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
t.isSigned() and bits = t.getSize() * 8
)
@@ -1056,10 +1077,10 @@ class FormatLiteral extends Literal {
exists(int sizeBits |
sizeBits =
min(int bits |
- bits = getIntegralDisplayType(n).getSize() * 8
+ bits = this.getIntegralDisplayType(n).getSize() * 8
or
exists(IntegralType t |
- t = getUse().getConversionArgument(n).getType().getUnderlyingType()
+ t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
t.isUnsigned() and bits = t.getSize() * 8
)
@@ -1074,26 +1095,26 @@ class FormatLiteral extends Literal {
exists(int sizeBytes, int baseLen |
sizeBytes =
min(int bytes |
- bytes = getIntegralDisplayType(n).getSize()
+ bytes = this.getIntegralDisplayType(n).getSize()
or
exists(IntegralType t |
- t = getUse().getConversionArgument(n).getType().getUnderlyingType()
+ t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
t.isUnsigned() and bytes = t.getSize()
)
) and
baseLen = sizeBytes * 2 and
(
- if hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
+ if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
)
)
or
this.getConversionChar(n).toLowerCase() = "p" and
exists(PointerType ptrType, int baseLen |
- ptrType = getFullyConverted().getType() and
+ ptrType = this.getFullyConverted().getType() and
baseLen = max(ptrType.getSize() * 2) and // e.g. "0x1234567812345678"; exact format is platform dependent
(
- if hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
+ if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
)
)
or
@@ -1102,17 +1123,17 @@ class FormatLiteral extends Literal {
exists(int sizeBits, int baseLen |
sizeBits =
min(int bits |
- bits = getIntegralDisplayType(n).getSize() * 8
+ bits = this.getIntegralDisplayType(n).getSize() * 8
or
exists(IntegralType t |
- t = getUse().getConversionArgument(n).getType().getUnderlyingType()
+ t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
t.isUnsigned() and bits = t.getSize() * 8
)
) and
baseLen = (sizeBits / 3.0).ceil() and
(
- if hasAlternateFlag(n) then len = 1 + baseLen else len = baseLen // "0"
+ if this.hasAlternateFlag(n) then len = 1 + baseLen else len = baseLen // "0"
)
)
or
@@ -1135,8 +1156,8 @@ class FormatLiteral extends Literal {
*/
int getMaxConvertedLengthLimited(int n) {
if this.getConversionChar(n).toLowerCase() = "f"
- then result = getMaxConvertedLength(n).minimum(8)
- else result = getMaxConvertedLength(n)
+ then result = this.getMaxConvertedLength(n).minimum(8)
+ else result = this.getMaxConvertedLength(n)
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll
index 461030f389d..58d980318d9 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll
@@ -24,7 +24,7 @@ abstract class ScanfFunction extends Function {
* Holds if the default meaning of `%s` is a `wchar_t*` string
* (rather than a `char*`).
*/
- predicate isWideCharDefault() { exists(getName().indexOf("wscanf")) }
+ predicate isWideCharDefault() { exists(this.getName().indexOf("wscanf")) }
}
/**
@@ -34,10 +34,10 @@ class Scanf extends ScanfFunction {
Scanf() {
this instanceof TopLevelFunction and
(
- hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...)
- hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...)
- hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...)
- hasGlobalName("_wscanf_l") // _wscanf_l(format, locale, args...)
+ this.hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...)
+ this.hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...)
+ this.hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...)
+ this.hasGlobalName("_wscanf_l") // _wscanf_l(format, locale, args...)
)
}
@@ -53,10 +53,10 @@ class Fscanf extends ScanfFunction {
Fscanf() {
this instanceof TopLevelFunction and
(
- hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...)
- hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...)
- hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...)
- hasGlobalName("_fwscanf_l") // _fwscanf_l(src_stream, format, locale, args...)
+ this.hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...)
+ this.hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...)
+ this.hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...)
+ this.hasGlobalName("_fwscanf_l") // _fwscanf_l(src_stream, format, locale, args...)
)
}
@@ -72,10 +72,10 @@ class Sscanf extends ScanfFunction {
Sscanf() {
this instanceof TopLevelFunction and
(
- hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...)
- hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...)
- hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...)
- hasGlobalName("_swscanf_l") // _swscanf_l(src, format, locale, args...)
+ this.hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...)
+ this.hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...)
+ this.hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...)
+ this.hasGlobalName("_swscanf_l") // _swscanf_l(src, format, locale, args...)
)
}
@@ -91,10 +91,10 @@ class Snscanf extends ScanfFunction {
Snscanf() {
this instanceof TopLevelFunction and
(
- hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...)
- hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...)
- hasGlobalName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...)
- hasGlobalName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...)
+ this.hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...)
+ this.hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...)
+ this.hasGlobalName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...)
+ this.hasGlobalName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...)
// note that the max_amount is not a limit on the output length, it's an input length
// limit used with non null-terminated strings.
)
@@ -120,18 +120,18 @@ class ScanfFunctionCall extends FunctionCall {
/**
* Gets the `scanf`-like function that is called.
*/
- ScanfFunction getScanfFunction() { result = getTarget() }
+ ScanfFunction getScanfFunction() { result = this.getTarget() }
/**
* Gets the position at which the input string or stream parameter occurs,
* if this function call does not read from standard input.
*/
- int getInputParameterIndex() { result = getScanfFunction().getInputParameterIndex() }
+ int getInputParameterIndex() { result = this.getScanfFunction().getInputParameterIndex() }
/**
* Gets the position at which the format parameter occurs.
*/
- int getFormatParameterIndex() { result = getScanfFunction().getFormatParameterIndex() }
+ int getFormatParameterIndex() { result = this.getScanfFunction().getFormatParameterIndex() }
/**
* Gets the format expression used in this call.
@@ -142,7 +142,7 @@ class ScanfFunctionCall extends FunctionCall {
* Holds if the default meaning of `%s` is a `wchar_t*` string
* (rather than a `char*`).
*/
- predicate isWideCharDefault() { getScanfFunction().isWideCharDefault() }
+ predicate isWideCharDefault() { this.getScanfFunction().isWideCharDefault() }
}
/**
@@ -158,7 +158,7 @@ class ScanfFormatLiteral extends Expr {
ScanfFunctionCall getUse() { result.getFormat() = this }
/** Holds if the default meaning of `%s` is a `wchar_t*` (rather than a `char*`). */
- predicate isWideCharDefault() { getUse().getTarget().(ScanfFunction).isWideCharDefault() }
+ predicate isWideCharDefault() { this.getUse().getTarget().(ScanfFunction).isWideCharDefault() }
/**
* Gets the format string itself, transformed as follows:
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Synchronization.qll b/cpp/ql/lib/semmle/code/cpp/commons/Synchronization.qll
index 92955ae3580..f1b9cf80d64 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/Synchronization.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/Synchronization.qll
@@ -40,8 +40,8 @@ abstract class MutexType extends Type {
* Gets a call that locks or tries to lock any mutex of this type.
*/
FunctionCall getLockAccess() {
- result = getMustlockAccess() or
- result = getTrylockAccess()
+ result = this.getMustlockAccess() or
+ result = this.getTrylockAccess()
}
/**
@@ -63,22 +63,22 @@ abstract class MutexType extends Type {
/**
* DEPRECATED: use mustlockAccess(fc, arg) instead.
*/
- deprecated Function getMustlockFunction() { result = getMustlockAccess().getTarget() }
+ deprecated Function getMustlockFunction() { result = this.getMustlockAccess().getTarget() }
/**
* DEPRECATED: use trylockAccess(fc, arg) instead.
*/
- deprecated Function getTrylockFunction() { result = getTrylockAccess().getTarget() }
+ deprecated Function getTrylockFunction() { result = this.getTrylockAccess().getTarget() }
/**
* DEPRECATED: use lockAccess(fc, arg) instead.
*/
- deprecated Function getLockFunction() { result = getLockAccess().getTarget() }
+ deprecated Function getLockFunction() { result = this.getLockAccess().getTarget() }
/**
* DEPRECATED: use unlockAccess(fc, arg) instead.
*/
- deprecated Function getUnlockFunction() { result = getUnlockAccess().getTarget() }
+ deprecated Function getUnlockFunction() { result = this.getUnlockAccess().getTarget() }
}
/**
@@ -155,17 +155,17 @@ class DefaultMutexType extends MutexType {
override predicate mustlockAccess(FunctionCall fc, Expr arg) {
fc.getTarget() = mustlockCandidate() and
- lockArgType(fc, arg)
+ this.lockArgType(fc, arg)
}
override predicate trylockAccess(FunctionCall fc, Expr arg) {
fc.getTarget() = trylockCandidate() and
- lockArgType(fc, arg)
+ this.lockArgType(fc, arg)
}
override predicate unlockAccess(FunctionCall fc, Expr arg) {
fc.getTarget() = unlockCandidate() and
- lockArgType(fc, arg)
+ this.lockArgType(fc, arg)
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll
index 16947019f54..34373d943af 100644
--- a/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll
+++ b/cpp/ql/lib/semmle/code/cpp/controlflow/BasicBlocks.qll
@@ -194,14 +194,14 @@ class BasicBlock extends ControlFlowNodeBase {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*
* Yields no result if this basic block spans multiple source files.
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
- hasLocationInfoInternal(filepath, startline, startcolumn, filepath, endline, endcolumn)
+ this.hasLocationInfoInternal(filepath, startline, startcolumn, filepath, endline, endcolumn)
}
pragma[noinline]
@@ -276,7 +276,7 @@ class EntryBasicBlock extends BasicBlock {
*/
class ExitBasicBlock extends BasicBlock {
ExitBasicBlock() {
- getEnd() instanceof Function or
- aborting(getEnd())
+ this.getEnd() instanceof Function or
+ aborting(this.getEnd())
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/ControlFlowGraph.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/ControlFlowGraph.qll
index bac051f6474..c7b3d1dc16f 100644
--- a/cpp/ql/lib/semmle/code/cpp/controlflow/ControlFlowGraph.qll
+++ b/cpp/ql/lib/semmle/code/cpp/controlflow/ControlFlowGraph.qll
@@ -66,7 +66,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase {
*/
ControlFlowNode getATrueSuccessor() {
qlCFGTrueSuccessor(this, result) and
- result = getASuccessor()
+ result = this.getASuccessor()
}
/**
@@ -75,7 +75,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase {
*/
ControlFlowNode getAFalseSuccessor() {
qlCFGFalseSuccessor(this, result) and
- result = getASuccessor()
+ result = this.getASuccessor()
}
/** Gets the `BasicBlock` containing this control-flow node. */
diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll
index d96fc34259c..9aee2556c1d 100644
--- a/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll
+++ b/cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll
@@ -121,7 +121,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
exists(boolean testIsTrue |
- comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
+ this.comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
)
}
@@ -135,7 +135,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
exists(boolean testIsTrue |
- comparesEq(left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue)
+ this.comparesEq(left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue)
)
}
}
@@ -147,27 +147,29 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
private class GuardConditionFromShortCircuitNot extends GuardCondition, NotExpr {
GuardConditionFromShortCircuitNot() {
not exists(Instruction inst | this.getFullyConverted() = inst.getAST()) and
- exists(IRGuardCondition ir | getOperand() = ir.getAST())
+ exists(IRGuardCondition ir | this.getOperand() = ir.getAST())
}
override predicate controls(BasicBlock controlled, boolean testIsTrue) {
- getOperand().(GuardCondition).controls(controlled, testIsTrue.booleanNot())
+ this.getOperand().(GuardCondition).controls(controlled, testIsTrue.booleanNot())
}
override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) {
- getOperand().(GuardCondition).comparesLt(left, right, k, isLessThan, testIsTrue.booleanNot())
+ this.getOperand()
+ .(GuardCondition)
+ .comparesLt(left, right, k, isLessThan, testIsTrue.booleanNot())
}
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
- getOperand().(GuardCondition).ensuresLt(left, right, k, block, isLessThan.booleanNot())
+ this.getOperand().(GuardCondition).ensuresLt(left, right, k, block, isLessThan.booleanNot())
}
override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
- getOperand().(GuardCondition).comparesEq(left, right, k, areEqual, testIsTrue.booleanNot())
+ this.getOperand().(GuardCondition).comparesEq(left, right, k, areEqual, testIsTrue.booleanNot())
}
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
- getOperand().(GuardCondition).ensuresEq(left, right, k, block, areEqual.booleanNot())
+ this.getOperand().(GuardCondition).ensuresEq(left, right, k, block, areEqual.booleanNot())
}
}
@@ -303,9 +305,9 @@ class IRGuardCondition extends Instruction {
cached
predicate controlsEdge(IRBlock pred, IRBlock succ, boolean testIsTrue) {
pred.getASuccessor() = succ and
- controls(pred, testIsTrue)
+ this.controls(pred, testIsTrue)
or
- succ = getBranchSuccessor(testIsTrue) and
+ succ = this.getBranchSuccessor(testIsTrue) and
branch.getCondition() = this and
branch.getBlock() = pred
}
diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/LocalScopeVariableReachability.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/LocalScopeVariableReachability.qll
index 32857146029..f6685865830 100644
--- a/cpp/ql/lib/semmle/code/cpp/controlflow/LocalScopeVariableReachability.qll
+++ b/cpp/ql/lib/semmle/code/cpp/controlflow/LocalScopeVariableReachability.qll
@@ -73,19 +73,19 @@ abstract deprecated class LocalScopeVariableReachability extends string {
*/
exists(BasicBlock bb, int i |
- isSource(source, v) and
+ this.isSource(source, v) and
bb.getNode(i) = source and
not bb.isUnreachable()
|
exists(int j |
j > i and
sink = bb.getNode(j) and
- isSink(sink, v) and
- not exists(int k | isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
+ this.isSink(sink, v) and
+ not exists(int k | this.isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
)
or
- not exists(int k | isBarrier(bb.getNode(k), v) | k > i) and
- bbSuccessorEntryReaches(bb, v, sink, _)
+ not exists(int k | this.isBarrier(bb.getNode(k), v) | k > i) and
+ this.bbSuccessorEntryReaches(bb, v, sink, _)
)
}
@@ -97,11 +97,11 @@ abstract deprecated class LocalScopeVariableReachability extends string {
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
succSkipsFirstLoopAlwaysTrueUponEntry)
|
- bbEntryReachesLocally(succ, v, node) and
+ this.bbEntryReachesLocally(succ, v, node) and
succSkipsFirstLoopAlwaysTrueUponEntry = false
or
- not isBarrier(succ.getNode(_), v) and
- bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
+ not this.isBarrier(succ.getNode(_), v) and
+ this.bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
)
}
@@ -110,7 +110,7 @@ abstract deprecated class LocalScopeVariableReachability extends string {
) {
exists(int n |
node = bb.getNode(n) and
- isSink(node, v)
+ this.isSink(node, v)
|
not exists(this.firstBarrierIndexIn(bb, v))
or
@@ -119,7 +119,7 @@ abstract deprecated class LocalScopeVariableReachability extends string {
}
private int firstBarrierIndexIn(BasicBlock bb, SemanticStackVariable v) {
- result = min(int m | isBarrier(bb.getNode(m), v))
+ result = min(int m | this.isBarrier(bb.getNode(m), v))
}
}
@@ -271,7 +271,7 @@ abstract deprecated class LocalScopeVariableReachabilityWithReassignment extends
* accounts for loops where the condition is provably true upon entry.
*/
override predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
- reachesTo(source, v, sink, _)
+ this.reachesTo(source, v, sink, _)
}
/**
@@ -281,21 +281,21 @@ abstract deprecated class LocalScopeVariableReachabilityWithReassignment extends
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink, SemanticStackVariable v0
) {
exists(ControlFlowNode def |
- actualSourceReaches(source, v, def, v0) and
+ this.actualSourceReaches(source, v, def, v0) and
LocalScopeVariableReachability.super.reaches(def, v0, sink) and
- isSinkActual(sink, v0)
+ this.isSinkActual(sink, v0)
)
}
private predicate actualSourceReaches(
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0
) {
- isSourceActual(source, v) and def = source and v0 = v
+ this.isSourceActual(source, v) and def = source and v0 = v
or
exists(ControlFlowNode source1, SemanticStackVariable v1 |
- actualSourceReaches(source, v, source1, v1)
+ this.actualSourceReaches(source, v, source1, v1)
|
- reassignment(source1, v1, def, v0)
+ this.reassignment(source1, v1, def, v0)
)
}
@@ -307,14 +307,14 @@ abstract deprecated class LocalScopeVariableReachabilityWithReassignment extends
}
final override predicate isSource(ControlFlowNode node, LocalScopeVariable v) {
- isSourceActual(node, v)
+ this.isSourceActual(node, v)
or
// Reassignment generates a new (non-actual) source
- reassignment(_, _, node, v)
+ this.reassignment(_, _, node, v)
}
final override predicate isSink(ControlFlowNode node, LocalScopeVariable v) {
- isSinkActual(node, v)
+ this.isSinkActual(node, v)
or
// Reassignment generates a new (non-actual) sink
exprDefinition(_, node, v.getAnAccess())
@@ -347,21 +347,21 @@ abstract deprecated class LocalScopeVariableReachabilityExt extends string {
/** See `LocalScopeVariableReachability.reaches`. */
predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
exists(BasicBlock bb, int i |
- isSource(source, v) and
+ this.isSource(source, v) and
bb.getNode(i) = source and
not bb.isUnreachable()
|
exists(int j |
j > i and
sink = bb.getNode(j) and
- isSink(sink, v) and
- not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
+ this.isSink(sink, v) and
+ not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
k in [i .. j - 1]
)
)
or
- not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
- bbSuccessorEntryReaches(source, bb, v, sink, _)
+ not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
+ this.bbSuccessorEntryReaches(source, bb, v, sink, _)
)
}
@@ -372,22 +372,22 @@ abstract deprecated class LocalScopeVariableReachabilityExt extends string {
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
succSkipsFirstLoopAlwaysTrueUponEntry) and
- not isBarrier(source, bb.getEnd(), succ.getStart(), v)
+ not this.isBarrier(source, bb.getEnd(), succ.getStart(), v)
|
- bbEntryReachesLocally(source, succ, v, node) and
+ this.bbEntryReachesLocally(source, succ, v, node) and
succSkipsFirstLoopAlwaysTrueUponEntry = false
or
- not exists(int k | isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
- bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
+ not exists(int k | this.isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
+ this.bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
)
}
private predicate bbEntryReachesLocally(
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node
) {
- isSource(source, v) and
- exists(int n | node = bb.getNode(n) and isSink(node, v) |
- not exists(int m | m < n | isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
+ this.isSource(source, v) and
+ exists(int n | node = bb.getNode(n) and this.isSink(node, v) |
+ not exists(int m | m < n | this.isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
)
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll
index 5c0f6b3ac14..49805b9fb3c 100644
--- a/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll
+++ b/cpp/ql/lib/semmle/code/cpp/controlflow/SSA.qll
@@ -59,7 +59,7 @@ class SsaDefinition extends ControlFlowNodeBase {
ControlFlowNode getDefinition() { result = this }
/** Gets the `BasicBlock` containing this definition. */
- BasicBlock getBasicBlock() { result.contains(getDefinition()) }
+ BasicBlock getBasicBlock() { result.contains(this.getDefinition()) }
/** Holds if this definition is a phi node for variable `v`. */
predicate isPhiNode(StackVariable v) { exists(StandardSSA x | x.phi_node(v, this.(BasicBlock))) }
diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/StackVariableReachability.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/StackVariableReachability.qll
index 6c50d254faa..7b5fcd504b1 100644
--- a/cpp/ql/lib/semmle/code/cpp/controlflow/StackVariableReachability.qll
+++ b/cpp/ql/lib/semmle/code/cpp/controlflow/StackVariableReachability.qll
@@ -72,19 +72,19 @@ abstract class StackVariableReachability extends string {
*/
exists(BasicBlock bb, int i |
- isSource(source, v) and
+ this.isSource(source, v) and
bb.getNode(i) = source and
not bb.isUnreachable()
|
exists(int j |
j > i and
sink = bb.getNode(j) and
- isSink(sink, v) and
- not exists(int k | isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
+ this.isSink(sink, v) and
+ not exists(int k | this.isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
)
or
- not exists(int k | isBarrier(bb.getNode(k), v) | k > i) and
- bbSuccessorEntryReaches(bb, v, sink, _)
+ not exists(int k | this.isBarrier(bb.getNode(k), v) | k > i) and
+ this.bbSuccessorEntryReaches(bb, v, sink, _)
)
}
@@ -96,11 +96,11 @@ abstract class StackVariableReachability extends string {
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
succSkipsFirstLoopAlwaysTrueUponEntry)
|
- bbEntryReachesLocally(succ, v, node) and
+ this.bbEntryReachesLocally(succ, v, node) and
succSkipsFirstLoopAlwaysTrueUponEntry = false
or
- not isBarrier(succ.getNode(_), v) and
- bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
+ not this.isBarrier(succ.getNode(_), v) and
+ this.bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
)
}
@@ -109,7 +109,7 @@ abstract class StackVariableReachability extends string {
) {
exists(int n |
node = bb.getNode(n) and
- isSink(node, v)
+ this.isSink(node, v)
|
not exists(this.firstBarrierIndexIn(bb, v))
or
@@ -118,7 +118,7 @@ abstract class StackVariableReachability extends string {
}
private int firstBarrierIndexIn(BasicBlock bb, SemanticStackVariable v) {
- result = min(int m | isBarrier(bb.getNode(m), v))
+ result = min(int m | this.isBarrier(bb.getNode(m), v))
}
}
@@ -268,7 +268,7 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
* accounts for loops where the condition is provably true upon entry.
*/
override predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
- reachesTo(source, v, sink, _)
+ this.reachesTo(source, v, sink, _)
}
/**
@@ -278,21 +278,21 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink, SemanticStackVariable v0
) {
exists(ControlFlowNode def |
- actualSourceReaches(source, v, def, v0) and
+ this.actualSourceReaches(source, v, def, v0) and
StackVariableReachability.super.reaches(def, v0, sink) and
- isSinkActual(sink, v0)
+ this.isSinkActual(sink, v0)
)
}
private predicate actualSourceReaches(
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0
) {
- isSourceActual(source, v) and def = source and v0 = v
+ this.isSourceActual(source, v) and def = source and v0 = v
or
exists(ControlFlowNode source1, SemanticStackVariable v1 |
- actualSourceReaches(source, v, source1, v1)
+ this.actualSourceReaches(source, v, source1, v1)
|
- reassignment(source1, v1, def, v0)
+ this.reassignment(source1, v1, def, v0)
)
}
@@ -304,14 +304,14 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
}
final override predicate isSource(ControlFlowNode node, StackVariable v) {
- isSourceActual(node, v)
+ this.isSourceActual(node, v)
or
// Reassignment generates a new (non-actual) source
- reassignment(_, _, node, v)
+ this.reassignment(_, _, node, v)
}
final override predicate isSink(ControlFlowNode node, StackVariable v) {
- isSinkActual(node, v)
+ this.isSinkActual(node, v)
or
// Reassignment generates a new (non-actual) sink
exprDefinition(_, node, v.getAnAccess())
@@ -342,21 +342,21 @@ abstract class StackVariableReachabilityExt extends string {
/** See `StackVariableReachability.reaches`. */
predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
exists(BasicBlock bb, int i |
- isSource(source, v) and
+ this.isSource(source, v) and
bb.getNode(i) = source and
not bb.isUnreachable()
|
exists(int j |
j > i and
sink = bb.getNode(j) and
- isSink(sink, v) and
- not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
+ this.isSink(sink, v) and
+ not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
k in [i .. j - 1]
)
)
or
- not exists(int k | isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
- bbSuccessorEntryReaches(source, bb, v, sink, _)
+ not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
+ this.bbSuccessorEntryReaches(source, bb, v, sink, _)
)
}
@@ -367,22 +367,22 @@ abstract class StackVariableReachabilityExt extends string {
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
succSkipsFirstLoopAlwaysTrueUponEntry) and
- not isBarrier(source, bb.getEnd(), succ.getStart(), v)
+ not this.isBarrier(source, bb.getEnd(), succ.getStart(), v)
|
- bbEntryReachesLocally(source, succ, v, node) and
+ this.bbEntryReachesLocally(source, succ, v, node) and
succSkipsFirstLoopAlwaysTrueUponEntry = false
or
- not exists(int k | isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
- bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
+ not exists(int k | this.isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
+ this.bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
)
}
private predicate bbEntryReachesLocally(
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node
) {
- isSource(source, v) and
- exists(int n | node = bb.getNode(n) and isSink(node, v) |
- not exists(int m | m < n | isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
+ this.isSource(source, v) and
+ exists(int n | node = bb.getNode(n) and this.isSink(node, v) |
+ not exists(int m | m < n | this.isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
)
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/SubBasicBlocks.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/SubBasicBlocks.qll
index fa9d2e94081..4fbea43b805 100644
--- a/cpp/ql/lib/semmle/code/cpp/controlflow/SubBasicBlocks.qll
+++ b/cpp/ql/lib/semmle/code/cpp/controlflow/SubBasicBlocks.qll
@@ -80,7 +80,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
* position.
*/
- deprecated int getPosInBasicBlock(BasicBlock bb) { result = getRankInBasicBlock(bb) - 1 }
+ deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
pragma[noinline]
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }
@@ -102,7 +102,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
exists(BasicBlock bb |
exists(int outerIndex |
result = bb.getNode(outerIndex) and
- index = outerToInnerIndex(bb, outerIndex)
+ index = this.outerToInnerIndex(bb, outerIndex)
)
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll
index 476f626e874..da5204bb063 100644
--- a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll
+++ b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll
@@ -344,14 +344,13 @@ private int convertIntToType(int val, IntegralType t) {
then if val = 0 then result = 0 else result = 1
else
if t.isUnsigned()
- then if val >= 0 and val.bitShiftRight(t.getSize() * 8) = 0 then result = val else none()
+ then val >= 0 and val.bitShiftRight(t.getSize() * 8) = 0 and result = val
else
if val >= 0 and val.bitShiftRight(t.getSize() * 8 - 1) = 0
then result = val
- else
- if (-(val + 1)).bitShiftRight(t.getSize() * 8 - 1) = 0
- then result = val
- else none()
+ else (
+ (-(val + 1)).bitShiftRight(t.getSize() * 8 - 1) = 0 and result = val
+ )
}
/**
@@ -386,7 +385,7 @@ library class ExprEvaluator extends int {
abstract predicate interesting(Expr e);
/** Gets the value of (interesting) expression `e`, if any. */
- int getValue(Expr e) { result = getValueInternal(e, e) }
+ int getValue(Expr e) { result = this.getValueInternal(e, e) }
/**
* When evaluating a syntactic subexpression of `e`, we may
@@ -426,9 +425,9 @@ library class ExprEvaluator extends int {
* calculates the values bottom-up.
*/
predicate interestingInternal(Expr e, Expr req, boolean sub) {
- interesting(e) and req = e and sub = true
+ this.interesting(e) and req = e and sub = true
or
- exists(Expr mid | interestingInternal(e, mid, sub) |
+ exists(Expr mid | this.interestingInternal(e, mid, sub) |
req = mid.(NotExpr).getOperand() or
req = mid.(BinaryLogicalOperation).getAnOperand() or
req = mid.(RelationalOperation).getAnOperand() or
@@ -443,36 +442,36 @@ library class ExprEvaluator extends int {
)
or
exists(VariableAccess va, Variable v, boolean sub1 |
- interestingVariableAccess(e, va, v, sub1) and
+ this.interestingVariableAccess(e, va, v, sub1) and
req = v.getAnAssignedValue() and
- (sub1 = true implies not ignoreVariableAssignment(e, v, req)) and
+ (sub1 = true implies not this.ignoreVariableAssignment(e, v, req)) and
sub = false
)
or
exists(Function f |
- interestingFunction(e, f) and
+ this.interestingFunction(e, f) and
returnStmt(f, req) and
sub = false
)
}
private predicate interestingVariableAccess(Expr e, VariableAccess va, Variable v, boolean sub) {
- interestingInternal(e, va, sub) and
+ this.interestingInternal(e, va, sub) and
v = getVariableTarget(va) and
(
v.hasInitializer()
or
- sub = true and allowVariableWithoutInitializer(e, v)
+ sub = true and this.allowVariableWithoutInitializer(e, v)
) and
tractableVariable(v) and
forall(StmtParent def | nonAnalyzableVariableDefinition(v, def) |
sub = true and
- ignoreNonAnalyzableVariableDefinition(e, v, def)
+ this.ignoreNonAnalyzableVariableDefinition(e, v, def)
)
}
private predicate interestingFunction(Expr e, Function f) {
- exists(FunctionCall fc | interestingInternal(e, fc, _) |
+ exists(FunctionCall fc | this.interestingInternal(e, fc, _) |
f = fc.getTarget() and
not obviouslyNonConstant(f) and
not f.getUnspecifiedType() instanceof VoidType
@@ -482,10 +481,10 @@ library class ExprEvaluator extends int {
/** Gets the value of subexpressions `req` for expression `e`, if any. */
private int getValueInternal(Expr e, Expr req) {
(
- interestingInternal(e, req, true) and
+ this.interestingInternal(e, req, true) and
(
result = req.(CompileTimeConstantInt).getIntValue() or
- result = getCompoundValue(e, req.(CompileTimeVariableExpr))
+ result = this.getCompoundValue(e, req.(CompileTimeVariableExpr))
) and
(
req.getUnderlyingType().(IntegralType).isSigned() or
@@ -496,109 +495,126 @@ library class ExprEvaluator extends int {
/** Gets the value of compound subexpressions `val` for expression `e`, if any. */
private int getCompoundValue(Expr e, CompileTimeVariableExpr val) {
- interestingInternal(e, val, true) and
+ this.interestingInternal(e, val, true) and
(
exists(NotExpr req | req = val |
- result = 1 and getValueInternal(e, req.getOperand()) = 0
+ result = 1 and this.getValueInternal(e, req.getOperand()) = 0
or
- result = 0 and getValueInternal(e, req.getOperand()) != 0
+ result = 0 and this.getValueInternal(e, req.getOperand()) != 0
)
or
exists(LogicalAndExpr req | req = val |
result = 1 and
- getValueInternal(e, req.getLeftOperand()) != 0 and
- getValueInternal(e, req.getRightOperand()) != 0
+ this.getValueInternal(e, req.getLeftOperand()) != 0 and
+ this.getValueInternal(e, req.getRightOperand()) != 0
or
- result = 0 and getValueInternal(e, req.getAnOperand()) = 0
+ result = 0 and this.getValueInternal(e, req.getAnOperand()) = 0
)
or
exists(LogicalOrExpr req | req = val |
- result = 1 and getValueInternal(e, req.getAnOperand()) != 0
+ result = 1 and this.getValueInternal(e, req.getAnOperand()) != 0
or
result = 0 and
- getValueInternal(e, req.getLeftOperand()) = 0 and
- getValueInternal(e, req.getRightOperand()) = 0
+ this.getValueInternal(e, req.getLeftOperand()) = 0 and
+ this.getValueInternal(e, req.getRightOperand()) = 0
)
or
exists(LTExpr req | req = val |
result = 1 and
- getValueInternal(e, req.getLeftOperand()) < getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) <
+ this.getValueInternal(e, req.getRightOperand())
or
result = 0 and
- getValueInternal(e, req.getLeftOperand()) >= getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) >=
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(GTExpr req | req = val |
result = 1 and
- getValueInternal(e, req.getLeftOperand()) > getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) >
+ this.getValueInternal(e, req.getRightOperand())
or
result = 0 and
- getValueInternal(e, req.getLeftOperand()) <= getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) <=
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(LEExpr req | req = val |
result = 1 and
- getValueInternal(e, req.getLeftOperand()) <= getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) <=
+ this.getValueInternal(e, req.getRightOperand())
or
result = 0 and
- getValueInternal(e, req.getLeftOperand()) > getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) >
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(GEExpr req | req = val |
result = 1 and
- getValueInternal(e, req.getLeftOperand()) >= getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) >=
+ this.getValueInternal(e, req.getRightOperand())
or
result = 0 and
- getValueInternal(e, req.getLeftOperand()) < getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) <
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(EQExpr req | req = val |
result = 1 and
- getValueInternal(e, req.getLeftOperand()) = getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) =
+ this.getValueInternal(e, req.getRightOperand())
or
result = 0 and
- getValueInternal(e, req.getLeftOperand()) != getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) !=
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(NEExpr req | req = val |
result = 0 and
- getValueInternal(e, req.getLeftOperand()) = getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) =
+ this.getValueInternal(e, req.getRightOperand())
or
result = 1 and
- getValueInternal(e, req.getLeftOperand()) != getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) !=
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(AddExpr req | req = val |
result =
- getValueInternal(e, req.getLeftOperand()) + getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) +
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(SubExpr req | req = val |
result =
- getValueInternal(e, req.getLeftOperand()) - getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) -
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(MulExpr req | req = val |
result =
- getValueInternal(e, req.getLeftOperand()) * getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) *
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(RemExpr req | req = val |
result =
- getValueInternal(e, req.getLeftOperand()) % getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) %
+ this.getValueInternal(e, req.getRightOperand())
)
or
exists(DivExpr req | req = val |
result =
- getValueInternal(e, req.getLeftOperand()) / getValueInternal(e, req.getRightOperand())
+ this.getValueInternal(e, req.getLeftOperand()) /
+ this.getValueInternal(e, req.getRightOperand())
)
or
- exists(AssignExpr req | req = val | result = getValueInternal(e, req.getRValue()))
+ exists(AssignExpr req | req = val | result = this.getValueInternal(e, req.getRValue()))
or
- result = getVariableValue(e, val.(VariableAccess))
+ result = this.getVariableValue(e, val.(VariableAccess))
or
exists(FunctionCall call | call = val and not callWithMultipleTargets(call) |
- result = getFunctionValue(call.getTarget())
+ result = this.getFunctionValue(call.getTarget())
)
)
}
@@ -606,7 +622,7 @@ library class ExprEvaluator extends int {
language[monotonicAggregates]
private int getVariableValue(Expr e, VariableAccess va) {
exists(Variable v |
- interestingVariableAccess(e, va, v, true) and
+ this.interestingVariableAccess(e, va, v, true) and
// All assignments must have the same int value
result =
unique(Expr value |
@@ -620,14 +636,16 @@ library class ExprEvaluator extends int {
/** Holds if the function `f` is considered by the analysis and may return `ret`. */
pragma[noinline]
private predicate interestingReturnValue(Function f, Expr ret) {
- interestingFunction(_, f) and
+ this.interestingFunction(_, f) and
returnStmt(f, ret)
}
private int getFunctionValue(Function f) {
// All returns must have the same int value
// And it must have at least one return
- forex(Expr ret | interestingReturnValue(f, ret) | result = getValueInternalNonSubExpr(ret))
+ forex(Expr ret | this.interestingReturnValue(f, ret) |
+ result = this.getValueInternalNonSubExpr(ret)
+ )
}
/**
@@ -642,10 +660,10 @@ library class ExprEvaluator extends int {
* omitted).
*/
private int getValueInternalNonSubExpr(Expr req) {
- interestingInternal(_, req, false) and
+ this.interestingInternal(_, req, false) and
(
result = req.(CompileTimeConstantInt).getIntValue() or
- result = getCompoundValueNonSubExpr(req.(CompileTimeVariableExpr))
+ result = this.getCompoundValueNonSubExpr(req.(CompileTimeVariableExpr))
) and
(
req.getUnderlyingType().(IntegralType).isSigned() or
@@ -656,131 +674,131 @@ library class ExprEvaluator extends int {
private int getCompoundValueNonSubExpr(CompileTimeVariableExpr val) {
(
exists(NotExpr req | req = val |
- result = 1 and getValueInternalNonSubExpr(req.getOperand()) = 0
+ result = 1 and this.getValueInternalNonSubExpr(req.getOperand()) = 0
or
- result = 0 and getValueInternalNonSubExpr(req.getOperand()) != 0
+ result = 0 and this.getValueInternalNonSubExpr(req.getOperand()) != 0
)
or
exists(LogicalAndExpr req | req = val |
result = 1 and
- getValueInternalNonSubExpr(req.getLeftOperand()) != 0 and
- getValueInternalNonSubExpr(req.getRightOperand()) != 0
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) != 0 and
+ this.getValueInternalNonSubExpr(req.getRightOperand()) != 0
or
- result = 0 and getValueInternalNonSubExpr(req.getAnOperand()) = 0
+ result = 0 and this.getValueInternalNonSubExpr(req.getAnOperand()) = 0
)
or
exists(LogicalOrExpr req | req = val |
- result = 1 and getValueInternalNonSubExpr(req.getAnOperand()) != 0
+ result = 1 and this.getValueInternalNonSubExpr(req.getAnOperand()) != 0
or
result = 0 and
- getValueInternalNonSubExpr(req.getLeftOperand()) = 0 and
- getValueInternalNonSubExpr(req.getRightOperand()) = 0
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) = 0 and
+ this.getValueInternalNonSubExpr(req.getRightOperand()) = 0
)
or
exists(LTExpr req | req = val |
result = 1 and
- getValueInternalNonSubExpr(req.getLeftOperand()) <
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) <
+ this.getValueInternalNonSubExpr(req.getRightOperand())
or
result = 0 and
- getValueInternalNonSubExpr(req.getLeftOperand()) >=
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) >=
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(GTExpr req | req = val |
result = 1 and
- getValueInternalNonSubExpr(req.getLeftOperand()) >
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) >
+ this.getValueInternalNonSubExpr(req.getRightOperand())
or
result = 0 and
- getValueInternalNonSubExpr(req.getLeftOperand()) <=
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) <=
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(LEExpr req | req = val |
result = 1 and
- getValueInternalNonSubExpr(req.getLeftOperand()) <=
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) <=
+ this.getValueInternalNonSubExpr(req.getRightOperand())
or
result = 0 and
- getValueInternalNonSubExpr(req.getLeftOperand()) >
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) >
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(GEExpr req | req = val |
result = 1 and
- getValueInternalNonSubExpr(req.getLeftOperand()) >=
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) >=
+ this.getValueInternalNonSubExpr(req.getRightOperand())
or
result = 0 and
- getValueInternalNonSubExpr(req.getLeftOperand()) <
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) <
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(EQExpr req | req = val |
result = 1 and
- getValueInternalNonSubExpr(req.getLeftOperand()) =
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) =
+ this.getValueInternalNonSubExpr(req.getRightOperand())
or
result = 0 and
- getValueInternalNonSubExpr(req.getLeftOperand()) !=
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) !=
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(NEExpr req | req = val |
result = 0 and
- getValueInternalNonSubExpr(req.getLeftOperand()) =
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) =
+ this.getValueInternalNonSubExpr(req.getRightOperand())
or
result = 1 and
- getValueInternalNonSubExpr(req.getLeftOperand()) !=
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) !=
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(AddExpr req | req = val |
result =
- getValueInternalNonSubExpr(req.getLeftOperand()) +
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) +
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(SubExpr req | req = val |
result =
- getValueInternalNonSubExpr(req.getLeftOperand()) -
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) -
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(MulExpr req | req = val |
result =
- getValueInternalNonSubExpr(req.getLeftOperand()) *
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) *
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(RemExpr req | req = val |
result =
- getValueInternalNonSubExpr(req.getLeftOperand()) %
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) %
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
exists(DivExpr req | req = val |
result =
- getValueInternalNonSubExpr(req.getLeftOperand()) /
- getValueInternalNonSubExpr(req.getRightOperand())
+ this.getValueInternalNonSubExpr(req.getLeftOperand()) /
+ this.getValueInternalNonSubExpr(req.getRightOperand())
)
or
- exists(AssignExpr req | req = val | result = getValueInternalNonSubExpr(req.getRValue()))
+ exists(AssignExpr req | req = val | result = this.getValueInternalNonSubExpr(req.getRValue()))
or
- result = getVariableValueNonSubExpr(val.(VariableAccess))
+ result = this.getVariableValueNonSubExpr(val.(VariableAccess))
or
exists(FunctionCall call | call = val and not callWithMultipleTargets(call) |
- result = getFunctionValue(call.getTarget())
+ result = this.getFunctionValue(call.getTarget())
)
)
}
private int getVariableValueNonSubExpr(VariableAccess va) {
// All assignments must have the same int value
- result = getMinVariableValueNonSubExpr(va) and
- result = getMaxVariableValueNonSubExpr(va)
+ result = this.getMinVariableValueNonSubExpr(va) and
+ result = this.getMaxVariableValueNonSubExpr(va)
}
/**
@@ -791,8 +809,9 @@ library class ExprEvaluator extends int {
pragma[noopt]
private int getMinVariableValueNonSubExpr(VariableAccess va) {
exists(Variable v |
- interestingVariableAccess(_, va, v, false) and
- result = min(Expr value | value = v.getAnAssignedValue() | getValueInternalNonSubExpr(value))
+ this.interestingVariableAccess(_, va, v, false) and
+ result =
+ min(Expr value | value = v.getAnAssignedValue() | this.getValueInternalNonSubExpr(value))
)
}
@@ -804,8 +823,9 @@ library class ExprEvaluator extends int {
pragma[noopt]
private int getMaxVariableValueNonSubExpr(VariableAccess va) {
exists(Variable v |
- interestingVariableAccess(_, va, v, false) and
- result = max(Expr value | value = v.getAnAssignedValue() | getValueInternalNonSubExpr(value))
+ this.interestingVariableAccess(_, va, v, false) and
+ result =
+ max(Expr value | value = v.getAnAssignedValue() | this.getValueInternalNonSubExpr(value))
)
}
}
@@ -968,9 +988,9 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
abstract predicate isLoopBody(Expr e, StmtParent s);
private predicate isLoopBodyDescendant(Expr e, StmtParent s) {
- isLoopBody(e, s)
+ this.isLoopBody(e, s)
or
- exists(StmtParent mid | isLoopBodyDescendant(e, mid) |
+ exists(StmtParent mid | this.isLoopBodyDescendant(e, mid) |
s = mid.(Stmt).getAChild() or
s = mid.(Expr).getAChild()
)
@@ -978,13 +998,13 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
// Same as `interestingInternal(e, sub, true)` but avoids negative recursion
private predicate interestingSubExpr(Expr e, Expr sub) {
- interesting(e) and e = sub
+ this.interesting(e) and e = sub
or
- exists(Expr mid | interestingSubExpr(e, mid) and sub = mid.getAChild())
+ exists(Expr mid | this.interestingSubExpr(e, mid) and sub = mid.getAChild())
}
private predicate maybeInterestingVariable(Expr e, Variable v) {
- exists(VariableAccess va | interestingSubExpr(e, va) | va.getTarget() = v)
+ exists(VariableAccess va | this.interestingSubExpr(e, va) | va.getTarget() = v)
}
/**
@@ -996,9 +1016,9 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
* definition of `v`.
*/
private predicate reachesLoopEntryFromLoopBody(Expr e, Variable v, StmtParent valueOrDef) {
- maybeInterestingVariable(e, v) and
+ this.maybeInterestingVariable(e, v) and
(valueOrDef = v.getAnAssignedValue() or nonAnalyzableVariableDefinition(v, valueOrDef)) and
- isLoopBodyDescendant(e, valueOrDef) and
+ this.isLoopBodyDescendant(e, valueOrDef) and
/*
* Use primitive basic blocks in reachability analysis for better performance.
* This is similar to the pattern used in e.g. `DefinitionsAndUses` and
@@ -1008,16 +1028,16 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
exists(PrimitiveBasicBlock bb1, int pos1 | bb1.getNode(pos1) = valueOrDef |
// Reaches in same basic block
exists(int pos2 |
- loopEntryAt(bb1, pos2, e) and
+ this.loopEntryAt(bb1, pos2, e) and
pos2 > pos1 and
- not exists(int k | assignmentAt(bb1, k, v) | k in [pos1 + 1 .. pos2 - 1])
+ not exists(int k | this.assignmentAt(bb1, k, v) | k in [pos1 + 1 .. pos2 - 1])
)
or
// Reaches in a successor block
exists(PrimitiveBasicBlock bb2 |
bb2 = bb1.getASuccessor() and
- not exists(int pos3 | assignmentAt(bb1, pos3, v) and pos3 > pos1) and
- bbReachesLoopEntry(bb2, e, v)
+ not exists(int pos3 | this.assignmentAt(bb1, pos3, v) and pos3 > pos1) and
+ this.bbReachesLoopEntry(bb2, e, v)
)
)
}
@@ -1025,12 +1045,12 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
private predicate loopEntryAt(PrimitiveBasicBlock bb, int pos, Expr e) {
exists(Node cfn |
bb.getNode(pos) = cfn and
- isLoopEntry(e, cfn)
+ this.isLoopEntry(e, cfn)
)
}
private predicate assignmentAt(PrimitiveBasicBlock bb, int pos, Variable v) {
- maybeInterestingVariable(_, v) and
+ this.maybeInterestingVariable(_, v) and
bb.getNode(pos) = v.getAnAssignedValue()
}
@@ -1039,19 +1059,19 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
* the loop belonging to `e` without crossing an assignment to `v`.
*/
private predicate bbReachesLoopEntry(PrimitiveBasicBlock bb, Expr e, Variable v) {
- bbReachesLoopEntryLocally(bb, e, v)
+ this.bbReachesLoopEntryLocally(bb, e, v)
or
exists(PrimitiveBasicBlock succ | succ = bb.getASuccessor() |
- bbReachesLoopEntry(succ, e, v) and
- not assignmentAt(bb, _, v)
+ this.bbReachesLoopEntry(succ, e, v) and
+ not this.assignmentAt(bb, _, v)
)
}
private predicate bbReachesLoopEntryLocally(PrimitiveBasicBlock bb, Expr e, Variable v) {
exists(int pos |
- loopEntryAt(bb, pos, e) and
- maybeInterestingVariable(e, v) and
- not exists(int pos1 | assignmentAt(bb, pos1, v) | pos1 < pos)
+ this.loopEntryAt(bb, pos, e) and
+ this.maybeInterestingVariable(e, v) and
+ not exists(int pos1 | this.assignmentAt(bb, pos1, v) | pos1 < pos)
)
}
@@ -1085,10 +1105,10 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
* ```
*/
override predicate ignoreNonAnalyzableVariableDefinition(Expr e, Variable v, StmtParent def) {
- maybeInterestingVariable(e, v) and
+ this.maybeInterestingVariable(e, v) and
nonAnalyzableVariableDefinition(v, def) and
- isLoopBodyDescendant(e, def) and
- not reachesLoopEntryFromLoopBody(e, v, def)
+ this.isLoopBodyDescendant(e, def) and
+ not this.reachesLoopEntryFromLoopBody(e, v, def)
}
/**
@@ -1121,10 +1141,10 @@ library class LoopEntryConditionEvaluator extends ExprEvaluator {
* ```
*/
override predicate ignoreVariableAssignment(Expr e, Variable v, Expr value) {
- maybeInterestingVariable(e, v) and
+ this.maybeInterestingVariable(e, v) and
value = v.getAnAssignedValue() and
- isLoopBodyDescendant(e, value) and
- not reachesLoopEntryFromLoopBody(e, v, value)
+ this.isLoopBodyDescendant(e, value) and
+ not this.reachesLoopEntryFromLoopBody(e, v, value)
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll
index f588a25a176..e11244c42b0 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll
@@ -801,6 +801,9 @@ private module Cached {
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call))
}
+ cached
+ predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
+
cached
newtype TCallContext =
TAnyCallContext() or
@@ -937,7 +940,7 @@ class CallContextSpecificCall extends CallContextCall, TSpecificCall {
}
override predicate relevantFor(DataFlowCallable callable) {
- recordDataFlowCallSite(getCall(), callable)
+ recordDataFlowCallSite(this.getCall(), callable)
}
override predicate matchesCall(DataFlowCall call) { call = this.getCall() }
@@ -1236,6 +1239,13 @@ class TypedContent extends MkTypedContent {
/** Gets a textual representation of this content. */
string toString() { result = c.toString() }
+
+ /**
+ * Holds if access paths with this `TypedContent` at their head always should
+ * be tracked at high precision. This disables adaptive access path precision
+ * for such access paths.
+ */
+ predicate forceHighPrecision() { forceHighPrecision(c) }
}
/**
@@ -1250,7 +1260,7 @@ abstract class AccessPathFront extends TAccessPathFront {
TypedContent getHead() { this = TFrontHead(result) }
- predicate isClearedAt(Node n) { clearsContentCached(n, getHead().getContent()) }
+ predicate isClearedAt(Node n) { clearsContentCached(n, this.getHead().getContent()) }
}
class AccessPathFrontNil extends AccessPathFront, TFrontNil {
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll
index a55e65a81f6..dd64fc70039 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll
@@ -175,6 +175,7 @@ module Consistency {
query predicate postWithInFlow(Node n, string msg) {
isPostUpdateNode(n) and
+ not clearsContent(n, _) and
simpleLocalFlowStep(_, n) and
msg = "PostUpdateNode should not be the target of local flow."
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
index e64f8277528..0eecf7a6040 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
@@ -219,15 +219,13 @@ class DataFlowExpr = Expr;
class DataFlowType = Type;
/** A function call relevant for data flow. */
-class DataFlowCall extends Expr {
- DataFlowCall() { this instanceof Call }
-
+class DataFlowCall extends Expr instanceof Call {
/**
* Gets the nth argument for this call.
*
* The range of `n` is from `0` to `getNumberOfArguments() - 1`.
*/
- Expr getArgument(int n) { result = this.(Call).getArgument(n) }
+ Expr getArgument(int n) { result = super.getArgument(n) }
/** Gets the data flow node corresponding to this call. */
ExprNode getNode() { result.getExpr() = this }
@@ -240,6 +238,12 @@ predicate isUnreachableInCall(Node n, DataFlowCall call) { none() } // stub impl
int accessPathLimit() { result = 5 }
+/**
+ * Holds if access paths with `c` at their head always should be tracked at high
+ * precision. This disables adaptive access path precision for such access paths.
+ */
+predicate forceHighPrecision(Content c) { none() }
+
/** The unit type. */
private newtype TUnit = TMkUnit()
@@ -283,3 +287,12 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { no
/** Extra data-flow steps needed for lambda flow analysis. */
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
+
+/**
+ * Holds if flow is allowed to pass from parameter `p` and back to itself as a
+ * side-effect, resulting in a summary from `p` to itself.
+ *
+ * One example would be to allow flow like `p.foo = p.bar;`, which is disallowed
+ * by default as a heuristic.
+ */
+predicate allowParameterReturnInSelf(ParameterNode p) { none() }
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
index 01338eaeff4..c67374c3db9 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
@@ -101,18 +101,18 @@ class Node extends TNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
- getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
+ this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/**
* Gets an upper bound on the type of this node.
*/
- Type getTypeBound() { result = getType() }
+ Type getTypeBound() { result = this.getType() }
}
/**
@@ -293,11 +293,11 @@ abstract class PostUpdateNode extends Node {
*/
abstract Node getPreUpdateNode();
- override Function getFunction() { result = getPreUpdateNode().getFunction() }
+ override Function getFunction() { result = this.getPreUpdateNode().getFunction() }
- override Type getType() { result = getPreUpdateNode().getType() }
+ override Type getType() { result = this.getPreUpdateNode().getType() }
- override Location getLocation() { result = getPreUpdateNode().getLocation() }
+ override Location getLocation() { result = this.getPreUpdateNode().getLocation() }
}
abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
@@ -309,7 +309,7 @@ abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDef
PartialDefinition getPartialDefinition() { result = pd }
- override string toString() { result = getPreUpdateNode().toString() + " [post update]" }
+ override string toString() { result = this.getPreUpdateNode().toString() + " [post update]" }
}
private class VariablePartialDefinitionNode extends PartialDefinitionNode {
@@ -380,13 +380,13 @@ private class ObjectInitializerNode extends PostUpdateNode, TExprNode {
class PreObjectInitializerNode extends Node, TPreObjectInitializerNode {
Expr getExpr() { this = TPreObjectInitializerNode(result) }
- override Function getFunction() { result = getExpr().getEnclosingFunction() }
+ override Function getFunction() { result = this.getExpr().getEnclosingFunction() }
- override Type getType() { result = getExpr().getType() }
+ override Type getType() { result = this.getExpr().getType() }
- override Location getLocation() { result = getExpr().getLocation() }
+ override Location getLocation() { result = this.getExpr().getLocation() }
- override string toString() { result = getExpr().toString() + " [pre init]" }
+ override string toString() { result = this.getExpr().toString() + " [pre init]" }
}
/**
@@ -401,7 +401,7 @@ private class PostConstructorInitThis extends PostUpdateNode, TPostConstructorIn
}
override string toString() {
- result = getPreUpdateNode().getConstructorFieldInit().toString() + " [post-this]"
+ result = this.getPreUpdateNode().getConstructorFieldInit().toString() + " [post-this]"
}
}
@@ -416,15 +416,17 @@ private class PostConstructorInitThis extends PostUpdateNode, TPostConstructorIn
class PreConstructorInitThis extends Node, TPreConstructorInitThis {
ConstructorFieldInit getConstructorFieldInit() { this = TPreConstructorInitThis(result) }
- override Constructor getFunction() { result = getConstructorFieldInit().getEnclosingFunction() }
-
- override PointerType getType() {
- result.getBaseType() = getConstructorFieldInit().getEnclosingFunction().getDeclaringType()
+ override Constructor getFunction() {
+ result = this.getConstructorFieldInit().getEnclosingFunction()
}
- override Location getLocation() { result = getConstructorFieldInit().getLocation() }
+ override PointerType getType() {
+ result.getBaseType() = this.getConstructorFieldInit().getEnclosingFunction().getDeclaringType()
+ }
- override string toString() { result = getConstructorFieldInit().toString() + " [pre-this]" }
+ override Location getLocation() { result = this.getConstructorFieldInit().getLocation() }
+
+ override string toString() { result = this.getConstructorFieldInit().toString() + " [pre-this]" }
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowVar.qll
index e3f8b6f68fb..c01edf0429a 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -354,7 +354,7 @@ module FlowVar_internal {
result = def.getAUse(v)
or
exists(SsaDefinition descendentDef |
- getASuccessorSsaVar+() = TSsaVar(descendentDef, _) and
+ this.getASuccessorSsaVar+() = TSsaVar(descendentDef, _) and
result = descendentDef.getAUse(v)
)
)
@@ -515,7 +515,7 @@ module FlowVar_internal {
this.bbInLoopCondition(bbInside) and
not this.bbInLoop(bbOutside) and
bbOutside = bbInside.getASuccessor() and
- not reachesWithoutAssignment(bbInside, v)
+ not this.reachesWithoutAssignment(bbInside, v)
}
/**
@@ -546,7 +546,7 @@ module FlowVar_internal {
private predicate bbInLoop(BasicBlock bb) {
bbDominates(this.(Loop).getStmt(), bb)
or
- bbInLoopCondition(bb)
+ this.bbInLoopCondition(bb)
}
/** Holds if `sbb` is inside this loop. */
@@ -563,7 +563,7 @@ module FlowVar_internal {
bb = this.(Loop).getStmt() and
v = this.getARelevantVariable()
or
- reachesWithoutAssignment(bb.getAPredecessor(), v) and
+ this.reachesWithoutAssignment(bb.getAPredecessor(), v) and
this.bbInLoop(bb)
) and
not assignsToVar(bb, v)
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll
index fa9d2e94081..4fbea43b805 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll
@@ -80,7 +80,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
* returns a 0-based position, while `getRankInBasicBlock` returns a 1-based
* position.
*/
- deprecated int getPosInBasicBlock(BasicBlock bb) { result = getRankInBasicBlock(bb) - 1 }
+ deprecated int getPosInBasicBlock(BasicBlock bb) { result = this.getRankInBasicBlock(bb) - 1 }
pragma[noinline]
private int getIndexInBasicBlock(BasicBlock bb) { this = bb.getNode(result) }
@@ -102,7 +102,7 @@ class SubBasicBlock extends ControlFlowNodeBase {
exists(BasicBlock bb |
exists(int outerIndex |
result = bb.getNode(outerIndex) and
- index = outerToInnerIndex(bb, outerIndex)
+ index = this.outerToInnerIndex(bb, outerIndex)
)
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Access.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Access.qll
index e18c0c78dc6..35cf1974127 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Access.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Access.qll
@@ -203,7 +203,7 @@ class PointerFieldAccess extends FieldAccess {
PointerFieldAccess() {
exists(PointerType t |
- t = getQualifier().getFullyConverted().getUnspecifiedType() and
+ t = this.getQualifier().getFullyConverted().getUnspecifiedType() and
t.getBaseType() instanceof Class
)
}
@@ -218,7 +218,9 @@ class PointerFieldAccess extends FieldAccess {
class DotFieldAccess extends FieldAccess {
override string getAPrimaryQlClass() { result = "DotFieldAccess" }
- DotFieldAccess() { exists(Class c | c = getQualifier().getFullyConverted().getUnspecifiedType()) }
+ DotFieldAccess() {
+ exists(Class c | c = this.getQualifier().getFullyConverted().getUnspecifiedType())
+ }
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/ArithmeticOperation.qll b/cpp/ql/lib/semmle/code/cpp/exprs/ArithmeticOperation.qll
index b94c9cee724..615192c86a7 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/ArithmeticOperation.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/ArithmeticOperation.qll
@@ -148,7 +148,7 @@ class PostfixIncrExpr extends IncrementOperation, PostfixCrementOperation, @post
override int getPrecedence() { result = 17 }
- override string toString() { result = "... " + getOperator() }
+ override string toString() { result = "... " + this.getOperator() }
}
/**
@@ -166,7 +166,7 @@ class PostfixDecrExpr extends DecrementOperation, PostfixCrementOperation, @post
override int getPrecedence() { result = 17 }
- override string toString() { result = "... " + getOperator() }
+ override string toString() { result = "... " + this.getOperator() }
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll
index b1f97f18802..dcbedde4475 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll
@@ -35,12 +35,12 @@ class BuiltInVarArgsStart extends VarArgsExpr, @vastartexpr {
/**
* Gets the `va_list` argument.
*/
- final Expr getVAList() { result = getChild(0) }
+ final Expr getVAList() { result = this.getChild(0) }
/**
* Gets the argument that specifies the last named parameter before the ellipsis.
*/
- final VariableAccess getLastNamedParameter() { result = getChild(1) }
+ final VariableAccess getLastNamedParameter() { result = this.getChild(1) }
}
/**
@@ -60,7 +60,7 @@ class BuiltInVarArgsEnd extends VarArgsExpr, @vaendexpr {
/**
* Gets the `va_list` argument.
*/
- final Expr getVAList() { result = getChild(0) }
+ final Expr getVAList() { result = this.getChild(0) }
}
/**
@@ -78,7 +78,7 @@ class BuiltInVarArg extends VarArgsExpr, @vaargexpr {
/**
* Gets the `va_list` argument.
*/
- final Expr getVAList() { result = getChild(0) }
+ final Expr getVAList() { result = this.getChild(0) }
}
/**
@@ -98,12 +98,12 @@ class BuiltInVarArgCopy extends VarArgsExpr, @vacopyexpr {
/**
* Gets the destination `va_list` argument.
*/
- final Expr getDestinationVAList() { result = getChild(0) }
+ final Expr getDestinationVAList() { result = this.getChild(0) }
/**
* Gets the the source `va_list` argument.
*/
- final Expr getSourceVAList() { result = getChild(1) }
+ final Expr getSourceVAList() { result = this.getChild(1) }
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll
index 6f6f710ac4b..b4761dffe9a 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll
@@ -71,10 +71,10 @@ class Call extends Expr, NameQualifiableElement, TCall {
* at index 2, respectively.
*/
Expr getAnArgumentSubExpr(int index) {
- result = getArgument(index)
+ result = this.getArgument(index)
or
exists(Expr mid |
- mid = getAnArgumentSubExpr(index) and
+ mid = this.getAnArgumentSubExpr(index) and
not mid instanceof Call and
not mid instanceof SizeofOperator and
result = mid.getAChild()
@@ -167,27 +167,27 @@ class FunctionCall extends Call, @funbindexpr {
override string getAPrimaryQlClass() { result = "FunctionCall" }
/** Gets an explicit template argument for this call. */
- Locatable getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) }
+ Locatable getAnExplicitTemplateArgument() { result = this.getExplicitTemplateArgument(_) }
/** Gets an explicit template argument value for this call. */
- Locatable getAnExplicitTemplateArgumentKind() { result = getExplicitTemplateArgumentKind(_) }
+ Locatable getAnExplicitTemplateArgumentKind() { result = this.getExplicitTemplateArgumentKind(_) }
/** Gets a template argument for this call. */
- Locatable getATemplateArgument() { result = getTarget().getATemplateArgument() }
+ Locatable getATemplateArgument() { result = this.getTarget().getATemplateArgument() }
/** Gets a template argument value for this call. */
- Locatable getATemplateArgumentKind() { result = getTarget().getATemplateArgumentKind() }
+ Locatable getATemplateArgumentKind() { result = this.getTarget().getATemplateArgumentKind() }
/** Gets the nth explicit template argument for this call. */
Locatable getExplicitTemplateArgument(int n) {
- n < getNumberOfExplicitTemplateArguments() and
- result = getTemplateArgument(n)
+ n < this.getNumberOfExplicitTemplateArguments() and
+ result = this.getTemplateArgument(n)
}
/** Gets the nth explicit template argument value for this call. */
Locatable getExplicitTemplateArgumentKind(int n) {
- n < getNumberOfExplicitTemplateArguments() and
- result = getTemplateArgumentKind(n)
+ n < this.getNumberOfExplicitTemplateArguments() and
+ result = this.getTemplateArgumentKind(n)
}
/** Gets the number of explicit template arguments for this call. */
@@ -198,19 +198,19 @@ class FunctionCall extends Call, @funbindexpr {
}
/** Gets the number of template arguments for this call. */
- int getNumberOfTemplateArguments() { result = count(int i | exists(getTemplateArgument(i))) }
+ int getNumberOfTemplateArguments() { result = count(int i | exists(this.getTemplateArgument(i))) }
/** Gets the nth template argument for this call (indexed from 0). */
- Locatable getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) }
+ Locatable getTemplateArgument(int n) { result = this.getTarget().getTemplateArgument(n) }
/** Gets the nth template argument value for this call (indexed from 0). */
- Locatable getTemplateArgumentKind(int n) { result = getTarget().getTemplateArgumentKind(n) }
+ Locatable getTemplateArgumentKind(int n) { result = this.getTarget().getTemplateArgumentKind(n) }
/** Holds if any template arguments for this call are implicit / deduced. */
predicate hasImplicitTemplateArguments() {
exists(int i |
- exists(getTemplateArgument(i)) and
- not exists(getExplicitTemplateArgument(i))
+ exists(this.getTemplateArgument(i)) and
+ not exists(this.getExplicitTemplateArgument(i))
)
}
@@ -233,9 +233,9 @@ class FunctionCall extends Call, @funbindexpr {
* visible at the call site.
*/
Type getExpectedReturnType() {
- if getTargetType() instanceof RoutineType
- then result = getTargetType().(RoutineType).getReturnType()
- else result = getTarget().getType()
+ if this.getTargetType() instanceof RoutineType
+ then result = this.getTargetType().(RoutineType).getReturnType()
+ else result = this.getTarget().getType()
}
/**
@@ -247,9 +247,9 @@ class FunctionCall extends Call, @funbindexpr {
* was visible at the call site.
*/
Type getExpectedParameterType(int n) {
- if getTargetType() instanceof RoutineType
- then result = getTargetType().(RoutineType).getParameterType(n)
- else result = getTarget().getParameter(n).getType()
+ if this.getTargetType() instanceof RoutineType
+ then result = this.getTargetType().(RoutineType).getParameterType(n)
+ else result = this.getTarget().getParameter(n).getType()
}
/**
@@ -263,7 +263,7 @@ class FunctionCall extends Call, @funbindexpr {
/**
* Gets the type of this expression, that is, the return type of the function being called.
*/
- override Type getType() { result = getExpectedReturnType() }
+ override Type getType() { result = this.getExpectedReturnType() }
/**
* Holds if this is a call to a virtual function.
@@ -280,7 +280,7 @@ class FunctionCall extends Call, @funbindexpr {
/** Gets a textual representation of this function call. */
override string toString() {
- if exists(getTarget())
+ if exists(this.getTarget())
then result = "call to " + this.getTarget().getName()
else result = "call to unknown function"
}
@@ -288,15 +288,15 @@ class FunctionCall extends Call, @funbindexpr {
override predicate mayBeImpure() {
this.getChild(_).mayBeImpure() or
this.getTarget().mayHaveSideEffects() or
- isVirtual() or
- getTarget().getAnAttribute().getName() = "weak"
+ this.isVirtual() or
+ this.getTarget().getAnAttribute().getName() = "weak"
}
override predicate mayBeGloballyImpure() {
this.getChild(_).mayBeGloballyImpure() or
this.getTarget().mayHaveSideEffects() or
- isVirtual() or
- getTarget().getAnAttribute().getName() = "weak"
+ this.isVirtual() or
+ this.getTarget().getAnAttribute().getName() = "weak"
}
}
@@ -367,7 +367,7 @@ class OverloadedPointerDereferenceExpr extends FunctionCall {
* ```
*/
class OverloadedArrayExpr extends FunctionCall {
- OverloadedArrayExpr() { getTarget().hasName("operator[]") }
+ OverloadedArrayExpr() { this.getTarget().hasName("operator[]") }
override string getAPrimaryQlClass() { result = "OverloadedArrayExpr" }
@@ -585,7 +585,7 @@ class ConstructorFieldInit extends ConstructorInit, @ctorfieldinit {
*/
Expr getExpr() { result = this.getChild(0) }
- override string toString() { result = "constructor init of field " + getTarget().getName() }
+ override string toString() { result = "constructor init of field " + this.getTarget().getName() }
override predicate mayBeImpure() { this.getExpr().mayBeImpure() }
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll
index ebe88ddf71c..273023a8229 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll
@@ -188,8 +188,8 @@ private predicate isPointerToMemberOrNullPointer(Type type) {
class ArithmeticConversion extends Cast {
ArithmeticConversion() {
conversionkinds(underlyingElement(this), 0) and
- isArithmeticOrEnum(getUnspecifiedType()) and
- isArithmeticOrEnum(getExpr().getUnspecifiedType())
+ isArithmeticOrEnum(this.getUnspecifiedType()) and
+ isArithmeticOrEnum(this.getExpr().getUnspecifiedType())
}
override string getSemanticConversionString() { result = "arithmetic conversion" }
@@ -204,8 +204,8 @@ class ArithmeticConversion extends Cast {
*/
class IntegralConversion extends ArithmeticConversion {
IntegralConversion() {
- isIntegralOrEnum(getUnspecifiedType()) and
- isIntegralOrEnum(getExpr().getUnspecifiedType())
+ isIntegralOrEnum(this.getUnspecifiedType()) and
+ isIntegralOrEnum(this.getExpr().getUnspecifiedType())
}
override string getAPrimaryQlClass() {
@@ -224,8 +224,8 @@ class IntegralConversion extends ArithmeticConversion {
*/
class FloatingPointConversion extends ArithmeticConversion {
FloatingPointConversion() {
- getUnspecifiedType() instanceof FloatingPointType and
- getExpr().getUnspecifiedType() instanceof FloatingPointType
+ this.getUnspecifiedType() instanceof FloatingPointType and
+ this.getExpr().getUnspecifiedType() instanceof FloatingPointType
}
override string getAPrimaryQlClass() {
@@ -244,8 +244,8 @@ class FloatingPointConversion extends ArithmeticConversion {
*/
class FloatingPointToIntegralConversion extends ArithmeticConversion {
FloatingPointToIntegralConversion() {
- isIntegralOrEnum(getUnspecifiedType()) and
- getExpr().getUnspecifiedType() instanceof FloatingPointType
+ isIntegralOrEnum(this.getUnspecifiedType()) and
+ this.getExpr().getUnspecifiedType() instanceof FloatingPointType
}
override string getAPrimaryQlClass() {
@@ -264,8 +264,8 @@ class FloatingPointToIntegralConversion extends ArithmeticConversion {
*/
class IntegralToFloatingPointConversion extends ArithmeticConversion {
IntegralToFloatingPointConversion() {
- getUnspecifiedType() instanceof FloatingPointType and
- isIntegralOrEnum(getExpr().getUnspecifiedType())
+ this.getUnspecifiedType() instanceof FloatingPointType and
+ isIntegralOrEnum(this.getExpr().getUnspecifiedType())
}
override string getAPrimaryQlClass() {
@@ -290,8 +290,8 @@ class IntegralToFloatingPointConversion extends ArithmeticConversion {
class PointerConversion extends Cast {
PointerConversion() {
conversionkinds(underlyingElement(this), 0) and
- isPointerOrNullPointer(getUnspecifiedType()) and
- isPointerOrNullPointer(getExpr().getUnspecifiedType())
+ isPointerOrNullPointer(this.getUnspecifiedType()) and
+ isPointerOrNullPointer(this.getExpr().getUnspecifiedType())
}
override string getAPrimaryQlClass() { not exists(qlCast(this)) and result = "PointerConversion" }
@@ -315,8 +315,8 @@ class PointerToMemberConversion extends Cast {
PointerToMemberConversion() {
conversionkinds(underlyingElement(this), 0) and
exists(Type fromType, Type toType |
- fromType = getExpr().getUnspecifiedType() and
- toType = getUnspecifiedType() and
+ fromType = this.getExpr().getUnspecifiedType() and
+ toType = this.getUnspecifiedType() and
isPointerToMemberOrNullPointer(fromType) and
isPointerToMemberOrNullPointer(toType) and
// A conversion from nullptr to nullptr is a `PointerConversion`, not a
@@ -345,8 +345,8 @@ class PointerToMemberConversion extends Cast {
class PointerToIntegralConversion extends Cast {
PointerToIntegralConversion() {
conversionkinds(underlyingElement(this), 0) and
- isIntegralOrEnum(getUnspecifiedType()) and
- isPointerOrNullPointer(getExpr().getUnspecifiedType())
+ isIntegralOrEnum(this.getUnspecifiedType()) and
+ isPointerOrNullPointer(this.getExpr().getUnspecifiedType())
}
override string getAPrimaryQlClass() {
@@ -366,8 +366,8 @@ class PointerToIntegralConversion extends Cast {
class IntegralToPointerConversion extends Cast {
IntegralToPointerConversion() {
conversionkinds(underlyingElement(this), 0) and
- isPointerOrNullPointer(getUnspecifiedType()) and
- isIntegralOrEnum(getExpr().getUnspecifiedType())
+ isPointerOrNullPointer(this.getUnspecifiedType()) and
+ isIntegralOrEnum(this.getExpr().getUnspecifiedType())
}
override string getAPrimaryQlClass() {
@@ -403,7 +403,7 @@ class BoolConversion extends Cast {
class VoidConversion extends Cast {
VoidConversion() {
conversionkinds(underlyingElement(this), 0) and
- getUnspecifiedType() instanceof VoidType
+ this.getUnspecifiedType() instanceof VoidType
}
override string getAPrimaryQlClass() { not exists(qlCast(this)) and result = "VoidConversion" }
@@ -434,8 +434,8 @@ class InheritanceConversion extends Cast {
* conversion is to an indirect virtual base class.
*/
final ClassDerivation getDerivation() {
- result.getBaseClass() = getBaseClass() and
- result.getDerivedClass() = getDerivedClass()
+ result.getBaseClass() = this.getBaseClass() and
+ result.getDerivedClass() = this.getDerivedClass()
}
/**
@@ -490,12 +490,12 @@ class BaseClassConversion extends InheritanceConversion {
override Class getBaseClass() { result = getConversionClass(this) }
- override Class getDerivedClass() { result = getConversionClass(getExpr()) }
+ override Class getDerivedClass() { result = getConversionClass(this.getExpr()) }
/**
* Holds if this conversion is to a virtual base class.
*/
- predicate isVirtual() { getDerivation().isVirtual() or not exists(getDerivation()) }
+ predicate isVirtual() { this.getDerivation().isVirtual() or not exists(this.getDerivation()) }
}
/**
@@ -515,7 +515,7 @@ class DerivedClassConversion extends InheritanceConversion {
override string getSemanticConversionString() { result = "derived class conversion" }
- override Class getBaseClass() { result = getConversionClass(getExpr()) }
+ override Class getBaseClass() { result = getConversionClass(this.getExpr()) }
override Class getDerivedClass() { result = getConversionClass(this) }
}
@@ -637,8 +637,8 @@ class DynamicCast extends Cast, @dynamic_cast {
*/
class UuidofOperator extends Expr, @uuidof {
override string toString() {
- if exists(getTypeOperand())
- then result = "__uuidof(" + getTypeOperand().getName() + ")"
+ if exists(this.getTypeOperand())
+ then result = "__uuidof(" + this.getTypeOperand().getName() + ")"
else result = "__uuidof(0)"
}
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll
index f77518c2f56..2811d1703aa 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll
@@ -26,7 +26,7 @@ class Expr extends StmtParent, @expr {
Function getEnclosingFunction() { result = exprEnclosingElement(this) }
/** Gets the nearest enclosing set of curly braces around this expression in the source, if any. */
- BlockStmt getEnclosingBlock() { result = getEnclosingStmt().getEnclosingBlock() }
+ BlockStmt getEnclosingBlock() { result = this.getEnclosingStmt().getEnclosingBlock() }
override Stmt getEnclosingStmt() {
result = this.getParent().(Expr).getEnclosingStmt()
@@ -219,13 +219,13 @@ class Expr extends StmtParent, @expr {
* Holds if this expression is a _glvalue_. A _glvalue_ is either an _lvalue_ or an
* _xvalue_.
*/
- predicate isGLValueCategory() { isLValueCategory() or isXValueCategory() }
+ predicate isGLValueCategory() { this.isLValueCategory() or this.isXValueCategory() }
/**
* Holds if this expression is an _rvalue_. An _rvalue_ is either a _prvalue_ or an
* _xvalue_.
*/
- predicate isRValueCategory() { isPRValueCategory() or isXValueCategory() }
+ predicate isRValueCategory() { this.isPRValueCategory() or this.isXValueCategory() }
/**
* Gets a string representation of the value category of the expression.
@@ -240,15 +240,15 @@ class Expr extends StmtParent, @expr {
* `hasLValueToRvalueConversion()` holds.
*/
string getValueCategoryString() {
- isLValueCategory() and
+ this.isLValueCategory() and
result = "lvalue"
or
- isXValueCategory() and
+ this.isXValueCategory() and
result = "xvalue"
or
(
- isPRValueCategory() and
- if hasLValueToRValueConversion() then result = "prvalue(load)" else result = "prvalue"
+ this.isPRValueCategory() and
+ if this.hasLValueToRValueConversion() then result = "prvalue(load)" else result = "prvalue"
)
}
@@ -263,7 +263,7 @@ class Expr extends StmtParent, @expr {
* such as an expression inside a sizeof.
*/
predicate isUnevaluated() {
- exists(Element e | e = getParentWithConversions+() |
+ exists(Element e | e = this.getParentWithConversions+() |
e instanceof SizeofOperator
or
exists(Expr e2 |
@@ -279,7 +279,7 @@ class Expr extends StmtParent, @expr {
e instanceof AlignofOperator
)
or
- exists(Decltype d | d.getExpr() = getParentWithConversions*())
+ exists(Decltype d | d.getExpr() = this.getParentWithConversions*())
}
/**
@@ -725,7 +725,7 @@ class PointerDereferenceExpr extends UnaryOperation, @indirect {
*
* Gets the expression that is being dereferenced.
*/
- deprecated Expr getExpr() { result = getOperand() }
+ deprecated Expr getExpr() { result = this.getOperand() }
override string getOperator() { result = "*" }
@@ -780,15 +780,15 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr {
* Gets the alignment argument passed to the allocation function, if any.
*/
Expr getAlignmentArgument() {
- hasAlignedAllocation() and
+ this.hasAlignedAllocation() and
(
// If we have an allocator call, the alignment is the second argument to
// that call.
- result = getAllocatorCall().getArgument(1)
+ result = this.getAllocatorCall().getArgument(1)
or
// Otherwise, the alignment winds up as child number 3 of the `new`
// itself.
- result = getChild(3)
+ result = this.getChild(3)
)
}
@@ -916,7 +916,7 @@ class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr {
* Gets the element type of the array being allocated.
*/
Type getAllocatedElementType() {
- result = getType().getUnderlyingType().(PointerType).getBaseType()
+ result = this.getType().getUnderlyingType().(PointerType).getBaseType()
}
/**
@@ -946,7 +946,12 @@ class DeleteExpr extends Expr, @delete_expr {
*/
Type getDeletedObjectType() {
result =
- getExpr().getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType()
+ this.getExpr()
+ .getFullyConverted()
+ .getType()
+ .stripTopLevelSpecifiers()
+ .(PointerType)
+ .getBaseType()
}
/**
@@ -957,7 +962,7 @@ class DeleteExpr extends Expr, @delete_expr {
/**
* Gets the destructor to be called to destroy the object, if any.
*/
- Destructor getDestructor() { result = getDestructorCall().getTarget() }
+ Destructor getDestructor() { result = this.getDestructorCall().getTarget() }
/**
* Gets the `operator delete` that deallocates storage. Does not hold
@@ -1020,7 +1025,12 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
*/
Type getDeletedElementType() {
result =
- getExpr().getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType()
+ this.getExpr()
+ .getFullyConverted()
+ .getType()
+ .stripTopLevelSpecifiers()
+ .(PointerType)
+ .getBaseType()
}
/**
@@ -1034,7 +1044,7 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
/**
* Gets the destructor to be called to destroy each element in the array, if any.
*/
- Destructor getDestructor() { result = getDestructorCall().getTarget() }
+ Destructor getDestructor() { result = this.getDestructorCall().getTarget() }
/**
* Gets the `operator delete[]` that deallocates storage.
@@ -1101,7 +1111,7 @@ class StmtExpr extends Expr, @expr_stmt {
* x = ({ dosomething(); a+b; });
* ```
*/
- Expr getResultExpr() { result = getStmtResultExpr(getStmt()) }
+ Expr getResultExpr() { result = getStmtResultExpr(this.getStmt()) }
}
/** Get the result expression of a statement. (Helper function for StmtExpr.) */
@@ -1230,20 +1240,20 @@ class FoldExpr extends Expr, @foldexpr {
predicate isRightFold() { fold(underlyingElement(this), _, false) }
/** Holds if this is a unary fold expression. */
- predicate isUnaryFold() { getNumChild() = 1 }
+ predicate isUnaryFold() { this.getNumChild() = 1 }
/** Holds if this is a binary fold expression. */
- predicate isBinaryFold() { getNumChild() = 2 }
+ predicate isBinaryFold() { this.getNumChild() = 2 }
/**
* Gets the child expression containing the unexpanded parameter pack.
*/
Expr getPackExpr() {
this.isUnaryFold() and
- result = getChild(0)
+ result = this.getChild(0)
or
this.isBinaryFold() and
- if this.isRightFold() then result = getChild(0) else result = getChild(1)
+ if this.isRightFold() then result = this.getChild(0) else result = this.getChild(1)
}
/**
@@ -1251,7 +1261,7 @@ class FoldExpr extends Expr, @foldexpr {
*/
Expr getInitExpr() {
this.isBinaryFold() and
- if this.isRightFold() then result = getChild(1) else result = getChild(0)
+ if this.isRightFold() then result = this.getChild(1) else result = this.getChild(0)
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Lambda.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Lambda.qll
index 8a51001f4d5..c885831c444 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Lambda.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Lambda.qll
@@ -24,7 +24,7 @@ class LambdaExpression extends Expr, @lambdaexpr {
/**
* Gets an implicitly or explicitly captured value of this lambda expression.
*/
- LambdaCapture getACapture() { result = getCapture(_) }
+ LambdaCapture getACapture() { result = this.getCapture(_) }
/**
* Gets the nth implicitly or explicitly captured value of this lambda expression.
@@ -58,13 +58,13 @@ class LambdaExpression extends Expr, @lambdaexpr {
* - The return type.
* - The statements comprising the lambda body.
*/
- Operator getLambdaFunction() { result = getType().(Closure).getLambdaFunction() }
+ Operator getLambdaFunction() { result = this.getType().(Closure).getLambdaFunction() }
/**
* Gets the initializer that initializes the captured variables in the closure, if any.
* A lambda that does not capture any variables will not have an initializer.
*/
- ClassAggregateLiteral getInitializer() { result = getChild(0) }
+ ClassAggregateLiteral getInitializer() { result = this.getChild(0) }
}
/**
@@ -103,7 +103,7 @@ class Closure extends Class {
* ```
*/
class LambdaCapture extends Locatable, @lambdacapture {
- override string toString() { result = getField().getName() }
+ override string toString() { result = this.getField().getName() }
override string getAPrimaryQlClass() { result = "LambdaCapture" }
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll
index 31790f85bfb..18ca03740ac 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll
@@ -60,12 +60,12 @@ class TextLiteral extends Literal {
/** Gets a hex escape sequence that appears in the character or string literal (see [lex.ccon] in the C++ Standard). */
string getAHexEscapeSequence(int occurrence, int offset) {
- result = getValueText().regexpFind("(?= 0 and
- elementIndex < getArraySize()
+ elementIndex < this.getArraySize()
}
/**
@@ -298,8 +298,8 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
*/
bindingset[elementIndex]
predicate isValueInitialized(int elementIndex) {
- isInitialized(elementIndex) and
- not exists(getElementExpr(elementIndex))
+ this.isInitialized(elementIndex) and
+ not exists(this.getElementExpr(elementIndex))
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/internal/QualifiedName.qll b/cpp/ql/lib/semmle/code/cpp/internal/QualifiedName.qll
index 692ce1fee19..7cf0c647142 100644
--- a/cpp/ql/lib/semmle/code/cpp/internal/QualifiedName.qll
+++ b/cpp/ql/lib/semmle/code/cpp/internal/QualifiedName.qll
@@ -173,7 +173,7 @@ class LocalVariable extends LocalScopeVariable, @localvariable { }
class VariableDeclarationEntry extends @var_decl {
string toString() { result = "QualifiedName DeclarationEntry" }
- Variable getDeclaration() { result = getVariable() }
+ Variable getDeclaration() { result = this.getVariable() }
/**
* Gets the variable which is being declared or defined.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll
index b77bc6cebf0..ece55d181bf 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll
@@ -4,7 +4,7 @@ private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.DataFlow3
private import semmle.code.cpp.ir.IR
-private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch
+private import semmle.code.cpp.ir.dataflow.ResolveCall
private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.models.interfaces.Taint
private import semmle.code.cpp.models.interfaces.DataFlow
@@ -355,20 +355,6 @@ predicate taintedIncludingGlobalVars(Expr source, Element tainted, string global
*/
GlobalOrNamespaceVariable globalVarFromId(string id) { id = result.getQualifiedName() }
-/**
- * Resolve potential target function(s) for `call`.
- *
- * If `call` is a call through a function pointer (`ExprCall`) or
- * targets a virtual method, simple data flow analysis is performed
- * in order to identify target(s).
- */
-Function resolveCall(Call call) {
- exists(CallInstruction callInstruction |
- callInstruction.getAST() = call and
- result = Dispatch::viableCallable(callInstruction)
- )
-}
-
/**
* Provides definitions for augmenting source/sink pairs with data-flow paths
* between them. From a `@kind path-problem` query, import this module in the
@@ -479,7 +465,7 @@ module TaintedWithPath {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll
new file mode 100644
index 00000000000..f25386d3ba8
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/ResolveCall.qll
@@ -0,0 +1,23 @@
+/**
+ * Provides a predicate for non-contextual virtual dispatch and function
+ * pointer resolution.
+ */
+
+import cpp
+private import semmle.code.cpp.ir.ValueNumbering
+private import internal.DataFlowDispatch
+private import semmle.code.cpp.ir.IR
+
+/**
+ * Resolve potential target function(s) for `call`.
+ *
+ * If `call` is a call through a function pointer (`ExprCall`) or its target is
+ * a virtual member function, simple data flow analysis is performed in order
+ * to identify the possible target(s).
+ */
+Function resolveCall(Call call) {
+ exists(CallInstruction callInstruction |
+ callInstruction.getAST() = call and
+ result = viableCallable(callInstruction)
+ )
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll
index f588a25a176..e11244c42b0 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll
@@ -801,6 +801,9 @@ private module Cached {
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call))
}
+ cached
+ predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
+
cached
newtype TCallContext =
TAnyCallContext() or
@@ -937,7 +940,7 @@ class CallContextSpecificCall extends CallContextCall, TSpecificCall {
}
override predicate relevantFor(DataFlowCallable callable) {
- recordDataFlowCallSite(getCall(), callable)
+ recordDataFlowCallSite(this.getCall(), callable)
}
override predicate matchesCall(DataFlowCall call) { call = this.getCall() }
@@ -1236,6 +1239,13 @@ class TypedContent extends MkTypedContent {
/** Gets a textual representation of this content. */
string toString() { result = c.toString() }
+
+ /**
+ * Holds if access paths with this `TypedContent` at their head always should
+ * be tracked at high precision. This disables adaptive access path precision
+ * for such access paths.
+ */
+ predicate forceHighPrecision() { forceHighPrecision(c) }
}
/**
@@ -1250,7 +1260,7 @@ abstract class AccessPathFront extends TAccessPathFront {
TypedContent getHead() { this = TFrontHead(result) }
- predicate isClearedAt(Node n) { clearsContentCached(n, getHead().getContent()) }
+ predicate isClearedAt(Node n) { clearsContentCached(n, this.getHead().getContent()) }
}
class AccessPathFrontNil extends AccessPathFront, TFrontNil {
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll
index a55e65a81f6..dd64fc70039 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll
@@ -175,6 +175,7 @@ module Consistency {
query predicate postWithInFlow(Node n, string msg) {
isPostUpdateNode(n) and
+ not clearsContent(n, _) and
simpleLocalFlowStep(_, n) and
msg = "PostUpdateNode should not be the target of local flow."
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
index 73bf72a3643..3f215883df3 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll
@@ -466,6 +466,12 @@ predicate isUnreachableInCall(Node n, DataFlowCall call) { none() } // stub impl
int accessPathLimit() { result = 5 }
+/**
+ * Holds if access paths with `c` at their head always should be tracked at high
+ * precision. This disables adaptive access path precision for such access paths.
+ */
+predicate forceHighPrecision(Content c) { none() }
+
/** The unit type. */
private newtype TUnit = TMkUnit()
@@ -501,3 +507,12 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { no
/** Extra data-flow steps needed for lambda flow analysis. */
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
+
+/**
+ * Holds if flow is allowed to pass from parameter `p` and back to itself as a
+ * side-effect, resulting in a summary from `p` to itself.
+ *
+ * One example would be to allow flow like `p.foo = p.bar;`, which is disallowed
+ * by default as a heuristic.
+ */
+predicate allowParameterReturnInSelf(ParameterNode p) { none() }
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
index bf21249d4ca..bdcaa856daa 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
@@ -110,7 +110,7 @@ class Node extends TIRDataFlowNode {
/**
* Gets an upper bound on the type of this node.
*/
- IRType getTypeBound() { result = getType() }
+ IRType getTypeBound() { result = this.getType() }
/** Gets the location of this element. */
Location getLocation() { none() } // overridden by subclasses
@@ -120,7 +120,7 @@ class Node extends TIRDataFlowNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -831,7 +831,7 @@ class FieldContent extends Content, TFieldContent {
FieldContent() { this = TFieldContent(c, startBit, endBit) }
// Ensure that there's just 1 result for `toString`.
- override string toString() { result = min(Field f | f = getAField() | f.toString()) }
+ override string toString() { result = min(Field f | f = this.getAField() | f.toString()) }
predicate hasOffset(Class cl, int start, int end) { cl = c and start = startBit and end = endBit }
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll
index 2f4037d4ec8..c7e61ea2e33 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll
@@ -38,5 +38,8 @@ Instruction callOutput(CallInstruction call, FunctionOutput output) {
effect.getPrimaryInstruction() = call and
output.isParameterDerefOrQualifierObject(effect.getIndex())
)
- // TODO: return value dereference
+ or
+ // TODO: modify this when we get return value dereferences
+ result = call and
+ output.isReturnValueDeref()
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll
index 4b86f9a7cec..bb8630a5e0c 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll
@@ -24,7 +24,7 @@ class IRBlockBase extends TIRBlock {
final string toString() { result = getFirstInstruction(this).toString() }
/** Gets the source location of the first non-`Phi` instruction in this block. */
- final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
+ final Language::Location getLocation() { result = this.getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
@@ -39,7 +39,7 @@ class IRBlockBase extends TIRBlock {
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
- funcBlock.getEnclosingFunction() = getEnclosingFunction() and
+ funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
@@ -59,15 +59,15 @@ class IRBlockBase extends TIRBlock {
* Get the `Phi` instructions that appear at the start of this block.
*/
final PhiInstruction getAPhiInstruction() {
- Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
+ Construction::getPhiInstructionBlockStart(result) = this.getFirstInstruction()
}
/**
* Gets an instruction in this block. This includes `Phi` instructions.
*/
final Instruction getAnInstruction() {
- result = getInstruction(_) or
- result = getAPhiInstruction()
+ result = this.getInstruction(_) or
+ result = this.getAPhiInstruction()
}
/**
@@ -78,7 +78,9 @@ class IRBlockBase extends TIRBlock {
/**
* Gets the last instruction in this block.
*/
- final Instruction getLastInstruction() { result = getInstruction(getInstructionCount() - 1) }
+ final Instruction getLastInstruction() {
+ result = this.getInstruction(this.getInstructionCount() - 1)
+ }
/**
* Gets the number of non-`Phi` instructions in this block.
@@ -149,7 +151,7 @@ class IRBlock extends IRBlockBase {
* Block `A` dominates block `B` if any control flow path from the entry block of the function to
* block `B` must pass through block `A`. A block always dominates itself.
*/
- final predicate dominates(IRBlock block) { strictlyDominates(block) or this = block }
+ final predicate dominates(IRBlock block) { this.strictlyDominates(block) or this = block }
/**
* Gets a block on the dominance frontier of this block.
@@ -159,8 +161,8 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock dominanceFrontier() {
- dominates(result.getAPredecessor()) and
- not strictlyDominates(result)
+ this.dominates(result.getAPredecessor()) and
+ not this.strictlyDominates(result)
}
/**
@@ -189,7 +191,7 @@ class IRBlock extends IRBlockBase {
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
- final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
+ final predicate postDominates(IRBlock block) { this.strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
@@ -199,16 +201,16 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
- postDominates(result.getASuccessor()) and
- not strictlyPostDominates(result)
+ this.postDominates(result.getASuccessor()) and
+ not this.strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
final predicate isReachableFromFunctionEntry() {
- this = getEnclosingIRFunction().getEntryBlock() or
- getAPredecessor().isReachableFromFunctionEntry()
+ this = this.getEnclosingIRFunction().getEntryBlock() or
+ this.getAPredecessor().isReachableFromFunctionEntry()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
index 2fb3edad602..88a973fc5a8 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll
@@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction {
}
/** Gets a textual representation of this element. */
- final string toString() { result = getOpcode().toString() + ": " + getAST().toString() }
+ final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() }
/**
* Gets a string showing the result, opcode, and operands of the instruction, equivalent to what
@@ -50,7 +50,8 @@ class Instruction extends Construction::TStageInstruction {
* `mu0_28(int) = Store r0_26, r0_27`
*/
final string getDumpString() {
- result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
+ result =
+ this.getResultString() + " = " + this.getOperationString() + " " + this.getOperandsString()
}
private predicate shouldGenerateDumpStrings() {
@@ -66,10 +67,13 @@ class Instruction extends Construction::TStageInstruction {
* VariableAddress[x]
*/
final string getOperationString() {
- shouldGenerateDumpStrings() and
- if exists(getImmediateString())
- then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
- else result = getOperationPrefix() + getOpcode().toString()
+ this.shouldGenerateDumpStrings() and
+ if exists(this.getImmediateString())
+ then
+ result =
+ this.getOperationPrefix() + this.getOpcode().toString() + "[" + this.getImmediateString() +
+ "]"
+ else result = this.getOperationPrefix() + this.getOpcode().toString()
}
/**
@@ -78,17 +82,17 @@ class Instruction extends Construction::TStageInstruction {
string getImmediateString() { none() }
private string getOperationPrefix() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = ""
}
private string getResultPrefix() {
- shouldGenerateDumpStrings() and
- if getResultIRType() instanceof IRVoidType
+ this.shouldGenerateDumpStrings() and
+ if this.getResultIRType() instanceof IRVoidType
then result = "v"
else
- if hasMemoryResult()
- then if isResultModeled() then result = "m" else result = "mu"
+ if this.hasMemoryResult()
+ then if this.isResultModeled() then result = "m" else result = "mu"
else result = "r"
}
@@ -97,7 +101,7 @@ class Instruction extends Construction::TStageInstruction {
* used by debugging and printing code only.
*/
int getDisplayIndexInBlock() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
exists(IRBlock block |
this = block.getInstruction(result)
or
@@ -111,12 +115,12 @@ class Instruction extends Construction::TStageInstruction {
}
private int getLineRank() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
this =
rank[result](Instruction instr |
instr =
- getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
- getLocation().getStartLine())
+ getAnInstructionAtLine(this.getEnclosingIRFunction(), this.getLocation().getFile(),
+ this.getLocation().getStartLine())
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
@@ -130,8 +134,9 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1`
*/
string getResultId() {
- shouldGenerateDumpStrings() and
- result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
+ this.shouldGenerateDumpStrings() and
+ result =
+ this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank()
}
/**
@@ -142,8 +147,8 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1(int*)`
*/
final string getResultString() {
- shouldGenerateDumpStrings() and
- result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
+ this.shouldGenerateDumpStrings() and
+ result = this.getResultId() + "(" + this.getResultLanguageType().getDumpString() + ")"
}
/**
@@ -153,10 +158,10 @@ class Instruction extends Construction::TStageInstruction {
* Example: `func:r3_4, this:r3_5`
*/
string getOperandsString() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
result =
concat(Operand operand |
- operand = getAnOperand()
+ operand = this.getAnOperand()
|
operand.getDumpString(), ", " order by operand.getDumpSortOrder()
)
@@ -190,7 +195,7 @@ class Instruction extends Construction::TStageInstruction {
* Gets the function that contains this instruction.
*/
final Language::Function getEnclosingFunction() {
- result = getEnclosingIRFunction().getFunction()
+ result = this.getEnclosingIRFunction().getFunction()
}
/**
@@ -208,7 +213,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the location of the source code for this instruction.
*/
- final Language::Location getLocation() { result = getAST().getLocation() }
+ final Language::Location getLocation() { result = this.getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
@@ -243,7 +248,7 @@ class Instruction extends Construction::TStageInstruction {
* a result, its result type will be `IRVoidType`.
*/
cached
- final IRType getResultIRType() { result = getResultLanguageType().getIRType() }
+ final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() }
/**
* Gets the type of the result produced by this instruction. If the
@@ -254,7 +259,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final Language::Type getResultType() {
exists(Language::LanguageType resultType |
- resultType = getResultLanguageType() and
+ resultType = this.getResultLanguageType() and
(
resultType.hasUnspecifiedType(result, _)
or
@@ -283,7 +288,7 @@ class Instruction extends Construction::TStageInstruction {
* result of the `Load` instruction is a prvalue of type `int`, representing
* the integer value loaded from variable `x`.
*/
- final predicate isGLValue() { getResultLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getResultLanguageType().hasType(_, true) }
/**
* Gets the size of the result produced by this instruction, in bytes. If the
@@ -292,7 +297,7 @@ class Instruction extends Construction::TStageInstruction {
* If `this.isGLValue()` holds for this instruction, the value of
* `getResultSize()` will always be the size of a pointer.
*/
- final int getResultSize() { result = getResultLanguageType().getByteSize() }
+ final int getResultSize() { result = this.getResultLanguageType().getByteSize() }
/**
* Gets the opcode that specifies the operation performed by this instruction.
@@ -314,14 +319,16 @@ class Instruction extends Construction::TStageInstruction {
/**
* Holds if this instruction produces a memory result.
*/
- final predicate hasMemoryResult() { exists(getResultMemoryAccess()) }
+ final predicate hasMemoryResult() { exists(this.getResultMemoryAccess()) }
/**
* Gets the kind of memory access performed by this instruction's result.
* Holds only for instructions with a memory result.
*/
pragma[inline]
- final MemoryAccessKind getResultMemoryAccess() { result = getOpcode().getWriteMemoryAccess() }
+ final MemoryAccessKind getResultMemoryAccess() {
+ result = this.getOpcode().getWriteMemoryAccess()
+ }
/**
* Holds if the memory access performed by this instruction's result will not always write to
@@ -332,7 +339,7 @@ class Instruction extends Construction::TStageInstruction {
* (for example, the global side effects of a function call).
*/
pragma[inline]
- final predicate hasResultMayMemoryAccess() { getOpcode().hasMayWriteMemoryAccess() }
+ final predicate hasResultMayMemoryAccess() { this.getOpcode().hasMayWriteMemoryAccess() }
/**
* Gets the operand that holds the memory address to which this instruction stores its
@@ -340,7 +347,7 @@ class Instruction extends Construction::TStageInstruction {
* is `r1`.
*/
final AddressOperand getResultAddressOperand() {
- getResultMemoryAccess().usesAddressOperand() and
+ this.getResultMemoryAccess().usesAddressOperand() and
result.getUse() = this
}
@@ -349,7 +356,7 @@ class Instruction extends Construction::TStageInstruction {
* result, if any. For example, in `m3 = Store r1, r2`, the result of `getResultAddressOperand()`
* is the instruction that defines `r1`.
*/
- final Instruction getResultAddress() { result = getResultAddressOperand().getDef() }
+ final Instruction getResultAddress() { result = this.getResultAddressOperand().getDef() }
/**
* Holds if the result of this instruction is precisely modeled in SSA. Always
@@ -368,7 +375,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final predicate isResultModeled() {
// Register results are always in SSA form.
- not hasMemoryResult() or
+ not this.hasMemoryResult() or
Construction::hasModeledMemoryResult(this)
}
@@ -412,7 +419,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct successors of this instruction.
*/
- final Instruction getASuccessor() { result = getSuccessor(_) }
+ final Instruction getASuccessor() { result = this.getSuccessor(_) }
/**
* Gets a predecessor of this instruction such that the predecessor reaches
@@ -423,7 +430,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct predecessors of this instruction.
*/
- final Instruction getAPredecessor() { result = getPredecessor(_) }
+ final Instruction getAPredecessor() { result = this.getPredecessor(_) }
}
/**
@@ -543,7 +550,7 @@ class IndexedInstruction extends Instruction {
* at this instruction. This instruction has no predecessors.
*/
class EnterFunctionInstruction extends Instruction {
- EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
+ EnterFunctionInstruction() { this.getOpcode() instanceof Opcode::EnterFunction }
}
/**
@@ -554,7 +561,7 @@ class EnterFunctionInstruction extends Instruction {
* struct, or union, see `FieldAddressInstruction`.
*/
class VariableAddressInstruction extends VariableInstruction {
- VariableAddressInstruction() { getOpcode() instanceof Opcode::VariableAddress }
+ VariableAddressInstruction() { this.getOpcode() instanceof Opcode::VariableAddress }
}
/**
@@ -566,7 +573,7 @@ class VariableAddressInstruction extends VariableInstruction {
* The result has an `IRFunctionAddress` type.
*/
class FunctionAddressInstruction extends FunctionInstruction {
- FunctionAddressInstruction() { getOpcode() instanceof Opcode::FunctionAddress }
+ FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
/**
@@ -577,7 +584,7 @@ class FunctionAddressInstruction extends FunctionInstruction {
* initializes that parameter.
*/
class InitializeParameterInstruction extends VariableInstruction {
- InitializeParameterInstruction() { getOpcode() instanceof Opcode::InitializeParameter }
+ InitializeParameterInstruction() { this.getOpcode() instanceof Opcode::InitializeParameter }
/**
* Gets the parameter initialized by this instruction.
@@ -603,7 +610,7 @@ class InitializeParameterInstruction extends VariableInstruction {
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
- InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
+ InitializeNonLocalInstruction() { this.getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
@@ -611,7 +618,7 @@ class InitializeNonLocalInstruction extends Instruction {
* with the value of that memory on entry to the function.
*/
class InitializeIndirectionInstruction extends VariableInstruction {
- InitializeIndirectionInstruction() { getOpcode() instanceof Opcode::InitializeIndirection }
+ InitializeIndirectionInstruction() { this.getOpcode() instanceof Opcode::InitializeIndirection }
/**
* Gets the parameter initialized by this instruction.
@@ -635,24 +642,24 @@ class InitializeIndirectionInstruction extends VariableInstruction {
* An instruction that initializes the `this` pointer parameter of the enclosing function.
*/
class InitializeThisInstruction extends Instruction {
- InitializeThisInstruction() { getOpcode() instanceof Opcode::InitializeThis }
+ InitializeThisInstruction() { this.getOpcode() instanceof Opcode::InitializeThis }
}
/**
* An instruction that computes the address of a non-static field of an object.
*/
class FieldAddressInstruction extends FieldInstruction {
- FieldAddressInstruction() { getOpcode() instanceof Opcode::FieldAddress }
+ FieldAddressInstruction() { this.getOpcode() instanceof Opcode::FieldAddress }
/**
* Gets the operand that provides the address of the object containing the field.
*/
- final UnaryOperand getObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the object containing the field.
*/
- final Instruction getObjectAddress() { result = getObjectAddressOperand().getDef() }
+ final Instruction getObjectAddress() { result = this.getObjectAddressOperand().getDef() }
}
/**
@@ -661,17 +668,19 @@ class FieldAddressInstruction extends FieldInstruction {
* This instruction is used for element access to C# arrays.
*/
class ElementsAddressInstruction extends UnaryInstruction {
- ElementsAddressInstruction() { getOpcode() instanceof Opcode::ElementsAddress }
+ ElementsAddressInstruction() { this.getOpcode() instanceof Opcode::ElementsAddress }
/**
* Gets the operand that provides the address of the array object.
*/
- final UnaryOperand getArrayObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getArrayObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the array object.
*/
- final Instruction getArrayObjectAddress() { result = getArrayObjectAddressOperand().getDef() }
+ final Instruction getArrayObjectAddress() {
+ result = this.getArrayObjectAddressOperand().getDef()
+ }
}
/**
@@ -685,7 +694,7 @@ class ElementsAddressInstruction extends UnaryInstruction {
* taken may want to ignore any function that contains an `ErrorInstruction`.
*/
class ErrorInstruction extends Instruction {
- ErrorInstruction() { getOpcode() instanceof Opcode::Error }
+ ErrorInstruction() { this.getOpcode() instanceof Opcode::Error }
}
/**
@@ -695,7 +704,7 @@ class ErrorInstruction extends Instruction {
* an initializer, or whose initializer only partially initializes the variable.
*/
class UninitializedInstruction extends VariableInstruction {
- UninitializedInstruction() { getOpcode() instanceof Opcode::Uninitialized }
+ UninitializedInstruction() { this.getOpcode() instanceof Opcode::Uninitialized }
/**
* Gets the variable that is uninitialized.
@@ -710,7 +719,7 @@ class UninitializedInstruction extends VariableInstruction {
* least one instruction, even when the AST has no semantic effect.
*/
class NoOpInstruction extends Instruction {
- NoOpInstruction() { getOpcode() instanceof Opcode::NoOp }
+ NoOpInstruction() { this.getOpcode() instanceof Opcode::NoOp }
}
/**
@@ -732,32 +741,32 @@ class NoOpInstruction extends Instruction {
* `void`-returning function.
*/
class ReturnInstruction extends Instruction {
- ReturnInstruction() { getOpcode() instanceof ReturnOpcode }
+ ReturnInstruction() { this.getOpcode() instanceof ReturnOpcode }
}
/**
* An instruction that returns control to the caller of the function, without returning a value.
*/
class ReturnVoidInstruction extends ReturnInstruction {
- ReturnVoidInstruction() { getOpcode() instanceof Opcode::ReturnVoid }
+ ReturnVoidInstruction() { this.getOpcode() instanceof Opcode::ReturnVoid }
}
/**
* An instruction that returns control to the caller of the function, including a return value.
*/
class ReturnValueInstruction extends ReturnInstruction {
- ReturnValueInstruction() { getOpcode() instanceof Opcode::ReturnValue }
+ ReturnValueInstruction() { this.getOpcode() instanceof Opcode::ReturnValue }
/**
* Gets the operand that provides the value being returned by the function.
*/
- final LoadOperand getReturnValueOperand() { result = getAnOperand() }
+ final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available.
*/
- final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
+ final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
}
/**
@@ -770,28 +779,28 @@ class ReturnValueInstruction extends ReturnInstruction {
* that the caller initialized the memory pointed to by the parameter before the call.
*/
class ReturnIndirectionInstruction extends VariableInstruction {
- ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
+ ReturnIndirectionInstruction() { this.getOpcode() instanceof Opcode::ReturnIndirection }
/**
* Gets the operand that provides the value of the pointed-to memory.
*/
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the pointed-to memory, if an exact
* definition is available.
*/
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/**
* Gets the operand that provides the address of the pointed-to memory.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the pointed-to memory.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
/**
* Gets the parameter for which this instruction reads the final pointed-to value within the
@@ -821,12 +830,12 @@ class ReturnIndirectionInstruction extends VariableInstruction {
*
* There are several different copy instructions, depending on the source and destination of the
* copy operation:
- * - `CopyInstruction` - Copies a register operand to a register result.
+ * - `CopyValueInstruction` - Copies a register operand to a register result.
* - `LoadInstruction` - Copies a memory operand to a register result.
* - `StoreInstruction` - Copies a register operand to a memory result.
*/
class CopyInstruction extends Instruction {
- CopyInstruction() { getOpcode() instanceof CopyOpcode }
+ CopyInstruction() { this.getOpcode() instanceof CopyOpcode }
/**
* Gets the operand that provides the input value of the copy.
@@ -837,16 +846,16 @@ class CopyInstruction extends Instruction {
* Gets the instruction whose result provides the input value of the copy, if an exact definition
* is available.
*/
- final Instruction getSourceValue() { result = getSourceValueOperand().getDef() }
+ final Instruction getSourceValue() { result = this.getSourceValueOperand().getDef() }
}
/**
* An instruction that returns a register result containing a copy of its register operand.
*/
class CopyValueInstruction extends CopyInstruction, UnaryInstruction {
- CopyValueInstruction() { getOpcode() instanceof Opcode::CopyValue }
+ CopyValueInstruction() { this.getOpcode() instanceof Opcode::CopyValue }
- final override UnaryOperand getSourceValueOperand() { result = getAnOperand() }
+ final override UnaryOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -863,47 +872,49 @@ private string getAddressOperandDescription(AddressOperand operand) {
* An instruction that returns a register result containing a copy of its memory operand.
*/
class LoadInstruction extends CopyInstruction {
- LoadInstruction() { getOpcode() instanceof Opcode::Load }
+ LoadInstruction() { this.getOpcode() instanceof Opcode::Load }
final override string getImmediateString() {
- result = getAddressOperandDescription(getSourceAddressOperand())
+ result = getAddressOperandDescription(this.getSourceAddressOperand())
}
/**
* Gets the operand that provides the address of the value being loaded.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the value being loaded.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
- final override LoadOperand getSourceValueOperand() { result = getAnOperand() }
+ final override LoadOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
* An instruction that returns a memory result containing a copy of its register operand.
*/
class StoreInstruction extends CopyInstruction {
- StoreInstruction() { getOpcode() instanceof Opcode::Store }
+ StoreInstruction() { this.getOpcode() instanceof Opcode::Store }
final override string getImmediateString() {
- result = getAddressOperandDescription(getDestinationAddressOperand())
+ result = getAddressOperandDescription(this.getDestinationAddressOperand())
}
/**
* Gets the operand that provides the address of the location to which the value will be stored.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the location to which the value will
* be stored, if an exact definition is available.
*/
- final Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ final Instruction getDestinationAddress() {
+ result = this.getDestinationAddressOperand().getDef()
+ }
- final override StoreValueOperand getSourceValueOperand() { result = getAnOperand() }
+ final override StoreValueOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -911,27 +922,27 @@ class StoreInstruction extends CopyInstruction {
* operand.
*/
class ConditionalBranchInstruction extends Instruction {
- ConditionalBranchInstruction() { getOpcode() instanceof Opcode::ConditionalBranch }
+ ConditionalBranchInstruction() { this.getOpcode() instanceof Opcode::ConditionalBranch }
/**
* Gets the operand that provides the Boolean condition controlling the branch.
*/
- final ConditionOperand getConditionOperand() { result = getAnOperand() }
+ final ConditionOperand getConditionOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the Boolean condition controlling the branch.
*/
- final Instruction getCondition() { result = getConditionOperand().getDef() }
+ final Instruction getCondition() { result = this.getConditionOperand().getDef() }
/**
* Gets the instruction to which control will flow if the condition is true.
*/
- final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }
+ final Instruction getTrueSuccessor() { result = this.getSuccessor(EdgeKind::trueEdge()) }
/**
* Gets the instruction to which control will flow if the condition is false.
*/
- final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
+ final Instruction getFalseSuccessor() { result = this.getSuccessor(EdgeKind::falseEdge()) }
}
/**
@@ -943,14 +954,14 @@ class ConditionalBranchInstruction extends Instruction {
* successors.
*/
class ExitFunctionInstruction extends Instruction {
- ExitFunctionInstruction() { getOpcode() instanceof Opcode::ExitFunction }
+ ExitFunctionInstruction() { this.getOpcode() instanceof Opcode::ExitFunction }
}
/**
* An instruction whose result is a constant value.
*/
class ConstantInstruction extends ConstantValueInstruction {
- ConstantInstruction() { getOpcode() instanceof Opcode::Constant }
+ ConstantInstruction() { this.getOpcode() instanceof Opcode::Constant }
}
/**
@@ -959,7 +970,7 @@ class ConstantInstruction extends ConstantValueInstruction {
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
exists(IRType resultType |
- resultType = getResultIRType() and
+ resultType = this.getResultIRType() and
(resultType instanceof IRIntegerType or resultType instanceof IRBooleanType)
)
}
@@ -969,7 +980,7 @@ class IntegerConstantInstruction extends ConstantInstruction {
* An instruction whose result is a constant value of floating-point type.
*/
class FloatConstantInstruction extends ConstantInstruction {
- FloatConstantInstruction() { getResultIRType() instanceof IRFloatingPointType }
+ FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType }
}
/**
@@ -978,7 +989,9 @@ class FloatConstantInstruction extends ConstantInstruction {
class StringConstantInstruction extends VariableInstruction {
override IRStringLiteral var;
- final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) }
+ final override string getImmediateString() {
+ result = Language::getStringLiteralText(this.getValue())
+ }
/**
* Gets the string literal whose address is returned by this instruction.
@@ -990,37 +1003,37 @@ class StringConstantInstruction extends VariableInstruction {
* An instruction whose result is computed from two operands.
*/
class BinaryInstruction extends Instruction {
- BinaryInstruction() { getOpcode() instanceof BinaryOpcode }
+ BinaryInstruction() { this.getOpcode() instanceof BinaryOpcode }
/**
* Gets the left operand of this binary instruction.
*/
- final LeftOperand getLeftOperand() { result = getAnOperand() }
+ final LeftOperand getLeftOperand() { result = this.getAnOperand() }
/**
* Gets the right operand of this binary instruction.
*/
- final RightOperand getRightOperand() { result = getAnOperand() }
+ final RightOperand getRightOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the left operand of this binary
* instruction.
*/
- final Instruction getLeft() { result = getLeftOperand().getDef() }
+ final Instruction getLeft() { result = this.getLeftOperand().getDef() }
/**
* Gets the instruction whose result provides the value of the right operand of this binary
* instruction.
*/
- final Instruction getRight() { result = getRightOperand().getDef() }
+ final Instruction getRight() { result = this.getRightOperand().getDef() }
/**
* Holds if this instruction's operands are `op1` and `op2`, in either order.
*/
final predicate hasOperands(Operand op1, Operand op2) {
- op1 = getLeftOperand() and op2 = getRightOperand()
+ op1 = this.getLeftOperand() and op2 = this.getRightOperand()
or
- op1 = getRightOperand() and op2 = getLeftOperand()
+ op1 = this.getRightOperand() and op2 = this.getLeftOperand()
}
}
@@ -1028,7 +1041,7 @@ class BinaryInstruction extends Instruction {
* An instruction that computes the result of an arithmetic operation.
*/
class ArithmeticInstruction extends Instruction {
- ArithmeticInstruction() { getOpcode() instanceof ArithmeticOpcode }
+ ArithmeticInstruction() { this.getOpcode() instanceof ArithmeticOpcode }
}
/**
@@ -1050,7 +1063,7 @@ class UnaryArithmeticInstruction extends ArithmeticInstruction, UnaryInstruction
* performed according to IEEE-754.
*/
class AddInstruction extends BinaryArithmeticInstruction {
- AddInstruction() { getOpcode() instanceof Opcode::Add }
+ AddInstruction() { this.getOpcode() instanceof Opcode::Add }
}
/**
@@ -1061,7 +1074,7 @@ class AddInstruction extends BinaryArithmeticInstruction {
* according to IEEE-754.
*/
class SubInstruction extends BinaryArithmeticInstruction {
- SubInstruction() { getOpcode() instanceof Opcode::Sub }
+ SubInstruction() { this.getOpcode() instanceof Opcode::Sub }
}
/**
@@ -1072,7 +1085,7 @@ class SubInstruction extends BinaryArithmeticInstruction {
* performed according to IEEE-754.
*/
class MulInstruction extends BinaryArithmeticInstruction {
- MulInstruction() { getOpcode() instanceof Opcode::Mul }
+ MulInstruction() { this.getOpcode() instanceof Opcode::Mul }
}
/**
@@ -1083,7 +1096,7 @@ class MulInstruction extends BinaryArithmeticInstruction {
* to IEEE-754.
*/
class DivInstruction extends BinaryArithmeticInstruction {
- DivInstruction() { getOpcode() instanceof Opcode::Div }
+ DivInstruction() { this.getOpcode() instanceof Opcode::Div }
}
/**
@@ -1093,7 +1106,7 @@ class DivInstruction extends BinaryArithmeticInstruction {
* division by zero or integer overflow is undefined.
*/
class RemInstruction extends BinaryArithmeticInstruction {
- RemInstruction() { getOpcode() instanceof Opcode::Rem }
+ RemInstruction() { this.getOpcode() instanceof Opcode::Rem }
}
/**
@@ -1104,14 +1117,14 @@ class RemInstruction extends BinaryArithmeticInstruction {
* is performed according to IEEE-754.
*/
class NegateInstruction extends UnaryArithmeticInstruction {
- NegateInstruction() { getOpcode() instanceof Opcode::Negate }
+ NegateInstruction() { this.getOpcode() instanceof Opcode::Negate }
}
/**
* An instruction that computes the result of a bitwise operation.
*/
class BitwiseInstruction extends Instruction {
- BitwiseInstruction() { getOpcode() instanceof BitwiseOpcode }
+ BitwiseInstruction() { this.getOpcode() instanceof BitwiseOpcode }
}
/**
@@ -1130,7 +1143,7 @@ class UnaryBitwiseInstruction extends BitwiseInstruction, UnaryInstruction { }
* Both operands must have the same integer type, which will also be the result type.
*/
class BitAndInstruction extends BinaryBitwiseInstruction {
- BitAndInstruction() { getOpcode() instanceof Opcode::BitAnd }
+ BitAndInstruction() { this.getOpcode() instanceof Opcode::BitAnd }
}
/**
@@ -1139,7 +1152,7 @@ class BitAndInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitOrInstruction extends BinaryBitwiseInstruction {
- BitOrInstruction() { getOpcode() instanceof Opcode::BitOr }
+ BitOrInstruction() { this.getOpcode() instanceof Opcode::BitOr }
}
/**
@@ -1148,7 +1161,7 @@ class BitOrInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitXorInstruction extends BinaryBitwiseInstruction {
- BitXorInstruction() { getOpcode() instanceof Opcode::BitXor }
+ BitXorInstruction() { this.getOpcode() instanceof Opcode::BitXor }
}
/**
@@ -1159,7 +1172,7 @@ class BitXorInstruction extends BinaryBitwiseInstruction {
* rightmost bits are zero-filled.
*/
class ShiftLeftInstruction extends BinaryBitwiseInstruction {
- ShiftLeftInstruction() { getOpcode() instanceof Opcode::ShiftLeft }
+ ShiftLeftInstruction() { this.getOpcode() instanceof Opcode::ShiftLeft }
}
/**
@@ -1172,7 +1185,7 @@ class ShiftLeftInstruction extends BinaryBitwiseInstruction {
* of the left operand.
*/
class ShiftRightInstruction extends BinaryBitwiseInstruction {
- ShiftRightInstruction() { getOpcode() instanceof Opcode::ShiftRight }
+ ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
@@ -1183,7 +1196,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
int elementSize;
PointerArithmeticInstruction() {
- getOpcode() instanceof PointerArithmeticOpcode and
+ this.getOpcode() instanceof PointerArithmeticOpcode and
elementSize = Raw::getInstructionElementSize(this)
}
@@ -1206,7 +1219,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
* An instruction that adds or subtracts an integer offset from a pointer.
*/
class PointerOffsetInstruction extends PointerArithmeticInstruction {
- PointerOffsetInstruction() { getOpcode() instanceof PointerOffsetOpcode }
+ PointerOffsetInstruction() { this.getOpcode() instanceof PointerOffsetOpcode }
}
/**
@@ -1217,7 +1230,7 @@ class PointerOffsetInstruction extends PointerArithmeticInstruction {
* overflow is undefined.
*/
class PointerAddInstruction extends PointerOffsetInstruction {
- PointerAddInstruction() { getOpcode() instanceof Opcode::PointerAdd }
+ PointerAddInstruction() { this.getOpcode() instanceof Opcode::PointerAdd }
}
/**
@@ -1228,7 +1241,7 @@ class PointerAddInstruction extends PointerOffsetInstruction {
* pointer underflow is undefined.
*/
class PointerSubInstruction extends PointerOffsetInstruction {
- PointerSubInstruction() { getOpcode() instanceof Opcode::PointerSub }
+ PointerSubInstruction() { this.getOpcode() instanceof Opcode::PointerSub }
}
/**
@@ -1241,31 +1254,31 @@ class PointerSubInstruction extends PointerOffsetInstruction {
* undefined.
*/
class PointerDiffInstruction extends PointerArithmeticInstruction {
- PointerDiffInstruction() { getOpcode() instanceof Opcode::PointerDiff }
+ PointerDiffInstruction() { this.getOpcode() instanceof Opcode::PointerDiff }
}
/**
* An instruction whose result is computed from a single operand.
*/
class UnaryInstruction extends Instruction {
- UnaryInstruction() { getOpcode() instanceof UnaryOpcode }
+ UnaryInstruction() { this.getOpcode() instanceof UnaryOpcode }
/**
* Gets the sole operand of this instruction.
*/
- final UnaryOperand getUnaryOperand() { result = getAnOperand() }
+ final UnaryOperand getUnaryOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the sole operand of this instruction.
*/
- final Instruction getUnary() { result = getUnaryOperand().getDef() }
+ final Instruction getUnary() { result = this.getUnaryOperand().getDef() }
}
/**
* An instruction that converts the value of its operand to a value of a different type.
*/
class ConvertInstruction extends UnaryInstruction {
- ConvertInstruction() { getOpcode() instanceof Opcode::Convert }
+ ConvertInstruction() { this.getOpcode() instanceof Opcode::Convert }
}
/**
@@ -1279,7 +1292,7 @@ class ConvertInstruction extends UnaryInstruction {
* `as` expression.
*/
class CheckedConvertOrNullInstruction extends UnaryInstruction {
- CheckedConvertOrNullInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrNull }
+ CheckedConvertOrNullInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrNull }
}
/**
@@ -1293,7 +1306,7 @@ class CheckedConvertOrNullInstruction extends UnaryInstruction {
* expression.
*/
class CheckedConvertOrThrowInstruction extends UnaryInstruction {
- CheckedConvertOrThrowInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrThrow }
+ CheckedConvertOrThrowInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrThrow }
}
/**
@@ -1306,7 +1319,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {
- CompleteObjectAddressInstruction() { getOpcode() instanceof Opcode::CompleteObjectAddress }
+ CompleteObjectAddressInstruction() { this.getOpcode() instanceof Opcode::CompleteObjectAddress }
}
/**
@@ -1351,7 +1364,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* An instruction that converts from the address of a derived class to the address of a base class.
*/
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
- ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode }
+ ConvertToBaseInstruction() { this.getOpcode() instanceof ConvertToBaseOpcode }
}
/**
@@ -1361,7 +1374,9 @@ class ConvertToBaseInstruction extends InheritanceConversionInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase }
+ ConvertToNonVirtualBaseInstruction() {
+ this.getOpcode() instanceof Opcode::ConvertToNonVirtualBase
+ }
}
/**
@@ -1371,7 +1386,7 @@ class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase }
+ ConvertToVirtualBaseInstruction() { this.getOpcode() instanceof Opcode::ConvertToVirtualBase }
}
/**
@@ -1381,7 +1396,7 @@ class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
- ConvertToDerivedInstruction() { getOpcode() instanceof Opcode::ConvertToDerived }
+ ConvertToDerivedInstruction() { this.getOpcode() instanceof Opcode::ConvertToDerived }
}
/**
@@ -1390,7 +1405,7 @@ class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
* The operand must have an integer type, which will also be the result type.
*/
class BitComplementInstruction extends UnaryBitwiseInstruction {
- BitComplementInstruction() { getOpcode() instanceof Opcode::BitComplement }
+ BitComplementInstruction() { this.getOpcode() instanceof Opcode::BitComplement }
}
/**
@@ -1399,14 +1414,14 @@ class BitComplementInstruction extends UnaryBitwiseInstruction {
* The operand must have a Boolean type, which will also be the result type.
*/
class LogicalNotInstruction extends UnaryInstruction {
- LogicalNotInstruction() { getOpcode() instanceof Opcode::LogicalNot }
+ LogicalNotInstruction() { this.getOpcode() instanceof Opcode::LogicalNot }
}
/**
* An instruction that compares two numeric operands.
*/
class CompareInstruction extends BinaryInstruction {
- CompareInstruction() { getOpcode() instanceof CompareOpcode }
+ CompareInstruction() { this.getOpcode() instanceof CompareOpcode }
}
/**
@@ -1417,7 +1432,7 @@ class CompareInstruction extends BinaryInstruction {
* unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareEQInstruction extends CompareInstruction {
- CompareEQInstruction() { getOpcode() instanceof Opcode::CompareEQ }
+ CompareEQInstruction() { this.getOpcode() instanceof Opcode::CompareEQ }
}
/**
@@ -1428,14 +1443,14 @@ class CompareEQInstruction extends CompareInstruction {
* `left == right`. Floating-point comparison is performed according to IEEE-754.
*/
class CompareNEInstruction extends CompareInstruction {
- CompareNEInstruction() { getOpcode() instanceof Opcode::CompareNE }
+ CompareNEInstruction() { this.getOpcode() instanceof Opcode::CompareNE }
}
/**
* An instruction that does a relative comparison of two values, such as `<` or `>=`.
*/
class RelationalInstruction extends CompareInstruction {
- RelationalInstruction() { getOpcode() instanceof RelationalOpcode }
+ RelationalInstruction() { this.getOpcode() instanceof RelationalOpcode }
/**
* Gets the operand on the "greater" (or "greater-or-equal") side
@@ -1467,11 +1482,11 @@ class RelationalInstruction extends CompareInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLTInstruction extends RelationalInstruction {
- CompareLTInstruction() { getOpcode() instanceof Opcode::CompareLT }
+ CompareLTInstruction() { this.getOpcode() instanceof Opcode::CompareLT }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { any() }
}
@@ -1484,11 +1499,11 @@ class CompareLTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGTInstruction extends RelationalInstruction {
- CompareGTInstruction() { getOpcode() instanceof Opcode::CompareGT }
+ CompareGTInstruction() { this.getOpcode() instanceof Opcode::CompareGT }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { any() }
}
@@ -1502,11 +1517,11 @@ class CompareGTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLEInstruction extends RelationalInstruction {
- CompareLEInstruction() { getOpcode() instanceof Opcode::CompareLE }
+ CompareLEInstruction() { this.getOpcode() instanceof Opcode::CompareLE }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { none() }
}
@@ -1520,11 +1535,11 @@ class CompareLEInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGEInstruction extends RelationalInstruction {
- CompareGEInstruction() { getOpcode() instanceof Opcode::CompareGE }
+ CompareGEInstruction() { this.getOpcode() instanceof Opcode::CompareGE }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { none() }
}
@@ -1543,78 +1558,78 @@ class CompareGEInstruction extends RelationalInstruction {
* of any case edge.
*/
class SwitchInstruction extends Instruction {
- SwitchInstruction() { getOpcode() instanceof Opcode::Switch }
+ SwitchInstruction() { this.getOpcode() instanceof Opcode::Switch }
/** Gets the operand that provides the integer value controlling the switch. */
- final ConditionOperand getExpressionOperand() { result = getAnOperand() }
+ final ConditionOperand getExpressionOperand() { result = this.getAnOperand() }
/** Gets the instruction whose result provides the integer value controlling the switch. */
- final Instruction getExpression() { result = getExpressionOperand().getDef() }
+ final Instruction getExpression() { result = this.getExpressionOperand().getDef() }
/** Gets the successor instructions along the case edges of the switch. */
- final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }
+ final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = this.getSuccessor(edge)) }
/** Gets the successor instruction along the default edge of the switch, if any. */
- final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
+ final Instruction getDefaultSuccessor() { result = this.getSuccessor(EdgeKind::defaultEdge()) }
}
/**
* An instruction that calls a function.
*/
class CallInstruction extends Instruction {
- CallInstruction() { getOpcode() instanceof Opcode::Call }
+ CallInstruction() { this.getOpcode() instanceof Opcode::Call }
final override string getImmediateString() {
- result = getStaticCallTarget().toString()
+ result = this.getStaticCallTarget().toString()
or
- not exists(getStaticCallTarget()) and result = "?"
+ not exists(this.getStaticCallTarget()) and result = "?"
}
/**
* Gets the operand the specifies the target function of the call.
*/
- final CallTargetOperand getCallTargetOperand() { result = getAnOperand() }
+ final CallTargetOperand getCallTargetOperand() { result = this.getAnOperand() }
/**
* Gets the `Instruction` that computes the target function of the call. This is usually a
* `FunctionAddress` instruction, but can also be an arbitrary instruction that produces a
* function pointer.
*/
- final Instruction getCallTarget() { result = getCallTargetOperand().getDef() }
+ final Instruction getCallTarget() { result = this.getCallTargetOperand().getDef() }
/**
* Gets all of the argument operands of the call, including the `this` pointer, if any.
*/
- final ArgumentOperand getAnArgumentOperand() { result = getAnOperand() }
+ final ArgumentOperand getAnArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
final Language::Function getStaticCallTarget() {
- result = getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
+ result = this.getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
}
/**
* Gets all of the arguments of the call, including the `this` pointer, if any.
*/
- final Instruction getAnArgument() { result = getAnArgumentOperand().getDef() }
+ final Instruction getAnArgument() { result = this.getAnArgumentOperand().getDef() }
/**
* Gets the `this` pointer argument operand of the call, if any.
*/
- final ThisArgumentOperand getThisArgumentOperand() { result = getAnOperand() }
+ final ThisArgumentOperand getThisArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `this` pointer argument of the call, if any.
*/
- final Instruction getThisArgument() { result = getThisArgumentOperand().getDef() }
+ final Instruction getThisArgument() { result = this.getThisArgumentOperand().getDef() }
/**
* Gets the argument operand at the specified index.
*/
pragma[noinline]
final PositionalArgumentOperand getPositionalArgumentOperand(int index) {
- result = getAnOperand() and
+ result = this.getAnOperand() and
result.getIndex() = index
}
@@ -1623,7 +1638,7 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final Instruction getPositionalArgument(int index) {
- result = getPositionalArgumentOperand(index).getDef()
+ result = this.getPositionalArgumentOperand(index).getDef()
}
/**
@@ -1631,16 +1646,16 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final ArgumentOperand getArgumentOperand(int index) {
- index >= 0 and result = getPositionalArgumentOperand(index)
+ index >= 0 and result = this.getPositionalArgumentOperand(index)
or
- index = -1 and result = getThisArgumentOperand()
+ index = -1 and result = this.getThisArgumentOperand()
}
/**
* Gets the argument at the specified index, or `this` if `index` is `-1`.
*/
pragma[noinline]
- final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() }
+ final Instruction getArgument(int index) { result = this.getArgumentOperand(index).getDef() }
/**
* Gets the number of arguments of the call, including the `this` pointer, if any.
@@ -1665,7 +1680,7 @@ class CallInstruction extends Instruction {
* An instruction representing a side effect of a function call.
*/
class SideEffectInstruction extends Instruction {
- SideEffectInstruction() { getOpcode() instanceof SideEffectOpcode }
+ SideEffectInstruction() { this.getOpcode() instanceof SideEffectOpcode }
/**
* Gets the instruction whose execution causes this side effect.
@@ -1680,7 +1695,7 @@ class SideEffectInstruction extends Instruction {
* accessed by that call.
*/
class CallSideEffectInstruction extends SideEffectInstruction {
- CallSideEffectInstruction() { getOpcode() instanceof Opcode::CallSideEffect }
+ CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
}
/**
@@ -1691,7 +1706,7 @@ class CallSideEffectInstruction extends SideEffectInstruction {
* call target cannot write to escaped memory.
*/
class CallReadSideEffectInstruction extends SideEffectInstruction {
- CallReadSideEffectInstruction() { getOpcode() instanceof Opcode::CallReadSideEffect }
+ CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
}
/**
@@ -1699,33 +1714,33 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
* specific parameter.
*/
class ReadSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- ReadSideEffectInstruction() { getOpcode() instanceof ReadSideEffectOpcode }
+ ReadSideEffectInstruction() { this.getOpcode() instanceof ReadSideEffectOpcode }
/** Gets the operand for the value that will be read from this instruction, if known. */
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/** Gets the value that will be read from this instruction, if known. */
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/** Gets the operand for the address from which this instruction may read. */
- final AddressOperand getArgumentOperand() { result = getAnOperand() }
+ final AddressOperand getArgumentOperand() { result = this.getAnOperand() }
/** Gets the address from which this instruction may read. */
- final Instruction getArgumentDef() { result = getArgumentOperand().getDef() }
+ final Instruction getArgumentDef() { result = this.getArgumentOperand().getDef() }
}
/**
* An instruction representing the read of an indirect parameter within a function call.
*/
class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
- IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
+ IndirectReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::IndirectReadSideEffect }
}
/**
* An instruction representing the read of an indirect buffer parameter within a function call.
*/
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
- BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
+ BufferReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::BufferReadSideEffect }
}
/**
@@ -1733,18 +1748,18 @@ class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
*/
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
SizedBufferReadSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferReadSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferReadSideEffect
}
/**
* Gets the operand that holds the number of bytes read from the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes read from the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1752,17 +1767,17 @@ class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
* specific parameter.
*/
class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
+ WriteSideEffectInstruction() { this.getOpcode() instanceof WriteSideEffectOpcode }
/**
* Get the operand that holds the address of the memory to be written.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the memory to be written.
*/
- Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ Instruction getDestinationAddress() { result = this.getDestinationAddressOperand().getDef() }
}
/**
@@ -1770,7 +1785,7 @@ class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstructi
*/
class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
}
}
@@ -1780,7 +1795,7 @@ class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction
*/
class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
BufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::BufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::BufferMustWriteSideEffect
}
}
@@ -1790,18 +1805,18 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1812,7 +1827,7 @@ class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstructi
*/
class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
}
}
@@ -1822,7 +1837,9 @@ class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
* Unlike `BufferWriteSideEffectInstruction`, the buffer might not be completely overwritten.
*/
class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
- BufferMayWriteSideEffectInstruction() { getOpcode() instanceof Opcode::BufferMayWriteSideEffect }
+ BufferMayWriteSideEffectInstruction() {
+ this.getOpcode() instanceof Opcode::BufferMayWriteSideEffect
+ }
}
/**
@@ -1832,18 +1849,18 @@ class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1852,80 +1869,80 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio
*/
class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
InitializeDynamicAllocationInstruction() {
- getOpcode() instanceof Opcode::InitializeDynamicAllocation
+ this.getOpcode() instanceof Opcode::InitializeDynamicAllocation
}
/**
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
- final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getAllocationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address for the allocation this instruction is initializing.
*/
- final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
+ final Instruction getAllocationAddress() { result = this.getAllocationAddressOperand().getDef() }
}
/**
* An instruction representing a GNU or MSVC inline assembly statement.
*/
class InlineAsmInstruction extends Instruction {
- InlineAsmInstruction() { getOpcode() instanceof Opcode::InlineAsm }
+ InlineAsmInstruction() { this.getOpcode() instanceof Opcode::InlineAsm }
}
/**
* An instruction that throws an exception.
*/
class ThrowInstruction extends Instruction {
- ThrowInstruction() { getOpcode() instanceof ThrowOpcode }
+ ThrowInstruction() { this.getOpcode() instanceof ThrowOpcode }
}
/**
* An instruction that throws a new exception.
*/
class ThrowValueInstruction extends ThrowInstruction {
- ThrowValueInstruction() { getOpcode() instanceof Opcode::ThrowValue }
+ ThrowValueInstruction() { this.getOpcode() instanceof Opcode::ThrowValue }
/**
* Gets the address operand of the exception thrown by this instruction.
*/
- final AddressOperand getExceptionAddressOperand() { result = getAnOperand() }
+ final AddressOperand getExceptionAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address of the exception thrown by this instruction.
*/
- final Instruction getExceptionAddress() { result = getExceptionAddressOperand().getDef() }
+ final Instruction getExceptionAddress() { result = this.getExceptionAddressOperand().getDef() }
/**
* Gets the operand for the exception thrown by this instruction.
*/
- final LoadOperand getExceptionOperand() { result = getAnOperand() }
+ final LoadOperand getExceptionOperand() { result = this.getAnOperand() }
/**
* Gets the exception thrown by this instruction.
*/
- final Instruction getException() { result = getExceptionOperand().getDef() }
+ final Instruction getException() { result = this.getExceptionOperand().getDef() }
}
/**
* An instruction that re-throws the current exception.
*/
class ReThrowInstruction extends ThrowInstruction {
- ReThrowInstruction() { getOpcode() instanceof Opcode::ReThrow }
+ ReThrowInstruction() { this.getOpcode() instanceof Opcode::ReThrow }
}
/**
* An instruction that exits the current function by propagating an exception.
*/
class UnwindInstruction extends Instruction {
- UnwindInstruction() { getOpcode() instanceof Opcode::Unwind }
+ UnwindInstruction() { this.getOpcode() instanceof Opcode::Unwind }
}
/**
* An instruction that starts a `catch` handler.
*/
class CatchInstruction extends Instruction {
- CatchInstruction() { getOpcode() instanceof CatchOpcode }
+ CatchInstruction() { this.getOpcode() instanceof CatchOpcode }
}
/**
@@ -1935,7 +1952,7 @@ class CatchByTypeInstruction extends CatchInstruction {
Language::LanguageType exceptionType;
CatchByTypeInstruction() {
- getOpcode() instanceof Opcode::CatchByType and
+ this.getOpcode() instanceof Opcode::CatchByType and
exceptionType = Raw::getInstructionExceptionType(this)
}
@@ -1951,21 +1968,21 @@ class CatchByTypeInstruction extends CatchInstruction {
* An instruction that catches any exception.
*/
class CatchAnyInstruction extends CatchInstruction {
- CatchAnyInstruction() { getOpcode() instanceof Opcode::CatchAny }
+ CatchAnyInstruction() { this.getOpcode() instanceof Opcode::CatchAny }
}
/**
* An instruction that initializes all escaped memory.
*/
class AliasedDefinitionInstruction extends Instruction {
- AliasedDefinitionInstruction() { getOpcode() instanceof Opcode::AliasedDefinition }
+ AliasedDefinitionInstruction() { this.getOpcode() instanceof Opcode::AliasedDefinition }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
- AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
+ AliasedUseInstruction() { this.getOpcode() instanceof Opcode::AliasedUse }
}
/**
@@ -1979,7 +1996,7 @@ class AliasedUseInstruction extends Instruction {
* runtime.
*/
class PhiInstruction extends Instruction {
- PhiInstruction() { getOpcode() instanceof Opcode::Phi }
+ PhiInstruction() { this.getOpcode() instanceof Opcode::Phi }
/**
* Gets all of the instruction's `PhiInputOperand`s, representing the values that flow from each predecessor block.
@@ -2047,29 +2064,29 @@ class PhiInstruction extends Instruction {
* https://link.springer.com/content/pdf/10.1007%2F3-540-61053-7_66.pdf.
*/
class ChiInstruction extends Instruction {
- ChiInstruction() { getOpcode() instanceof Opcode::Chi }
+ ChiInstruction() { this.getOpcode() instanceof Opcode::Chi }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final ChiTotalOperand getTotalOperand() { result = getAnOperand() }
+ final ChiTotalOperand getTotalOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final Instruction getTotal() { result = getTotalOperand().getDef() }
+ final Instruction getTotal() { result = this.getTotalOperand().getDef() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final ChiPartialOperand getPartialOperand() { result = getAnOperand() }
+ final ChiPartialOperand getPartialOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final Instruction getPartial() { result = getPartialOperand().getDef() }
+ final Instruction getPartial() { result = this.getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
@@ -2093,7 +2110,7 @@ class ChiInstruction extends Instruction {
* or `Switch` instruction where that particular edge is infeasible.
*/
class UnreachedInstruction extends Instruction {
- UnreachedInstruction() { getOpcode() instanceof Opcode::Unreached }
+ UnreachedInstruction() { this.getOpcode() instanceof Opcode::Unreached }
}
/**
@@ -2106,7 +2123,7 @@ class BuiltInOperationInstruction extends Instruction {
Language::BuiltInOperation operation;
BuiltInOperationInstruction() {
- getOpcode() instanceof BuiltInOperationOpcode and
+ this.getOpcode() instanceof BuiltInOperationOpcode and
operation = Raw::getInstructionBuiltInOperation(this)
}
@@ -2122,9 +2139,9 @@ class BuiltInOperationInstruction extends Instruction {
* actual operation is specified by the `getBuiltInOperation()` predicate.
*/
class BuiltInInstruction extends BuiltInOperationInstruction {
- BuiltInInstruction() { getOpcode() instanceof Opcode::BuiltIn }
+ BuiltInInstruction() { this.getOpcode() instanceof Opcode::BuiltIn }
- final override string getImmediateString() { result = getBuiltInOperation().toString() }
+ final override string getImmediateString() { result = this.getBuiltInOperation().toString() }
}
/**
@@ -2135,7 +2152,7 @@ class BuiltInInstruction extends BuiltInOperationInstruction {
* to the `...` parameter.
*/
class VarArgsStartInstruction extends UnaryInstruction {
- VarArgsStartInstruction() { getOpcode() instanceof Opcode::VarArgsStart }
+ VarArgsStartInstruction() { this.getOpcode() instanceof Opcode::VarArgsStart }
}
/**
@@ -2145,7 +2162,7 @@ class VarArgsStartInstruction extends UnaryInstruction {
* a result.
*/
class VarArgsEndInstruction extends UnaryInstruction {
- VarArgsEndInstruction() { getOpcode() instanceof Opcode::VarArgsEnd }
+ VarArgsEndInstruction() { this.getOpcode() instanceof Opcode::VarArgsEnd }
}
/**
@@ -2155,7 +2172,7 @@ class VarArgsEndInstruction extends UnaryInstruction {
* argument.
*/
class VarArgInstruction extends UnaryInstruction {
- VarArgInstruction() { getOpcode() instanceof Opcode::VarArg }
+ VarArgInstruction() { this.getOpcode() instanceof Opcode::VarArg }
}
/**
@@ -2166,7 +2183,7 @@ class VarArgInstruction extends UnaryInstruction {
* argument of the `...` parameter.
*/
class NextVarArgInstruction extends UnaryInstruction {
- NextVarArgInstruction() { getOpcode() instanceof Opcode::NextVarArg }
+ NextVarArgInstruction() { this.getOpcode() instanceof Opcode::NextVarArg }
}
/**
@@ -2180,5 +2197,5 @@ class NextVarArgInstruction extends UnaryInstruction {
* The result is the address of the newly allocated object.
*/
class NewObjInstruction extends Instruction {
- NewObjInstruction() { getOpcode() instanceof Opcode::NewObj }
+ NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll
index d7cf89ca9aa..85d217bd361 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll
@@ -46,12 +46,12 @@ class Operand extends TStageOperand {
/**
* Gets the location of the source code for this operand.
*/
- final Language::Location getLocation() { result = getUse().getLocation() }
+ final Language::Location getLocation() { result = this.getUse().getLocation() }
/**
* Gets the function that contains this operand.
*/
- final IRFunction getEnclosingIRFunction() { result = getUse().getEnclosingIRFunction() }
+ final IRFunction getEnclosingIRFunction() { result = this.getUse().getEnclosingIRFunction() }
/**
* Gets the `Instruction` that consumes this operand.
@@ -74,7 +74,7 @@ class Operand extends TStageOperand {
*/
final Instruction getDef() {
result = this.getAnyDef() and
- getDefinitionOverlap() instanceof MustExactlyOverlap
+ this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
@@ -82,7 +82,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` that consumes this operand.
*/
- deprecated final Instruction getUseInstruction() { result = getUse() }
+ deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
@@ -91,7 +91,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` whose result is the value of the operand.
*/
- deprecated final Instruction getDefinitionInstruction() { result = getAnyDef() }
+ deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
@@ -101,7 +101,9 @@ class Operand extends TStageOperand {
/**
* Holds if the result of the definition instruction does not exactly overlap this use.
*/
- final predicate isDefinitionInexact() { not getDefinitionOverlap() instanceof MustExactlyOverlap }
+ final predicate isDefinitionInexact() {
+ not this.getDefinitionOverlap() instanceof MustExactlyOverlap
+ }
/**
* Gets a prefix to use when dumping the operand in an operand list.
@@ -121,7 +123,7 @@ class Operand extends TStageOperand {
* For example: `this:r3_5`
*/
final string getDumpString() {
- result = getDumpLabel() + getInexactSpecifier() + getDefinitionId()
+ result = this.getDumpLabel() + this.getInexactSpecifier() + this.getDefinitionId()
}
/**
@@ -129,9 +131,9 @@ class Operand extends TStageOperand {
* definition is not modeled in SSA.
*/
private string getDefinitionId() {
- result = getAnyDef().getResultId()
+ result = this.getAnyDef().getResultId()
or
- not exists(getAnyDef()) and result = "m?"
+ not exists(this.getAnyDef()) and result = "m?"
}
/**
@@ -140,7 +142,7 @@ class Operand extends TStageOperand {
* the empty string.
*/
private string getInexactSpecifier() {
- if isDefinitionInexact() then result = "~" else result = ""
+ if this.isDefinitionInexact() then result = "~" else result = ""
}
/**
@@ -155,7 +157,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- Language::LanguageType getLanguageType() { result = getAnyDef().getResultLanguageType() }
+ Language::LanguageType getLanguageType() { result = this.getAnyDef().getResultLanguageType() }
/**
* Gets the language-neutral type of the value consumed by this operand. This is usually the same
@@ -164,7 +166,7 @@ class Operand extends TStageOperand {
* from the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final IRType getIRType() { result = getLanguageType().getIRType() }
+ final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the value consumed by this operand. This is usually the same as the
@@ -173,7 +175,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final Language::Type getType() { getLanguageType().hasType(result, _) }
+ final Language::Type getType() { this.getLanguageType().hasType(result, _) }
/**
* Holds if the value consumed by this operand is a glvalue. If this
@@ -182,13 +184,13 @@ class Operand extends TStageOperand {
* not hold, the value of the operand represents a value whose type is
* given by `getType()`.
*/
- final predicate isGLValue() { getLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getLanguageType().hasType(_, true) }
/**
* Gets the size of the value consumed by this operand, in bytes. If the operand does not have
* a known constant size, this predicate does not hold.
*/
- final int getSize() { result = getLanguageType().getByteSize() }
+ final int getSize() { result = this.getLanguageType().getByteSize() }
}
/**
@@ -205,7 +207,7 @@ class MemoryOperand extends Operand {
/**
* Gets the kind of memory access performed by the operand.
*/
- MemoryAccessKind getMemoryAccess() { result = getUse().getOpcode().getReadMemoryAccess() }
+ MemoryAccessKind getMemoryAccess() { result = this.getUse().getOpcode().getReadMemoryAccess() }
/**
* Holds if the memory access performed by this operand will not always read from every bit in the
@@ -215,7 +217,7 @@ class MemoryOperand extends Operand {
* conservative estimate of the memory that might actually be accessed at runtime (for example,
* the global side effects of a function call).
*/
- predicate hasMayReadMemoryAccess() { getUse().getOpcode().hasMayReadMemoryAccess() }
+ predicate hasMayReadMemoryAccess() { this.getUse().getOpcode().hasMayReadMemoryAccess() }
/**
* Returns the operand that holds the memory address from which the current operand loads its
@@ -223,8 +225,8 @@ class MemoryOperand extends Operand {
* is `r1`.
*/
final AddressOperand getAddressOperand() {
- getMemoryAccess().usesAddressOperand() and
- result.getUse() = getUse()
+ this.getMemoryAccess().usesAddressOperand() and
+ result.getUse() = this.getUse()
}
}
@@ -294,7 +296,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
- final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
+ final override Overlap getDefinitionOverlap() { this.hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
@@ -449,13 +451,17 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
final override Overlap getDefinitionOverlap() { result = overlap }
- final override int getDumpSortOrder() { result = 11 + getPredecessorBlock().getDisplayIndex() }
-
- final override string getDumpLabel() {
- result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
+ final override int getDumpSortOrder() {
+ result = 11 + this.getPredecessorBlock().getDisplayIndex()
}
- final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
+ final override string getDumpLabel() {
+ result = "from " + this.getPredecessorBlock().getDisplayIndex().toString() + ":"
+ }
+
+ final override string getDumpId() {
+ result = this.getPredecessorBlock().getDisplayIndex().toString()
+ }
/**
* Gets the predecessor block from which this value comes.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll
index 4b86f9a7cec..bb8630a5e0c 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll
@@ -24,7 +24,7 @@ class IRBlockBase extends TIRBlock {
final string toString() { result = getFirstInstruction(this).toString() }
/** Gets the source location of the first non-`Phi` instruction in this block. */
- final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
+ final Language::Location getLocation() { result = this.getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
@@ -39,7 +39,7 @@ class IRBlockBase extends TIRBlock {
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
- funcBlock.getEnclosingFunction() = getEnclosingFunction() and
+ funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
@@ -59,15 +59,15 @@ class IRBlockBase extends TIRBlock {
* Get the `Phi` instructions that appear at the start of this block.
*/
final PhiInstruction getAPhiInstruction() {
- Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
+ Construction::getPhiInstructionBlockStart(result) = this.getFirstInstruction()
}
/**
* Gets an instruction in this block. This includes `Phi` instructions.
*/
final Instruction getAnInstruction() {
- result = getInstruction(_) or
- result = getAPhiInstruction()
+ result = this.getInstruction(_) or
+ result = this.getAPhiInstruction()
}
/**
@@ -78,7 +78,9 @@ class IRBlockBase extends TIRBlock {
/**
* Gets the last instruction in this block.
*/
- final Instruction getLastInstruction() { result = getInstruction(getInstructionCount() - 1) }
+ final Instruction getLastInstruction() {
+ result = this.getInstruction(this.getInstructionCount() - 1)
+ }
/**
* Gets the number of non-`Phi` instructions in this block.
@@ -149,7 +151,7 @@ class IRBlock extends IRBlockBase {
* Block `A` dominates block `B` if any control flow path from the entry block of the function to
* block `B` must pass through block `A`. A block always dominates itself.
*/
- final predicate dominates(IRBlock block) { strictlyDominates(block) or this = block }
+ final predicate dominates(IRBlock block) { this.strictlyDominates(block) or this = block }
/**
* Gets a block on the dominance frontier of this block.
@@ -159,8 +161,8 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock dominanceFrontier() {
- dominates(result.getAPredecessor()) and
- not strictlyDominates(result)
+ this.dominates(result.getAPredecessor()) and
+ not this.strictlyDominates(result)
}
/**
@@ -189,7 +191,7 @@ class IRBlock extends IRBlockBase {
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
- final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
+ final predicate postDominates(IRBlock block) { this.strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
@@ -199,16 +201,16 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
- postDominates(result.getASuccessor()) and
- not strictlyPostDominates(result)
+ this.postDominates(result.getASuccessor()) and
+ not this.strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
final predicate isReachableFromFunctionEntry() {
- this = getEnclosingIRFunction().getEntryBlock() or
- getAPredecessor().isReachableFromFunctionEntry()
+ this = this.getEnclosingIRFunction().getEntryBlock() or
+ this.getAPredecessor().isReachableFromFunctionEntry()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll
index 2fb3edad602..88a973fc5a8 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll
@@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction {
}
/** Gets a textual representation of this element. */
- final string toString() { result = getOpcode().toString() + ": " + getAST().toString() }
+ final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() }
/**
* Gets a string showing the result, opcode, and operands of the instruction, equivalent to what
@@ -50,7 +50,8 @@ class Instruction extends Construction::TStageInstruction {
* `mu0_28(int) = Store r0_26, r0_27`
*/
final string getDumpString() {
- result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
+ result =
+ this.getResultString() + " = " + this.getOperationString() + " " + this.getOperandsString()
}
private predicate shouldGenerateDumpStrings() {
@@ -66,10 +67,13 @@ class Instruction extends Construction::TStageInstruction {
* VariableAddress[x]
*/
final string getOperationString() {
- shouldGenerateDumpStrings() and
- if exists(getImmediateString())
- then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
- else result = getOperationPrefix() + getOpcode().toString()
+ this.shouldGenerateDumpStrings() and
+ if exists(this.getImmediateString())
+ then
+ result =
+ this.getOperationPrefix() + this.getOpcode().toString() + "[" + this.getImmediateString() +
+ "]"
+ else result = this.getOperationPrefix() + this.getOpcode().toString()
}
/**
@@ -78,17 +82,17 @@ class Instruction extends Construction::TStageInstruction {
string getImmediateString() { none() }
private string getOperationPrefix() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = ""
}
private string getResultPrefix() {
- shouldGenerateDumpStrings() and
- if getResultIRType() instanceof IRVoidType
+ this.shouldGenerateDumpStrings() and
+ if this.getResultIRType() instanceof IRVoidType
then result = "v"
else
- if hasMemoryResult()
- then if isResultModeled() then result = "m" else result = "mu"
+ if this.hasMemoryResult()
+ then if this.isResultModeled() then result = "m" else result = "mu"
else result = "r"
}
@@ -97,7 +101,7 @@ class Instruction extends Construction::TStageInstruction {
* used by debugging and printing code only.
*/
int getDisplayIndexInBlock() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
exists(IRBlock block |
this = block.getInstruction(result)
or
@@ -111,12 +115,12 @@ class Instruction extends Construction::TStageInstruction {
}
private int getLineRank() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
this =
rank[result](Instruction instr |
instr =
- getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
- getLocation().getStartLine())
+ getAnInstructionAtLine(this.getEnclosingIRFunction(), this.getLocation().getFile(),
+ this.getLocation().getStartLine())
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
@@ -130,8 +134,9 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1`
*/
string getResultId() {
- shouldGenerateDumpStrings() and
- result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
+ this.shouldGenerateDumpStrings() and
+ result =
+ this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank()
}
/**
@@ -142,8 +147,8 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1(int*)`
*/
final string getResultString() {
- shouldGenerateDumpStrings() and
- result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
+ this.shouldGenerateDumpStrings() and
+ result = this.getResultId() + "(" + this.getResultLanguageType().getDumpString() + ")"
}
/**
@@ -153,10 +158,10 @@ class Instruction extends Construction::TStageInstruction {
* Example: `func:r3_4, this:r3_5`
*/
string getOperandsString() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
result =
concat(Operand operand |
- operand = getAnOperand()
+ operand = this.getAnOperand()
|
operand.getDumpString(), ", " order by operand.getDumpSortOrder()
)
@@ -190,7 +195,7 @@ class Instruction extends Construction::TStageInstruction {
* Gets the function that contains this instruction.
*/
final Language::Function getEnclosingFunction() {
- result = getEnclosingIRFunction().getFunction()
+ result = this.getEnclosingIRFunction().getFunction()
}
/**
@@ -208,7 +213,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the location of the source code for this instruction.
*/
- final Language::Location getLocation() { result = getAST().getLocation() }
+ final Language::Location getLocation() { result = this.getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
@@ -243,7 +248,7 @@ class Instruction extends Construction::TStageInstruction {
* a result, its result type will be `IRVoidType`.
*/
cached
- final IRType getResultIRType() { result = getResultLanguageType().getIRType() }
+ final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() }
/**
* Gets the type of the result produced by this instruction. If the
@@ -254,7 +259,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final Language::Type getResultType() {
exists(Language::LanguageType resultType |
- resultType = getResultLanguageType() and
+ resultType = this.getResultLanguageType() and
(
resultType.hasUnspecifiedType(result, _)
or
@@ -283,7 +288,7 @@ class Instruction extends Construction::TStageInstruction {
* result of the `Load` instruction is a prvalue of type `int`, representing
* the integer value loaded from variable `x`.
*/
- final predicate isGLValue() { getResultLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getResultLanguageType().hasType(_, true) }
/**
* Gets the size of the result produced by this instruction, in bytes. If the
@@ -292,7 +297,7 @@ class Instruction extends Construction::TStageInstruction {
* If `this.isGLValue()` holds for this instruction, the value of
* `getResultSize()` will always be the size of a pointer.
*/
- final int getResultSize() { result = getResultLanguageType().getByteSize() }
+ final int getResultSize() { result = this.getResultLanguageType().getByteSize() }
/**
* Gets the opcode that specifies the operation performed by this instruction.
@@ -314,14 +319,16 @@ class Instruction extends Construction::TStageInstruction {
/**
* Holds if this instruction produces a memory result.
*/
- final predicate hasMemoryResult() { exists(getResultMemoryAccess()) }
+ final predicate hasMemoryResult() { exists(this.getResultMemoryAccess()) }
/**
* Gets the kind of memory access performed by this instruction's result.
* Holds only for instructions with a memory result.
*/
pragma[inline]
- final MemoryAccessKind getResultMemoryAccess() { result = getOpcode().getWriteMemoryAccess() }
+ final MemoryAccessKind getResultMemoryAccess() {
+ result = this.getOpcode().getWriteMemoryAccess()
+ }
/**
* Holds if the memory access performed by this instruction's result will not always write to
@@ -332,7 +339,7 @@ class Instruction extends Construction::TStageInstruction {
* (for example, the global side effects of a function call).
*/
pragma[inline]
- final predicate hasResultMayMemoryAccess() { getOpcode().hasMayWriteMemoryAccess() }
+ final predicate hasResultMayMemoryAccess() { this.getOpcode().hasMayWriteMemoryAccess() }
/**
* Gets the operand that holds the memory address to which this instruction stores its
@@ -340,7 +347,7 @@ class Instruction extends Construction::TStageInstruction {
* is `r1`.
*/
final AddressOperand getResultAddressOperand() {
- getResultMemoryAccess().usesAddressOperand() and
+ this.getResultMemoryAccess().usesAddressOperand() and
result.getUse() = this
}
@@ -349,7 +356,7 @@ class Instruction extends Construction::TStageInstruction {
* result, if any. For example, in `m3 = Store r1, r2`, the result of `getResultAddressOperand()`
* is the instruction that defines `r1`.
*/
- final Instruction getResultAddress() { result = getResultAddressOperand().getDef() }
+ final Instruction getResultAddress() { result = this.getResultAddressOperand().getDef() }
/**
* Holds if the result of this instruction is precisely modeled in SSA. Always
@@ -368,7 +375,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final predicate isResultModeled() {
// Register results are always in SSA form.
- not hasMemoryResult() or
+ not this.hasMemoryResult() or
Construction::hasModeledMemoryResult(this)
}
@@ -412,7 +419,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct successors of this instruction.
*/
- final Instruction getASuccessor() { result = getSuccessor(_) }
+ final Instruction getASuccessor() { result = this.getSuccessor(_) }
/**
* Gets a predecessor of this instruction such that the predecessor reaches
@@ -423,7 +430,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct predecessors of this instruction.
*/
- final Instruction getAPredecessor() { result = getPredecessor(_) }
+ final Instruction getAPredecessor() { result = this.getPredecessor(_) }
}
/**
@@ -543,7 +550,7 @@ class IndexedInstruction extends Instruction {
* at this instruction. This instruction has no predecessors.
*/
class EnterFunctionInstruction extends Instruction {
- EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
+ EnterFunctionInstruction() { this.getOpcode() instanceof Opcode::EnterFunction }
}
/**
@@ -554,7 +561,7 @@ class EnterFunctionInstruction extends Instruction {
* struct, or union, see `FieldAddressInstruction`.
*/
class VariableAddressInstruction extends VariableInstruction {
- VariableAddressInstruction() { getOpcode() instanceof Opcode::VariableAddress }
+ VariableAddressInstruction() { this.getOpcode() instanceof Opcode::VariableAddress }
}
/**
@@ -566,7 +573,7 @@ class VariableAddressInstruction extends VariableInstruction {
* The result has an `IRFunctionAddress` type.
*/
class FunctionAddressInstruction extends FunctionInstruction {
- FunctionAddressInstruction() { getOpcode() instanceof Opcode::FunctionAddress }
+ FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
/**
@@ -577,7 +584,7 @@ class FunctionAddressInstruction extends FunctionInstruction {
* initializes that parameter.
*/
class InitializeParameterInstruction extends VariableInstruction {
- InitializeParameterInstruction() { getOpcode() instanceof Opcode::InitializeParameter }
+ InitializeParameterInstruction() { this.getOpcode() instanceof Opcode::InitializeParameter }
/**
* Gets the parameter initialized by this instruction.
@@ -603,7 +610,7 @@ class InitializeParameterInstruction extends VariableInstruction {
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
- InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
+ InitializeNonLocalInstruction() { this.getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
@@ -611,7 +618,7 @@ class InitializeNonLocalInstruction extends Instruction {
* with the value of that memory on entry to the function.
*/
class InitializeIndirectionInstruction extends VariableInstruction {
- InitializeIndirectionInstruction() { getOpcode() instanceof Opcode::InitializeIndirection }
+ InitializeIndirectionInstruction() { this.getOpcode() instanceof Opcode::InitializeIndirection }
/**
* Gets the parameter initialized by this instruction.
@@ -635,24 +642,24 @@ class InitializeIndirectionInstruction extends VariableInstruction {
* An instruction that initializes the `this` pointer parameter of the enclosing function.
*/
class InitializeThisInstruction extends Instruction {
- InitializeThisInstruction() { getOpcode() instanceof Opcode::InitializeThis }
+ InitializeThisInstruction() { this.getOpcode() instanceof Opcode::InitializeThis }
}
/**
* An instruction that computes the address of a non-static field of an object.
*/
class FieldAddressInstruction extends FieldInstruction {
- FieldAddressInstruction() { getOpcode() instanceof Opcode::FieldAddress }
+ FieldAddressInstruction() { this.getOpcode() instanceof Opcode::FieldAddress }
/**
* Gets the operand that provides the address of the object containing the field.
*/
- final UnaryOperand getObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the object containing the field.
*/
- final Instruction getObjectAddress() { result = getObjectAddressOperand().getDef() }
+ final Instruction getObjectAddress() { result = this.getObjectAddressOperand().getDef() }
}
/**
@@ -661,17 +668,19 @@ class FieldAddressInstruction extends FieldInstruction {
* This instruction is used for element access to C# arrays.
*/
class ElementsAddressInstruction extends UnaryInstruction {
- ElementsAddressInstruction() { getOpcode() instanceof Opcode::ElementsAddress }
+ ElementsAddressInstruction() { this.getOpcode() instanceof Opcode::ElementsAddress }
/**
* Gets the operand that provides the address of the array object.
*/
- final UnaryOperand getArrayObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getArrayObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the array object.
*/
- final Instruction getArrayObjectAddress() { result = getArrayObjectAddressOperand().getDef() }
+ final Instruction getArrayObjectAddress() {
+ result = this.getArrayObjectAddressOperand().getDef()
+ }
}
/**
@@ -685,7 +694,7 @@ class ElementsAddressInstruction extends UnaryInstruction {
* taken may want to ignore any function that contains an `ErrorInstruction`.
*/
class ErrorInstruction extends Instruction {
- ErrorInstruction() { getOpcode() instanceof Opcode::Error }
+ ErrorInstruction() { this.getOpcode() instanceof Opcode::Error }
}
/**
@@ -695,7 +704,7 @@ class ErrorInstruction extends Instruction {
* an initializer, or whose initializer only partially initializes the variable.
*/
class UninitializedInstruction extends VariableInstruction {
- UninitializedInstruction() { getOpcode() instanceof Opcode::Uninitialized }
+ UninitializedInstruction() { this.getOpcode() instanceof Opcode::Uninitialized }
/**
* Gets the variable that is uninitialized.
@@ -710,7 +719,7 @@ class UninitializedInstruction extends VariableInstruction {
* least one instruction, even when the AST has no semantic effect.
*/
class NoOpInstruction extends Instruction {
- NoOpInstruction() { getOpcode() instanceof Opcode::NoOp }
+ NoOpInstruction() { this.getOpcode() instanceof Opcode::NoOp }
}
/**
@@ -732,32 +741,32 @@ class NoOpInstruction extends Instruction {
* `void`-returning function.
*/
class ReturnInstruction extends Instruction {
- ReturnInstruction() { getOpcode() instanceof ReturnOpcode }
+ ReturnInstruction() { this.getOpcode() instanceof ReturnOpcode }
}
/**
* An instruction that returns control to the caller of the function, without returning a value.
*/
class ReturnVoidInstruction extends ReturnInstruction {
- ReturnVoidInstruction() { getOpcode() instanceof Opcode::ReturnVoid }
+ ReturnVoidInstruction() { this.getOpcode() instanceof Opcode::ReturnVoid }
}
/**
* An instruction that returns control to the caller of the function, including a return value.
*/
class ReturnValueInstruction extends ReturnInstruction {
- ReturnValueInstruction() { getOpcode() instanceof Opcode::ReturnValue }
+ ReturnValueInstruction() { this.getOpcode() instanceof Opcode::ReturnValue }
/**
* Gets the operand that provides the value being returned by the function.
*/
- final LoadOperand getReturnValueOperand() { result = getAnOperand() }
+ final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available.
*/
- final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
+ final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
}
/**
@@ -770,28 +779,28 @@ class ReturnValueInstruction extends ReturnInstruction {
* that the caller initialized the memory pointed to by the parameter before the call.
*/
class ReturnIndirectionInstruction extends VariableInstruction {
- ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
+ ReturnIndirectionInstruction() { this.getOpcode() instanceof Opcode::ReturnIndirection }
/**
* Gets the operand that provides the value of the pointed-to memory.
*/
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the pointed-to memory, if an exact
* definition is available.
*/
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/**
* Gets the operand that provides the address of the pointed-to memory.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the pointed-to memory.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
/**
* Gets the parameter for which this instruction reads the final pointed-to value within the
@@ -821,12 +830,12 @@ class ReturnIndirectionInstruction extends VariableInstruction {
*
* There are several different copy instructions, depending on the source and destination of the
* copy operation:
- * - `CopyInstruction` - Copies a register operand to a register result.
+ * - `CopyValueInstruction` - Copies a register operand to a register result.
* - `LoadInstruction` - Copies a memory operand to a register result.
* - `StoreInstruction` - Copies a register operand to a memory result.
*/
class CopyInstruction extends Instruction {
- CopyInstruction() { getOpcode() instanceof CopyOpcode }
+ CopyInstruction() { this.getOpcode() instanceof CopyOpcode }
/**
* Gets the operand that provides the input value of the copy.
@@ -837,16 +846,16 @@ class CopyInstruction extends Instruction {
* Gets the instruction whose result provides the input value of the copy, if an exact definition
* is available.
*/
- final Instruction getSourceValue() { result = getSourceValueOperand().getDef() }
+ final Instruction getSourceValue() { result = this.getSourceValueOperand().getDef() }
}
/**
* An instruction that returns a register result containing a copy of its register operand.
*/
class CopyValueInstruction extends CopyInstruction, UnaryInstruction {
- CopyValueInstruction() { getOpcode() instanceof Opcode::CopyValue }
+ CopyValueInstruction() { this.getOpcode() instanceof Opcode::CopyValue }
- final override UnaryOperand getSourceValueOperand() { result = getAnOperand() }
+ final override UnaryOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -863,47 +872,49 @@ private string getAddressOperandDescription(AddressOperand operand) {
* An instruction that returns a register result containing a copy of its memory operand.
*/
class LoadInstruction extends CopyInstruction {
- LoadInstruction() { getOpcode() instanceof Opcode::Load }
+ LoadInstruction() { this.getOpcode() instanceof Opcode::Load }
final override string getImmediateString() {
- result = getAddressOperandDescription(getSourceAddressOperand())
+ result = getAddressOperandDescription(this.getSourceAddressOperand())
}
/**
* Gets the operand that provides the address of the value being loaded.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the value being loaded.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
- final override LoadOperand getSourceValueOperand() { result = getAnOperand() }
+ final override LoadOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
* An instruction that returns a memory result containing a copy of its register operand.
*/
class StoreInstruction extends CopyInstruction {
- StoreInstruction() { getOpcode() instanceof Opcode::Store }
+ StoreInstruction() { this.getOpcode() instanceof Opcode::Store }
final override string getImmediateString() {
- result = getAddressOperandDescription(getDestinationAddressOperand())
+ result = getAddressOperandDescription(this.getDestinationAddressOperand())
}
/**
* Gets the operand that provides the address of the location to which the value will be stored.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the location to which the value will
* be stored, if an exact definition is available.
*/
- final Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ final Instruction getDestinationAddress() {
+ result = this.getDestinationAddressOperand().getDef()
+ }
- final override StoreValueOperand getSourceValueOperand() { result = getAnOperand() }
+ final override StoreValueOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -911,27 +922,27 @@ class StoreInstruction extends CopyInstruction {
* operand.
*/
class ConditionalBranchInstruction extends Instruction {
- ConditionalBranchInstruction() { getOpcode() instanceof Opcode::ConditionalBranch }
+ ConditionalBranchInstruction() { this.getOpcode() instanceof Opcode::ConditionalBranch }
/**
* Gets the operand that provides the Boolean condition controlling the branch.
*/
- final ConditionOperand getConditionOperand() { result = getAnOperand() }
+ final ConditionOperand getConditionOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the Boolean condition controlling the branch.
*/
- final Instruction getCondition() { result = getConditionOperand().getDef() }
+ final Instruction getCondition() { result = this.getConditionOperand().getDef() }
/**
* Gets the instruction to which control will flow if the condition is true.
*/
- final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }
+ final Instruction getTrueSuccessor() { result = this.getSuccessor(EdgeKind::trueEdge()) }
/**
* Gets the instruction to which control will flow if the condition is false.
*/
- final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
+ final Instruction getFalseSuccessor() { result = this.getSuccessor(EdgeKind::falseEdge()) }
}
/**
@@ -943,14 +954,14 @@ class ConditionalBranchInstruction extends Instruction {
* successors.
*/
class ExitFunctionInstruction extends Instruction {
- ExitFunctionInstruction() { getOpcode() instanceof Opcode::ExitFunction }
+ ExitFunctionInstruction() { this.getOpcode() instanceof Opcode::ExitFunction }
}
/**
* An instruction whose result is a constant value.
*/
class ConstantInstruction extends ConstantValueInstruction {
- ConstantInstruction() { getOpcode() instanceof Opcode::Constant }
+ ConstantInstruction() { this.getOpcode() instanceof Opcode::Constant }
}
/**
@@ -959,7 +970,7 @@ class ConstantInstruction extends ConstantValueInstruction {
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
exists(IRType resultType |
- resultType = getResultIRType() and
+ resultType = this.getResultIRType() and
(resultType instanceof IRIntegerType or resultType instanceof IRBooleanType)
)
}
@@ -969,7 +980,7 @@ class IntegerConstantInstruction extends ConstantInstruction {
* An instruction whose result is a constant value of floating-point type.
*/
class FloatConstantInstruction extends ConstantInstruction {
- FloatConstantInstruction() { getResultIRType() instanceof IRFloatingPointType }
+ FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType }
}
/**
@@ -978,7 +989,9 @@ class FloatConstantInstruction extends ConstantInstruction {
class StringConstantInstruction extends VariableInstruction {
override IRStringLiteral var;
- final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) }
+ final override string getImmediateString() {
+ result = Language::getStringLiteralText(this.getValue())
+ }
/**
* Gets the string literal whose address is returned by this instruction.
@@ -990,37 +1003,37 @@ class StringConstantInstruction extends VariableInstruction {
* An instruction whose result is computed from two operands.
*/
class BinaryInstruction extends Instruction {
- BinaryInstruction() { getOpcode() instanceof BinaryOpcode }
+ BinaryInstruction() { this.getOpcode() instanceof BinaryOpcode }
/**
* Gets the left operand of this binary instruction.
*/
- final LeftOperand getLeftOperand() { result = getAnOperand() }
+ final LeftOperand getLeftOperand() { result = this.getAnOperand() }
/**
* Gets the right operand of this binary instruction.
*/
- final RightOperand getRightOperand() { result = getAnOperand() }
+ final RightOperand getRightOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the left operand of this binary
* instruction.
*/
- final Instruction getLeft() { result = getLeftOperand().getDef() }
+ final Instruction getLeft() { result = this.getLeftOperand().getDef() }
/**
* Gets the instruction whose result provides the value of the right operand of this binary
* instruction.
*/
- final Instruction getRight() { result = getRightOperand().getDef() }
+ final Instruction getRight() { result = this.getRightOperand().getDef() }
/**
* Holds if this instruction's operands are `op1` and `op2`, in either order.
*/
final predicate hasOperands(Operand op1, Operand op2) {
- op1 = getLeftOperand() and op2 = getRightOperand()
+ op1 = this.getLeftOperand() and op2 = this.getRightOperand()
or
- op1 = getRightOperand() and op2 = getLeftOperand()
+ op1 = this.getRightOperand() and op2 = this.getLeftOperand()
}
}
@@ -1028,7 +1041,7 @@ class BinaryInstruction extends Instruction {
* An instruction that computes the result of an arithmetic operation.
*/
class ArithmeticInstruction extends Instruction {
- ArithmeticInstruction() { getOpcode() instanceof ArithmeticOpcode }
+ ArithmeticInstruction() { this.getOpcode() instanceof ArithmeticOpcode }
}
/**
@@ -1050,7 +1063,7 @@ class UnaryArithmeticInstruction extends ArithmeticInstruction, UnaryInstruction
* performed according to IEEE-754.
*/
class AddInstruction extends BinaryArithmeticInstruction {
- AddInstruction() { getOpcode() instanceof Opcode::Add }
+ AddInstruction() { this.getOpcode() instanceof Opcode::Add }
}
/**
@@ -1061,7 +1074,7 @@ class AddInstruction extends BinaryArithmeticInstruction {
* according to IEEE-754.
*/
class SubInstruction extends BinaryArithmeticInstruction {
- SubInstruction() { getOpcode() instanceof Opcode::Sub }
+ SubInstruction() { this.getOpcode() instanceof Opcode::Sub }
}
/**
@@ -1072,7 +1085,7 @@ class SubInstruction extends BinaryArithmeticInstruction {
* performed according to IEEE-754.
*/
class MulInstruction extends BinaryArithmeticInstruction {
- MulInstruction() { getOpcode() instanceof Opcode::Mul }
+ MulInstruction() { this.getOpcode() instanceof Opcode::Mul }
}
/**
@@ -1083,7 +1096,7 @@ class MulInstruction extends BinaryArithmeticInstruction {
* to IEEE-754.
*/
class DivInstruction extends BinaryArithmeticInstruction {
- DivInstruction() { getOpcode() instanceof Opcode::Div }
+ DivInstruction() { this.getOpcode() instanceof Opcode::Div }
}
/**
@@ -1093,7 +1106,7 @@ class DivInstruction extends BinaryArithmeticInstruction {
* division by zero or integer overflow is undefined.
*/
class RemInstruction extends BinaryArithmeticInstruction {
- RemInstruction() { getOpcode() instanceof Opcode::Rem }
+ RemInstruction() { this.getOpcode() instanceof Opcode::Rem }
}
/**
@@ -1104,14 +1117,14 @@ class RemInstruction extends BinaryArithmeticInstruction {
* is performed according to IEEE-754.
*/
class NegateInstruction extends UnaryArithmeticInstruction {
- NegateInstruction() { getOpcode() instanceof Opcode::Negate }
+ NegateInstruction() { this.getOpcode() instanceof Opcode::Negate }
}
/**
* An instruction that computes the result of a bitwise operation.
*/
class BitwiseInstruction extends Instruction {
- BitwiseInstruction() { getOpcode() instanceof BitwiseOpcode }
+ BitwiseInstruction() { this.getOpcode() instanceof BitwiseOpcode }
}
/**
@@ -1130,7 +1143,7 @@ class UnaryBitwiseInstruction extends BitwiseInstruction, UnaryInstruction { }
* Both operands must have the same integer type, which will also be the result type.
*/
class BitAndInstruction extends BinaryBitwiseInstruction {
- BitAndInstruction() { getOpcode() instanceof Opcode::BitAnd }
+ BitAndInstruction() { this.getOpcode() instanceof Opcode::BitAnd }
}
/**
@@ -1139,7 +1152,7 @@ class BitAndInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitOrInstruction extends BinaryBitwiseInstruction {
- BitOrInstruction() { getOpcode() instanceof Opcode::BitOr }
+ BitOrInstruction() { this.getOpcode() instanceof Opcode::BitOr }
}
/**
@@ -1148,7 +1161,7 @@ class BitOrInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitXorInstruction extends BinaryBitwiseInstruction {
- BitXorInstruction() { getOpcode() instanceof Opcode::BitXor }
+ BitXorInstruction() { this.getOpcode() instanceof Opcode::BitXor }
}
/**
@@ -1159,7 +1172,7 @@ class BitXorInstruction extends BinaryBitwiseInstruction {
* rightmost bits are zero-filled.
*/
class ShiftLeftInstruction extends BinaryBitwiseInstruction {
- ShiftLeftInstruction() { getOpcode() instanceof Opcode::ShiftLeft }
+ ShiftLeftInstruction() { this.getOpcode() instanceof Opcode::ShiftLeft }
}
/**
@@ -1172,7 +1185,7 @@ class ShiftLeftInstruction extends BinaryBitwiseInstruction {
* of the left operand.
*/
class ShiftRightInstruction extends BinaryBitwiseInstruction {
- ShiftRightInstruction() { getOpcode() instanceof Opcode::ShiftRight }
+ ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
@@ -1183,7 +1196,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
int elementSize;
PointerArithmeticInstruction() {
- getOpcode() instanceof PointerArithmeticOpcode and
+ this.getOpcode() instanceof PointerArithmeticOpcode and
elementSize = Raw::getInstructionElementSize(this)
}
@@ -1206,7 +1219,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
* An instruction that adds or subtracts an integer offset from a pointer.
*/
class PointerOffsetInstruction extends PointerArithmeticInstruction {
- PointerOffsetInstruction() { getOpcode() instanceof PointerOffsetOpcode }
+ PointerOffsetInstruction() { this.getOpcode() instanceof PointerOffsetOpcode }
}
/**
@@ -1217,7 +1230,7 @@ class PointerOffsetInstruction extends PointerArithmeticInstruction {
* overflow is undefined.
*/
class PointerAddInstruction extends PointerOffsetInstruction {
- PointerAddInstruction() { getOpcode() instanceof Opcode::PointerAdd }
+ PointerAddInstruction() { this.getOpcode() instanceof Opcode::PointerAdd }
}
/**
@@ -1228,7 +1241,7 @@ class PointerAddInstruction extends PointerOffsetInstruction {
* pointer underflow is undefined.
*/
class PointerSubInstruction extends PointerOffsetInstruction {
- PointerSubInstruction() { getOpcode() instanceof Opcode::PointerSub }
+ PointerSubInstruction() { this.getOpcode() instanceof Opcode::PointerSub }
}
/**
@@ -1241,31 +1254,31 @@ class PointerSubInstruction extends PointerOffsetInstruction {
* undefined.
*/
class PointerDiffInstruction extends PointerArithmeticInstruction {
- PointerDiffInstruction() { getOpcode() instanceof Opcode::PointerDiff }
+ PointerDiffInstruction() { this.getOpcode() instanceof Opcode::PointerDiff }
}
/**
* An instruction whose result is computed from a single operand.
*/
class UnaryInstruction extends Instruction {
- UnaryInstruction() { getOpcode() instanceof UnaryOpcode }
+ UnaryInstruction() { this.getOpcode() instanceof UnaryOpcode }
/**
* Gets the sole operand of this instruction.
*/
- final UnaryOperand getUnaryOperand() { result = getAnOperand() }
+ final UnaryOperand getUnaryOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the sole operand of this instruction.
*/
- final Instruction getUnary() { result = getUnaryOperand().getDef() }
+ final Instruction getUnary() { result = this.getUnaryOperand().getDef() }
}
/**
* An instruction that converts the value of its operand to a value of a different type.
*/
class ConvertInstruction extends UnaryInstruction {
- ConvertInstruction() { getOpcode() instanceof Opcode::Convert }
+ ConvertInstruction() { this.getOpcode() instanceof Opcode::Convert }
}
/**
@@ -1279,7 +1292,7 @@ class ConvertInstruction extends UnaryInstruction {
* `as` expression.
*/
class CheckedConvertOrNullInstruction extends UnaryInstruction {
- CheckedConvertOrNullInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrNull }
+ CheckedConvertOrNullInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrNull }
}
/**
@@ -1293,7 +1306,7 @@ class CheckedConvertOrNullInstruction extends UnaryInstruction {
* expression.
*/
class CheckedConvertOrThrowInstruction extends UnaryInstruction {
- CheckedConvertOrThrowInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrThrow }
+ CheckedConvertOrThrowInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrThrow }
}
/**
@@ -1306,7 +1319,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {
- CompleteObjectAddressInstruction() { getOpcode() instanceof Opcode::CompleteObjectAddress }
+ CompleteObjectAddressInstruction() { this.getOpcode() instanceof Opcode::CompleteObjectAddress }
}
/**
@@ -1351,7 +1364,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* An instruction that converts from the address of a derived class to the address of a base class.
*/
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
- ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode }
+ ConvertToBaseInstruction() { this.getOpcode() instanceof ConvertToBaseOpcode }
}
/**
@@ -1361,7 +1374,9 @@ class ConvertToBaseInstruction extends InheritanceConversionInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase }
+ ConvertToNonVirtualBaseInstruction() {
+ this.getOpcode() instanceof Opcode::ConvertToNonVirtualBase
+ }
}
/**
@@ -1371,7 +1386,7 @@ class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase }
+ ConvertToVirtualBaseInstruction() { this.getOpcode() instanceof Opcode::ConvertToVirtualBase }
}
/**
@@ -1381,7 +1396,7 @@ class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
- ConvertToDerivedInstruction() { getOpcode() instanceof Opcode::ConvertToDerived }
+ ConvertToDerivedInstruction() { this.getOpcode() instanceof Opcode::ConvertToDerived }
}
/**
@@ -1390,7 +1405,7 @@ class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
* The operand must have an integer type, which will also be the result type.
*/
class BitComplementInstruction extends UnaryBitwiseInstruction {
- BitComplementInstruction() { getOpcode() instanceof Opcode::BitComplement }
+ BitComplementInstruction() { this.getOpcode() instanceof Opcode::BitComplement }
}
/**
@@ -1399,14 +1414,14 @@ class BitComplementInstruction extends UnaryBitwiseInstruction {
* The operand must have a Boolean type, which will also be the result type.
*/
class LogicalNotInstruction extends UnaryInstruction {
- LogicalNotInstruction() { getOpcode() instanceof Opcode::LogicalNot }
+ LogicalNotInstruction() { this.getOpcode() instanceof Opcode::LogicalNot }
}
/**
* An instruction that compares two numeric operands.
*/
class CompareInstruction extends BinaryInstruction {
- CompareInstruction() { getOpcode() instanceof CompareOpcode }
+ CompareInstruction() { this.getOpcode() instanceof CompareOpcode }
}
/**
@@ -1417,7 +1432,7 @@ class CompareInstruction extends BinaryInstruction {
* unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareEQInstruction extends CompareInstruction {
- CompareEQInstruction() { getOpcode() instanceof Opcode::CompareEQ }
+ CompareEQInstruction() { this.getOpcode() instanceof Opcode::CompareEQ }
}
/**
@@ -1428,14 +1443,14 @@ class CompareEQInstruction extends CompareInstruction {
* `left == right`. Floating-point comparison is performed according to IEEE-754.
*/
class CompareNEInstruction extends CompareInstruction {
- CompareNEInstruction() { getOpcode() instanceof Opcode::CompareNE }
+ CompareNEInstruction() { this.getOpcode() instanceof Opcode::CompareNE }
}
/**
* An instruction that does a relative comparison of two values, such as `<` or `>=`.
*/
class RelationalInstruction extends CompareInstruction {
- RelationalInstruction() { getOpcode() instanceof RelationalOpcode }
+ RelationalInstruction() { this.getOpcode() instanceof RelationalOpcode }
/**
* Gets the operand on the "greater" (or "greater-or-equal") side
@@ -1467,11 +1482,11 @@ class RelationalInstruction extends CompareInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLTInstruction extends RelationalInstruction {
- CompareLTInstruction() { getOpcode() instanceof Opcode::CompareLT }
+ CompareLTInstruction() { this.getOpcode() instanceof Opcode::CompareLT }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { any() }
}
@@ -1484,11 +1499,11 @@ class CompareLTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGTInstruction extends RelationalInstruction {
- CompareGTInstruction() { getOpcode() instanceof Opcode::CompareGT }
+ CompareGTInstruction() { this.getOpcode() instanceof Opcode::CompareGT }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { any() }
}
@@ -1502,11 +1517,11 @@ class CompareGTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLEInstruction extends RelationalInstruction {
- CompareLEInstruction() { getOpcode() instanceof Opcode::CompareLE }
+ CompareLEInstruction() { this.getOpcode() instanceof Opcode::CompareLE }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { none() }
}
@@ -1520,11 +1535,11 @@ class CompareLEInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGEInstruction extends RelationalInstruction {
- CompareGEInstruction() { getOpcode() instanceof Opcode::CompareGE }
+ CompareGEInstruction() { this.getOpcode() instanceof Opcode::CompareGE }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { none() }
}
@@ -1543,78 +1558,78 @@ class CompareGEInstruction extends RelationalInstruction {
* of any case edge.
*/
class SwitchInstruction extends Instruction {
- SwitchInstruction() { getOpcode() instanceof Opcode::Switch }
+ SwitchInstruction() { this.getOpcode() instanceof Opcode::Switch }
/** Gets the operand that provides the integer value controlling the switch. */
- final ConditionOperand getExpressionOperand() { result = getAnOperand() }
+ final ConditionOperand getExpressionOperand() { result = this.getAnOperand() }
/** Gets the instruction whose result provides the integer value controlling the switch. */
- final Instruction getExpression() { result = getExpressionOperand().getDef() }
+ final Instruction getExpression() { result = this.getExpressionOperand().getDef() }
/** Gets the successor instructions along the case edges of the switch. */
- final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }
+ final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = this.getSuccessor(edge)) }
/** Gets the successor instruction along the default edge of the switch, if any. */
- final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
+ final Instruction getDefaultSuccessor() { result = this.getSuccessor(EdgeKind::defaultEdge()) }
}
/**
* An instruction that calls a function.
*/
class CallInstruction extends Instruction {
- CallInstruction() { getOpcode() instanceof Opcode::Call }
+ CallInstruction() { this.getOpcode() instanceof Opcode::Call }
final override string getImmediateString() {
- result = getStaticCallTarget().toString()
+ result = this.getStaticCallTarget().toString()
or
- not exists(getStaticCallTarget()) and result = "?"
+ not exists(this.getStaticCallTarget()) and result = "?"
}
/**
* Gets the operand the specifies the target function of the call.
*/
- final CallTargetOperand getCallTargetOperand() { result = getAnOperand() }
+ final CallTargetOperand getCallTargetOperand() { result = this.getAnOperand() }
/**
* Gets the `Instruction` that computes the target function of the call. This is usually a
* `FunctionAddress` instruction, but can also be an arbitrary instruction that produces a
* function pointer.
*/
- final Instruction getCallTarget() { result = getCallTargetOperand().getDef() }
+ final Instruction getCallTarget() { result = this.getCallTargetOperand().getDef() }
/**
* Gets all of the argument operands of the call, including the `this` pointer, if any.
*/
- final ArgumentOperand getAnArgumentOperand() { result = getAnOperand() }
+ final ArgumentOperand getAnArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
final Language::Function getStaticCallTarget() {
- result = getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
+ result = this.getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
}
/**
* Gets all of the arguments of the call, including the `this` pointer, if any.
*/
- final Instruction getAnArgument() { result = getAnArgumentOperand().getDef() }
+ final Instruction getAnArgument() { result = this.getAnArgumentOperand().getDef() }
/**
* Gets the `this` pointer argument operand of the call, if any.
*/
- final ThisArgumentOperand getThisArgumentOperand() { result = getAnOperand() }
+ final ThisArgumentOperand getThisArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `this` pointer argument of the call, if any.
*/
- final Instruction getThisArgument() { result = getThisArgumentOperand().getDef() }
+ final Instruction getThisArgument() { result = this.getThisArgumentOperand().getDef() }
/**
* Gets the argument operand at the specified index.
*/
pragma[noinline]
final PositionalArgumentOperand getPositionalArgumentOperand(int index) {
- result = getAnOperand() and
+ result = this.getAnOperand() and
result.getIndex() = index
}
@@ -1623,7 +1638,7 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final Instruction getPositionalArgument(int index) {
- result = getPositionalArgumentOperand(index).getDef()
+ result = this.getPositionalArgumentOperand(index).getDef()
}
/**
@@ -1631,16 +1646,16 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final ArgumentOperand getArgumentOperand(int index) {
- index >= 0 and result = getPositionalArgumentOperand(index)
+ index >= 0 and result = this.getPositionalArgumentOperand(index)
or
- index = -1 and result = getThisArgumentOperand()
+ index = -1 and result = this.getThisArgumentOperand()
}
/**
* Gets the argument at the specified index, or `this` if `index` is `-1`.
*/
pragma[noinline]
- final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() }
+ final Instruction getArgument(int index) { result = this.getArgumentOperand(index).getDef() }
/**
* Gets the number of arguments of the call, including the `this` pointer, if any.
@@ -1665,7 +1680,7 @@ class CallInstruction extends Instruction {
* An instruction representing a side effect of a function call.
*/
class SideEffectInstruction extends Instruction {
- SideEffectInstruction() { getOpcode() instanceof SideEffectOpcode }
+ SideEffectInstruction() { this.getOpcode() instanceof SideEffectOpcode }
/**
* Gets the instruction whose execution causes this side effect.
@@ -1680,7 +1695,7 @@ class SideEffectInstruction extends Instruction {
* accessed by that call.
*/
class CallSideEffectInstruction extends SideEffectInstruction {
- CallSideEffectInstruction() { getOpcode() instanceof Opcode::CallSideEffect }
+ CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
}
/**
@@ -1691,7 +1706,7 @@ class CallSideEffectInstruction extends SideEffectInstruction {
* call target cannot write to escaped memory.
*/
class CallReadSideEffectInstruction extends SideEffectInstruction {
- CallReadSideEffectInstruction() { getOpcode() instanceof Opcode::CallReadSideEffect }
+ CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
}
/**
@@ -1699,33 +1714,33 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
* specific parameter.
*/
class ReadSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- ReadSideEffectInstruction() { getOpcode() instanceof ReadSideEffectOpcode }
+ ReadSideEffectInstruction() { this.getOpcode() instanceof ReadSideEffectOpcode }
/** Gets the operand for the value that will be read from this instruction, if known. */
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/** Gets the value that will be read from this instruction, if known. */
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/** Gets the operand for the address from which this instruction may read. */
- final AddressOperand getArgumentOperand() { result = getAnOperand() }
+ final AddressOperand getArgumentOperand() { result = this.getAnOperand() }
/** Gets the address from which this instruction may read. */
- final Instruction getArgumentDef() { result = getArgumentOperand().getDef() }
+ final Instruction getArgumentDef() { result = this.getArgumentOperand().getDef() }
}
/**
* An instruction representing the read of an indirect parameter within a function call.
*/
class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
- IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
+ IndirectReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::IndirectReadSideEffect }
}
/**
* An instruction representing the read of an indirect buffer parameter within a function call.
*/
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
- BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
+ BufferReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::BufferReadSideEffect }
}
/**
@@ -1733,18 +1748,18 @@ class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
*/
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
SizedBufferReadSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferReadSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferReadSideEffect
}
/**
* Gets the operand that holds the number of bytes read from the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes read from the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1752,17 +1767,17 @@ class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
* specific parameter.
*/
class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
+ WriteSideEffectInstruction() { this.getOpcode() instanceof WriteSideEffectOpcode }
/**
* Get the operand that holds the address of the memory to be written.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the memory to be written.
*/
- Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ Instruction getDestinationAddress() { result = this.getDestinationAddressOperand().getDef() }
}
/**
@@ -1770,7 +1785,7 @@ class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstructi
*/
class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
}
}
@@ -1780,7 +1795,7 @@ class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction
*/
class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
BufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::BufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::BufferMustWriteSideEffect
}
}
@@ -1790,18 +1805,18 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1812,7 +1827,7 @@ class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstructi
*/
class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
}
}
@@ -1822,7 +1837,9 @@ class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
* Unlike `BufferWriteSideEffectInstruction`, the buffer might not be completely overwritten.
*/
class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
- BufferMayWriteSideEffectInstruction() { getOpcode() instanceof Opcode::BufferMayWriteSideEffect }
+ BufferMayWriteSideEffectInstruction() {
+ this.getOpcode() instanceof Opcode::BufferMayWriteSideEffect
+ }
}
/**
@@ -1832,18 +1849,18 @@ class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1852,80 +1869,80 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio
*/
class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
InitializeDynamicAllocationInstruction() {
- getOpcode() instanceof Opcode::InitializeDynamicAllocation
+ this.getOpcode() instanceof Opcode::InitializeDynamicAllocation
}
/**
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
- final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getAllocationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address for the allocation this instruction is initializing.
*/
- final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
+ final Instruction getAllocationAddress() { result = this.getAllocationAddressOperand().getDef() }
}
/**
* An instruction representing a GNU or MSVC inline assembly statement.
*/
class InlineAsmInstruction extends Instruction {
- InlineAsmInstruction() { getOpcode() instanceof Opcode::InlineAsm }
+ InlineAsmInstruction() { this.getOpcode() instanceof Opcode::InlineAsm }
}
/**
* An instruction that throws an exception.
*/
class ThrowInstruction extends Instruction {
- ThrowInstruction() { getOpcode() instanceof ThrowOpcode }
+ ThrowInstruction() { this.getOpcode() instanceof ThrowOpcode }
}
/**
* An instruction that throws a new exception.
*/
class ThrowValueInstruction extends ThrowInstruction {
- ThrowValueInstruction() { getOpcode() instanceof Opcode::ThrowValue }
+ ThrowValueInstruction() { this.getOpcode() instanceof Opcode::ThrowValue }
/**
* Gets the address operand of the exception thrown by this instruction.
*/
- final AddressOperand getExceptionAddressOperand() { result = getAnOperand() }
+ final AddressOperand getExceptionAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address of the exception thrown by this instruction.
*/
- final Instruction getExceptionAddress() { result = getExceptionAddressOperand().getDef() }
+ final Instruction getExceptionAddress() { result = this.getExceptionAddressOperand().getDef() }
/**
* Gets the operand for the exception thrown by this instruction.
*/
- final LoadOperand getExceptionOperand() { result = getAnOperand() }
+ final LoadOperand getExceptionOperand() { result = this.getAnOperand() }
/**
* Gets the exception thrown by this instruction.
*/
- final Instruction getException() { result = getExceptionOperand().getDef() }
+ final Instruction getException() { result = this.getExceptionOperand().getDef() }
}
/**
* An instruction that re-throws the current exception.
*/
class ReThrowInstruction extends ThrowInstruction {
- ReThrowInstruction() { getOpcode() instanceof Opcode::ReThrow }
+ ReThrowInstruction() { this.getOpcode() instanceof Opcode::ReThrow }
}
/**
* An instruction that exits the current function by propagating an exception.
*/
class UnwindInstruction extends Instruction {
- UnwindInstruction() { getOpcode() instanceof Opcode::Unwind }
+ UnwindInstruction() { this.getOpcode() instanceof Opcode::Unwind }
}
/**
* An instruction that starts a `catch` handler.
*/
class CatchInstruction extends Instruction {
- CatchInstruction() { getOpcode() instanceof CatchOpcode }
+ CatchInstruction() { this.getOpcode() instanceof CatchOpcode }
}
/**
@@ -1935,7 +1952,7 @@ class CatchByTypeInstruction extends CatchInstruction {
Language::LanguageType exceptionType;
CatchByTypeInstruction() {
- getOpcode() instanceof Opcode::CatchByType and
+ this.getOpcode() instanceof Opcode::CatchByType and
exceptionType = Raw::getInstructionExceptionType(this)
}
@@ -1951,21 +1968,21 @@ class CatchByTypeInstruction extends CatchInstruction {
* An instruction that catches any exception.
*/
class CatchAnyInstruction extends CatchInstruction {
- CatchAnyInstruction() { getOpcode() instanceof Opcode::CatchAny }
+ CatchAnyInstruction() { this.getOpcode() instanceof Opcode::CatchAny }
}
/**
* An instruction that initializes all escaped memory.
*/
class AliasedDefinitionInstruction extends Instruction {
- AliasedDefinitionInstruction() { getOpcode() instanceof Opcode::AliasedDefinition }
+ AliasedDefinitionInstruction() { this.getOpcode() instanceof Opcode::AliasedDefinition }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
- AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
+ AliasedUseInstruction() { this.getOpcode() instanceof Opcode::AliasedUse }
}
/**
@@ -1979,7 +1996,7 @@ class AliasedUseInstruction extends Instruction {
* runtime.
*/
class PhiInstruction extends Instruction {
- PhiInstruction() { getOpcode() instanceof Opcode::Phi }
+ PhiInstruction() { this.getOpcode() instanceof Opcode::Phi }
/**
* Gets all of the instruction's `PhiInputOperand`s, representing the values that flow from each predecessor block.
@@ -2047,29 +2064,29 @@ class PhiInstruction extends Instruction {
* https://link.springer.com/content/pdf/10.1007%2F3-540-61053-7_66.pdf.
*/
class ChiInstruction extends Instruction {
- ChiInstruction() { getOpcode() instanceof Opcode::Chi }
+ ChiInstruction() { this.getOpcode() instanceof Opcode::Chi }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final ChiTotalOperand getTotalOperand() { result = getAnOperand() }
+ final ChiTotalOperand getTotalOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final Instruction getTotal() { result = getTotalOperand().getDef() }
+ final Instruction getTotal() { result = this.getTotalOperand().getDef() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final ChiPartialOperand getPartialOperand() { result = getAnOperand() }
+ final ChiPartialOperand getPartialOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final Instruction getPartial() { result = getPartialOperand().getDef() }
+ final Instruction getPartial() { result = this.getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
@@ -2093,7 +2110,7 @@ class ChiInstruction extends Instruction {
* or `Switch` instruction where that particular edge is infeasible.
*/
class UnreachedInstruction extends Instruction {
- UnreachedInstruction() { getOpcode() instanceof Opcode::Unreached }
+ UnreachedInstruction() { this.getOpcode() instanceof Opcode::Unreached }
}
/**
@@ -2106,7 +2123,7 @@ class BuiltInOperationInstruction extends Instruction {
Language::BuiltInOperation operation;
BuiltInOperationInstruction() {
- getOpcode() instanceof BuiltInOperationOpcode and
+ this.getOpcode() instanceof BuiltInOperationOpcode and
operation = Raw::getInstructionBuiltInOperation(this)
}
@@ -2122,9 +2139,9 @@ class BuiltInOperationInstruction extends Instruction {
* actual operation is specified by the `getBuiltInOperation()` predicate.
*/
class BuiltInInstruction extends BuiltInOperationInstruction {
- BuiltInInstruction() { getOpcode() instanceof Opcode::BuiltIn }
+ BuiltInInstruction() { this.getOpcode() instanceof Opcode::BuiltIn }
- final override string getImmediateString() { result = getBuiltInOperation().toString() }
+ final override string getImmediateString() { result = this.getBuiltInOperation().toString() }
}
/**
@@ -2135,7 +2152,7 @@ class BuiltInInstruction extends BuiltInOperationInstruction {
* to the `...` parameter.
*/
class VarArgsStartInstruction extends UnaryInstruction {
- VarArgsStartInstruction() { getOpcode() instanceof Opcode::VarArgsStart }
+ VarArgsStartInstruction() { this.getOpcode() instanceof Opcode::VarArgsStart }
}
/**
@@ -2145,7 +2162,7 @@ class VarArgsStartInstruction extends UnaryInstruction {
* a result.
*/
class VarArgsEndInstruction extends UnaryInstruction {
- VarArgsEndInstruction() { getOpcode() instanceof Opcode::VarArgsEnd }
+ VarArgsEndInstruction() { this.getOpcode() instanceof Opcode::VarArgsEnd }
}
/**
@@ -2155,7 +2172,7 @@ class VarArgsEndInstruction extends UnaryInstruction {
* argument.
*/
class VarArgInstruction extends UnaryInstruction {
- VarArgInstruction() { getOpcode() instanceof Opcode::VarArg }
+ VarArgInstruction() { this.getOpcode() instanceof Opcode::VarArg }
}
/**
@@ -2166,7 +2183,7 @@ class VarArgInstruction extends UnaryInstruction {
* argument of the `...` parameter.
*/
class NextVarArgInstruction extends UnaryInstruction {
- NextVarArgInstruction() { getOpcode() instanceof Opcode::NextVarArg }
+ NextVarArgInstruction() { this.getOpcode() instanceof Opcode::NextVarArg }
}
/**
@@ -2180,5 +2197,5 @@ class NextVarArgInstruction extends UnaryInstruction {
* The result is the address of the newly allocated object.
*/
class NewObjInstruction extends Instruction {
- NewObjInstruction() { getOpcode() instanceof Opcode::NewObj }
+ NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll
index d7cf89ca9aa..85d217bd361 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Operand.qll
@@ -46,12 +46,12 @@ class Operand extends TStageOperand {
/**
* Gets the location of the source code for this operand.
*/
- final Language::Location getLocation() { result = getUse().getLocation() }
+ final Language::Location getLocation() { result = this.getUse().getLocation() }
/**
* Gets the function that contains this operand.
*/
- final IRFunction getEnclosingIRFunction() { result = getUse().getEnclosingIRFunction() }
+ final IRFunction getEnclosingIRFunction() { result = this.getUse().getEnclosingIRFunction() }
/**
* Gets the `Instruction` that consumes this operand.
@@ -74,7 +74,7 @@ class Operand extends TStageOperand {
*/
final Instruction getDef() {
result = this.getAnyDef() and
- getDefinitionOverlap() instanceof MustExactlyOverlap
+ this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
@@ -82,7 +82,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` that consumes this operand.
*/
- deprecated final Instruction getUseInstruction() { result = getUse() }
+ deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
@@ -91,7 +91,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` whose result is the value of the operand.
*/
- deprecated final Instruction getDefinitionInstruction() { result = getAnyDef() }
+ deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
@@ -101,7 +101,9 @@ class Operand extends TStageOperand {
/**
* Holds if the result of the definition instruction does not exactly overlap this use.
*/
- final predicate isDefinitionInexact() { not getDefinitionOverlap() instanceof MustExactlyOverlap }
+ final predicate isDefinitionInexact() {
+ not this.getDefinitionOverlap() instanceof MustExactlyOverlap
+ }
/**
* Gets a prefix to use when dumping the operand in an operand list.
@@ -121,7 +123,7 @@ class Operand extends TStageOperand {
* For example: `this:r3_5`
*/
final string getDumpString() {
- result = getDumpLabel() + getInexactSpecifier() + getDefinitionId()
+ result = this.getDumpLabel() + this.getInexactSpecifier() + this.getDefinitionId()
}
/**
@@ -129,9 +131,9 @@ class Operand extends TStageOperand {
* definition is not modeled in SSA.
*/
private string getDefinitionId() {
- result = getAnyDef().getResultId()
+ result = this.getAnyDef().getResultId()
or
- not exists(getAnyDef()) and result = "m?"
+ not exists(this.getAnyDef()) and result = "m?"
}
/**
@@ -140,7 +142,7 @@ class Operand extends TStageOperand {
* the empty string.
*/
private string getInexactSpecifier() {
- if isDefinitionInexact() then result = "~" else result = ""
+ if this.isDefinitionInexact() then result = "~" else result = ""
}
/**
@@ -155,7 +157,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- Language::LanguageType getLanguageType() { result = getAnyDef().getResultLanguageType() }
+ Language::LanguageType getLanguageType() { result = this.getAnyDef().getResultLanguageType() }
/**
* Gets the language-neutral type of the value consumed by this operand. This is usually the same
@@ -164,7 +166,7 @@ class Operand extends TStageOperand {
* from the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final IRType getIRType() { result = getLanguageType().getIRType() }
+ final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the value consumed by this operand. This is usually the same as the
@@ -173,7 +175,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final Language::Type getType() { getLanguageType().hasType(result, _) }
+ final Language::Type getType() { this.getLanguageType().hasType(result, _) }
/**
* Holds if the value consumed by this operand is a glvalue. If this
@@ -182,13 +184,13 @@ class Operand extends TStageOperand {
* not hold, the value of the operand represents a value whose type is
* given by `getType()`.
*/
- final predicate isGLValue() { getLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getLanguageType().hasType(_, true) }
/**
* Gets the size of the value consumed by this operand, in bytes. If the operand does not have
* a known constant size, this predicate does not hold.
*/
- final int getSize() { result = getLanguageType().getByteSize() }
+ final int getSize() { result = this.getLanguageType().getByteSize() }
}
/**
@@ -205,7 +207,7 @@ class MemoryOperand extends Operand {
/**
* Gets the kind of memory access performed by the operand.
*/
- MemoryAccessKind getMemoryAccess() { result = getUse().getOpcode().getReadMemoryAccess() }
+ MemoryAccessKind getMemoryAccess() { result = this.getUse().getOpcode().getReadMemoryAccess() }
/**
* Holds if the memory access performed by this operand will not always read from every bit in the
@@ -215,7 +217,7 @@ class MemoryOperand extends Operand {
* conservative estimate of the memory that might actually be accessed at runtime (for example,
* the global side effects of a function call).
*/
- predicate hasMayReadMemoryAccess() { getUse().getOpcode().hasMayReadMemoryAccess() }
+ predicate hasMayReadMemoryAccess() { this.getUse().getOpcode().hasMayReadMemoryAccess() }
/**
* Returns the operand that holds the memory address from which the current operand loads its
@@ -223,8 +225,8 @@ class MemoryOperand extends Operand {
* is `r1`.
*/
final AddressOperand getAddressOperand() {
- getMemoryAccess().usesAddressOperand() and
- result.getUse() = getUse()
+ this.getMemoryAccess().usesAddressOperand() and
+ result.getUse() = this.getUse()
}
}
@@ -294,7 +296,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
- final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
+ final override Overlap getDefinitionOverlap() { this.hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
@@ -449,13 +451,17 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
final override Overlap getDefinitionOverlap() { result = overlap }
- final override int getDumpSortOrder() { result = 11 + getPredecessorBlock().getDisplayIndex() }
-
- final override string getDumpLabel() {
- result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
+ final override int getDumpSortOrder() {
+ result = 11 + this.getPredecessorBlock().getDisplayIndex()
}
- final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
+ final override string getDumpLabel() {
+ result = "from " + this.getPredecessorBlock().getDisplayIndex().toString() + ":"
+ }
+
+ final override string getDumpId() {
+ result = this.getPredecessorBlock().getDisplayIndex().toString()
+ }
/**
* Gets the predecessor block from which this value comes.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
index a9f408bf161..3f0f4f10ee3 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
@@ -55,7 +55,7 @@ abstract class TranslatedExpr extends TranslatedElement {
abstract predicate producesExprResult();
final CppType getResultType() {
- if isResultGLValue()
+ if this.isResultGLValue()
then result = getTypeForGLValue(expr.getType())
else result = getTypeForPRValue(expr.getType())
}
@@ -128,9 +128,9 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
TTranslatedConditionValue {
TranslatedConditionValue() { this = TTranslatedConditionValue(expr) }
- override TranslatedElement getChild(int id) { id = 0 and result = getCondition() }
+ override TranslatedElement getChild(int id) { id = 0 and result = this.getCondition() }
- override Instruction getFirstInstruction() { result = getCondition().getFirstInstruction() }
+ override Instruction getFirstInstruction() { result = this.getCondition().getFirstInstruction() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
(
@@ -146,46 +146,46 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
tag = ConditionValueFalseConstantTag()
) and
opcode instanceof Opcode::Constant and
- resultType = getResultType()
+ resultType = this.getResultType()
or
(
tag = ConditionValueTrueStoreTag() or
tag = ConditionValueFalseStoreTag()
) and
opcode instanceof Opcode::Store and
- resultType = getResultType()
+ resultType = this.getResultType()
or
tag = ConditionValueResultLoadTag() and
opcode instanceof Opcode::Load and
- resultType = getResultType()
+ resultType = this.getResultType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
tag = ConditionValueTrueTempAddressTag() and
- result = getInstruction(ConditionValueTrueConstantTag())
+ result = this.getInstruction(ConditionValueTrueConstantTag())
or
tag = ConditionValueTrueConstantTag() and
- result = getInstruction(ConditionValueTrueStoreTag())
+ result = this.getInstruction(ConditionValueTrueStoreTag())
or
tag = ConditionValueTrueStoreTag() and
- result = getInstruction(ConditionValueResultTempAddressTag())
+ result = this.getInstruction(ConditionValueResultTempAddressTag())
or
tag = ConditionValueFalseTempAddressTag() and
- result = getInstruction(ConditionValueFalseConstantTag())
+ result = this.getInstruction(ConditionValueFalseConstantTag())
or
tag = ConditionValueFalseConstantTag() and
- result = getInstruction(ConditionValueFalseStoreTag())
+ result = this.getInstruction(ConditionValueFalseStoreTag())
or
tag = ConditionValueFalseStoreTag() and
- result = getInstruction(ConditionValueResultTempAddressTag())
+ result = this.getInstruction(ConditionValueResultTempAddressTag())
or
tag = ConditionValueResultTempAddressTag() and
- result = getInstruction(ConditionValueResultLoadTag())
+ result = this.getInstruction(ConditionValueResultLoadTag())
or
tag = ConditionValueResultLoadTag() and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
)
}
@@ -193,25 +193,25 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
tag = ConditionValueTrueStoreTag() and
(
operandTag instanceof AddressOperandTag and
- result = getInstruction(ConditionValueTrueTempAddressTag())
+ result = this.getInstruction(ConditionValueTrueTempAddressTag())
or
operandTag instanceof StoreValueOperandTag and
- result = getInstruction(ConditionValueTrueConstantTag())
+ result = this.getInstruction(ConditionValueTrueConstantTag())
)
or
tag = ConditionValueFalseStoreTag() and
(
operandTag instanceof AddressOperandTag and
- result = getInstruction(ConditionValueFalseTempAddressTag())
+ result = this.getInstruction(ConditionValueFalseTempAddressTag())
or
operandTag instanceof StoreValueOperandTag and
- result = getInstruction(ConditionValueFalseConstantTag())
+ result = this.getInstruction(ConditionValueFalseConstantTag())
)
or
tag = ConditionValueResultLoadTag() and
(
operandTag instanceof AddressOperandTag and
- result = getInstruction(ConditionValueResultTempAddressTag())
+ result = this.getInstruction(ConditionValueResultTempAddressTag())
)
}
@@ -226,7 +226,7 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
tag = ConditionValueFalseTempAddressTag() or
tag = ConditionValueResultTempAddressTag()
) and
- result = getTempVariable(ConditionValueTempVar())
+ result = this.getTempVariable(ConditionValueTempVar())
}
override string getInstructionConstantValue(InstructionTag tag) {
@@ -235,18 +235,18 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
tag = ConditionValueFalseConstantTag() and result = "0"
}
- override Instruction getResult() { result = getInstruction(ConditionValueResultLoadTag()) }
+ override Instruction getResult() { result = this.getInstruction(ConditionValueResultLoadTag()) }
override Instruction getChildSuccessor(TranslatedElement child) { none() }
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
- child = getCondition() and
- result = getInstruction(ConditionValueTrueTempAddressTag())
+ child = this.getCondition() and
+ result = this.getInstruction(ConditionValueTrueTempAddressTag())
}
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
- child = getCondition() and
- result = getInstruction(ConditionValueFalseTempAddressTag())
+ child = this.getCondition() and
+ result = this.getInstruction(ConditionValueFalseTempAddressTag())
}
private TranslatedCondition getCondition() { result = getTranslatedCondition(expr) }
@@ -260,9 +260,11 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
* temporary variable.
*/
abstract class TranslatedValueCategoryAdjustment extends TranslatedExpr {
- final override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
+ final override Instruction getFirstInstruction() {
+ result = this.getOperand().getFirstInstruction()
+ }
- final override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
final override predicate producesExprResult() {
// A temp object always produces the result of the expression.
@@ -284,28 +286,28 @@ class TranslatedLoad extends TranslatedValueCategoryAdjustment, TTranslatedLoad
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = LoadTag() and
opcode instanceof Opcode::Load and
- resultType = getResultType()
+ resultType = this.getResultType()
}
override predicate isResultGLValue() { none() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = LoadTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getOperand() and result = getInstruction(LoadTag())
+ child = this.getOperand() and result = this.getInstruction(LoadTag())
}
- override Instruction getResult() { result = getInstruction(LoadTag()) }
+ override Instruction getResult() { result = this.getInstruction(LoadTag()) }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = LoadTag() and
(
operandTag instanceof AddressOperandTag and
- result = getOperand().getResult()
+ result = this.getOperand().getResult()
)
}
}
@@ -337,28 +339,28 @@ class TranslatedSyntheticTemporaryObject extends TranslatedValueCategoryAdjustme
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = InitializerVariableAddressTag() and
- result = getInstruction(InitializerStoreTag()) and
+ result = this.getInstruction(InitializerStoreTag()) and
kind instanceof GotoEdge
or
tag = InitializerStoreTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getOperand() and result = getInstruction(InitializerVariableAddressTag())
+ child = this.getOperand() and result = this.getInstruction(InitializerVariableAddressTag())
}
- override Instruction getResult() { result = getInstruction(InitializerVariableAddressTag()) }
+ override Instruction getResult() { result = this.getInstruction(InitializerVariableAddressTag()) }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerStoreTag() and
(
operandTag instanceof AddressOperandTag and
- result = getInstruction(InitializerVariableAddressTag())
+ result = this.getInstruction(InitializerVariableAddressTag())
or
operandTag instanceof StoreValueOperandTag and
- result = getOperand().getResult()
+ result = this.getOperand().getResult()
)
}
@@ -383,32 +385,32 @@ class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy {
override string toString() { result = "Result of " + expr.toString() }
- override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
+ override Instruction getFirstInstruction() { result = this.getOperand().getFirstInstruction() }
- override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
+ override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = ResultCopyTag() and
opcode instanceof Opcode::CopyValue and
- resultType = getOperand().getResultType()
+ resultType = this.getOperand().getResultType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = ResultCopyTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getOperand() and result = getInstruction(ResultCopyTag())
+ child = this.getOperand() and result = this.getInstruction(ResultCopyTag())
}
- override Instruction getResult() { result = getInstruction(ResultCopyTag()) }
+ override Instruction getResult() { result = this.getInstruction(ResultCopyTag()) }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = ResultCopyTag() and
operandTag instanceof UnaryOperandTag and
- result = getOperand().getResult()
+ result = this.getOperand().getResult()
}
final override predicate producesExprResult() { any() }
@@ -419,23 +421,25 @@ class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy {
class TranslatedCommaExpr extends TranslatedNonConstantExpr {
override CommaExpr expr;
- override Instruction getFirstInstruction() { result = getLeftOperand().getFirstInstruction() }
-
- override TranslatedElement getChild(int id) {
- id = 0 and result = getLeftOperand()
- or
- id = 1 and result = getRightOperand()
+ override Instruction getFirstInstruction() {
+ result = this.getLeftOperand().getFirstInstruction()
}
- override Instruction getResult() { result = getRightOperand().getResult() }
+ override TranslatedElement getChild(int id) {
+ id = 0 and result = this.getLeftOperand()
+ or
+ id = 1 and result = this.getRightOperand()
+ }
+
+ override Instruction getResult() { result = this.getRightOperand().getResult() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getLeftOperand() and
- result = getRightOperand().getFirstInstruction()
+ child = this.getLeftOperand() and
+ result = this.getRightOperand().getFirstInstruction()
or
- child = getRightOperand() and result = getParent().getChildSuccessor(this)
+ child = this.getRightOperand() and result = this.getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -462,7 +466,7 @@ private int getElementSize(Type type) {
abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
override CrementOperation expr;
- final override TranslatedElement getChild(int id) { id = 0 and result = getLoadedOperand() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getLoadedOperand() }
final override string getInstructionConstantValue(InstructionTag tag) {
tag = CrementConstantTag() and
@@ -493,10 +497,10 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = CrementConstantTag() and
opcode instanceof Opcode::Constant and
- resultType = getConstantType()
+ resultType = this.getConstantType()
or
tag = CrementOpTag() and
- opcode = getOpcode() and
+ opcode = this.getOpcode() and
resultType = getTypeForPRValue(expr.getType())
or
tag = CrementStoreTag() and
@@ -508,49 +512,49 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
tag = CrementOpTag() and
(
operandTag instanceof LeftOperandTag and
- result = getLoadedOperand().getResult()
+ result = this.getLoadedOperand().getResult()
or
operandTag instanceof RightOperandTag and
- result = getInstruction(CrementConstantTag())
+ result = this.getInstruction(CrementConstantTag())
)
or
tag = CrementStoreTag() and
(
operandTag instanceof AddressOperandTag and
- result = getUnloadedOperand().getResult()
+ result = this.getUnloadedOperand().getResult()
or
operandTag instanceof StoreValueOperandTag and
- result = getInstruction(CrementOpTag())
+ result = this.getInstruction(CrementOpTag())
)
}
final override Instruction getFirstInstruction() {
- result = getLoadedOperand().getFirstInstruction()
+ result = this.getLoadedOperand().getFirstInstruction()
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
tag = CrementConstantTag() and
- result = getInstruction(CrementOpTag())
+ result = this.getInstruction(CrementOpTag())
or
tag = CrementOpTag() and
- result = getInstruction(CrementStoreTag())
+ result = this.getInstruction(CrementStoreTag())
or
tag = CrementStoreTag() and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getLoadedOperand() and result = getInstruction(CrementConstantTag())
+ child = this.getLoadedOperand() and result = this.getInstruction(CrementConstantTag())
}
final override int getInstructionElementSize(InstructionTag tag) {
tag = CrementOpTag() and
(
- getOpcode() instanceof Opcode::PointerAdd or
- getOpcode() instanceof Opcode::PointerSub
+ this.getOpcode() instanceof Opcode::PointerAdd or
+ this.getOpcode() instanceof Opcode::PointerSub
) and
result = getElementSize(expr.getType())
}
@@ -567,7 +571,7 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
/**
* Gets the address to which the result of this crement will be stored.
*/
- final TranslatedExpr getUnloadedOperand() { result = getLoadedOperand().getOperand() }
+ final TranslatedExpr getUnloadedOperand() { result = this.getLoadedOperand().getOperand() }
final Opcode getOpcode() {
exists(Type resultType |
@@ -601,18 +605,18 @@ class TranslatedPrefixCrementOperation extends TranslatedCrementOperation {
// new value assigned to the operand. If this is C++, then the result is
// an lvalue, but that lvalue is being loaded as part of this expression.
// EDG doesn't mark this as a load.
- result = getInstruction(CrementOpTag())
+ result = this.getInstruction(CrementOpTag())
else
// This is C++, where the result is an lvalue for the operand, and that
// lvalue is not being loaded as part of this expression.
- result = getUnloadedOperand().getResult()
+ result = this.getUnloadedOperand().getResult()
}
}
class TranslatedPostfixCrementOperation extends TranslatedCrementOperation {
override PostfixCrementOperation expr;
- override Instruction getResult() { result = getLoadedOperand().getResult() }
+ override Instruction getResult() { result = this.getLoadedOperand().getResult() }
}
/**
@@ -624,30 +628,30 @@ class TranslatedArrayExpr extends TranslatedNonConstantExpr {
override ArrayExpr expr;
final override Instruction getFirstInstruction() {
- result = getBaseOperand().getFirstInstruction()
+ result = this.getBaseOperand().getFirstInstruction()
}
final override TranslatedElement getChild(int id) {
- id = 0 and result = getBaseOperand()
+ id = 0 and result = this.getBaseOperand()
or
- id = 1 and result = getOffsetOperand()
+ id = 1 and result = this.getOffsetOperand()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getBaseOperand() and
- result = getOffsetOperand().getFirstInstruction()
+ child = this.getBaseOperand() and
+ result = this.getOffsetOperand().getFirstInstruction()
or
- child = getOffsetOperand() and
- result = getInstruction(OnlyInstructionTag())
+ child = this.getOffsetOperand() and
+ result = this.getInstruction(OnlyInstructionTag())
}
- override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
+ override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -659,10 +663,10 @@ class TranslatedArrayExpr extends TranslatedNonConstantExpr {
tag = OnlyInstructionTag() and
(
operandTag instanceof LeftOperandTag and
- result = getBaseOperand().getResult()
+ result = this.getBaseOperand().getResult()
or
operandTag instanceof RightOperandTag and
- result = getOffsetOperand().getResult()
+ result = this.getOffsetOperand().getResult()
)
}
@@ -681,21 +685,23 @@ class TranslatedArrayExpr extends TranslatedNonConstantExpr {
}
abstract class TranslatedTransparentExpr extends TranslatedNonConstantExpr {
- final override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
+ final override Instruction getFirstInstruction() {
+ result = this.getOperand().getFirstInstruction()
+ }
- final override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getOperand() and result = getParent().getChildSuccessor(this)
+ child = this.getOperand() and result = this.getParent().getChildSuccessor(this)
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
}
- final override Instruction getResult() { result = getOperand().getResult() }
+ final override Instruction getResult() { result = this.getOperand().getResult() }
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
none()
@@ -749,21 +755,23 @@ class TranslatedThisExpr extends TranslatedNonConstantExpr {
or
tag = ThisLoadTag() and
opcode instanceof Opcode::Load and
- resultType = getResultType()
+ resultType = this.getResultType()
}
- final override Instruction getResult() { result = getInstruction(ThisLoadTag()) }
+ final override Instruction getResult() { result = this.getInstruction(ThisLoadTag()) }
- final override Instruction getFirstInstruction() { result = getInstruction(ThisAddressTag()) }
+ final override Instruction getFirstInstruction() {
+ result = this.getInstruction(ThisAddressTag())
+ }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
tag = ThisAddressTag() and
- result = getInstruction(ThisLoadTag())
+ result = this.getInstruction(ThisLoadTag())
or
kind instanceof GotoEdge and
tag = ThisLoadTag() and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
final override Instruction getChildSuccessor(TranslatedElement child) { none() }
@@ -771,7 +779,7 @@ class TranslatedThisExpr extends TranslatedNonConstantExpr {
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = ThisLoadTag() and
operandTag instanceof AddressOperandTag and
- result = getInstruction(ThisAddressTag())
+ result = this.getInstruction(ThisAddressTag())
}
override IRVariable getInstructionVariable(InstructionTag tag) {
@@ -784,23 +792,23 @@ abstract class TranslatedVariableAccess extends TranslatedNonConstantExpr {
override VariableAccess expr;
final override TranslatedElement getChild(int id) {
- id = 0 and result = getQualifier() // Might not exist
+ id = 0 and result = this.getQualifier() // Might not exist
}
final TranslatedExpr getQualifier() {
result = getTranslatedExpr(expr.getQualifier().getFullyConverted())
}
- override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
+ override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getQualifier() and result = getInstruction(OnlyInstructionTag())
+ child = this.getQualifier() and result = this.getInstruction(OnlyInstructionTag())
}
}
@@ -808,9 +816,9 @@ class TranslatedNonFieldVariableAccess extends TranslatedVariableAccess {
TranslatedNonFieldVariableAccess() { not expr instanceof FieldAccess }
override Instruction getFirstInstruction() {
- if exists(getQualifier())
- then result = getQualifier().getFirstInstruction()
- else result = getInstruction(OnlyInstructionTag())
+ if exists(this.getQualifier())
+ then result = this.getQualifier().getFirstInstruction()
+ else result = this.getInstruction(OnlyInstructionTag())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -832,12 +840,12 @@ class TranslatedNonFieldVariableAccess extends TranslatedVariableAccess {
class TranslatedFieldAccess extends TranslatedVariableAccess {
override FieldAccess expr;
- override Instruction getFirstInstruction() { result = getQualifier().getFirstInstruction() }
+ override Instruction getFirstInstruction() { result = this.getQualifier().getFirstInstruction() }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
- result = getQualifier().getResult()
+ result = this.getQualifier().getResult()
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -857,20 +865,20 @@ class TranslatedFunctionAccess extends TranslatedNonConstantExpr {
override TranslatedElement getChild(int id) { none() }
- override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
+ override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
- override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
+ override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
opcode instanceof Opcode::FunctionAddress and
- resultType = getResultType()
+ resultType = this.getResultType()
}
override Function getInstructionFunction(InstructionTag tag) {
@@ -902,11 +910,13 @@ abstract class TranslatedConstantExpr extends TranslatedCoreExpr, TTranslatedVal
isIRConstant(expr)
}
- final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getFirstInstruction() {
+ result = this.getInstruction(OnlyInstructionTag())
+ }
final override TranslatedElement getChild(int id) { none() }
- final override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
none()
@@ -914,13 +924,13 @@ abstract class TranslatedConstantExpr extends TranslatedCoreExpr, TTranslatedVal
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
- opcode = getOpcode() and
- resultType = getResultType()
+ opcode = this.getOpcode() and
+ resultType = this.getResultType()
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
@@ -962,12 +972,12 @@ abstract class TranslatedSingleInstructionExpr extends TranslatedNonConstantExpr
abstract Opcode getOpcode();
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
- opcode = getOpcode() and
+ opcode = this.getOpcode() and
tag = OnlyInstructionTag() and
- resultType = getResultType()
+ resultType = this.getResultType()
}
- final override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
}
class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr {
@@ -978,23 +988,25 @@ class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr {
expr instanceof UnaryMinusExpr
}
- final override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
+ final override Instruction getFirstInstruction() {
+ result = this.getOperand().getFirstInstruction()
+ }
- final override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getOperand() and result = getInstruction(OnlyInstructionTag())
+ child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
- result = getOperand().getResult() and
+ result = this.getOperand().getResult() and
operandTag instanceof UnaryOperandTag
}
@@ -1016,9 +1028,9 @@ class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr {
abstract class TranslatedConversion extends TranslatedNonConstantExpr {
override Conversion expr;
- override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
+ override Instruction getFirstInstruction() { result = this.getOperand().getFirstInstruction() }
- final override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
final TranslatedExpr getOperand() { result = getTranslatedExpr(expr.(Conversion).getExpr()) }
}
@@ -1030,26 +1042,26 @@ abstract class TranslatedConversion extends TranslatedNonConstantExpr {
abstract class TranslatedSingleInstructionConversion extends TranslatedConversion {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getOperand() and result = getInstruction(OnlyInstructionTag())
+ child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
- opcode = getOpcode() and
- resultType = getResultType()
+ opcode = this.getOpcode() and
+ resultType = this.getResultType()
}
- override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
+ override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
- result = getOperand().getResult()
+ result = this.getOperand().getResult()
}
/**
@@ -1133,37 +1145,37 @@ class TranslatedBoolConversion extends TranslatedConversion {
kind instanceof GotoEdge and
(
tag = BoolConversionConstantTag() and
- result = getInstruction(BoolConversionCompareTag())
+ result = this.getInstruction(BoolConversionCompareTag())
or
tag = BoolConversionCompareTag() and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
)
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getOperand() and result = getInstruction(BoolConversionConstantTag())
+ child = this.getOperand() and result = this.getInstruction(BoolConversionConstantTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = BoolConversionConstantTag() and
opcode instanceof Opcode::Constant and
- resultType = getOperand().getResultType()
+ resultType = this.getOperand().getResultType()
or
tag = BoolConversionCompareTag() and
opcode instanceof Opcode::CompareNE and
resultType = getBoolType()
}
- override Instruction getResult() { result = getInstruction(BoolConversionCompareTag()) }
+ override Instruction getResult() { result = this.getInstruction(BoolConversionCompareTag()) }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = BoolConversionCompareTag() and
(
operandTag instanceof LeftOperandTag and
- result = getOperand().getResult()
+ result = this.getOperand().getResult()
or
operandTag instanceof RightOperandTag and
- result = getInstruction(BoolConversionConstantTag())
+ result = this.getInstruction(BoolConversionConstantTag())
)
}
@@ -1250,44 +1262,46 @@ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr {
expr instanceof ComparisonOperation
}
- override Instruction getFirstInstruction() { result = getLeftOperand().getFirstInstruction() }
+ override Instruction getFirstInstruction() {
+ result = this.getLeftOperand().getFirstInstruction()
+ }
final override TranslatedElement getChild(int id) {
- id = 0 and result = getLeftOperand()
+ id = 0 and result = this.getLeftOperand()
or
- id = 1 and result = getRightOperand()
+ id = 1 and result = this.getRightOperand()
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
- if swapOperandsOnOp()
+ if this.swapOperandsOnOp()
then (
operandTag instanceof RightOperandTag and
- result = getLeftOperand().getResult()
+ result = this.getLeftOperand().getResult()
or
operandTag instanceof LeftOperandTag and
- result = getRightOperand().getResult()
+ result = this.getRightOperand().getResult()
) else (
operandTag instanceof LeftOperandTag and
- result = getLeftOperand().getResult()
+ result = this.getLeftOperand().getResult()
or
operandTag instanceof RightOperandTag and
- result = getRightOperand().getResult()
+ result = this.getRightOperand().getResult()
)
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getLeftOperand() and
- result = getRightOperand().getFirstInstruction()
+ child = this.getLeftOperand() and
+ result = this.getRightOperand().getFirstInstruction()
or
- child = getRightOperand() and
- result = getInstruction(OnlyInstructionTag())
+ child = this.getRightOperand() and
+ result = this.getInstruction(OnlyInstructionTag())
}
override Opcode getOpcode() {
@@ -1299,18 +1313,20 @@ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr {
override int getInstructionElementSize(InstructionTag tag) {
tag = OnlyInstructionTag() and
exists(Opcode opcode |
- opcode = getOpcode() and
+ opcode = this.getOpcode() and
(
opcode instanceof Opcode::PointerAdd or
opcode instanceof Opcode::PointerSub or
opcode instanceof Opcode::PointerDiff
) and
- result = getElementSize(getPointerOperand().getExpr().getType())
+ result = getElementSize(this.getPointerOperand().getExpr().getType())
)
}
private TranslatedExpr getPointerOperand() {
- if swapOperandsOnOp() then result = getRightOperand() else result = getLeftOperand()
+ if this.swapOperandsOnOp()
+ then result = this.getRightOperand()
+ else result = this.getLeftOperand()
}
private predicate swapOperandsOnOp() {
@@ -1337,14 +1353,14 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
override AssignExpr expr;
final override TranslatedElement getChild(int id) {
- id = 0 and result = getLeftOperand()
+ id = 0 and result = this.getLeftOperand()
or
- id = 1 and result = getRightOperand()
+ id = 1 and result = this.getRightOperand()
}
final override Instruction getFirstInstruction() {
// Evaluation is right-to-left
- result = getRightOperand().getFirstInstruction()
+ result = this.getRightOperand().getFirstInstruction()
}
final override Instruction getResult() {
@@ -1354,11 +1370,11 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
// value assigned to the left operand. If this is C++, then the result is
// an lvalue, but that lvalue is being loaded as part of this expression.
// EDG doesn't mark this as a load.
- result = getRightOperand().getResult()
+ result = this.getRightOperand().getResult()
else
// This is C++, where the result is an lvalue for the left operand,
// and that lvalue is not being loaded as part of this expression.
- result = getLeftOperand().getResult()
+ result = this.getLeftOperand().getResult()
}
abstract Instruction getStoredValue();
@@ -1373,17 +1389,17 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = AssignmentStoreTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
// Operands are evaluated right-to-left.
- child = getRightOperand() and
- result = getLeftOperand().getFirstInstruction()
+ child = this.getRightOperand() and
+ result = this.getLeftOperand().getFirstInstruction()
or
- child = getLeftOperand() and
- result = getInstruction(AssignmentStoreTag())
+ child = this.getLeftOperand() and
+ result = this.getInstruction(AssignmentStoreTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -1396,10 +1412,10 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
tag = AssignmentStoreTag() and
(
operandTag instanceof AddressOperandTag and
- result = getLeftOperand().getResult()
+ result = this.getLeftOperand().getResult()
or
operandTag instanceof StoreValueOperandTag and
- result = getRightOperand().getResult()
+ result = this.getRightOperand().getResult()
)
}
}
@@ -1408,14 +1424,14 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr {
override AssignOperation expr;
final override TranslatedElement getChild(int id) {
- id = 0 and result = getLoadedLeftOperand()
+ id = 0 and result = this.getLoadedLeftOperand()
or
- id = 1 and result = getRightOperand()
+ id = 1 and result = this.getRightOperand()
}
final override Instruction getFirstInstruction() {
// Evaluation is right-to-left
- result = getRightOperand().getFirstInstruction()
+ result = this.getRightOperand().getFirstInstruction()
}
final override Instruction getResult() {
@@ -1425,14 +1441,16 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr {
// value assigned to the left operand. If this is C++, then the result is
// an lvalue, but that lvalue is being loaded as part of this expression.
// EDG doesn't mark this as a load.
- result = getStoredValue()
+ result = this.getStoredValue()
else
// This is C++, where the result is an lvalue for the left operand,
// and that lvalue is not being loaded as part of this expression.
- result = getUnloadedLeftOperand().getResult()
+ result = this.getUnloadedLeftOperand().getResult()
}
- final TranslatedExpr getUnloadedLeftOperand() { result = getLoadedLeftOperand().getOperand() }
+ final TranslatedExpr getUnloadedLeftOperand() {
+ result = this.getLoadedLeftOperand().getOperand()
+ }
/**
* Gets the `TranslatedLoad` on the `e` in this `e += ...` which is the
@@ -1454,38 +1472,38 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr {
kind instanceof GotoEdge and
(
tag = AssignOperationConvertLeftTag() and
- result = getInstruction(AssignOperationOpTag())
+ result = this.getInstruction(AssignOperationOpTag())
or
(
tag = AssignOperationOpTag() and
- if leftOperandNeedsConversion()
- then result = getInstruction(AssignOperationConvertResultTag())
- else result = getInstruction(AssignmentStoreTag())
+ if this.leftOperandNeedsConversion()
+ then result = this.getInstruction(AssignOperationConvertResultTag())
+ else result = this.getInstruction(AssignmentStoreTag())
)
or
tag = AssignOperationConvertResultTag() and
- result = getInstruction(AssignmentStoreTag())
+ result = this.getInstruction(AssignmentStoreTag())
or
tag = AssignmentStoreTag() and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
)
}
override Instruction getChildSuccessor(TranslatedElement child) {
// Operands are evaluated right-to-left.
- child = getRightOperand() and
- result = getLoadedLeftOperand().getFirstInstruction()
+ child = this.getRightOperand() and
+ result = this.getLoadedLeftOperand().getFirstInstruction()
or
- child = getLoadedLeftOperand() and
- if leftOperandNeedsConversion()
- then result = getInstruction(AssignOperationConvertLeftTag())
- else result = getInstruction(AssignOperationOpTag())
+ child = this.getLoadedLeftOperand() and
+ if this.leftOperandNeedsConversion()
+ then result = this.getInstruction(AssignOperationConvertLeftTag())
+ else result = this.getInstruction(AssignOperationOpTag())
}
private Instruction getStoredValue() {
- if leftOperandNeedsConversion()
- then result = getInstruction(AssignOperationConvertResultTag())
- else result = getInstruction(AssignOperationOpTag())
+ if this.leftOperandNeedsConversion()
+ then result = this.getInstruction(AssignOperationConvertResultTag())
+ else result = this.getInstruction(AssignOperationOpTag())
}
private Type getConvertedLeftOperandType() {
@@ -1502,15 +1520,15 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr {
// anyway. If we really want to model this case perfectly, we'll need the
// extractor to tell us what the promoted type of the left operand would
// be.
- result = getLoadedLeftOperand().getExpr().getType()
+ result = this.getLoadedLeftOperand().getExpr().getType()
else
// The right operand has already been converted to the type of the op.
- result = getRightOperand().getExpr().getType()
+ result = this.getRightOperand().getExpr().getType()
}
private predicate leftOperandNeedsConversion() {
- getConvertedLeftOperandType().getUnspecifiedType() !=
- getLoadedLeftOperand().getExpr().getUnspecifiedType()
+ this.getConvertedLeftOperandType().getUnspecifiedType() !=
+ this.getLoadedLeftOperand().getExpr().getUnspecifiedType()
}
private Opcode getOpcode() {
@@ -1541,64 +1559,64 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = AssignOperationOpTag() and
- opcode = getOpcode() and
- resultType = getTypeForPRValue(getConvertedLeftOperandType())
+ opcode = this.getOpcode() and
+ resultType = getTypeForPRValue(this.getConvertedLeftOperandType())
or
tag = AssignmentStoreTag() and
opcode instanceof Opcode::Store and
resultType = getTypeForPRValue(expr.getType()) // Always a prvalue
or
- leftOperandNeedsConversion() and
+ this.leftOperandNeedsConversion() and
opcode instanceof Opcode::Convert and
(
tag = AssignOperationConvertLeftTag() and
- resultType = getTypeForPRValue(getConvertedLeftOperandType())
+ resultType = getTypeForPRValue(this.getConvertedLeftOperandType())
or
tag = AssignOperationConvertResultTag() and
- resultType = getTypeForPRValue(getLoadedLeftOperand().getExpr().getType())
+ resultType = getTypeForPRValue(this.getLoadedLeftOperand().getExpr().getType())
)
}
override int getInstructionElementSize(InstructionTag tag) {
tag = AssignOperationOpTag() and
exists(Opcode opcode |
- opcode = getOpcode() and
+ opcode = this.getOpcode() and
(opcode instanceof Opcode::PointerAdd or opcode instanceof Opcode::PointerSub)
) and
result = getElementSize(expr.getType())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
- leftOperandNeedsConversion() and
+ this.leftOperandNeedsConversion() and
tag = AssignOperationConvertLeftTag() and
operandTag instanceof UnaryOperandTag and
- result = getLoadedLeftOperand().getResult()
+ result = this.getLoadedLeftOperand().getResult()
or
tag = AssignOperationOpTag() and
(
(
operandTag instanceof LeftOperandTag and
- if leftOperandNeedsConversion()
- then result = getInstruction(AssignOperationConvertLeftTag())
- else result = getLoadedLeftOperand().getResult()
+ if this.leftOperandNeedsConversion()
+ then result = this.getInstruction(AssignOperationConvertLeftTag())
+ else result = this.getLoadedLeftOperand().getResult()
)
or
operandTag instanceof RightOperandTag and
- result = getRightOperand().getResult()
+ result = this.getRightOperand().getResult()
)
or
- leftOperandNeedsConversion() and
+ this.leftOperandNeedsConversion() and
tag = AssignOperationConvertResultTag() and
operandTag instanceof UnaryOperandTag and
- result = getInstruction(AssignOperationOpTag())
+ result = this.getInstruction(AssignOperationOpTag())
or
tag = AssignmentStoreTag() and
(
operandTag instanceof AddressOperandTag and
- result = getUnloadedLeftOperand().getResult()
+ result = this.getUnloadedLeftOperand().getResult()
or
operandTag instanceof StoreValueOperandTag and
- result = getStoredValue()
+ result = this.getStoredValue()
)
}
}
@@ -1619,7 +1637,7 @@ abstract class TranslatedAllocationSize extends TranslatedExpr, TTranslatedAlloc
final override predicate producesExprResult() { none() }
- final override Instruction getResult() { result = getInstruction(AllocationSizeTag()) }
+ final override Instruction getResult() { result = this.getInstruction(AllocationSizeTag()) }
}
TranslatedAllocationSize getTranslatedAllocationSize(NewOrNewArrayExpr newExpr) {
@@ -1636,7 +1654,9 @@ TranslatedAllocationSize getTranslatedAllocationSize(NewOrNewArrayExpr newExpr)
class TranslatedConstantAllocationSize extends TranslatedAllocationSize {
TranslatedConstantAllocationSize() { not exists(expr.(NewArrayExpr).getExtent()) }
- final override Instruction getFirstInstruction() { result = getInstruction(AllocationSizeTag()) }
+ final override Instruction getFirstInstruction() {
+ result = this.getInstruction(AllocationSizeTag())
+ }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = AllocationSizeTag() and
@@ -1647,7 +1667,7 @@ class TranslatedConstantAllocationSize extends TranslatedAllocationSize {
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = AllocationSizeTag() and
kind instanceof GotoEdge and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
final override TranslatedElement getChild(int id) { none() }
@@ -1672,7 +1692,9 @@ class TranslatedNonConstantAllocationSize extends TranslatedAllocationSize {
TranslatedNonConstantAllocationSize() { exists(expr.getExtent()) }
- final override Instruction getFirstInstruction() { result = getExtent().getFirstInstruction() }
+ final override Instruction getFirstInstruction() {
+ result = this.getExtent().getFirstInstruction()
+ }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
resultType = getTypeForPRValue(expr.getAllocator().getParameter(0).getType()) and
@@ -1690,21 +1712,21 @@ class TranslatedNonConstantAllocationSize extends TranslatedAllocationSize {
kind instanceof GotoEdge and
(
tag = AllocationExtentConvertTag() and
- result = getInstruction(AllocationElementSizeTag())
+ result = this.getInstruction(AllocationElementSizeTag())
or
tag = AllocationElementSizeTag() and
- result = getInstruction(AllocationSizeTag())
+ result = this.getInstruction(AllocationSizeTag())
or
tag = AllocationSizeTag() and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
)
}
- final override TranslatedElement getChild(int id) { id = 0 and result = getExtent() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getExtent() }
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getExtent() and
- result = getInstruction(AllocationExtentConvertTag())
+ child = this.getExtent() and
+ result = this.getInstruction(AllocationExtentConvertTag())
}
final override string getInstructionConstantValue(InstructionTag tag) {
@@ -1715,14 +1737,16 @@ class TranslatedNonConstantAllocationSize extends TranslatedAllocationSize {
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = AllocationSizeTag() and
(
- operandTag instanceof LeftOperandTag and result = getInstruction(AllocationExtentConvertTag())
+ operandTag instanceof LeftOperandTag and
+ result = this.getInstruction(AllocationExtentConvertTag())
or
- operandTag instanceof RightOperandTag and result = getInstruction(AllocationElementSizeTag())
+ operandTag instanceof RightOperandTag and
+ result = this.getInstruction(AllocationElementSizeTag())
)
or
tag = AllocationExtentConvertTag() and
operandTag instanceof UnaryOperandTag and
- result = getExtent().getResult()
+ result = this.getExtent().getResult()
}
private TranslatedExpr getExtent() {
@@ -1806,7 +1830,7 @@ abstract class StructorCallContext extends TranslatedElement {
class TranslatedDestructorFieldDestruction extends TranslatedNonConstantExpr, StructorCallContext {
override DestructorFieldDestruction expr;
- final override TranslatedElement getChild(int id) { id = 0 and result = getDestructorCall() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getDestructorCall() }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -1817,17 +1841,19 @@ class TranslatedDestructorFieldDestruction extends TranslatedNonConstantExpr, St
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind instanceof GotoEdge and
- result = getDestructorCall().getFirstInstruction()
+ result = this.getDestructorCall().getFirstInstruction()
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getDestructorCall() and
- result = getParent().getChildSuccessor(this)
+ child = this.getDestructorCall() and
+ result = this.getParent().getChildSuccessor(this)
}
final override Instruction getResult() { none() }
- final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getFirstInstruction() {
+ result = this.getInstruction(OnlyInstructionTag())
+ }
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
@@ -1840,7 +1866,7 @@ class TranslatedDestructorFieldDestruction extends TranslatedNonConstantExpr, St
result = expr.getTarget()
}
- final override Instruction getReceiver() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getReceiver() { result = this.getInstruction(OnlyInstructionTag()) }
private TranslatedExpr getDestructorCall() { result = getTranslatedExpr(expr.getExpr()) }
}
@@ -1859,12 +1885,12 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
// the condition directly to the appropriate then/else block via
// `getChild[True|False]Successor()`.
// The binary flavor will override this predicate to add the `ConditionalBranch`.
- not resultIsVoid() and
+ not this.resultIsVoid() and
(
(
- not thenIsVoid() and tag = ConditionValueTrueTempAddressTag()
+ not this.thenIsVoid() and tag = ConditionValueTrueTempAddressTag()
or
- not elseIsVoid() and tag = ConditionValueFalseTempAddressTag()
+ not this.elseIsVoid() and tag = ConditionValueFalseTempAddressTag()
or
tag = ConditionValueResultTempAddressTag()
) and
@@ -1876,106 +1902,106 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
)
or
(
- not thenIsVoid() and tag = ConditionValueTrueStoreTag()
+ not this.thenIsVoid() and tag = ConditionValueTrueStoreTag()
or
- not elseIsVoid() and tag = ConditionValueFalseStoreTag()
+ not this.elseIsVoid() and tag = ConditionValueFalseStoreTag()
) and
opcode instanceof Opcode::Store and
- resultType = getResultType()
+ resultType = this.getResultType()
or
tag = ConditionValueResultLoadTag() and
opcode instanceof Opcode::Load and
- resultType = getResultType()
+ resultType = this.getResultType()
)
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
- not resultIsVoid() and
+ not this.resultIsVoid() and
kind instanceof GotoEdge and
(
- not thenIsVoid() and
+ not this.thenIsVoid() and
(
tag = ConditionValueTrueTempAddressTag() and
- result = getInstruction(ConditionValueTrueStoreTag())
+ result = this.getInstruction(ConditionValueTrueStoreTag())
or
tag = ConditionValueTrueStoreTag() and
- result = getInstruction(ConditionValueResultTempAddressTag())
+ result = this.getInstruction(ConditionValueResultTempAddressTag())
)
or
- not elseIsVoid() and
+ not this.elseIsVoid() and
(
tag = ConditionValueFalseTempAddressTag() and
- result = getInstruction(ConditionValueFalseStoreTag())
+ result = this.getInstruction(ConditionValueFalseStoreTag())
or
tag = ConditionValueFalseStoreTag() and
- result = getInstruction(ConditionValueResultTempAddressTag())
+ result = this.getInstruction(ConditionValueResultTempAddressTag())
)
or
tag = ConditionValueResultTempAddressTag() and
- result = getInstruction(ConditionValueResultLoadTag())
+ result = this.getInstruction(ConditionValueResultLoadTag())
or
tag = ConditionValueResultLoadTag() and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
)
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
- not resultIsVoid() and
+ not this.resultIsVoid() and
(
- not thenIsVoid() and
+ not this.thenIsVoid() and
tag = ConditionValueTrueStoreTag() and
(
operandTag instanceof AddressOperandTag and
- result = getInstruction(ConditionValueTrueTempAddressTag())
+ result = this.getInstruction(ConditionValueTrueTempAddressTag())
or
operandTag instanceof StoreValueOperandTag and
- result = getThen().getResult()
+ result = this.getThen().getResult()
)
or
- not elseIsVoid() and
+ not this.elseIsVoid() and
tag = ConditionValueFalseStoreTag() and
(
operandTag instanceof AddressOperandTag and
- result = getInstruction(ConditionValueFalseTempAddressTag())
+ result = this.getInstruction(ConditionValueFalseTempAddressTag())
or
operandTag instanceof StoreValueOperandTag and
- result = getElse().getResult()
+ result = this.getElse().getResult()
)
or
tag = ConditionValueResultLoadTag() and
(
operandTag instanceof AddressOperandTag and
- result = getInstruction(ConditionValueResultTempAddressTag())
+ result = this.getInstruction(ConditionValueResultTempAddressTag())
)
)
}
final override predicate hasTempVariable(TempVariableTag tag, CppType type) {
- not resultIsVoid() and
+ not this.resultIsVoid() and
tag = ConditionValueTempVar() and
- type = getResultType()
+ type = this.getResultType()
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
- not resultIsVoid() and
+ not this.resultIsVoid() and
(
tag = ConditionValueTrueTempAddressTag() or
tag = ConditionValueFalseTempAddressTag() or
tag = ConditionValueResultTempAddressTag()
) and
- result = getTempVariable(ConditionValueTempVar())
+ result = this.getTempVariable(ConditionValueTempVar())
}
final override Instruction getResult() {
- not resultIsVoid() and
- result = getInstruction(ConditionValueResultLoadTag())
+ not this.resultIsVoid() and
+ result = this.getInstruction(ConditionValueResultLoadTag())
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getElse() and
- if elseIsVoid()
- then result = getParent().getChildSuccessor(this)
- else result = getInstruction(ConditionValueFalseTempAddressTag())
+ child = this.getElse() and
+ if this.elseIsVoid()
+ then result = this.getParent().getChildSuccessor(this)
+ else result = this.getInstruction(ConditionValueFalseTempAddressTag())
}
/**
@@ -1990,7 +2016,7 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
final TranslatedExpr getElse() { result = getTranslatedExpr(expr.getElse().getFullyConverted()) }
final predicate thenIsVoid() {
- getThen().getResultType().getIRType() instanceof IRVoidType
+ this.getThen().getResultType().getIRType() instanceof IRVoidType
or
// A `ThrowExpr.getType()` incorrectly returns the type of exception being
// thrown, rather than `void`. Handle that case here.
@@ -1998,14 +2024,14 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
}
private predicate elseIsVoid() {
- getElse().getResultType().getIRType() instanceof IRVoidType
+ this.getElse().getResultType().getIRType() instanceof IRVoidType
or
// A `ThrowExpr.getType()` incorrectly returns the type of exception being
// thrown, rather than `void`. Handle that case here.
expr.getElse() instanceof ThrowExpr
}
- private predicate resultIsVoid() { getResultType().getIRType() instanceof IRVoidType }
+ private predicate resultIsVoid() { this.getResultType().getIRType() instanceof IRVoidType }
}
/**
@@ -2017,34 +2043,34 @@ class TranslatedTernaryConditionalExpr extends TranslatedConditionalExpr, Condit
TranslatedTernaryConditionalExpr() { not expr.isTwoOperand() }
final override TranslatedElement getChild(int id) {
- id = 0 and result = getCondition()
+ id = 0 and result = this.getCondition()
or
- id = 1 and result = getThen()
+ id = 1 and result = this.getThen()
or
- id = 2 and result = getElse()
+ id = 2 and result = this.getElse()
}
- override Instruction getFirstInstruction() { result = getCondition().getFirstInstruction() }
+ override Instruction getFirstInstruction() { result = this.getCondition().getFirstInstruction() }
override Instruction getChildSuccessor(TranslatedElement child) {
result = TranslatedConditionalExpr.super.getChildSuccessor(child)
or
(
- child = getThen() and
- if thenIsVoid()
- then result = getParent().getChildSuccessor(this)
- else result = getInstruction(ConditionValueTrueTempAddressTag())
+ child = this.getThen() and
+ if this.thenIsVoid()
+ then result = this.getParent().getChildSuccessor(this)
+ else result = this.getInstruction(ConditionValueTrueTempAddressTag())
)
}
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
- child = getCondition() and
- result = getThen().getFirstInstruction()
+ child = this.getCondition() and
+ result = this.getThen().getFirstInstruction()
}
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
- child = getCondition() and
- result = getElse().getFirstInstruction()
+ child = this.getCondition() and
+ result = this.getElse().getFirstInstruction()
}
private TranslatedCondition getCondition() {
@@ -2069,12 +2095,12 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr {
final override TranslatedElement getChild(int id) {
// We only truly have two children, because our "condition" and "then" are the same as far as
// the extractor is concerned.
- id = 0 and result = getCondition()
+ id = 0 and result = this.getCondition()
or
- id = 1 and result = getElse()
+ id = 1 and result = this.getElse()
}
- override Instruction getFirstInstruction() { result = getCondition().getFirstInstruction() }
+ override Instruction getFirstInstruction() { result = this.getCondition().getFirstInstruction() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
super.hasInstruction(opcode, tag, resultType)
@@ -2091,10 +2117,10 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr {
tag = ValueConditionConditionalBranchTag() and
(
kind instanceof TrueEdge and
- result = getInstruction(ConditionValueTrueTempAddressTag())
+ result = this.getInstruction(ConditionValueTrueTempAddressTag())
or
kind instanceof FalseEdge and
- result = getElse().getFirstInstruction()
+ result = this.getElse().getFirstInstruction()
)
}
@@ -2103,13 +2129,14 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr {
or
tag = ValueConditionConditionalBranchTag() and
operandTag instanceof ConditionOperandTag and
- result = getCondition().getResult()
+ result = this.getCondition().getResult()
}
override Instruction getChildSuccessor(TranslatedElement child) {
result = super.getChildSuccessor(child)
or
- child = getCondition() and result = getInstruction(ValueConditionConditionalBranchTag())
+ child = this.getCondition() and
+ result = this.getInstruction(ValueConditionConditionalBranchTag())
}
private TranslatedExpr getCondition() {
@@ -2154,10 +2181,10 @@ class TranslatedTemporaryObjectExpr extends TranslatedNonConstantExpr,
}
final override Instruction getInitializationSuccessor() {
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
- final override Instruction getResult() { result = getTargetAddress() }
+ final override Instruction getResult() { result = this.getTargetAddress() }
}
/**
@@ -2168,14 +2195,14 @@ abstract class TranslatedThrowExpr extends TranslatedNonConstantExpr {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = ThrowTag() and
- opcode = getThrowOpcode() and
+ opcode = this.getThrowOpcode() and
resultType = getVoidType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = ThrowTag() and
kind instanceof ExceptionEdge and
- result = getParent().getExceptionSuccessorInstruction()
+ result = this.getParent().getExceptionSuccessorInstruction()
}
override Instruction getResult() { none() }
@@ -2202,11 +2229,13 @@ class TranslatedThrowValueExpr extends TranslatedThrowExpr, TranslatedVariableIn
result = TranslatedVariableInitialization.super.getInstructionSuccessor(tag, kind)
}
- final override Instruction getInitializationSuccessor() { result = getInstruction(ThrowTag()) }
+ final override Instruction getInitializationSuccessor() {
+ result = this.getInstruction(ThrowTag())
+ }
final override predicate hasTempVariable(TempVariableTag tag, CppType type) {
tag = ThrowTempVar() and
- type = getTypeForPRValue(getExceptionType())
+ type = getTypeForPRValue(this.getExceptionType())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -2215,7 +2244,7 @@ class TranslatedThrowValueExpr extends TranslatedThrowExpr, TranslatedVariableIn
tag = ThrowTag() and
(
operandTag instanceof AddressOperandTag and
- result = getInstruction(InitializerVariableAddressTag())
+ result = this.getInstruction(InitializerVariableAddressTag())
)
}
@@ -2224,10 +2253,10 @@ class TranslatedThrowValueExpr extends TranslatedThrowExpr, TranslatedVariableIn
) {
tag = ThrowTag() and
operandTag instanceof LoadOperandTag and
- result = getTypeForPRValue(getExceptionType())
+ result = getTypeForPRValue(this.getExceptionType())
}
- override Type getTargetType() { result = getExceptionType() }
+ override Type getTargetType() { result = this.getExceptionType() }
final override TranslatedInitialization getInitialization() {
result = getTranslatedInitialization(expr.getExpr().getFullyConverted())
@@ -2248,7 +2277,7 @@ class TranslatedReThrowExpr extends TranslatedThrowExpr {
override TranslatedElement getChild(int id) { none() }
- override Instruction getFirstInstruction() { result = getInstruction(ThrowTag()) }
+ override Instruction getFirstInstruction() { result = this.getInstruction(ThrowTag()) }
override Instruction getChildSuccessor(TranslatedElement child) { none() }
@@ -2271,12 +2300,12 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
not expr instanceof BuiltInVarArgCopy
}
- final override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
final override Instruction getFirstInstruction() {
- if exists(getChild(0))
- then result = getChild(0).getFirstInstruction()
- else result = getInstruction(OnlyInstructionTag())
+ if exists(this.getChild(0))
+ then result = this.getChild(0).getFirstInstruction()
+ else result = this.getInstruction(OnlyInstructionTag())
}
final override TranslatedElement getChild(int id) {
@@ -2286,31 +2315,31 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr {
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind instanceof GotoEdge and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
exists(int id |
- child = getChild(id) and
+ child = this.getChild(id) and
(
- result = getChild(id + 1).getFirstInstruction()
+ result = this.getChild(id + 1).getFirstInstruction()
or
- not exists(getChild(id + 1)) and result = getInstruction(OnlyInstructionTag())
+ not exists(this.getChild(id + 1)) and result = this.getInstruction(OnlyInstructionTag())
)
)
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
- opcode = getOpcode() and
- resultType = getResultType()
+ opcode = this.getOpcode() and
+ resultType = this.getResultType()
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
exists(int index |
operandTag = positionalArgumentOperand(index) and
- result = getChild(index).(TranslatedExpr).getResult()
+ result = this.getChild(index).(TranslatedExpr).getResult()
)
}
@@ -2391,12 +2420,12 @@ class TranslatedVarArgsStart extends TranslatedNonConstantExpr {
}
final override Instruction getFirstInstruction() {
- result = getInstruction(VarArgsStartEllipsisAddressTag())
+ result = this.getInstruction(VarArgsStartEllipsisAddressTag())
}
final override Instruction getResult() { none() }
- final override TranslatedElement getChild(int id) { id = 0 and result = getVAList() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getVAList() }
private TranslatedExpr getVAList() {
result = getTranslatedExpr(expr.getVAList().getFullyConverted())
@@ -2405,37 +2434,37 @@ class TranslatedVarArgsStart extends TranslatedNonConstantExpr {
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = VarArgsStartEllipsisAddressTag() and
kind instanceof GotoEdge and
- result = getInstruction(VarArgsStartTag())
+ result = this.getInstruction(VarArgsStartTag())
or
tag = VarArgsStartTag() and
kind instanceof GotoEdge and
- result = getVAList().getFirstInstruction()
+ result = this.getVAList().getFirstInstruction()
or
tag = VarArgsVAListStoreTag() and
kind instanceof GotoEdge and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getVAList() and
- result = getInstruction(VarArgsVAListStoreTag())
+ child = this.getVAList() and
+ result = this.getInstruction(VarArgsVAListStoreTag())
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
tag = VarArgsStartEllipsisAddressTag() and
- result = getEnclosingFunction().getEllipsisVariable()
+ result = this.getEnclosingFunction().getEllipsisVariable()
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = VarArgsStartTag() and
operandTag instanceof UnaryOperandTag and
- result = getInstruction(VarArgsStartEllipsisAddressTag())
+ result = this.getInstruction(VarArgsStartEllipsisAddressTag())
or
tag = VarArgsVAListStoreTag() and
(
- operandTag instanceof AddressOperandTag and result = getVAList().getResult()
+ operandTag instanceof AddressOperandTag and result = this.getVAList().getResult()
or
- operandTag instanceof StoreValueOperandTag and result = getInstruction(VarArgsStartTag())
+ operandTag instanceof StoreValueOperandTag and result = this.getInstruction(VarArgsStartTag())
)
}
}
@@ -2453,7 +2482,7 @@ class TranslatedVarArg extends TranslatedNonConstantExpr {
or
tag = VarArgsArgAddressTag() and
opcode instanceof Opcode::VarArg and
- resultType = getResultType()
+ resultType = this.getResultType()
or
tag = VarArgsMoveNextTag() and
opcode instanceof Opcode::NextVarArg and
@@ -2464,11 +2493,13 @@ class TranslatedVarArg extends TranslatedNonConstantExpr {
resultType = getTypeForPRValue(getVAListType(expr.getVAList().getFullyConverted()))
}
- final override Instruction getFirstInstruction() { result = getVAList().getFirstInstruction() }
+ final override Instruction getFirstInstruction() {
+ result = this.getVAList().getFirstInstruction()
+ }
- final override Instruction getResult() { result = getInstruction(VarArgsArgAddressTag()) }
+ final override Instruction getResult() { result = this.getInstruction(VarArgsArgAddressTag()) }
- final override TranslatedElement getChild(int id) { id = 0 and result = getVAList() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getVAList() }
private TranslatedExpr getVAList() {
result = getTranslatedExpr(expr.getVAList().getFullyConverted())
@@ -2477,46 +2508,47 @@ class TranslatedVarArg extends TranslatedNonConstantExpr {
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = VarArgsVAListLoadTag() and
kind instanceof GotoEdge and
- result = getInstruction(VarArgsArgAddressTag())
+ result = this.getInstruction(VarArgsArgAddressTag())
or
tag = VarArgsArgAddressTag() and
kind instanceof GotoEdge and
- result = getInstruction(VarArgsMoveNextTag())
+ result = this.getInstruction(VarArgsMoveNextTag())
or
tag = VarArgsMoveNextTag() and
kind instanceof GotoEdge and
- result = getInstruction(VarArgsVAListStoreTag())
+ result = this.getInstruction(VarArgsVAListStoreTag())
or
tag = VarArgsVAListStoreTag() and
kind instanceof GotoEdge and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getVAList() and
- result = getInstruction(VarArgsVAListLoadTag())
+ child = this.getVAList() and
+ result = this.getInstruction(VarArgsVAListLoadTag())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = VarArgsVAListLoadTag() and
(
operandTag instanceof AddressOperandTag and
- result = getVAList().getResult()
+ result = this.getVAList().getResult()
)
or
tag = VarArgsArgAddressTag() and
operandTag instanceof UnaryOperandTag and
- result = getInstruction(VarArgsVAListLoadTag())
+ result = this.getInstruction(VarArgsVAListLoadTag())
or
tag = VarArgsMoveNextTag() and
operandTag instanceof UnaryOperandTag and
- result = getInstruction(VarArgsVAListLoadTag())
+ result = this.getInstruction(VarArgsVAListLoadTag())
or
tag = VarArgsVAListStoreTag() and
(
- operandTag instanceof AddressOperandTag and result = getVAList().getResult()
+ operandTag instanceof AddressOperandTag and result = this.getVAList().getResult()
or
- operandTag instanceof StoreValueOperandTag and result = getInstruction(VarArgsMoveNextTag())
+ operandTag instanceof StoreValueOperandTag and
+ result = this.getInstruction(VarArgsMoveNextTag())
)
}
}
@@ -2533,11 +2565,13 @@ class TranslatedVarArgsEnd extends TranslatedNonConstantExpr {
resultType = getVoidType()
}
- final override Instruction getFirstInstruction() { result = getVAList().getFirstInstruction() }
+ final override Instruction getFirstInstruction() {
+ result = this.getVAList().getFirstInstruction()
+ }
final override Instruction getResult() { none() }
- final override TranslatedElement getChild(int id) { id = 0 and result = getVAList() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getVAList() }
private TranslatedExpr getVAList() {
result = getTranslatedExpr(expr.getVAList().getFullyConverted())
@@ -2546,18 +2580,18 @@ class TranslatedVarArgsEnd extends TranslatedNonConstantExpr {
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind instanceof GotoEdge and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getVAList() and
- result = getInstruction(OnlyInstructionTag())
+ child = this.getVAList() and
+ result = this.getInstruction(OnlyInstructionTag())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
- result = getVAList().getResult()
+ result = this.getVAList().getResult()
}
}
@@ -2578,15 +2612,15 @@ class TranslatedVarArgCopy extends TranslatedNonConstantExpr {
}
final override Instruction getFirstInstruction() {
- result = getSourceVAList().getFirstInstruction()
+ result = this.getSourceVAList().getFirstInstruction()
}
- final override Instruction getResult() { result = getInstruction(VarArgsVAListStoreTag()) }
+ final override Instruction getResult() { result = this.getInstruction(VarArgsVAListStoreTag()) }
final override TranslatedElement getChild(int id) {
- id = 0 and result = getDestinationVAList()
+ id = 0 and result = this.getDestinationVAList()
or
- id = 1 and result = getSourceVAList()
+ id = 1 and result = this.getSourceVAList()
}
private TranslatedExpr getDestinationVAList() {
@@ -2600,33 +2634,34 @@ class TranslatedVarArgCopy extends TranslatedNonConstantExpr {
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = VarArgsVAListLoadTag() and
kind instanceof GotoEdge and
- result = getDestinationVAList().getFirstInstruction()
+ result = this.getDestinationVAList().getFirstInstruction()
or
tag = VarArgsVAListStoreTag() and
kind instanceof GotoEdge and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getSourceVAList() and
- result = getInstruction(VarArgsVAListLoadTag())
+ child = this.getSourceVAList() and
+ result = this.getInstruction(VarArgsVAListLoadTag())
or
- child = getDestinationVAList() and
- result = getInstruction(VarArgsVAListStoreTag())
+ child = this.getDestinationVAList() and
+ result = this.getInstruction(VarArgsVAListStoreTag())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = VarArgsVAListLoadTag() and
(
operandTag instanceof AddressOperandTag and
- result = getSourceVAList().getResult()
+ result = this.getSourceVAList().getResult()
)
or
tag = VarArgsVAListStoreTag() and
(
- operandTag instanceof AddressOperandTag and result = getDestinationVAList().getResult()
+ operandTag instanceof AddressOperandTag and result = this.getDestinationVAList().getResult()
or
- operandTag instanceof StoreValueOperandTag and result = getInstruction(VarArgsVAListLoadTag())
+ operandTag instanceof StoreValueOperandTag and
+ result = this.getInstruction(VarArgsVAListLoadTag())
)
}
}
@@ -2638,44 +2673,46 @@ abstract class TranslatedNewOrNewArrayExpr extends TranslatedNonConstantExpr, In
override NewOrNewArrayExpr expr;
final override TranslatedElement getChild(int id) {
- id = 0 and result = getAllocatorCall()
+ id = 0 and result = this.getAllocatorCall()
or
- id = 1 and result = getInitialization()
+ id = 1 and result = this.getInitialization()
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
opcode instanceof Opcode::Convert and
- resultType = getResultType()
+ resultType = this.getResultType()
}
final override Instruction getFirstInstruction() {
- result = getAllocatorCall().getFirstInstruction()
+ result = this.getAllocatorCall().getFirstInstruction()
}
- final override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
tag = OnlyInstructionTag() and
- if exists(getInitialization())
- then result = getInitialization().getFirstInstruction()
- else result = getParent().getChildSuccessor(this)
+ if exists(this.getInitialization())
+ then result = this.getInitialization().getFirstInstruction()
+ else result = this.getParent().getChildSuccessor(this)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getAllocatorCall() and result = getInstruction(OnlyInstructionTag())
+ child = this.getAllocatorCall() and result = this.getInstruction(OnlyInstructionTag())
or
- child = getInitialization() and result = getParent().getChildSuccessor(this)
+ child = this.getInitialization() and result = this.getParent().getChildSuccessor(this)
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
- result = getAllocatorCall().getResult()
+ result = this.getAllocatorCall().getResult()
}
- final override Instruction getTargetAddress() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getTargetAddress() {
+ result = this.getInstruction(OnlyInstructionTag())
+ }
private TranslatedAllocatorCall getAllocatorCall() { result = getTranslatedAllocatorCall(expr) }
@@ -2718,18 +2755,20 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr {
class TranslatedDeleteArrayExprPlaceHolder extends TranslatedSingleInstructionExpr {
override DeleteArrayExpr expr;
- final override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
+ final override Instruction getFirstInstruction() {
+ result = this.getOperand().getFirstInstruction()
+ }
- final override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getOperand() and result = getInstruction(OnlyInstructionTag())
+ child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -2752,18 +2791,20 @@ class TranslatedDeleteArrayExprPlaceHolder extends TranslatedSingleInstructionEx
class TranslatedDeleteExprPlaceHolder extends TranslatedSingleInstructionExpr {
override DeleteExpr expr;
- final override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
+ final override Instruction getFirstInstruction() {
+ result = this.getOperand().getFirstInstruction()
+ }
- final override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
final override Instruction getChildSuccessor(TranslatedElement child) {
- child = getOperand() and result = getInstruction(OnlyInstructionTag())
+ child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -2788,23 +2829,23 @@ class TranslatedDeleteExprPlaceHolder extends TranslatedSingleInstructionExpr {
class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr {
override ConditionDeclExpr expr;
- final override Instruction getFirstInstruction() { result = getDecl().getFirstInstruction() }
+ final override Instruction getFirstInstruction() { result = this.getDecl().getFirstInstruction() }
final override TranslatedElement getChild(int id) {
- id = 0 and result = getDecl()
+ id = 0 and result = this.getDecl()
or
- id = 1 and result = getConditionExpr()
+ id = 1 and result = this.getConditionExpr()
}
- override Instruction getResult() { result = getConditionExpr().getResult() }
+ override Instruction getResult() { result = this.getConditionExpr().getResult() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getDecl() and
- result = getConditionExpr().getFirstInstruction()
+ child = this.getDecl() and
+ result = this.getConditionExpr().getFirstInstruction()
or
- child = getConditionExpr() and result = getParent().getChildSuccessor(this)
+ child = this.getConditionExpr() and result = this.getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -2826,34 +2867,34 @@ class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationCont
override LambdaExpression expr;
final override Instruction getFirstInstruction() {
- result = getInstruction(InitializerVariableAddressTag())
+ result = this.getInstruction(InitializerVariableAddressTag())
}
- final override TranslatedElement getChild(int id) { id = 0 and result = getInitialization() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
- override Instruction getResult() { result = getInstruction(LoadTag()) }
+ override Instruction getResult() { result = this.getInstruction(LoadTag()) }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = InitializerVariableAddressTag() and
kind instanceof GotoEdge and
- result = getInstruction(InitializerStoreTag())
+ result = this.getInstruction(InitializerStoreTag())
or
tag = InitializerStoreTag() and
kind instanceof GotoEdge and
(
- result = getInitialization().getFirstInstruction()
+ result = this.getInitialization().getFirstInstruction()
or
- not hasInitializer() and result = getInstruction(LoadTag())
+ not this.hasInitializer() and result = this.getInstruction(LoadTag())
)
or
tag = LoadTag() and
kind instanceof GotoEdge and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getInitialization() and
- result = getInstruction(LoadTag())
+ child = this.getInitialization() and
+ result = this.getInstruction(LoadTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -2873,12 +2914,12 @@ class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationCont
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerStoreTag() and
operandTag instanceof AddressOperandTag and
- result = getInstruction(InitializerVariableAddressTag())
+ result = this.getInstruction(InitializerVariableAddressTag())
or
tag = LoadTag() and
(
operandTag instanceof AddressOperandTag and
- result = getInstruction(InitializerVariableAddressTag())
+ result = this.getInstruction(InitializerVariableAddressTag())
)
}
@@ -2887,7 +2928,7 @@ class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationCont
tag = InitializerVariableAddressTag() or
tag = InitializerStoreTag()
) and
- result = getTempVariable(LambdaTempVar())
+ result = this.getTempVariable(LambdaTempVar())
}
override predicate hasTempVariable(TempVariableTag tag, CppType type) {
@@ -2896,12 +2937,12 @@ class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationCont
}
final override Instruction getTargetAddress() {
- result = getInstruction(InitializerVariableAddressTag())
+ result = this.getInstruction(InitializerVariableAddressTag())
}
final override Type getTargetType() { result = expr.getType() }
- private predicate hasInitializer() { exists(getInitialization()) }
+ private predicate hasInitializer() { exists(this.getInitialization()) }
private TranslatedInitialization getInitialization() {
result = getTranslatedInitialization(expr.getChild(0).getFullyConverted())
@@ -2915,28 +2956,28 @@ class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationCont
class TranslatedStmtExpr extends TranslatedNonConstantExpr {
override StmtExpr expr;
- final override Instruction getFirstInstruction() { result = getStmt().getFirstInstruction() }
+ final override Instruction getFirstInstruction() { result = this.getStmt().getFirstInstruction() }
- final override TranslatedElement getChild(int id) { id = 0 and result = getStmt() }
+ final override TranslatedElement getChild(int id) { id = 0 and result = this.getStmt() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag instanceof OnlyInstructionTag and
kind instanceof GotoEdge and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getStmt() and
- result = getInstruction(OnlyInstructionTag())
+ child = this.getStmt() and
+ result = this.getInstruction(OnlyInstructionTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
opcode instanceof Opcode::CopyValue and
tag instanceof OnlyInstructionTag and
- resultType = getResultType()
+ resultType = this.getResultType()
}
- override Instruction getResult() { result = getInstruction(OnlyInstructionTag()) }
+ override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag instanceof OnlyInstructionTag and
@@ -2950,13 +2991,15 @@ class TranslatedStmtExpr extends TranslatedNonConstantExpr {
class TranslatedErrorExpr extends TranslatedSingleInstructionExpr {
override ErrorExpr expr;
- final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getFirstInstruction() {
+ result = this.getInstruction(OnlyInstructionTag())
+ }
final override TranslatedElement getChild(int id) { none() }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
@@ -3034,13 +3077,15 @@ class TranslatedAssumeExpr extends TranslatedSingleInstructionExpr {
final override Opcode getOpcode() { result instanceof Opcode::NoOp }
- final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
+ final override Instruction getFirstInstruction() {
+ result = this.getInstruction(OnlyInstructionTag())
+ }
final override TranslatedElement getChild(int id) { none() }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
- result = getParent().getChildSuccessor(this) and
+ result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll
index 4b86f9a7cec..bb8630a5e0c 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll
@@ -24,7 +24,7 @@ class IRBlockBase extends TIRBlock {
final string toString() { result = getFirstInstruction(this).toString() }
/** Gets the source location of the first non-`Phi` instruction in this block. */
- final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
+ final Language::Location getLocation() { result = this.getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
@@ -39,7 +39,7 @@ class IRBlockBase extends TIRBlock {
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
- funcBlock.getEnclosingFunction() = getEnclosingFunction() and
+ funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
@@ -59,15 +59,15 @@ class IRBlockBase extends TIRBlock {
* Get the `Phi` instructions that appear at the start of this block.
*/
final PhiInstruction getAPhiInstruction() {
- Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
+ Construction::getPhiInstructionBlockStart(result) = this.getFirstInstruction()
}
/**
* Gets an instruction in this block. This includes `Phi` instructions.
*/
final Instruction getAnInstruction() {
- result = getInstruction(_) or
- result = getAPhiInstruction()
+ result = this.getInstruction(_) or
+ result = this.getAPhiInstruction()
}
/**
@@ -78,7 +78,9 @@ class IRBlockBase extends TIRBlock {
/**
* Gets the last instruction in this block.
*/
- final Instruction getLastInstruction() { result = getInstruction(getInstructionCount() - 1) }
+ final Instruction getLastInstruction() {
+ result = this.getInstruction(this.getInstructionCount() - 1)
+ }
/**
* Gets the number of non-`Phi` instructions in this block.
@@ -149,7 +151,7 @@ class IRBlock extends IRBlockBase {
* Block `A` dominates block `B` if any control flow path from the entry block of the function to
* block `B` must pass through block `A`. A block always dominates itself.
*/
- final predicate dominates(IRBlock block) { strictlyDominates(block) or this = block }
+ final predicate dominates(IRBlock block) { this.strictlyDominates(block) or this = block }
/**
* Gets a block on the dominance frontier of this block.
@@ -159,8 +161,8 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock dominanceFrontier() {
- dominates(result.getAPredecessor()) and
- not strictlyDominates(result)
+ this.dominates(result.getAPredecessor()) and
+ not this.strictlyDominates(result)
}
/**
@@ -189,7 +191,7 @@ class IRBlock extends IRBlockBase {
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
- final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
+ final predicate postDominates(IRBlock block) { this.strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
@@ -199,16 +201,16 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
- postDominates(result.getASuccessor()) and
- not strictlyPostDominates(result)
+ this.postDominates(result.getASuccessor()) and
+ not this.strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
final predicate isReachableFromFunctionEntry() {
- this = getEnclosingIRFunction().getEntryBlock() or
- getAPredecessor().isReachableFromFunctionEntry()
+ this = this.getEnclosingIRFunction().getEntryBlock() or
+ this.getAPredecessor().isReachableFromFunctionEntry()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
index 2fb3edad602..88a973fc5a8 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll
@@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction {
}
/** Gets a textual representation of this element. */
- final string toString() { result = getOpcode().toString() + ": " + getAST().toString() }
+ final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() }
/**
* Gets a string showing the result, opcode, and operands of the instruction, equivalent to what
@@ -50,7 +50,8 @@ class Instruction extends Construction::TStageInstruction {
* `mu0_28(int) = Store r0_26, r0_27`
*/
final string getDumpString() {
- result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
+ result =
+ this.getResultString() + " = " + this.getOperationString() + " " + this.getOperandsString()
}
private predicate shouldGenerateDumpStrings() {
@@ -66,10 +67,13 @@ class Instruction extends Construction::TStageInstruction {
* VariableAddress[x]
*/
final string getOperationString() {
- shouldGenerateDumpStrings() and
- if exists(getImmediateString())
- then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
- else result = getOperationPrefix() + getOpcode().toString()
+ this.shouldGenerateDumpStrings() and
+ if exists(this.getImmediateString())
+ then
+ result =
+ this.getOperationPrefix() + this.getOpcode().toString() + "[" + this.getImmediateString() +
+ "]"
+ else result = this.getOperationPrefix() + this.getOpcode().toString()
}
/**
@@ -78,17 +82,17 @@ class Instruction extends Construction::TStageInstruction {
string getImmediateString() { none() }
private string getOperationPrefix() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = ""
}
private string getResultPrefix() {
- shouldGenerateDumpStrings() and
- if getResultIRType() instanceof IRVoidType
+ this.shouldGenerateDumpStrings() and
+ if this.getResultIRType() instanceof IRVoidType
then result = "v"
else
- if hasMemoryResult()
- then if isResultModeled() then result = "m" else result = "mu"
+ if this.hasMemoryResult()
+ then if this.isResultModeled() then result = "m" else result = "mu"
else result = "r"
}
@@ -97,7 +101,7 @@ class Instruction extends Construction::TStageInstruction {
* used by debugging and printing code only.
*/
int getDisplayIndexInBlock() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
exists(IRBlock block |
this = block.getInstruction(result)
or
@@ -111,12 +115,12 @@ class Instruction extends Construction::TStageInstruction {
}
private int getLineRank() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
this =
rank[result](Instruction instr |
instr =
- getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
- getLocation().getStartLine())
+ getAnInstructionAtLine(this.getEnclosingIRFunction(), this.getLocation().getFile(),
+ this.getLocation().getStartLine())
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
@@ -130,8 +134,9 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1`
*/
string getResultId() {
- shouldGenerateDumpStrings() and
- result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
+ this.shouldGenerateDumpStrings() and
+ result =
+ this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank()
}
/**
@@ -142,8 +147,8 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1(int*)`
*/
final string getResultString() {
- shouldGenerateDumpStrings() and
- result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
+ this.shouldGenerateDumpStrings() and
+ result = this.getResultId() + "(" + this.getResultLanguageType().getDumpString() + ")"
}
/**
@@ -153,10 +158,10 @@ class Instruction extends Construction::TStageInstruction {
* Example: `func:r3_4, this:r3_5`
*/
string getOperandsString() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
result =
concat(Operand operand |
- operand = getAnOperand()
+ operand = this.getAnOperand()
|
operand.getDumpString(), ", " order by operand.getDumpSortOrder()
)
@@ -190,7 +195,7 @@ class Instruction extends Construction::TStageInstruction {
* Gets the function that contains this instruction.
*/
final Language::Function getEnclosingFunction() {
- result = getEnclosingIRFunction().getFunction()
+ result = this.getEnclosingIRFunction().getFunction()
}
/**
@@ -208,7 +213,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the location of the source code for this instruction.
*/
- final Language::Location getLocation() { result = getAST().getLocation() }
+ final Language::Location getLocation() { result = this.getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
@@ -243,7 +248,7 @@ class Instruction extends Construction::TStageInstruction {
* a result, its result type will be `IRVoidType`.
*/
cached
- final IRType getResultIRType() { result = getResultLanguageType().getIRType() }
+ final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() }
/**
* Gets the type of the result produced by this instruction. If the
@@ -254,7 +259,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final Language::Type getResultType() {
exists(Language::LanguageType resultType |
- resultType = getResultLanguageType() and
+ resultType = this.getResultLanguageType() and
(
resultType.hasUnspecifiedType(result, _)
or
@@ -283,7 +288,7 @@ class Instruction extends Construction::TStageInstruction {
* result of the `Load` instruction is a prvalue of type `int`, representing
* the integer value loaded from variable `x`.
*/
- final predicate isGLValue() { getResultLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getResultLanguageType().hasType(_, true) }
/**
* Gets the size of the result produced by this instruction, in bytes. If the
@@ -292,7 +297,7 @@ class Instruction extends Construction::TStageInstruction {
* If `this.isGLValue()` holds for this instruction, the value of
* `getResultSize()` will always be the size of a pointer.
*/
- final int getResultSize() { result = getResultLanguageType().getByteSize() }
+ final int getResultSize() { result = this.getResultLanguageType().getByteSize() }
/**
* Gets the opcode that specifies the operation performed by this instruction.
@@ -314,14 +319,16 @@ class Instruction extends Construction::TStageInstruction {
/**
* Holds if this instruction produces a memory result.
*/
- final predicate hasMemoryResult() { exists(getResultMemoryAccess()) }
+ final predicate hasMemoryResult() { exists(this.getResultMemoryAccess()) }
/**
* Gets the kind of memory access performed by this instruction's result.
* Holds only for instructions with a memory result.
*/
pragma[inline]
- final MemoryAccessKind getResultMemoryAccess() { result = getOpcode().getWriteMemoryAccess() }
+ final MemoryAccessKind getResultMemoryAccess() {
+ result = this.getOpcode().getWriteMemoryAccess()
+ }
/**
* Holds if the memory access performed by this instruction's result will not always write to
@@ -332,7 +339,7 @@ class Instruction extends Construction::TStageInstruction {
* (for example, the global side effects of a function call).
*/
pragma[inline]
- final predicate hasResultMayMemoryAccess() { getOpcode().hasMayWriteMemoryAccess() }
+ final predicate hasResultMayMemoryAccess() { this.getOpcode().hasMayWriteMemoryAccess() }
/**
* Gets the operand that holds the memory address to which this instruction stores its
@@ -340,7 +347,7 @@ class Instruction extends Construction::TStageInstruction {
* is `r1`.
*/
final AddressOperand getResultAddressOperand() {
- getResultMemoryAccess().usesAddressOperand() and
+ this.getResultMemoryAccess().usesAddressOperand() and
result.getUse() = this
}
@@ -349,7 +356,7 @@ class Instruction extends Construction::TStageInstruction {
* result, if any. For example, in `m3 = Store r1, r2`, the result of `getResultAddressOperand()`
* is the instruction that defines `r1`.
*/
- final Instruction getResultAddress() { result = getResultAddressOperand().getDef() }
+ final Instruction getResultAddress() { result = this.getResultAddressOperand().getDef() }
/**
* Holds if the result of this instruction is precisely modeled in SSA. Always
@@ -368,7 +375,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final predicate isResultModeled() {
// Register results are always in SSA form.
- not hasMemoryResult() or
+ not this.hasMemoryResult() or
Construction::hasModeledMemoryResult(this)
}
@@ -412,7 +419,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct successors of this instruction.
*/
- final Instruction getASuccessor() { result = getSuccessor(_) }
+ final Instruction getASuccessor() { result = this.getSuccessor(_) }
/**
* Gets a predecessor of this instruction such that the predecessor reaches
@@ -423,7 +430,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct predecessors of this instruction.
*/
- final Instruction getAPredecessor() { result = getPredecessor(_) }
+ final Instruction getAPredecessor() { result = this.getPredecessor(_) }
}
/**
@@ -543,7 +550,7 @@ class IndexedInstruction extends Instruction {
* at this instruction. This instruction has no predecessors.
*/
class EnterFunctionInstruction extends Instruction {
- EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
+ EnterFunctionInstruction() { this.getOpcode() instanceof Opcode::EnterFunction }
}
/**
@@ -554,7 +561,7 @@ class EnterFunctionInstruction extends Instruction {
* struct, or union, see `FieldAddressInstruction`.
*/
class VariableAddressInstruction extends VariableInstruction {
- VariableAddressInstruction() { getOpcode() instanceof Opcode::VariableAddress }
+ VariableAddressInstruction() { this.getOpcode() instanceof Opcode::VariableAddress }
}
/**
@@ -566,7 +573,7 @@ class VariableAddressInstruction extends VariableInstruction {
* The result has an `IRFunctionAddress` type.
*/
class FunctionAddressInstruction extends FunctionInstruction {
- FunctionAddressInstruction() { getOpcode() instanceof Opcode::FunctionAddress }
+ FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
/**
@@ -577,7 +584,7 @@ class FunctionAddressInstruction extends FunctionInstruction {
* initializes that parameter.
*/
class InitializeParameterInstruction extends VariableInstruction {
- InitializeParameterInstruction() { getOpcode() instanceof Opcode::InitializeParameter }
+ InitializeParameterInstruction() { this.getOpcode() instanceof Opcode::InitializeParameter }
/**
* Gets the parameter initialized by this instruction.
@@ -603,7 +610,7 @@ class InitializeParameterInstruction extends VariableInstruction {
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
- InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
+ InitializeNonLocalInstruction() { this.getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
@@ -611,7 +618,7 @@ class InitializeNonLocalInstruction extends Instruction {
* with the value of that memory on entry to the function.
*/
class InitializeIndirectionInstruction extends VariableInstruction {
- InitializeIndirectionInstruction() { getOpcode() instanceof Opcode::InitializeIndirection }
+ InitializeIndirectionInstruction() { this.getOpcode() instanceof Opcode::InitializeIndirection }
/**
* Gets the parameter initialized by this instruction.
@@ -635,24 +642,24 @@ class InitializeIndirectionInstruction extends VariableInstruction {
* An instruction that initializes the `this` pointer parameter of the enclosing function.
*/
class InitializeThisInstruction extends Instruction {
- InitializeThisInstruction() { getOpcode() instanceof Opcode::InitializeThis }
+ InitializeThisInstruction() { this.getOpcode() instanceof Opcode::InitializeThis }
}
/**
* An instruction that computes the address of a non-static field of an object.
*/
class FieldAddressInstruction extends FieldInstruction {
- FieldAddressInstruction() { getOpcode() instanceof Opcode::FieldAddress }
+ FieldAddressInstruction() { this.getOpcode() instanceof Opcode::FieldAddress }
/**
* Gets the operand that provides the address of the object containing the field.
*/
- final UnaryOperand getObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the object containing the field.
*/
- final Instruction getObjectAddress() { result = getObjectAddressOperand().getDef() }
+ final Instruction getObjectAddress() { result = this.getObjectAddressOperand().getDef() }
}
/**
@@ -661,17 +668,19 @@ class FieldAddressInstruction extends FieldInstruction {
* This instruction is used for element access to C# arrays.
*/
class ElementsAddressInstruction extends UnaryInstruction {
- ElementsAddressInstruction() { getOpcode() instanceof Opcode::ElementsAddress }
+ ElementsAddressInstruction() { this.getOpcode() instanceof Opcode::ElementsAddress }
/**
* Gets the operand that provides the address of the array object.
*/
- final UnaryOperand getArrayObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getArrayObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the array object.
*/
- final Instruction getArrayObjectAddress() { result = getArrayObjectAddressOperand().getDef() }
+ final Instruction getArrayObjectAddress() {
+ result = this.getArrayObjectAddressOperand().getDef()
+ }
}
/**
@@ -685,7 +694,7 @@ class ElementsAddressInstruction extends UnaryInstruction {
* taken may want to ignore any function that contains an `ErrorInstruction`.
*/
class ErrorInstruction extends Instruction {
- ErrorInstruction() { getOpcode() instanceof Opcode::Error }
+ ErrorInstruction() { this.getOpcode() instanceof Opcode::Error }
}
/**
@@ -695,7 +704,7 @@ class ErrorInstruction extends Instruction {
* an initializer, or whose initializer only partially initializes the variable.
*/
class UninitializedInstruction extends VariableInstruction {
- UninitializedInstruction() { getOpcode() instanceof Opcode::Uninitialized }
+ UninitializedInstruction() { this.getOpcode() instanceof Opcode::Uninitialized }
/**
* Gets the variable that is uninitialized.
@@ -710,7 +719,7 @@ class UninitializedInstruction extends VariableInstruction {
* least one instruction, even when the AST has no semantic effect.
*/
class NoOpInstruction extends Instruction {
- NoOpInstruction() { getOpcode() instanceof Opcode::NoOp }
+ NoOpInstruction() { this.getOpcode() instanceof Opcode::NoOp }
}
/**
@@ -732,32 +741,32 @@ class NoOpInstruction extends Instruction {
* `void`-returning function.
*/
class ReturnInstruction extends Instruction {
- ReturnInstruction() { getOpcode() instanceof ReturnOpcode }
+ ReturnInstruction() { this.getOpcode() instanceof ReturnOpcode }
}
/**
* An instruction that returns control to the caller of the function, without returning a value.
*/
class ReturnVoidInstruction extends ReturnInstruction {
- ReturnVoidInstruction() { getOpcode() instanceof Opcode::ReturnVoid }
+ ReturnVoidInstruction() { this.getOpcode() instanceof Opcode::ReturnVoid }
}
/**
* An instruction that returns control to the caller of the function, including a return value.
*/
class ReturnValueInstruction extends ReturnInstruction {
- ReturnValueInstruction() { getOpcode() instanceof Opcode::ReturnValue }
+ ReturnValueInstruction() { this.getOpcode() instanceof Opcode::ReturnValue }
/**
* Gets the operand that provides the value being returned by the function.
*/
- final LoadOperand getReturnValueOperand() { result = getAnOperand() }
+ final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available.
*/
- final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
+ final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
}
/**
@@ -770,28 +779,28 @@ class ReturnValueInstruction extends ReturnInstruction {
* that the caller initialized the memory pointed to by the parameter before the call.
*/
class ReturnIndirectionInstruction extends VariableInstruction {
- ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
+ ReturnIndirectionInstruction() { this.getOpcode() instanceof Opcode::ReturnIndirection }
/**
* Gets the operand that provides the value of the pointed-to memory.
*/
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the pointed-to memory, if an exact
* definition is available.
*/
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/**
* Gets the operand that provides the address of the pointed-to memory.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the pointed-to memory.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
/**
* Gets the parameter for which this instruction reads the final pointed-to value within the
@@ -821,12 +830,12 @@ class ReturnIndirectionInstruction extends VariableInstruction {
*
* There are several different copy instructions, depending on the source and destination of the
* copy operation:
- * - `CopyInstruction` - Copies a register operand to a register result.
+ * - `CopyValueInstruction` - Copies a register operand to a register result.
* - `LoadInstruction` - Copies a memory operand to a register result.
* - `StoreInstruction` - Copies a register operand to a memory result.
*/
class CopyInstruction extends Instruction {
- CopyInstruction() { getOpcode() instanceof CopyOpcode }
+ CopyInstruction() { this.getOpcode() instanceof CopyOpcode }
/**
* Gets the operand that provides the input value of the copy.
@@ -837,16 +846,16 @@ class CopyInstruction extends Instruction {
* Gets the instruction whose result provides the input value of the copy, if an exact definition
* is available.
*/
- final Instruction getSourceValue() { result = getSourceValueOperand().getDef() }
+ final Instruction getSourceValue() { result = this.getSourceValueOperand().getDef() }
}
/**
* An instruction that returns a register result containing a copy of its register operand.
*/
class CopyValueInstruction extends CopyInstruction, UnaryInstruction {
- CopyValueInstruction() { getOpcode() instanceof Opcode::CopyValue }
+ CopyValueInstruction() { this.getOpcode() instanceof Opcode::CopyValue }
- final override UnaryOperand getSourceValueOperand() { result = getAnOperand() }
+ final override UnaryOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -863,47 +872,49 @@ private string getAddressOperandDescription(AddressOperand operand) {
* An instruction that returns a register result containing a copy of its memory operand.
*/
class LoadInstruction extends CopyInstruction {
- LoadInstruction() { getOpcode() instanceof Opcode::Load }
+ LoadInstruction() { this.getOpcode() instanceof Opcode::Load }
final override string getImmediateString() {
- result = getAddressOperandDescription(getSourceAddressOperand())
+ result = getAddressOperandDescription(this.getSourceAddressOperand())
}
/**
* Gets the operand that provides the address of the value being loaded.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the value being loaded.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
- final override LoadOperand getSourceValueOperand() { result = getAnOperand() }
+ final override LoadOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
* An instruction that returns a memory result containing a copy of its register operand.
*/
class StoreInstruction extends CopyInstruction {
- StoreInstruction() { getOpcode() instanceof Opcode::Store }
+ StoreInstruction() { this.getOpcode() instanceof Opcode::Store }
final override string getImmediateString() {
- result = getAddressOperandDescription(getDestinationAddressOperand())
+ result = getAddressOperandDescription(this.getDestinationAddressOperand())
}
/**
* Gets the operand that provides the address of the location to which the value will be stored.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the location to which the value will
* be stored, if an exact definition is available.
*/
- final Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ final Instruction getDestinationAddress() {
+ result = this.getDestinationAddressOperand().getDef()
+ }
- final override StoreValueOperand getSourceValueOperand() { result = getAnOperand() }
+ final override StoreValueOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -911,27 +922,27 @@ class StoreInstruction extends CopyInstruction {
* operand.
*/
class ConditionalBranchInstruction extends Instruction {
- ConditionalBranchInstruction() { getOpcode() instanceof Opcode::ConditionalBranch }
+ ConditionalBranchInstruction() { this.getOpcode() instanceof Opcode::ConditionalBranch }
/**
* Gets the operand that provides the Boolean condition controlling the branch.
*/
- final ConditionOperand getConditionOperand() { result = getAnOperand() }
+ final ConditionOperand getConditionOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the Boolean condition controlling the branch.
*/
- final Instruction getCondition() { result = getConditionOperand().getDef() }
+ final Instruction getCondition() { result = this.getConditionOperand().getDef() }
/**
* Gets the instruction to which control will flow if the condition is true.
*/
- final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }
+ final Instruction getTrueSuccessor() { result = this.getSuccessor(EdgeKind::trueEdge()) }
/**
* Gets the instruction to which control will flow if the condition is false.
*/
- final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
+ final Instruction getFalseSuccessor() { result = this.getSuccessor(EdgeKind::falseEdge()) }
}
/**
@@ -943,14 +954,14 @@ class ConditionalBranchInstruction extends Instruction {
* successors.
*/
class ExitFunctionInstruction extends Instruction {
- ExitFunctionInstruction() { getOpcode() instanceof Opcode::ExitFunction }
+ ExitFunctionInstruction() { this.getOpcode() instanceof Opcode::ExitFunction }
}
/**
* An instruction whose result is a constant value.
*/
class ConstantInstruction extends ConstantValueInstruction {
- ConstantInstruction() { getOpcode() instanceof Opcode::Constant }
+ ConstantInstruction() { this.getOpcode() instanceof Opcode::Constant }
}
/**
@@ -959,7 +970,7 @@ class ConstantInstruction extends ConstantValueInstruction {
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
exists(IRType resultType |
- resultType = getResultIRType() and
+ resultType = this.getResultIRType() and
(resultType instanceof IRIntegerType or resultType instanceof IRBooleanType)
)
}
@@ -969,7 +980,7 @@ class IntegerConstantInstruction extends ConstantInstruction {
* An instruction whose result is a constant value of floating-point type.
*/
class FloatConstantInstruction extends ConstantInstruction {
- FloatConstantInstruction() { getResultIRType() instanceof IRFloatingPointType }
+ FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType }
}
/**
@@ -978,7 +989,9 @@ class FloatConstantInstruction extends ConstantInstruction {
class StringConstantInstruction extends VariableInstruction {
override IRStringLiteral var;
- final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) }
+ final override string getImmediateString() {
+ result = Language::getStringLiteralText(this.getValue())
+ }
/**
* Gets the string literal whose address is returned by this instruction.
@@ -990,37 +1003,37 @@ class StringConstantInstruction extends VariableInstruction {
* An instruction whose result is computed from two operands.
*/
class BinaryInstruction extends Instruction {
- BinaryInstruction() { getOpcode() instanceof BinaryOpcode }
+ BinaryInstruction() { this.getOpcode() instanceof BinaryOpcode }
/**
* Gets the left operand of this binary instruction.
*/
- final LeftOperand getLeftOperand() { result = getAnOperand() }
+ final LeftOperand getLeftOperand() { result = this.getAnOperand() }
/**
* Gets the right operand of this binary instruction.
*/
- final RightOperand getRightOperand() { result = getAnOperand() }
+ final RightOperand getRightOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the left operand of this binary
* instruction.
*/
- final Instruction getLeft() { result = getLeftOperand().getDef() }
+ final Instruction getLeft() { result = this.getLeftOperand().getDef() }
/**
* Gets the instruction whose result provides the value of the right operand of this binary
* instruction.
*/
- final Instruction getRight() { result = getRightOperand().getDef() }
+ final Instruction getRight() { result = this.getRightOperand().getDef() }
/**
* Holds if this instruction's operands are `op1` and `op2`, in either order.
*/
final predicate hasOperands(Operand op1, Operand op2) {
- op1 = getLeftOperand() and op2 = getRightOperand()
+ op1 = this.getLeftOperand() and op2 = this.getRightOperand()
or
- op1 = getRightOperand() and op2 = getLeftOperand()
+ op1 = this.getRightOperand() and op2 = this.getLeftOperand()
}
}
@@ -1028,7 +1041,7 @@ class BinaryInstruction extends Instruction {
* An instruction that computes the result of an arithmetic operation.
*/
class ArithmeticInstruction extends Instruction {
- ArithmeticInstruction() { getOpcode() instanceof ArithmeticOpcode }
+ ArithmeticInstruction() { this.getOpcode() instanceof ArithmeticOpcode }
}
/**
@@ -1050,7 +1063,7 @@ class UnaryArithmeticInstruction extends ArithmeticInstruction, UnaryInstruction
* performed according to IEEE-754.
*/
class AddInstruction extends BinaryArithmeticInstruction {
- AddInstruction() { getOpcode() instanceof Opcode::Add }
+ AddInstruction() { this.getOpcode() instanceof Opcode::Add }
}
/**
@@ -1061,7 +1074,7 @@ class AddInstruction extends BinaryArithmeticInstruction {
* according to IEEE-754.
*/
class SubInstruction extends BinaryArithmeticInstruction {
- SubInstruction() { getOpcode() instanceof Opcode::Sub }
+ SubInstruction() { this.getOpcode() instanceof Opcode::Sub }
}
/**
@@ -1072,7 +1085,7 @@ class SubInstruction extends BinaryArithmeticInstruction {
* performed according to IEEE-754.
*/
class MulInstruction extends BinaryArithmeticInstruction {
- MulInstruction() { getOpcode() instanceof Opcode::Mul }
+ MulInstruction() { this.getOpcode() instanceof Opcode::Mul }
}
/**
@@ -1083,7 +1096,7 @@ class MulInstruction extends BinaryArithmeticInstruction {
* to IEEE-754.
*/
class DivInstruction extends BinaryArithmeticInstruction {
- DivInstruction() { getOpcode() instanceof Opcode::Div }
+ DivInstruction() { this.getOpcode() instanceof Opcode::Div }
}
/**
@@ -1093,7 +1106,7 @@ class DivInstruction extends BinaryArithmeticInstruction {
* division by zero or integer overflow is undefined.
*/
class RemInstruction extends BinaryArithmeticInstruction {
- RemInstruction() { getOpcode() instanceof Opcode::Rem }
+ RemInstruction() { this.getOpcode() instanceof Opcode::Rem }
}
/**
@@ -1104,14 +1117,14 @@ class RemInstruction extends BinaryArithmeticInstruction {
* is performed according to IEEE-754.
*/
class NegateInstruction extends UnaryArithmeticInstruction {
- NegateInstruction() { getOpcode() instanceof Opcode::Negate }
+ NegateInstruction() { this.getOpcode() instanceof Opcode::Negate }
}
/**
* An instruction that computes the result of a bitwise operation.
*/
class BitwiseInstruction extends Instruction {
- BitwiseInstruction() { getOpcode() instanceof BitwiseOpcode }
+ BitwiseInstruction() { this.getOpcode() instanceof BitwiseOpcode }
}
/**
@@ -1130,7 +1143,7 @@ class UnaryBitwiseInstruction extends BitwiseInstruction, UnaryInstruction { }
* Both operands must have the same integer type, which will also be the result type.
*/
class BitAndInstruction extends BinaryBitwiseInstruction {
- BitAndInstruction() { getOpcode() instanceof Opcode::BitAnd }
+ BitAndInstruction() { this.getOpcode() instanceof Opcode::BitAnd }
}
/**
@@ -1139,7 +1152,7 @@ class BitAndInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitOrInstruction extends BinaryBitwiseInstruction {
- BitOrInstruction() { getOpcode() instanceof Opcode::BitOr }
+ BitOrInstruction() { this.getOpcode() instanceof Opcode::BitOr }
}
/**
@@ -1148,7 +1161,7 @@ class BitOrInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitXorInstruction extends BinaryBitwiseInstruction {
- BitXorInstruction() { getOpcode() instanceof Opcode::BitXor }
+ BitXorInstruction() { this.getOpcode() instanceof Opcode::BitXor }
}
/**
@@ -1159,7 +1172,7 @@ class BitXorInstruction extends BinaryBitwiseInstruction {
* rightmost bits are zero-filled.
*/
class ShiftLeftInstruction extends BinaryBitwiseInstruction {
- ShiftLeftInstruction() { getOpcode() instanceof Opcode::ShiftLeft }
+ ShiftLeftInstruction() { this.getOpcode() instanceof Opcode::ShiftLeft }
}
/**
@@ -1172,7 +1185,7 @@ class ShiftLeftInstruction extends BinaryBitwiseInstruction {
* of the left operand.
*/
class ShiftRightInstruction extends BinaryBitwiseInstruction {
- ShiftRightInstruction() { getOpcode() instanceof Opcode::ShiftRight }
+ ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
@@ -1183,7 +1196,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
int elementSize;
PointerArithmeticInstruction() {
- getOpcode() instanceof PointerArithmeticOpcode and
+ this.getOpcode() instanceof PointerArithmeticOpcode and
elementSize = Raw::getInstructionElementSize(this)
}
@@ -1206,7 +1219,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
* An instruction that adds or subtracts an integer offset from a pointer.
*/
class PointerOffsetInstruction extends PointerArithmeticInstruction {
- PointerOffsetInstruction() { getOpcode() instanceof PointerOffsetOpcode }
+ PointerOffsetInstruction() { this.getOpcode() instanceof PointerOffsetOpcode }
}
/**
@@ -1217,7 +1230,7 @@ class PointerOffsetInstruction extends PointerArithmeticInstruction {
* overflow is undefined.
*/
class PointerAddInstruction extends PointerOffsetInstruction {
- PointerAddInstruction() { getOpcode() instanceof Opcode::PointerAdd }
+ PointerAddInstruction() { this.getOpcode() instanceof Opcode::PointerAdd }
}
/**
@@ -1228,7 +1241,7 @@ class PointerAddInstruction extends PointerOffsetInstruction {
* pointer underflow is undefined.
*/
class PointerSubInstruction extends PointerOffsetInstruction {
- PointerSubInstruction() { getOpcode() instanceof Opcode::PointerSub }
+ PointerSubInstruction() { this.getOpcode() instanceof Opcode::PointerSub }
}
/**
@@ -1241,31 +1254,31 @@ class PointerSubInstruction extends PointerOffsetInstruction {
* undefined.
*/
class PointerDiffInstruction extends PointerArithmeticInstruction {
- PointerDiffInstruction() { getOpcode() instanceof Opcode::PointerDiff }
+ PointerDiffInstruction() { this.getOpcode() instanceof Opcode::PointerDiff }
}
/**
* An instruction whose result is computed from a single operand.
*/
class UnaryInstruction extends Instruction {
- UnaryInstruction() { getOpcode() instanceof UnaryOpcode }
+ UnaryInstruction() { this.getOpcode() instanceof UnaryOpcode }
/**
* Gets the sole operand of this instruction.
*/
- final UnaryOperand getUnaryOperand() { result = getAnOperand() }
+ final UnaryOperand getUnaryOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the sole operand of this instruction.
*/
- final Instruction getUnary() { result = getUnaryOperand().getDef() }
+ final Instruction getUnary() { result = this.getUnaryOperand().getDef() }
}
/**
* An instruction that converts the value of its operand to a value of a different type.
*/
class ConvertInstruction extends UnaryInstruction {
- ConvertInstruction() { getOpcode() instanceof Opcode::Convert }
+ ConvertInstruction() { this.getOpcode() instanceof Opcode::Convert }
}
/**
@@ -1279,7 +1292,7 @@ class ConvertInstruction extends UnaryInstruction {
* `as` expression.
*/
class CheckedConvertOrNullInstruction extends UnaryInstruction {
- CheckedConvertOrNullInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrNull }
+ CheckedConvertOrNullInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrNull }
}
/**
@@ -1293,7 +1306,7 @@ class CheckedConvertOrNullInstruction extends UnaryInstruction {
* expression.
*/
class CheckedConvertOrThrowInstruction extends UnaryInstruction {
- CheckedConvertOrThrowInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrThrow }
+ CheckedConvertOrThrowInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrThrow }
}
/**
@@ -1306,7 +1319,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {
- CompleteObjectAddressInstruction() { getOpcode() instanceof Opcode::CompleteObjectAddress }
+ CompleteObjectAddressInstruction() { this.getOpcode() instanceof Opcode::CompleteObjectAddress }
}
/**
@@ -1351,7 +1364,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* An instruction that converts from the address of a derived class to the address of a base class.
*/
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
- ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode }
+ ConvertToBaseInstruction() { this.getOpcode() instanceof ConvertToBaseOpcode }
}
/**
@@ -1361,7 +1374,9 @@ class ConvertToBaseInstruction extends InheritanceConversionInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase }
+ ConvertToNonVirtualBaseInstruction() {
+ this.getOpcode() instanceof Opcode::ConvertToNonVirtualBase
+ }
}
/**
@@ -1371,7 +1386,7 @@ class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase }
+ ConvertToVirtualBaseInstruction() { this.getOpcode() instanceof Opcode::ConvertToVirtualBase }
}
/**
@@ -1381,7 +1396,7 @@ class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
- ConvertToDerivedInstruction() { getOpcode() instanceof Opcode::ConvertToDerived }
+ ConvertToDerivedInstruction() { this.getOpcode() instanceof Opcode::ConvertToDerived }
}
/**
@@ -1390,7 +1405,7 @@ class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
* The operand must have an integer type, which will also be the result type.
*/
class BitComplementInstruction extends UnaryBitwiseInstruction {
- BitComplementInstruction() { getOpcode() instanceof Opcode::BitComplement }
+ BitComplementInstruction() { this.getOpcode() instanceof Opcode::BitComplement }
}
/**
@@ -1399,14 +1414,14 @@ class BitComplementInstruction extends UnaryBitwiseInstruction {
* The operand must have a Boolean type, which will also be the result type.
*/
class LogicalNotInstruction extends UnaryInstruction {
- LogicalNotInstruction() { getOpcode() instanceof Opcode::LogicalNot }
+ LogicalNotInstruction() { this.getOpcode() instanceof Opcode::LogicalNot }
}
/**
* An instruction that compares two numeric operands.
*/
class CompareInstruction extends BinaryInstruction {
- CompareInstruction() { getOpcode() instanceof CompareOpcode }
+ CompareInstruction() { this.getOpcode() instanceof CompareOpcode }
}
/**
@@ -1417,7 +1432,7 @@ class CompareInstruction extends BinaryInstruction {
* unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareEQInstruction extends CompareInstruction {
- CompareEQInstruction() { getOpcode() instanceof Opcode::CompareEQ }
+ CompareEQInstruction() { this.getOpcode() instanceof Opcode::CompareEQ }
}
/**
@@ -1428,14 +1443,14 @@ class CompareEQInstruction extends CompareInstruction {
* `left == right`. Floating-point comparison is performed according to IEEE-754.
*/
class CompareNEInstruction extends CompareInstruction {
- CompareNEInstruction() { getOpcode() instanceof Opcode::CompareNE }
+ CompareNEInstruction() { this.getOpcode() instanceof Opcode::CompareNE }
}
/**
* An instruction that does a relative comparison of two values, such as `<` or `>=`.
*/
class RelationalInstruction extends CompareInstruction {
- RelationalInstruction() { getOpcode() instanceof RelationalOpcode }
+ RelationalInstruction() { this.getOpcode() instanceof RelationalOpcode }
/**
* Gets the operand on the "greater" (or "greater-or-equal") side
@@ -1467,11 +1482,11 @@ class RelationalInstruction extends CompareInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLTInstruction extends RelationalInstruction {
- CompareLTInstruction() { getOpcode() instanceof Opcode::CompareLT }
+ CompareLTInstruction() { this.getOpcode() instanceof Opcode::CompareLT }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { any() }
}
@@ -1484,11 +1499,11 @@ class CompareLTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGTInstruction extends RelationalInstruction {
- CompareGTInstruction() { getOpcode() instanceof Opcode::CompareGT }
+ CompareGTInstruction() { this.getOpcode() instanceof Opcode::CompareGT }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { any() }
}
@@ -1502,11 +1517,11 @@ class CompareGTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLEInstruction extends RelationalInstruction {
- CompareLEInstruction() { getOpcode() instanceof Opcode::CompareLE }
+ CompareLEInstruction() { this.getOpcode() instanceof Opcode::CompareLE }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { none() }
}
@@ -1520,11 +1535,11 @@ class CompareLEInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGEInstruction extends RelationalInstruction {
- CompareGEInstruction() { getOpcode() instanceof Opcode::CompareGE }
+ CompareGEInstruction() { this.getOpcode() instanceof Opcode::CompareGE }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { none() }
}
@@ -1543,78 +1558,78 @@ class CompareGEInstruction extends RelationalInstruction {
* of any case edge.
*/
class SwitchInstruction extends Instruction {
- SwitchInstruction() { getOpcode() instanceof Opcode::Switch }
+ SwitchInstruction() { this.getOpcode() instanceof Opcode::Switch }
/** Gets the operand that provides the integer value controlling the switch. */
- final ConditionOperand getExpressionOperand() { result = getAnOperand() }
+ final ConditionOperand getExpressionOperand() { result = this.getAnOperand() }
/** Gets the instruction whose result provides the integer value controlling the switch. */
- final Instruction getExpression() { result = getExpressionOperand().getDef() }
+ final Instruction getExpression() { result = this.getExpressionOperand().getDef() }
/** Gets the successor instructions along the case edges of the switch. */
- final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }
+ final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = this.getSuccessor(edge)) }
/** Gets the successor instruction along the default edge of the switch, if any. */
- final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
+ final Instruction getDefaultSuccessor() { result = this.getSuccessor(EdgeKind::defaultEdge()) }
}
/**
* An instruction that calls a function.
*/
class CallInstruction extends Instruction {
- CallInstruction() { getOpcode() instanceof Opcode::Call }
+ CallInstruction() { this.getOpcode() instanceof Opcode::Call }
final override string getImmediateString() {
- result = getStaticCallTarget().toString()
+ result = this.getStaticCallTarget().toString()
or
- not exists(getStaticCallTarget()) and result = "?"
+ not exists(this.getStaticCallTarget()) and result = "?"
}
/**
* Gets the operand the specifies the target function of the call.
*/
- final CallTargetOperand getCallTargetOperand() { result = getAnOperand() }
+ final CallTargetOperand getCallTargetOperand() { result = this.getAnOperand() }
/**
* Gets the `Instruction` that computes the target function of the call. This is usually a
* `FunctionAddress` instruction, but can also be an arbitrary instruction that produces a
* function pointer.
*/
- final Instruction getCallTarget() { result = getCallTargetOperand().getDef() }
+ final Instruction getCallTarget() { result = this.getCallTargetOperand().getDef() }
/**
* Gets all of the argument operands of the call, including the `this` pointer, if any.
*/
- final ArgumentOperand getAnArgumentOperand() { result = getAnOperand() }
+ final ArgumentOperand getAnArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
final Language::Function getStaticCallTarget() {
- result = getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
+ result = this.getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
}
/**
* Gets all of the arguments of the call, including the `this` pointer, if any.
*/
- final Instruction getAnArgument() { result = getAnArgumentOperand().getDef() }
+ final Instruction getAnArgument() { result = this.getAnArgumentOperand().getDef() }
/**
* Gets the `this` pointer argument operand of the call, if any.
*/
- final ThisArgumentOperand getThisArgumentOperand() { result = getAnOperand() }
+ final ThisArgumentOperand getThisArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `this` pointer argument of the call, if any.
*/
- final Instruction getThisArgument() { result = getThisArgumentOperand().getDef() }
+ final Instruction getThisArgument() { result = this.getThisArgumentOperand().getDef() }
/**
* Gets the argument operand at the specified index.
*/
pragma[noinline]
final PositionalArgumentOperand getPositionalArgumentOperand(int index) {
- result = getAnOperand() and
+ result = this.getAnOperand() and
result.getIndex() = index
}
@@ -1623,7 +1638,7 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final Instruction getPositionalArgument(int index) {
- result = getPositionalArgumentOperand(index).getDef()
+ result = this.getPositionalArgumentOperand(index).getDef()
}
/**
@@ -1631,16 +1646,16 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final ArgumentOperand getArgumentOperand(int index) {
- index >= 0 and result = getPositionalArgumentOperand(index)
+ index >= 0 and result = this.getPositionalArgumentOperand(index)
or
- index = -1 and result = getThisArgumentOperand()
+ index = -1 and result = this.getThisArgumentOperand()
}
/**
* Gets the argument at the specified index, or `this` if `index` is `-1`.
*/
pragma[noinline]
- final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() }
+ final Instruction getArgument(int index) { result = this.getArgumentOperand(index).getDef() }
/**
* Gets the number of arguments of the call, including the `this` pointer, if any.
@@ -1665,7 +1680,7 @@ class CallInstruction extends Instruction {
* An instruction representing a side effect of a function call.
*/
class SideEffectInstruction extends Instruction {
- SideEffectInstruction() { getOpcode() instanceof SideEffectOpcode }
+ SideEffectInstruction() { this.getOpcode() instanceof SideEffectOpcode }
/**
* Gets the instruction whose execution causes this side effect.
@@ -1680,7 +1695,7 @@ class SideEffectInstruction extends Instruction {
* accessed by that call.
*/
class CallSideEffectInstruction extends SideEffectInstruction {
- CallSideEffectInstruction() { getOpcode() instanceof Opcode::CallSideEffect }
+ CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
}
/**
@@ -1691,7 +1706,7 @@ class CallSideEffectInstruction extends SideEffectInstruction {
* call target cannot write to escaped memory.
*/
class CallReadSideEffectInstruction extends SideEffectInstruction {
- CallReadSideEffectInstruction() { getOpcode() instanceof Opcode::CallReadSideEffect }
+ CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
}
/**
@@ -1699,33 +1714,33 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
* specific parameter.
*/
class ReadSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- ReadSideEffectInstruction() { getOpcode() instanceof ReadSideEffectOpcode }
+ ReadSideEffectInstruction() { this.getOpcode() instanceof ReadSideEffectOpcode }
/** Gets the operand for the value that will be read from this instruction, if known. */
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/** Gets the value that will be read from this instruction, if known. */
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/** Gets the operand for the address from which this instruction may read. */
- final AddressOperand getArgumentOperand() { result = getAnOperand() }
+ final AddressOperand getArgumentOperand() { result = this.getAnOperand() }
/** Gets the address from which this instruction may read. */
- final Instruction getArgumentDef() { result = getArgumentOperand().getDef() }
+ final Instruction getArgumentDef() { result = this.getArgumentOperand().getDef() }
}
/**
* An instruction representing the read of an indirect parameter within a function call.
*/
class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
- IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
+ IndirectReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::IndirectReadSideEffect }
}
/**
* An instruction representing the read of an indirect buffer parameter within a function call.
*/
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
- BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
+ BufferReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::BufferReadSideEffect }
}
/**
@@ -1733,18 +1748,18 @@ class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
*/
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
SizedBufferReadSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferReadSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferReadSideEffect
}
/**
* Gets the operand that holds the number of bytes read from the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes read from the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1752,17 +1767,17 @@ class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
* specific parameter.
*/
class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
+ WriteSideEffectInstruction() { this.getOpcode() instanceof WriteSideEffectOpcode }
/**
* Get the operand that holds the address of the memory to be written.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the memory to be written.
*/
- Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ Instruction getDestinationAddress() { result = this.getDestinationAddressOperand().getDef() }
}
/**
@@ -1770,7 +1785,7 @@ class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstructi
*/
class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
}
}
@@ -1780,7 +1795,7 @@ class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction
*/
class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
BufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::BufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::BufferMustWriteSideEffect
}
}
@@ -1790,18 +1805,18 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1812,7 +1827,7 @@ class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstructi
*/
class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
}
}
@@ -1822,7 +1837,9 @@ class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
* Unlike `BufferWriteSideEffectInstruction`, the buffer might not be completely overwritten.
*/
class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
- BufferMayWriteSideEffectInstruction() { getOpcode() instanceof Opcode::BufferMayWriteSideEffect }
+ BufferMayWriteSideEffectInstruction() {
+ this.getOpcode() instanceof Opcode::BufferMayWriteSideEffect
+ }
}
/**
@@ -1832,18 +1849,18 @@ class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1852,80 +1869,80 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio
*/
class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
InitializeDynamicAllocationInstruction() {
- getOpcode() instanceof Opcode::InitializeDynamicAllocation
+ this.getOpcode() instanceof Opcode::InitializeDynamicAllocation
}
/**
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
- final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getAllocationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address for the allocation this instruction is initializing.
*/
- final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
+ final Instruction getAllocationAddress() { result = this.getAllocationAddressOperand().getDef() }
}
/**
* An instruction representing a GNU or MSVC inline assembly statement.
*/
class InlineAsmInstruction extends Instruction {
- InlineAsmInstruction() { getOpcode() instanceof Opcode::InlineAsm }
+ InlineAsmInstruction() { this.getOpcode() instanceof Opcode::InlineAsm }
}
/**
* An instruction that throws an exception.
*/
class ThrowInstruction extends Instruction {
- ThrowInstruction() { getOpcode() instanceof ThrowOpcode }
+ ThrowInstruction() { this.getOpcode() instanceof ThrowOpcode }
}
/**
* An instruction that throws a new exception.
*/
class ThrowValueInstruction extends ThrowInstruction {
- ThrowValueInstruction() { getOpcode() instanceof Opcode::ThrowValue }
+ ThrowValueInstruction() { this.getOpcode() instanceof Opcode::ThrowValue }
/**
* Gets the address operand of the exception thrown by this instruction.
*/
- final AddressOperand getExceptionAddressOperand() { result = getAnOperand() }
+ final AddressOperand getExceptionAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address of the exception thrown by this instruction.
*/
- final Instruction getExceptionAddress() { result = getExceptionAddressOperand().getDef() }
+ final Instruction getExceptionAddress() { result = this.getExceptionAddressOperand().getDef() }
/**
* Gets the operand for the exception thrown by this instruction.
*/
- final LoadOperand getExceptionOperand() { result = getAnOperand() }
+ final LoadOperand getExceptionOperand() { result = this.getAnOperand() }
/**
* Gets the exception thrown by this instruction.
*/
- final Instruction getException() { result = getExceptionOperand().getDef() }
+ final Instruction getException() { result = this.getExceptionOperand().getDef() }
}
/**
* An instruction that re-throws the current exception.
*/
class ReThrowInstruction extends ThrowInstruction {
- ReThrowInstruction() { getOpcode() instanceof Opcode::ReThrow }
+ ReThrowInstruction() { this.getOpcode() instanceof Opcode::ReThrow }
}
/**
* An instruction that exits the current function by propagating an exception.
*/
class UnwindInstruction extends Instruction {
- UnwindInstruction() { getOpcode() instanceof Opcode::Unwind }
+ UnwindInstruction() { this.getOpcode() instanceof Opcode::Unwind }
}
/**
* An instruction that starts a `catch` handler.
*/
class CatchInstruction extends Instruction {
- CatchInstruction() { getOpcode() instanceof CatchOpcode }
+ CatchInstruction() { this.getOpcode() instanceof CatchOpcode }
}
/**
@@ -1935,7 +1952,7 @@ class CatchByTypeInstruction extends CatchInstruction {
Language::LanguageType exceptionType;
CatchByTypeInstruction() {
- getOpcode() instanceof Opcode::CatchByType and
+ this.getOpcode() instanceof Opcode::CatchByType and
exceptionType = Raw::getInstructionExceptionType(this)
}
@@ -1951,21 +1968,21 @@ class CatchByTypeInstruction extends CatchInstruction {
* An instruction that catches any exception.
*/
class CatchAnyInstruction extends CatchInstruction {
- CatchAnyInstruction() { getOpcode() instanceof Opcode::CatchAny }
+ CatchAnyInstruction() { this.getOpcode() instanceof Opcode::CatchAny }
}
/**
* An instruction that initializes all escaped memory.
*/
class AliasedDefinitionInstruction extends Instruction {
- AliasedDefinitionInstruction() { getOpcode() instanceof Opcode::AliasedDefinition }
+ AliasedDefinitionInstruction() { this.getOpcode() instanceof Opcode::AliasedDefinition }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
- AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
+ AliasedUseInstruction() { this.getOpcode() instanceof Opcode::AliasedUse }
}
/**
@@ -1979,7 +1996,7 @@ class AliasedUseInstruction extends Instruction {
* runtime.
*/
class PhiInstruction extends Instruction {
- PhiInstruction() { getOpcode() instanceof Opcode::Phi }
+ PhiInstruction() { this.getOpcode() instanceof Opcode::Phi }
/**
* Gets all of the instruction's `PhiInputOperand`s, representing the values that flow from each predecessor block.
@@ -2047,29 +2064,29 @@ class PhiInstruction extends Instruction {
* https://link.springer.com/content/pdf/10.1007%2F3-540-61053-7_66.pdf.
*/
class ChiInstruction extends Instruction {
- ChiInstruction() { getOpcode() instanceof Opcode::Chi }
+ ChiInstruction() { this.getOpcode() instanceof Opcode::Chi }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final ChiTotalOperand getTotalOperand() { result = getAnOperand() }
+ final ChiTotalOperand getTotalOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final Instruction getTotal() { result = getTotalOperand().getDef() }
+ final Instruction getTotal() { result = this.getTotalOperand().getDef() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final ChiPartialOperand getPartialOperand() { result = getAnOperand() }
+ final ChiPartialOperand getPartialOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final Instruction getPartial() { result = getPartialOperand().getDef() }
+ final Instruction getPartial() { result = this.getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
@@ -2093,7 +2110,7 @@ class ChiInstruction extends Instruction {
* or `Switch` instruction where that particular edge is infeasible.
*/
class UnreachedInstruction extends Instruction {
- UnreachedInstruction() { getOpcode() instanceof Opcode::Unreached }
+ UnreachedInstruction() { this.getOpcode() instanceof Opcode::Unreached }
}
/**
@@ -2106,7 +2123,7 @@ class BuiltInOperationInstruction extends Instruction {
Language::BuiltInOperation operation;
BuiltInOperationInstruction() {
- getOpcode() instanceof BuiltInOperationOpcode and
+ this.getOpcode() instanceof BuiltInOperationOpcode and
operation = Raw::getInstructionBuiltInOperation(this)
}
@@ -2122,9 +2139,9 @@ class BuiltInOperationInstruction extends Instruction {
* actual operation is specified by the `getBuiltInOperation()` predicate.
*/
class BuiltInInstruction extends BuiltInOperationInstruction {
- BuiltInInstruction() { getOpcode() instanceof Opcode::BuiltIn }
+ BuiltInInstruction() { this.getOpcode() instanceof Opcode::BuiltIn }
- final override string getImmediateString() { result = getBuiltInOperation().toString() }
+ final override string getImmediateString() { result = this.getBuiltInOperation().toString() }
}
/**
@@ -2135,7 +2152,7 @@ class BuiltInInstruction extends BuiltInOperationInstruction {
* to the `...` parameter.
*/
class VarArgsStartInstruction extends UnaryInstruction {
- VarArgsStartInstruction() { getOpcode() instanceof Opcode::VarArgsStart }
+ VarArgsStartInstruction() { this.getOpcode() instanceof Opcode::VarArgsStart }
}
/**
@@ -2145,7 +2162,7 @@ class VarArgsStartInstruction extends UnaryInstruction {
* a result.
*/
class VarArgsEndInstruction extends UnaryInstruction {
- VarArgsEndInstruction() { getOpcode() instanceof Opcode::VarArgsEnd }
+ VarArgsEndInstruction() { this.getOpcode() instanceof Opcode::VarArgsEnd }
}
/**
@@ -2155,7 +2172,7 @@ class VarArgsEndInstruction extends UnaryInstruction {
* argument.
*/
class VarArgInstruction extends UnaryInstruction {
- VarArgInstruction() { getOpcode() instanceof Opcode::VarArg }
+ VarArgInstruction() { this.getOpcode() instanceof Opcode::VarArg }
}
/**
@@ -2166,7 +2183,7 @@ class VarArgInstruction extends UnaryInstruction {
* argument of the `...` parameter.
*/
class NextVarArgInstruction extends UnaryInstruction {
- NextVarArgInstruction() { getOpcode() instanceof Opcode::NextVarArg }
+ NextVarArgInstruction() { this.getOpcode() instanceof Opcode::NextVarArg }
}
/**
@@ -2180,5 +2197,5 @@ class NextVarArgInstruction extends UnaryInstruction {
* The result is the address of the newly allocated object.
*/
class NewObjInstruction extends Instruction {
- NewObjInstruction() { getOpcode() instanceof Opcode::NewObj }
+ NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll
index d7cf89ca9aa..85d217bd361 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll
@@ -46,12 +46,12 @@ class Operand extends TStageOperand {
/**
* Gets the location of the source code for this operand.
*/
- final Language::Location getLocation() { result = getUse().getLocation() }
+ final Language::Location getLocation() { result = this.getUse().getLocation() }
/**
* Gets the function that contains this operand.
*/
- final IRFunction getEnclosingIRFunction() { result = getUse().getEnclosingIRFunction() }
+ final IRFunction getEnclosingIRFunction() { result = this.getUse().getEnclosingIRFunction() }
/**
* Gets the `Instruction` that consumes this operand.
@@ -74,7 +74,7 @@ class Operand extends TStageOperand {
*/
final Instruction getDef() {
result = this.getAnyDef() and
- getDefinitionOverlap() instanceof MustExactlyOverlap
+ this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
@@ -82,7 +82,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` that consumes this operand.
*/
- deprecated final Instruction getUseInstruction() { result = getUse() }
+ deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
@@ -91,7 +91,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` whose result is the value of the operand.
*/
- deprecated final Instruction getDefinitionInstruction() { result = getAnyDef() }
+ deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
@@ -101,7 +101,9 @@ class Operand extends TStageOperand {
/**
* Holds if the result of the definition instruction does not exactly overlap this use.
*/
- final predicate isDefinitionInexact() { not getDefinitionOverlap() instanceof MustExactlyOverlap }
+ final predicate isDefinitionInexact() {
+ not this.getDefinitionOverlap() instanceof MustExactlyOverlap
+ }
/**
* Gets a prefix to use when dumping the operand in an operand list.
@@ -121,7 +123,7 @@ class Operand extends TStageOperand {
* For example: `this:r3_5`
*/
final string getDumpString() {
- result = getDumpLabel() + getInexactSpecifier() + getDefinitionId()
+ result = this.getDumpLabel() + this.getInexactSpecifier() + this.getDefinitionId()
}
/**
@@ -129,9 +131,9 @@ class Operand extends TStageOperand {
* definition is not modeled in SSA.
*/
private string getDefinitionId() {
- result = getAnyDef().getResultId()
+ result = this.getAnyDef().getResultId()
or
- not exists(getAnyDef()) and result = "m?"
+ not exists(this.getAnyDef()) and result = "m?"
}
/**
@@ -140,7 +142,7 @@ class Operand extends TStageOperand {
* the empty string.
*/
private string getInexactSpecifier() {
- if isDefinitionInexact() then result = "~" else result = ""
+ if this.isDefinitionInexact() then result = "~" else result = ""
}
/**
@@ -155,7 +157,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- Language::LanguageType getLanguageType() { result = getAnyDef().getResultLanguageType() }
+ Language::LanguageType getLanguageType() { result = this.getAnyDef().getResultLanguageType() }
/**
* Gets the language-neutral type of the value consumed by this operand. This is usually the same
@@ -164,7 +166,7 @@ class Operand extends TStageOperand {
* from the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final IRType getIRType() { result = getLanguageType().getIRType() }
+ final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the value consumed by this operand. This is usually the same as the
@@ -173,7 +175,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final Language::Type getType() { getLanguageType().hasType(result, _) }
+ final Language::Type getType() { this.getLanguageType().hasType(result, _) }
/**
* Holds if the value consumed by this operand is a glvalue. If this
@@ -182,13 +184,13 @@ class Operand extends TStageOperand {
* not hold, the value of the operand represents a value whose type is
* given by `getType()`.
*/
- final predicate isGLValue() { getLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getLanguageType().hasType(_, true) }
/**
* Gets the size of the value consumed by this operand, in bytes. If the operand does not have
* a known constant size, this predicate does not hold.
*/
- final int getSize() { result = getLanguageType().getByteSize() }
+ final int getSize() { result = this.getLanguageType().getByteSize() }
}
/**
@@ -205,7 +207,7 @@ class MemoryOperand extends Operand {
/**
* Gets the kind of memory access performed by the operand.
*/
- MemoryAccessKind getMemoryAccess() { result = getUse().getOpcode().getReadMemoryAccess() }
+ MemoryAccessKind getMemoryAccess() { result = this.getUse().getOpcode().getReadMemoryAccess() }
/**
* Holds if the memory access performed by this operand will not always read from every bit in the
@@ -215,7 +217,7 @@ class MemoryOperand extends Operand {
* conservative estimate of the memory that might actually be accessed at runtime (for example,
* the global side effects of a function call).
*/
- predicate hasMayReadMemoryAccess() { getUse().getOpcode().hasMayReadMemoryAccess() }
+ predicate hasMayReadMemoryAccess() { this.getUse().getOpcode().hasMayReadMemoryAccess() }
/**
* Returns the operand that holds the memory address from which the current operand loads its
@@ -223,8 +225,8 @@ class MemoryOperand extends Operand {
* is `r1`.
*/
final AddressOperand getAddressOperand() {
- getMemoryAccess().usesAddressOperand() and
- result.getUse() = getUse()
+ this.getMemoryAccess().usesAddressOperand() and
+ result.getUse() = this.getUse()
}
}
@@ -294,7 +296,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
- final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
+ final override Overlap getDefinitionOverlap() { this.hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
@@ -449,13 +451,17 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
final override Overlap getDefinitionOverlap() { result = overlap }
- final override int getDumpSortOrder() { result = 11 + getPredecessorBlock().getDisplayIndex() }
-
- final override string getDumpLabel() {
- result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
+ final override int getDumpSortOrder() {
+ result = 11 + this.getPredecessorBlock().getDisplayIndex()
}
- final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
+ final override string getDumpLabel() {
+ result = "from " + this.getPredecessorBlock().getDisplayIndex().toString() + ":"
+ }
+
+ final override string getDumpId() {
+ result = this.getPredecessorBlock().getDisplayIndex().toString()
+ }
/**
* Gets the predecessor block from which this value comes.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerInterval.qll b/cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerInterval.qll
index cd12b9b627a..4f8f4b4e672 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerInterval.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/internal/IntegerInterval.qll
@@ -18,10 +18,11 @@ Overlap getOverlap(IntValue defStart, IntValue defEnd, IntValue useStart, IntVal
else
if isLE(defStart, useStart) and isGE(defEnd, useEnd)
then result instanceof MustTotallyOverlap
- else
- if isLE(defEnd, useStart) or isGE(defStart, useEnd)
- then none()
- else result instanceof MayPartiallyOverlap
+ else (
+ not isLE(defEnd, useStart) and
+ not isGE(defStart, useEnd) and
+ result instanceof MayPartiallyOverlap
+ )
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/metrics/MetricClass.qll b/cpp/ql/lib/semmle/code/cpp/metrics/MetricClass.qll
index 33a256ce3e5..496e3f4511d 100644
--- a/cpp/ql/lib/semmle/code/cpp/metrics/MetricClass.qll
+++ b/cpp/ql/lib/semmle/code/cpp/metrics/MetricClass.qll
@@ -366,7 +366,7 @@ class MetricClass extends Class {
1 +
count(string s |
exists(Operation op | op = this.getAnEnclosedExpression() and s = op.getOperator())
- ) + count(string s | s = getAUsedHalsteadN1Operator())
+ ) + count(string s | s = this.getAUsedHalsteadN1Operator())
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/metrics/MetricFile.qll b/cpp/ql/lib/semmle/code/cpp/metrics/MetricFile.qll
index f12d1011865..b3838ce4a5a 100644
--- a/cpp/ql/lib/semmle/code/cpp/metrics/MetricFile.qll
+++ b/cpp/ql/lib/semmle/code/cpp/metrics/MetricFile.qll
@@ -134,7 +134,7 @@ class MetricFile extends File {
result =
// avoid 0 values
1 + count(string s | exists(Operation op | op.getFile() = this and s = op.getOperator())) +
- count(string s | s = getAUsedHalsteadN1Operator())
+ count(string s | s = this.getAUsedHalsteadN1Operator())
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/metrics/MetricFunction.qll b/cpp/ql/lib/semmle/code/cpp/metrics/MetricFunction.qll
index 45036cfddf3..960e06c8375 100644
--- a/cpp/ql/lib/semmle/code/cpp/metrics/MetricFunction.qll
+++ b/cpp/ql/lib/semmle/code/cpp/metrics/MetricFunction.qll
@@ -41,7 +41,7 @@ class MetricFunction extends Function {
* `&&`, and `||`) plus one.
*/
int getCyclomaticComplexity() {
- result = 1 + cyclomaticComplexityBranches(getBlock()) and
+ result = 1 + cyclomaticComplexityBranches(this.getBlock()) and
not this.isMultiplyDefined()
}
@@ -295,7 +295,7 @@ class MetricFunction extends Function {
int getNestingDepth() {
result =
max(Stmt s, int aDepth | s.getEnclosingFunction() = this and nestingDepth(s, aDepth) | aDepth) and
- not isMultiplyDefined()
+ not this.isMultiplyDefined()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll
index f6e40d140bd..3eed4341cce 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll
@@ -36,3 +36,4 @@ private import implementations.Select
private import implementations.MySql
private import implementations.SqLite3
private import implementations.PostgreSql
+private import implementations.System
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Allocation.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Allocation.qll
index 25dae1c2fd1..1da6e3b0b3b 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Allocation.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Allocation.qll
@@ -15,10 +15,10 @@ private class MallocAllocationFunction extends AllocationFunction {
MallocAllocationFunction() {
// --- C library allocation
- hasGlobalOrStdOrBslName("malloc") and // malloc(size)
+ this.hasGlobalOrStdOrBslName("malloc") and // malloc(size)
sizeArg = 0
or
- hasGlobalName([
+ this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"MmAllocateContiguousMemory", // MmAllocateContiguousMemory(size, maxaddress)
"MmAllocateContiguousNodeMemory", // MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer)
@@ -39,7 +39,7 @@ private class MallocAllocationFunction extends AllocationFunction {
]) and
sizeArg = 0
or
- hasGlobalName([
+ this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"ExAllocatePool", // ExAllocatePool(type, size)
"ExAllocatePoolWithTag", // ExAllocatePool(type, size, tag)
@@ -56,10 +56,10 @@ private class MallocAllocationFunction extends AllocationFunction {
]) and
sizeArg = 1
or
- hasGlobalName(["HeapAlloc"]) and // HeapAlloc(heap, flags, size)
+ this.hasGlobalName("HeapAlloc") and // HeapAlloc(heap, flags, size)
sizeArg = 2
or
- hasGlobalName([
+ this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"MmAllocatePagesForMdl", // MmAllocatePagesForMdl(minaddress, maxaddress, skip, size)
"MmAllocatePagesForMdlEx", // MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags)
@@ -79,7 +79,7 @@ private class AllocaAllocationFunction extends AllocationFunction {
int sizeArg;
AllocaAllocationFunction() {
- hasGlobalName([
+ this.hasGlobalName([
// --- stack allocation
"alloca", // // alloca(size)
"__builtin_alloca", // __builtin_alloca(size)
@@ -104,7 +104,7 @@ private class CallocAllocationFunction extends AllocationFunction {
CallocAllocationFunction() {
// --- C library allocation
- hasGlobalOrStdOrBslName("calloc") and // calloc(num, size)
+ this.hasGlobalOrStdOrBslName("calloc") and // calloc(num, size)
sizeArg = 1 and
multArg = 0
}
@@ -124,11 +124,11 @@ private class ReallocAllocationFunction extends AllocationFunction {
ReallocAllocationFunction() {
// --- C library allocation
- hasGlobalOrStdOrBslName("realloc") and // realloc(ptr, size)
+ this.hasGlobalOrStdOrBslName("realloc") and // realloc(ptr, size)
sizeArg = 1 and
reallocArg = 0
or
- hasGlobalName([
+ this.hasGlobalName([
// --- Windows Global / Local legacy allocation
"LocalReAlloc", // LocalReAlloc(ptr, size, flags)
"GlobalReAlloc", // GlobalReAlloc(ptr, size, flags)
@@ -140,7 +140,7 @@ private class ReallocAllocationFunction extends AllocationFunction {
sizeArg = 1 and
reallocArg = 0
or
- hasGlobalName("HeapReAlloc") and // HeapReAlloc(heap, flags, ptr, size)
+ this.hasGlobalName("HeapReAlloc") and // HeapReAlloc(heap, flags, ptr, size)
sizeArg = 3 and
reallocArg = 2
}
@@ -156,7 +156,7 @@ private class ReallocAllocationFunction extends AllocationFunction {
*/
private class SizelessAllocationFunction extends AllocationFunction {
SizelessAllocationFunction() {
- hasGlobalName([
+ this.hasGlobalName([
// --- Windows Memory Management for Windows Drivers
"ExAllocateFromLookasideListEx", // ExAllocateFromLookasideListEx(list)
"ExAllocateFromPagedLookasideList", // ExAllocateFromPagedLookasideList(list)
@@ -209,18 +209,18 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
AllocationFunction target;
CallAllocationExpr() {
- target = getTarget() and
+ target = this.getTarget() and
// realloc(ptr, 0) only frees the pointer
not (
exists(target.getReallocPtrArg()) and
- getArgument(target.getSizeArg()).getValue().toInt() = 0
+ this.getArgument(target.getSizeArg()).getValue().toInt() = 0
) and
// these are modelled directly (and more accurately), avoid duplication
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
}
override Expr getSizeExpr() {
- exists(Expr sizeExpr | sizeExpr = getArgument(target.getSizeArg()) |
+ exists(Expr sizeExpr | sizeExpr = this.getArgument(target.getSizeArg()) |
if exists(target.getSizeMult())
then result = sizeExpr
else
@@ -233,16 +233,18 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
override int getSizeMult() {
// malloc with multiplier argument that is a constant
- result = getArgument(target.getSizeMult()).getValue().toInt()
+ result = this.getArgument(target.getSizeMult()).getValue().toInt()
or
// malloc with no multiplier argument
not exists(target.getSizeMult()) and
- deconstructSizeExpr(getArgument(target.getSizeArg()), _, result)
+ deconstructSizeExpr(this.getArgument(target.getSizeArg()), _, result)
}
- override int getSizeBytes() { result = getSizeExpr().getValue().toInt() * getSizeMult() }
+ override int getSizeBytes() {
+ result = this.getSizeExpr().getValue().toInt() * this.getSizeMult()
+ }
- override Expr getReallocPtr() { result = getArgument(target.getReallocPtrArg()) }
+ override Expr getReallocPtr() { result = this.getArgument(target.getReallocPtrArg()) }
override Type getAllocatedElementType() {
result =
@@ -259,11 +261,11 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
private class NewAllocationExpr extends AllocationExpr, NewExpr {
NewAllocationExpr() { this instanceof NewExpr }
- override int getSizeBytes() { result = getAllocatedType().getSize() }
+ override int getSizeBytes() { result = this.getAllocatedType().getSize() }
- override Type getAllocatedElementType() { result = getAllocatedType() }
+ override Type getAllocatedElementType() { result = this.getAllocatedType() }
- override predicate requiresDealloc() { not exists(getPlacementPointer()) }
+ override predicate requiresDealloc() { not exists(this.getPlacementPointer()) }
}
/**
@@ -274,18 +276,18 @@ private class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
override Expr getSizeExpr() {
// new array expr with variable size
- result = getExtent()
+ result = this.getExtent()
}
override int getSizeMult() {
// new array expr with variable size
- exists(getExtent()) and
- result = getAllocatedElementType().getSize()
+ exists(this.getExtent()) and
+ result = this.getAllocatedElementType().getSize()
}
override Type getAllocatedElementType() { result = NewArrayExpr.super.getAllocatedElementType() }
- override int getSizeBytes() { result = getAllocatedType().getSize() }
+ override int getSizeBytes() { result = this.getAllocatedType().getSize() }
- override predicate requiresDealloc() { not exists(getPlacementPointer()) }
+ override predicate requiresDealloc() { not exists(this.getPlacementPointer()) }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll
index e2015406346..67950b6e135 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll
@@ -8,7 +8,7 @@ import semmle.code.cpp.models.interfaces.FlowSource
*/
private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction,
RemoteFlowSourceFunction {
- GetDelimFunction() { hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
+ GetDelimFunction() { this.hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) }
override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) {
i.isParameter(3) and o.isParameterDeref(0)
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll
index 08222c2cd6a..407c11834e5 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll
@@ -19,7 +19,7 @@ private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunctio
// gets(str)
// fgets(str, num, stream)
// fgetws(wstr, num, stream)
- hasGlobalOrStdOrBslName(["gets", "fgets", "fgetws"])
+ this.hasGlobalOrStdOrBslName(["gets", "fgets", "fgetws"])
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
@@ -54,13 +54,13 @@ private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunctio
}
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
- not hasName("gets") and
+ not this.hasName("gets") and
bufParam = 0 and
countParam = 1
}
override predicate hasArrayWithUnknownSize(int bufParam) {
- hasName("gets") and
+ this.hasName("gets") and
bufParam = 0
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll
index b7d8aed60fa..a8d0e94f43c 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll
@@ -44,27 +44,27 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
*/
int getParamSize() { if this.hasGlobalName("memccpy") then result = 3 else result = 2 }
- override predicate hasArrayInput(int bufParam) { bufParam = getParamSrc() }
+ override predicate hasArrayInput(int bufParam) { bufParam = this.getParamSrc() }
- override predicate hasArrayOutput(int bufParam) { bufParam = getParamDest() }
+ override predicate hasArrayOutput(int bufParam) { bufParam = this.getParamDest() }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
- input.isParameterDeref(getParamSrc()) and
- output.isParameterDeref(getParamDest())
+ input.isParameterDeref(this.getParamSrc()) and
+ output.isParameterDeref(this.getParamDest())
or
- input.isParameterDeref(getParamSrc()) and
+ input.isParameterDeref(this.getParamSrc()) and
output.isReturnValueDeref()
or
- input.isParameter(getParamDest()) and
+ input.isParameter(this.getParamDest()) and
output.isReturnValue()
}
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
(
- bufParam = getParamDest() or
- bufParam = getParamSrc()
+ bufParam = this.getParamDest() or
+ bufParam = this.getParamSrc()
) and
- countParam = getParamSize()
+ countParam = this.getParamSize()
}
override predicate hasOnlySpecificReadSideEffects() { any() }
@@ -72,37 +72,37 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
- i = getParamDest() and
+ i = this.getParamDest() and
buffer = true and
// memccpy only writes until a given character `c` is found
(if this.hasGlobalName("memccpy") then mustWrite = false else mustWrite = true)
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
- i = getParamSrc() and buffer = true
+ i = this.getParamSrc() and buffer = true
}
override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
- result = getParamSize() and
+ result = this.getParamSize() and
(
- i = getParamDest() or
- i = getParamSrc()
+ i = this.getParamDest() or
+ i = this.getParamSrc()
)
}
override predicate parameterNeverEscapes(int index) {
- index = getParamSrc()
+ index = this.getParamSrc()
or
- this.hasGlobalName("bcopy") and index = getParamDest()
+ this.hasGlobalName("bcopy") and index = this.getParamDest()
}
override predicate parameterEscapesOnlyViaReturn(int index) {
- not this.hasGlobalName("bcopy") and index = getParamDest()
+ not this.hasGlobalName("bcopy") and index = this.getParamDest()
}
override predicate parameterIsAlwaysReturned(int index) {
not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and
- index = getParamDest()
+ index = this.getParamDest()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll
index d646be0363d..11ef853a0bc 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memset.qll
@@ -31,17 +31,17 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
bufParam = 0 and
- (if hasGlobalName(bzero()) then countParam = 1 else countParam = 2)
+ (if this.hasGlobalName(bzero()) then countParam = 1 else countParam = 2)
}
- override predicate parameterNeverEscapes(int index) { hasGlobalName(bzero()) and index = 0 }
+ override predicate parameterNeverEscapes(int index) { this.hasGlobalName(bzero()) and index = 0 }
override predicate parameterEscapesOnlyViaReturn(int index) {
- not hasGlobalName(bzero()) and index = 0
+ not this.hasGlobalName(bzero()) and index = 0
}
override predicate parameterIsAlwaysReturned(int index) {
- not hasGlobalName(bzero()) and index = 0
+ not this.hasGlobalName(bzero()) and index = 0
}
override predicate hasOnlySpecificReadSideEffects() { any() }
@@ -54,7 +54,7 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
i = 0 and
- if hasGlobalName(bzero()) then result = 1 else result = 2
+ if this.hasGlobalName(bzero()) then result = 1 else result = 2
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll
index d728a66463d..4efab29cabf 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll
@@ -10,49 +10,49 @@ import semmle.code.cpp.models.interfaces.SideEffect
private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction {
PureStrFunction() {
- hasGlobalOrStdOrBslName([
+ this.hasGlobalOrStdOrBslName([
atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr",
"strspn", strtol(), strrev(), strcmp(), strlwr(), strupr()
])
}
override predicate hasArrayInput(int bufParam) {
- getParameter(bufParam).getUnspecifiedType() instanceof PointerType
+ this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
}
override predicate hasArrayWithNullTerminator(int bufParam) {
- getParameter(bufParam).getUnspecifiedType() instanceof PointerType
+ this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i |
(
input.isParameter(i) and
- exists(getParameter(i))
+ exists(this.getParameter(i))
or
input.isParameterDeref(i) and
- getParameter(i).getUnspecifiedType() instanceof PointerType
+ this.getParameter(i).getUnspecifiedType() instanceof PointerType
) and
// Functions that end with _l also take a locale argument (always as the last argument),
// and we don't want taint from those arguments.
- (not this.getName().matches("%\\_l") or exists(getParameter(i + 1)))
+ (not this.getName().matches("%\\_l") or exists(this.getParameter(i + 1)))
) and
(
output.isReturnValueDeref() and
- getUnspecifiedType() instanceof PointerType
+ this.getUnspecifiedType() instanceof PointerType
or
output.isReturnValue()
)
}
override predicate parameterNeverEscapes(int i) {
- getParameter(i).getUnspecifiedType() instanceof PointerType and
- not parameterEscapesOnlyViaReturn(i)
+ this.getParameter(i).getUnspecifiedType() instanceof PointerType and
+ not this.parameterEscapesOnlyViaReturn(i)
}
override predicate parameterEscapesOnlyViaReturn(int i) {
i = 0 and
- getUnspecifiedType() instanceof PointerType
+ this.getUnspecifiedType() instanceof PointerType
}
override predicate parameterIsAlwaysReturned(int i) { none() }
@@ -62,7 +62,7 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
- getParameter(i).getUnspecifiedType() instanceof PointerType and
+ this.getParameter(i).getUnspecifiedType() instanceof PointerType and
buffer = true
}
}
@@ -97,21 +97,21 @@ private string strcmp() {
*/
private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFunction {
StrLenFunction() {
- hasGlobalOrStdOrBslName(["strlen", "strnlen", "wcslen"])
+ this.hasGlobalOrStdOrBslName(["strlen", "strnlen", "wcslen"])
or
- hasGlobalName(["_mbslen", "_mbslen_l", "_mbstrlen", "_mbstrlen_l"])
+ this.hasGlobalName(["_mbslen", "_mbslen_l", "_mbstrlen", "_mbstrlen_l"])
}
override predicate hasArrayInput(int bufParam) {
- getParameter(bufParam).getUnspecifiedType() instanceof PointerType
+ this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
}
override predicate hasArrayWithNullTerminator(int bufParam) {
- getParameter(bufParam).getUnspecifiedType() instanceof PointerType
+ this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
}
override predicate parameterNeverEscapes(int i) {
- getParameter(i).getUnspecifiedType() instanceof PointerType
+ this.getParameter(i).getUnspecifiedType() instanceof PointerType
}
override predicate parameterEscapesOnlyViaReturn(int i) { none() }
@@ -123,7 +123,7 @@ private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFun
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
- getParameter(i).getUnspecifiedType() instanceof PointerType and
+ this.getParameter(i).getUnspecifiedType() instanceof PointerType and
buffer = true
}
}
@@ -133,12 +133,12 @@ private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFun
* side-effect free. Excludes functions modeled by `PureStrFunction` and `PureMemFunction`.
*/
private class PureFunction extends TaintFunction, SideEffectFunction {
- PureFunction() { hasGlobalOrStdOrBslName(["abs", "labs"]) }
+ PureFunction() { this.hasGlobalOrStdOrBslName(["abs", "labs"]) }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i |
input.isParameter(i) and
- exists(getParameter(i))
+ exists(this.getParameter(i))
) and
output.isReturnValue()
}
@@ -155,44 +155,44 @@ private class PureFunction extends TaintFunction, SideEffectFunction {
private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunction,
SideEffectFunction {
PureMemFunction() {
- hasGlobalOrStdOrBslName([
+ this.hasGlobalOrStdOrBslName([
"memchr", "__builtin_memchr", "memrchr", "rawmemchr", "memcmp", "__builtin_memcmp", "memmem"
]) or
this.hasGlobalName("memfrob")
}
override predicate hasArrayInput(int bufParam) {
- getParameter(bufParam).getUnspecifiedType() instanceof PointerType
+ this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists(ParameterIndex i |
(
input.isParameter(i) and
- exists(getParameter(i))
+ exists(this.getParameter(i))
or
input.isParameterDeref(i) and
- getParameter(i).getUnspecifiedType() instanceof PointerType
+ this.getParameter(i).getUnspecifiedType() instanceof PointerType
) and
// `memfrob` should not have taint from the size argument.
(not this.hasGlobalName("memfrob") or i = 0)
) and
(
output.isReturnValueDeref() and
- getUnspecifiedType() instanceof PointerType
+ this.getUnspecifiedType() instanceof PointerType
or
output.isReturnValue()
)
}
override predicate parameterNeverEscapes(int i) {
- getParameter(i).getUnspecifiedType() instanceof PointerType and
- not parameterEscapesOnlyViaReturn(i)
+ this.getParameter(i).getUnspecifiedType() instanceof PointerType and
+ not this.parameterEscapesOnlyViaReturn(i)
}
override predicate parameterEscapesOnlyViaReturn(int i) {
i = 0 and
- getUnspecifiedType() instanceof PointerType
+ this.getUnspecifiedType() instanceof PointerType
}
override predicate parameterIsAlwaysReturned(int i) { none() }
@@ -202,7 +202,7 @@ private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunctio
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
- getParameter(i).getUnspecifiedType() instanceof PointerType and
+ this.getParameter(i).getUnspecifiedType() instanceof PointerType and
buffer = true
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll
index 691ba528f42..0551185ba14 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Recv.qll
@@ -85,4 +85,6 @@ private class Recv extends AliasFunction, ArrayFunction, SideEffectFunction,
) and
description = "Buffer read by " + this.getName()
}
+
+ override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll
index 6086bc7748f..d871bad68af 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Send.qll
@@ -60,4 +60,6 @@ private class Send extends AliasFunction, ArrayFunction, SideEffectFunction, Rem
override predicate hasRemoteFlowSink(FunctionInput input, string description) {
input.isParameterDeref(1) and description = "Buffer sent by " + this.getName()
}
+
+ override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/SmartPointer.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/SmartPointer.qll
index e249a164061..389ce6c5ab0 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/SmartPointer.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/SmartPointer.qll
@@ -72,9 +72,9 @@ private class MakeUniqueOrShared extends TaintFunction {
// since these just take a size argument, which we don't want to propagate taint through.
not this.isArray() and
(
- input.isParameter([0 .. getNumberOfParameters() - 1])
+ input.isParameter([0 .. this.getNumberOfParameters() - 1])
or
- input.isParameterDeref([0 .. getNumberOfParameters() - 1])
+ input.isParameterDeref([0 .. this.getNumberOfParameters() - 1])
) and
output.isReturnValue()
}
@@ -116,14 +116,14 @@ private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, Side
or
// When taking ownership of a smart pointer via an rvalue reference, always overwrite the input
// smart pointer.
- getPointerInput().isParameterDeref(i) and
+ this.getPointerInput().isParameterDeref(i) and
this.getParameter(i).getUnspecifiedType() instanceof RValueReferenceType and
buffer = false and
mustWrite = true
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
- getPointerInput().isParameterDeref(i) and
+ this.getPointerInput().isParameterDeref(i) and
buffer = false
or
not this instanceof Constructor and
@@ -136,7 +136,7 @@ private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, Side
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
override predicate hasAddressFlow(FunctionInput input, FunctionOutput output) {
- input = getPointerInput() and
+ input = this.getPointerInput() and
output.isQualifierObject()
or
// Assignment operator always returns a reference to `*this`.
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Sscanf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Sscanf.qll
index b6120abf05a..42166ae9baa 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Sscanf.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Sscanf.qll
@@ -23,15 +23,15 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
bufParam = this.(ScanfFunction).getInputParameterIndex()
}
- override predicate hasArrayInput(int bufParam) { hasArrayWithNullTerminator(bufParam) }
+ override predicate hasArrayInput(int bufParam) { this.hasArrayWithNullTerminator(bufParam) }
private int getLengthParameterIndex() { result = this.(Snscanf).getInputLengthParameterIndex() }
private int getLocaleParameterIndex() {
this.getName().matches("%\\_l") and
(
- if exists(getLengthParameterIndex())
- then result = getLengthParameterIndex() + 2
+ if exists(this.getLengthParameterIndex())
+ then result = this.getLengthParameterIndex() + 2
else result = 2
)
}
@@ -40,11 +40,11 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and
- output.isParameterDeref(any(int i | i >= getArgsStartPosition()))
+ output.isParameterDeref(any(int i | i >= this.getArgsStartPosition()))
}
override predicate parameterNeverEscapes(int index) {
- index = [0 .. max(getACallToThisFunction().getNumberOfArguments())]
+ index = [0 .. max(this.getACallToThisFunction().getNumberOfArguments())]
}
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
@@ -56,7 +56,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
- i >= getArgsStartPosition() and
+ i >= this.getArgsStartPosition() and
buffer = true and
mustWrite = true
}
@@ -66,7 +66,7 @@ private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, S
i =
[
this.(ScanfFunction).getInputParameterIndex(),
- this.(ScanfFunction).getFormatParameterIndex(), getLocaleParameterIndex()
+ this.(ScanfFunction).getFormatParameterIndex(), this.getLocaleParameterIndex()
]
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll
index 367db1613fc..c93a5ad147b 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll
@@ -61,20 +61,20 @@ private class StdSequenceContainerConstructor extends Constructor, TaintFunction
* value type of the container.
*/
int getAValueTypeParameterIndex() {
- getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
- getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector`
+ this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
+ this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
- int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
+ int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of the value type to the returned object
(
- input.isParameterDeref(getAValueTypeParameterIndex()) or
- input.isParameter(getAnIteratorParameterIndex())
+ input.isParameterDeref(this.getAValueTypeParameterIndex()) or
+ input.isParameter(this.getAnIteratorParameterIndex())
) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
@@ -158,21 +158,21 @@ private class StdSequenceContainerInsert extends TaintFunction {
* value type of the container.
*/
int getAValueTypeParameterIndex() {
- getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
- getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector`
+ this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
+ this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
- int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
+ int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to container itself (qualifier) and return value
(
input.isQualifierObject() or
- input.isParameterDeref(getAValueTypeParameterIndex()) or
- input.isParameter(getAnIteratorParameterIndex())
+ input.isParameterDeref(this.getAValueTypeParameterIndex()) or
+ input.isParameter(this.getAnIteratorParameterIndex())
) and
(
output.isQualifierObject() or
@@ -197,20 +197,20 @@ private class StdSequenceContainerAssign extends TaintFunction {
* value type of the container.
*/
int getAValueTypeParameterIndex() {
- getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
- getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector`
+ this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
+ this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
- int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
+ int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to container itself (qualifier)
(
- input.isParameterDeref(getAValueTypeParameterIndex()) or
- input.isParameter(getAnIteratorParameterIndex())
+ input.isParameterDeref(this.getAValueTypeParameterIndex()) or
+ input.isParameter(this.getAnIteratorParameterIndex())
) and
output.isQualifierObject()
}
@@ -246,7 +246,7 @@ class StdVectorEmplace extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from any parameter except the position iterator to qualifier and return value
// (here we assume taint flow from any constructor parameter to the constructed object)
- input.isParameterDeref([1 .. getNumberOfParameters() - 1]) and
+ input.isParameterDeref([1 .. this.getNumberOfParameters() - 1]) and
(
output.isQualifierObject() or
output.isReturnValue()
@@ -263,7 +263,7 @@ class StdVectorEmplaceBack extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from any parameter to qualifier
// (here we assume taint flow from any constructor parameter to the constructed object)
- input.isParameterDeref([0 .. getNumberOfParameters() - 1]) and
+ input.isParameterDeref([0 .. this.getNumberOfParameters() - 1]) and
output.isQualifierObject()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll
index aecd98981e8..9dc220e79af 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll
@@ -22,12 +22,12 @@ private class StdMapConstructor extends Constructor, TaintFunction {
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() {
- getParameter(result).getUnspecifiedType() instanceof Iterator
+ this.getParameter(result).getUnspecifiedType() instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of an iterator type to the qualifier
- input.isParameterDeref(getAnIteratorParameterIndex()) and
+ input.isParameterDeref(this.getAnIteratorParameterIndex()) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
@@ -47,7 +47,7 @@ private class StdMapInsert extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from last parameter to qualifier and return value
// (where the return value is a pair, this should really flow just to the first part of it)
- input.isParameterDeref(getNumberOfParameters() - 1) and
+ input.isParameterDeref(this.getNumberOfParameters() - 1) and
(
output.isQualifierObject() or
output.isReturnValue()
@@ -66,7 +66,7 @@ private class StdMapEmplace extends TaintFunction {
// construct a pair, or a pair to be copied / moved) to the qualifier and
// return value.
// (where the return value is a pair, this should really flow just to the first part of it)
- input.isParameterDeref(getNumberOfParameters() - 1) and
+ input.isParameterDeref(this.getNumberOfParameters() - 1) and
(
output.isQualifierObject() or
output.isReturnValue()
@@ -87,9 +87,9 @@ private class StdMapTryEmplace extends TaintFunction {
// flow from any parameter apart from the key to qualifier and return value
// (here we assume taint flow from any constructor parameter to the constructed object)
// (where the return value is a pair, this should really flow just to the first part of it)
- exists(int arg | arg = [1 .. getNumberOfParameters() - 1] |
+ exists(int arg | arg = [1 .. this.getNumberOfParameters() - 1] |
(
- not getUnspecifiedType() instanceof Iterator or
+ not this.getUnspecifiedType() instanceof Iterator or
arg != 1
) and
input.isParameterDeref(arg)
@@ -154,7 +154,7 @@ private class StdMapErase extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to iterator return value
- getType().getUnderlyingType() instanceof Iterator and
+ this.getType().getUnderlyingType() instanceof Iterator and
input.isQualifierObject() and
output.isReturnValue()
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdPair.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdPair.qll
index 755f6a48520..c6fabcac314 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdPair.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdPair.qll
@@ -51,13 +51,13 @@ private class StdPairConstructor extends Constructor, TaintFunction {
* either value type of the pair.
*/
int getAValueTypeParameterIndex() {
- getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
- getDeclaringType().getTemplateArgument(_).(Type).getUnspecifiedType() // i.e. the `T1` or `T2` of this `std::pair`
+ this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
+ this.getDeclaringType().getTemplateArgument(_).(Type).getUnspecifiedType() // i.e. the `T1` or `T2` of this `std::pair`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from second parameter of a value type to the qualifier
- getAValueTypeParameterIndex() = 1 and
+ this.getAValueTypeParameterIndex() = 1 and
input.isParameterDeref(1) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll
index d2e9892abcb..3e26d80c136 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll
@@ -22,12 +22,12 @@ private class StdSetConstructor extends Constructor, TaintFunction {
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() {
- getParameter(result).getUnspecifiedType() instanceof Iterator
+ this.getParameter(result).getUnspecifiedType() instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of an iterator type to the qualifier
- input.isParameterDeref(getAnIteratorParameterIndex()) and
+ input.isParameterDeref(this.getAnIteratorParameterIndex()) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
@@ -45,7 +45,7 @@ private class StdSetInsert extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from last parameter to qualifier and return value
// (where the return value is a pair, this should really flow just to the first part of it)
- input.isParameterDeref(getNumberOfParameters() - 1) and
+ input.isParameterDeref(this.getNumberOfParameters() - 1) and
(
output.isQualifierObject() or
output.isReturnValue()
@@ -63,7 +63,7 @@ private class StdSetEmplace extends TaintFunction {
// flow from any parameter to qualifier and return value
// (here we assume taint flow from any constructor parameter to the constructed object)
// (where the return value is a pair, this should really flow just to the first part of it)
- input.isParameterDeref([0 .. getNumberOfParameters() - 1]) and
+ input.isParameterDeref([0 .. this.getNumberOfParameters() - 1]) and
(
output.isQualifierObject() or
output.isReturnValue()
@@ -107,7 +107,7 @@ private class StdSetErase extends TaintFunction {
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to iterator return value
- getType().getUnderlyingType() instanceof Iterator and
+ this.getType().getUnderlyingType() instanceof Iterator and
input.isQualifierObject() and
output.isReturnValue()
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll
index 73a0f6edf26..ae190688b70 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll
@@ -31,31 +31,31 @@ private class StdStringConstructor extends Constructor, TaintFunction {
* character).
*/
int getAStringParameterIndex() {
- exists(Type paramType | paramType = getParameter(result).getUnspecifiedType() |
+ exists(Type paramType | paramType = this.getParameter(result).getUnspecifiedType() |
// e.g. `std::basic_string::CharT *`
paramType instanceof PointerType
or
// e.g. `std::basic_string &`, avoiding `const Allocator&`
paramType instanceof ReferenceType and
not paramType.(ReferenceType).getBaseType() =
- getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType()
+ this.getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType()
or
// i.e. `std::basic_string::CharT`
- getParameter(result).getUnspecifiedType() =
- getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType()
+ this.getParameter(result).getUnspecifiedType() =
+ this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType()
)
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
- int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
+ int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of the value type to the returned object
(
- input.isParameterDeref(getAStringParameterIndex()) or
- input.isParameter(getAnIteratorParameterIndex())
+ input.isParameterDeref(this.getAStringParameterIndex()) or
+ input.isParameter(this.getAnIteratorParameterIndex())
) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
@@ -156,23 +156,23 @@ private class StdStringAppend extends TaintFunction {
* character).
*/
int getAStringParameterIndex() {
- getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
- getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
- getParameter(result).getUnspecifiedType() =
- getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
+ this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
+ this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
+ this.getParameter(result).getUnspecifiedType() =
+ this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
- int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
+ int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string and parameter to string (qualifier) and return value
(
input.isQualifierObject() or
- input.isParameterDeref(getAStringParameterIndex()) or
- input.isParameter(getAnIteratorParameterIndex())
+ input.isParameterDeref(this.getAStringParameterIndex()) or
+ input.isParameter(this.getAnIteratorParameterIndex())
) and
(
output.isQualifierObject() or
@@ -197,22 +197,22 @@ private class StdStringAssign extends TaintFunction {
* character).
*/
int getAStringParameterIndex() {
- getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
- getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
- getParameter(result).getUnspecifiedType() =
- getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
+ this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
+ this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
+ this.getParameter(result).getUnspecifiedType() =
+ this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
- int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
+ int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to string itself (qualifier) and return value
(
- input.isParameterDeref(getAStringParameterIndex()) or
- input.isParameter(getAnIteratorParameterIndex())
+ input.isParameterDeref(this.getAStringParameterIndex()) or
+ input.isParameter(this.getAnIteratorParameterIndex())
) and
(
output.isQualifierObject() or
@@ -574,12 +574,12 @@ private class StdStringStreamConstructor extends Constructor, TaintFunction {
* Gets the index of a parameter to this function that is a string.
*/
int getAStringParameterIndex() {
- getParameter(result).getType() instanceof ReferenceType // `const std::basic_string &`
+ this.getParameter(result).getType() instanceof ReferenceType // `const std::basic_string &`
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of string type to the returned object
- input.isParameterDeref(getAStringParameterIndex()) and
+ input.isParameterDeref(this.getAStringParameterIndex()) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll
index ee9af547582..1a65e7b6ca4 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll
@@ -32,7 +32,7 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
/**
* Gets the index of the parameter that is the size of the copy (in characters).
*/
- int getParamSize() { exists(getParameter(2)) and result = 2 }
+ int getParamSize() { exists(this.getParameter(2)) and result = 2 }
/**
* Gets the index of the parameter that is the source of the copy.
@@ -50,11 +50,11 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
- getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and
+ this.getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and
input.isParameter(2) and
output.isParameterDeref(0)
or
- getName() = ["_mbsncat_l", "_mbsnbcat_l"] and
+ this.getName() = ["_mbsncat_l", "_mbsnbcat_l"] and
input.isParameter(3) and
output.isParameterDeref(0)
or
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll
index 432fbf999ef..10b160dee47 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll
@@ -45,22 +45,22 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
) and
// exclude the 2-parameter template versions
// that find the size of a fixed size destination buffer.
- getNumberOfParameters() = 3
+ this.getNumberOfParameters() = 3
}
/**
* Holds if this is one of the `strcpy_s` variants.
*/
- private predicate isSVariant() { getName().matches("%\\_s") }
+ private predicate isSVariant() { this.getName().matches("%\\_s") }
/**
* Gets the index of the parameter that is the maximum size of the copy (in characters).
*/
int getParamSize() {
- if isSVariant()
+ if this.isSVariant()
then result = 1
else (
- getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and
+ this.getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and
result = 2
)
}
@@ -68,49 +68,49 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
/**
* Gets the index of the parameter that is the source of the copy.
*/
- int getParamSrc() { if isSVariant() then result = 2 else result = 1 }
+ int getParamSrc() { if this.isSVariant() then result = 2 else result = 1 }
/**
* Gets the index of the parameter that is the destination of the copy.
*/
int getParamDest() { result = 0 }
- override predicate hasArrayInput(int bufParam) { bufParam = getParamSrc() }
+ override predicate hasArrayInput(int bufParam) { bufParam = this.getParamSrc() }
- override predicate hasArrayOutput(int bufParam) { bufParam = getParamDest() }
+ override predicate hasArrayOutput(int bufParam) { bufParam = this.getParamDest() }
- override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = getParamSrc() }
+ override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = this.getParamSrc() }
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
- bufParam = getParamDest() and
- countParam = getParamSize()
+ bufParam = this.getParamDest() and
+ countParam = this.getParamSize()
}
override predicate hasArrayWithUnknownSize(int bufParam) {
- not exists(getParamSize()) and
- bufParam = getParamDest()
+ not exists(this.getParamSize()) and
+ bufParam = this.getParamDest()
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
- not exists(getParamSize()) and
- input.isParameterDeref(getParamSrc()) and
- output.isParameterDeref(getParamDest())
+ not exists(this.getParamSize()) and
+ input.isParameterDeref(this.getParamSrc()) and
+ output.isParameterDeref(this.getParamDest())
or
- not exists(getParamSize()) and
- input.isParameterDeref(getParamSrc()) and
+ not exists(this.getParamSize()) and
+ input.isParameterDeref(this.getParamSrc()) and
output.isReturnValueDeref()
or
- input.isParameter(getParamDest()) and
+ input.isParameter(this.getParamDest()) and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// these may do only a partial copy of the input buffer to the output
// buffer
- exists(getParamSize()) and
- input.isParameter(getParamSrc()) and
+ exists(this.getParamSize()) and
+ input.isParameter(this.getParamSrc()) and
(
- output.isParameterDeref(getParamDest()) or
+ output.isParameterDeref(this.getParamDest()) or
output.isReturnValueDeref()
)
}
@@ -120,18 +120,18 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
- i = getParamDest() and
+ i = this.getParamDest() and
buffer = true and
mustWrite = false
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
- i = getParamSrc() and
+ i = this.getParamSrc() and
buffer = true
}
override ParameterIndex getParameterSizeIndex(ParameterIndex i) {
- i = getParamDest() and
- result = getParamSize()
+ i = this.getParamDest() and
+ result = this.getParamSize()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcrement.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcrement.qll
index 4c335c8581e..8f6c17aae54 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcrement.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcrement.qll
@@ -29,10 +29,10 @@ private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunctio
this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType
}
- override predicate hasArrayInput(int bufParam) { hasArrayWithNullTerminator(bufParam) }
+ override predicate hasArrayInput(int bufParam) { this.hasArrayWithNullTerminator(bufParam) }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
- exists(int index | hasArrayInput(index) |
+ exists(int index | this.hasArrayInput(index) |
input.isParameter(index) and output.isReturnValue()
or
input.isParameterDeref(index) and output.isReturnValueDeref()
@@ -44,6 +44,6 @@ private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunctio
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
- hasArrayInput(i) and buffer = true
+ this.hasArrayInput(i) and buffer = true
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll
index b79f7afe5d9..446e659fac5 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll
@@ -31,7 +31,7 @@ private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction {
this.hasName("swap") and
this.getNumberOfParameters() = 1 and
this.getParameter(0).getType().(ReferenceType).getBaseType().getUnspecifiedType() =
- getDeclaringType()
+ this.getDeclaringType()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/System.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/System.qll
new file mode 100644
index 00000000000..02a9d0d6744
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/System.qll
@@ -0,0 +1,43 @@
+import cpp
+import semmle.code.cpp.models.interfaces.SideEffect
+import semmle.code.cpp.models.interfaces.Alias
+import semmle.code.cpp.models.interfaces.CommandExecution
+
+/**
+ * A function for running a command using a command interpreter.
+ */
+private class SystemFunction extends CommandExecutionFunction, ArrayFunction, AliasFunction,
+ SideEffectFunction {
+ SystemFunction() {
+ hasGlobalOrStdName("system") or // system(command)
+ hasGlobalName("popen") or // popen(command, mode)
+ // Windows variants
+ hasGlobalName("_popen") or // _popen(command, mode)
+ hasGlobalName("_wpopen") or // _wpopen(command, mode)
+ hasGlobalName("_wsystem") // _wsystem(command)
+ }
+
+ override predicate hasCommandArgument(FunctionInput input) { input.isParameterDeref(0) }
+
+ override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 or bufParam = 1 }
+
+ override predicate hasArrayInput(int bufParam) { bufParam = 0 or bufParam = 1 }
+
+ override predicate parameterNeverEscapes(int index) { index = 0 or index = 1 }
+
+ override predicate parameterEscapesOnlyViaReturn(int index) { none() }
+
+ override predicate parameterIsAlwaysReturned(int index) { none() }
+
+ override predicate hasOnlySpecificReadSideEffects() { any() }
+
+ override predicate hasOnlySpecificWriteSideEffects() {
+ hasGlobalOrStdName("system") or
+ hasGlobalName("_wsystem")
+ }
+
+ override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
+ (i = 0 or i = 1) and
+ buffer = true
+ }
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/CommandExecution.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/CommandExecution.qll
new file mode 100644
index 00000000000..a6e32341140
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/CommandExecution.qll
@@ -0,0 +1,23 @@
+/**
+ * Provides classes for modeling functions that execute new programs by
+ * interpreting string data as shell commands. To use this QL library, create
+ * a QL class extending `CommandExecutionFunction` with a characteristic
+ * predicate that selects the function or set of functions you are modeling.
+ * Within that class, override the `hasCommandArgument` predicate to indicate
+ * which parameters are interpreted as shell commands.
+ */
+
+import cpp
+import FunctionInputsAndOutputs
+import semmle.code.cpp.models.Models
+
+/**
+ * A function, such as `exec` or `popen` that starts a new process by
+ * interpreting a string as a shell command.
+ */
+abstract class CommandExecutionFunction extends Function {
+ /**
+ * Holds if `input` is interpreted as a shell command.
+ */
+ abstract predicate hasCommandArgument(FunctionInput input);
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowSource.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowSource.qll
index 8c80377c8ec..d454257ea86 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowSource.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FlowSource.qll
@@ -18,6 +18,12 @@ abstract class RemoteFlowSourceFunction extends Function {
* Holds if remote data described by `description` flows from `output` of a call to this function.
*/
abstract predicate hasRemoteFlowSource(FunctionOutput output, string description);
+
+ /**
+ * Holds if remote data from this source comes from a socket described by
+ * `input`. There is no result if a socket is not specified.
+ */
+ predicate hasSocketInput(FunctionInput input) { none() }
}
/**
@@ -51,4 +57,10 @@ abstract class RemoteFlowSinkFunction extends Function {
* send over a network connection.
*/
abstract predicate hasRemoteFlowSink(FunctionInput input, string description);
+
+ /**
+ * Holds if data put into this sink is transmitted through a socket described
+ * by `input`. There is no result if a socket is not specified.
+ */
+ predicate hasSocketInput(FunctionInput input) { none() }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll
index 4ab55ee5b3f..5e899be68d4 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll
@@ -44,7 +44,7 @@ class FunctionInput extends TFunctionInput {
* Holds if this is the input value of the parameter with index `index`.
* DEPRECATED: Use `isParameter(index)` instead.
*/
- deprecated final predicate isInParameter(ParameterIndex index) { isParameter(index) }
+ deprecated final predicate isInParameter(ParameterIndex index) { this.isParameter(index) }
/**
* Holds if this is the input value pointed to by a pointer parameter to a function, or the input
@@ -70,7 +70,9 @@ class FunctionInput extends TFunctionInput {
* `index`.
* DEPRECATED: Use `isParameterDeref(index)` instead.
*/
- deprecated final predicate isInParameterPointer(ParameterIndex index) { isParameterDeref(index) }
+ deprecated final predicate isInParameterPointer(ParameterIndex index) {
+ this.isParameterDeref(index)
+ }
/**
* Holds if this is the input value pointed to by the `this` pointer of an instance member
@@ -92,7 +94,7 @@ class FunctionInput extends TFunctionInput {
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
- deprecated final predicate isInQualifier() { isQualifierObject() }
+ deprecated final predicate isInQualifier() { this.isQualifierObject() }
/**
* Holds if this is the input value of the `this` pointer of an instance member function.
@@ -314,7 +316,9 @@ class FunctionOutput extends TFunctionOutput {
* index `index`.
* DEPRECATED: Use `isParameterDeref(index)` instead.
*/
- deprecated final predicate isOutParameterPointer(ParameterIndex index) { isParameterDeref(index) }
+ deprecated final predicate isOutParameterPointer(ParameterIndex index) {
+ this.isParameterDeref(index)
+ }
/**
* Holds if this is the output value pointed to by the `this` pointer of an instance member
@@ -336,7 +340,7 @@ class FunctionOutput extends TFunctionOutput {
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
- deprecated final predicate isOutQualifier() { isQualifierObject() }
+ deprecated final predicate isOutQualifier() { this.isQualifierObject() }
/**
* Holds if this is the value returned by a function.
@@ -361,7 +365,7 @@ class FunctionOutput extends TFunctionOutput {
* Holds if this is the value returned by a function.
* DEPRECATED: Use `isReturnValue()` instead.
*/
- deprecated final predicate isOutReturnValue() { isReturnValue() }
+ deprecated final predicate isOutReturnValue() { this.isReturnValue() }
/**
* Holds if this is the output value pointed to by the return value of a function, if the function
@@ -389,7 +393,7 @@ class FunctionOutput extends TFunctionOutput {
* function returns a reference.
* DEPRECATED: Use `isReturnValueDeref()` instead.
*/
- deprecated final predicate isOutReturnPointer() { isReturnValueDeref() }
+ deprecated final predicate isOutReturnPointer() { this.isReturnValueDeref() }
/**
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this is the value, or
diff --git a/cpp/ql/lib/semmle/code/cpp/padding/Padding.qll b/cpp/ql/lib/semmle/code/cpp/padding/Padding.qll
index 7446569451d..e9bde69cfda 100644
--- a/cpp/ql/lib/semmle/code/cpp/padding/Padding.qll
+++ b/cpp/ql/lib/semmle/code/cpp/padding/Padding.qll
@@ -72,7 +72,7 @@ abstract class Architecture extends string {
or
t instanceof CharType and result = 8
or
- t instanceof WideCharType and result = wideCharSize()
+ t instanceof WideCharType and result = this.wideCharSize()
or
t instanceof Char8Type and result = 8
or
@@ -84,22 +84,22 @@ abstract class Architecture extends string {
or
t instanceof IntType and result = 32
or
- t instanceof LongType and result = longSize()
+ t instanceof LongType and result = this.longSize()
or
- t instanceof LongLongType and result = longLongSize()
+ t instanceof LongLongType and result = this.longLongSize()
or
- result = enumBitSize(t.(Enum))
+ result = this.enumBitSize(t.(Enum))
or
- result = integralBitSize(t.(SpecifiedType).getBaseType())
+ result = this.integralBitSize(t.(SpecifiedType).getBaseType())
or
- result = integralBitSize(t.(TypedefType).getBaseType())
+ result = this.integralBitSize(t.(TypedefType).getBaseType())
}
/**
* Gets the bit size of enum type `e`.
*/
int enumBitSize(Enum e) {
- result = integralBitSize(e.getExplicitUnderlyingType())
+ result = this.integralBitSize(e.getExplicitUnderlyingType())
or
not exists(e.getExplicitUnderlyingType()) and result = 32
}
@@ -108,7 +108,7 @@ abstract class Architecture extends string {
* Gets the alignment of enum type `e`.
*/
int enumAlignment(Enum e) {
- result = alignment(e.getExplicitUnderlyingType())
+ result = this.alignment(e.getExplicitUnderlyingType())
or
not exists(e.getExplicitUnderlyingType()) and result = 32
}
@@ -120,26 +120,26 @@ abstract class Architecture extends string {
*/
cached
int bitSize(Type t) {
- result = integralBitSize(t)
+ result = this.integralBitSize(t)
or
t instanceof FloatType and result = 32
or
t instanceof DoubleType and result = 64
or
- t instanceof LongDoubleType and result = longDoubleSize()
+ t instanceof LongDoubleType and result = this.longDoubleSize()
or
- t instanceof PointerType and result = pointerSize()
+ t instanceof PointerType and result = this.pointerSize()
or
- t instanceof ReferenceType and result = pointerSize()
+ t instanceof ReferenceType and result = this.pointerSize()
or
- t instanceof FunctionPointerType and result = pointerSize()
+ t instanceof FunctionPointerType and result = this.pointerSize()
or
- result = bitSize(t.(SpecifiedType).getBaseType())
+ result = this.bitSize(t.(SpecifiedType).getBaseType())
or
- result = bitSize(t.(TypedefType).getBaseType())
+ result = this.bitSize(t.(TypedefType).getBaseType())
or
exists(ArrayType array | array = t |
- result = array.getArraySize() * paddedSize(array.getBaseType())
+ result = array.getArraySize() * this.paddedSize(array.getBaseType())
)
or
result = t.(PaddedType).typeBitSize(this)
@@ -155,7 +155,7 @@ abstract class Architecture extends string {
or
t instanceof CharType and result = 8
or
- t instanceof WideCharType and result = wideCharSize()
+ t instanceof WideCharType and result = this.wideCharSize()
or
t instanceof Char8Type and result = 8
or
@@ -169,27 +169,27 @@ abstract class Architecture extends string {
or
t instanceof FloatType and result = 32
or
- t instanceof DoubleType and result = doubleAlign()
+ t instanceof DoubleType and result = this.doubleAlign()
or
- t instanceof LongType and result = longSize()
+ t instanceof LongType and result = this.longSize()
or
- t instanceof LongDoubleType and result = longDoubleAlign()
+ t instanceof LongDoubleType and result = this.longDoubleAlign()
or
- t instanceof LongLongType and result = longLongAlign()
+ t instanceof LongLongType and result = this.longLongAlign()
or
- t instanceof PointerType and result = pointerSize()
+ t instanceof PointerType and result = this.pointerSize()
or
- t instanceof FunctionPointerType and result = pointerSize()
+ t instanceof FunctionPointerType and result = this.pointerSize()
or
- t instanceof ReferenceType and result = pointerSize()
+ t instanceof ReferenceType and result = this.pointerSize()
or
- result = enumAlignment(t.(Enum))
+ result = this.enumAlignment(t.(Enum))
or
- result = alignment(t.(SpecifiedType).getBaseType())
+ result = this.alignment(t.(SpecifiedType).getBaseType())
or
- result = alignment(t.(TypedefType).getBaseType())
+ result = this.alignment(t.(TypedefType).getBaseType())
or
- result = alignment(t.(ArrayType).getBaseType())
+ result = this.alignment(t.(ArrayType).getBaseType())
or
result = t.(PaddedType).typeAlignment(this)
}
@@ -203,7 +203,7 @@ abstract class Architecture extends string {
exists(Type realType | realType = stripSpecifiers(t) |
if realType instanceof PaddedType
then result = realType.(PaddedType).paddedSize(this)
- else result = bitSize(realType)
+ else result = this.bitSize(realType)
)
}
@@ -429,7 +429,7 @@ class PaddedType extends Class {
* Gets the number of bits wasted by padding at the end of this
* struct.
*/
- int trailingPadding(Architecture arch) { result = paddedSize(arch) - arch.bitSize(this) }
+ int trailingPadding(Architecture arch) { result = this.paddedSize(arch) - arch.bitSize(this) }
/**
* Gets the number of bits wasted in this struct definition; that is.
@@ -440,7 +440,7 @@ class PaddedType extends Class {
* laid out one after another, and hence there is no padding between
* them.
*/
- int wastedSpace(Architecture arch) { result = arch.paddedSize(this) - dataSize(arch) }
+ int wastedSpace(Architecture arch) { result = arch.paddedSize(this) - this.dataSize(arch) }
/**
* Gets the total size of all fields declared in this class, not including any
@@ -448,8 +448,8 @@ class PaddedType extends Class {
*/
private int fieldDataSize(Architecture arch) {
if this instanceof Union
- then result = max(Field f | f = this.getAMember() | fieldSize(f, arch))
- else result = sum(Field f | f = this.getAMember() | fieldSize(f, arch))
+ then result = max(Field f | f = this.getAMember() | this.fieldSize(f, arch))
+ else result = sum(Field f | f = this.getAMember() | this.fieldSize(f, arch))
}
/**
@@ -472,7 +472,7 @@ class PaddedType extends Class {
* reorganizing member structs' field layouts.
*/
int optimalSize(Architecture arch) {
- result = alignUp(dataSize(arch), arch.alignment(this)).maximum(8)
+ result = alignUp(this.dataSize(arch), arch.alignment(this)).maximum(8)
}
/**
@@ -490,11 +490,11 @@ class PaddedType extends Class {
// but that uses a recursive aggregate, which isn't supported in
// QL. We therefore use this slightly more complex implementation
// instead.
- result = biggestFieldSizeUpTo(lastFieldIndex(), arch)
+ result = this.biggestFieldSizeUpTo(this.lastFieldIndex(), arch)
else
// If we're not a union type, the size is the padded
// sum of field sizes, padded.
- result = fieldEnd(lastFieldIndex(), arch)
+ result = this.fieldEnd(this.lastFieldIndex(), arch)
}
/**
@@ -522,8 +522,8 @@ class PaddedType extends Class {
if index = 0
then result = 0
else
- exists(Field f, int fSize | index = fieldIndex(f) and fSize = fieldSize(f, arch) |
- result = fSize.maximum(biggestFieldSizeUpTo(index - 1, arch))
+ exists(Field f, int fSize | index = this.fieldIndex(f) and fSize = this.fieldSize(f, arch) |
+ result = fSize.maximum(this.biggestFieldSizeUpTo(index - 1, arch))
)
}
@@ -536,8 +536,10 @@ class PaddedType extends Class {
if index = 0
then result = 1 // Minimum possible alignment
else
- exists(Field f, int fAlign | index = fieldIndex(f) and fAlign = arch.alignment(f.getType()) |
- result = fAlign.maximum(biggestAlignmentUpTo(index - 1, arch))
+ exists(Field f, int fAlign |
+ index = this.fieldIndex(f) and fAlign = arch.alignment(f.getType())
+ |
+ result = fAlign.maximum(this.biggestAlignmentUpTo(index - 1, arch))
)
}
@@ -545,17 +547,18 @@ class PaddedType extends Class {
* Gets the 1-based index for each field.
*/
int fieldIndex(Field f) {
- memberIndex(f) = rank[result](Field field, int index | memberIndex(field) = index | index)
+ this.memberIndex(f) =
+ rank[result](Field field, int index | this.memberIndex(field) = index | index)
}
- private int memberIndex(Field f) { result = min(int i | getCanonicalMember(i) = f) }
+ private int memberIndex(Field f) { result = min(int i | this.getCanonicalMember(i) = f) }
/**
* Gets the 1-based index for the last field.
*/
int lastFieldIndex() {
- if exists(lastField())
- then result = fieldIndex(lastField())
+ if exists(this.lastField())
+ then result = this.fieldIndex(this.lastField())
else
// Field indices are 1-based, so return 0 to represent the lack of fields.
result = 0
@@ -566,25 +569,27 @@ class PaddedType extends Class {
* `arch`.
*/
int fieldSize(Field f, Architecture arch) {
- exists(fieldIndex(f)) and
+ exists(this.fieldIndex(f)) and
if f instanceof BitField
then result = f.(BitField).getNumBits()
else result = arch.paddedSize(f.getType())
}
/** Gets the last field of this type. */
- Field lastField() { fieldIndex(result) = max(Field other | | fieldIndex(other)) }
+ Field lastField() { this.fieldIndex(result) = max(Field other | | this.fieldIndex(other)) }
/**
* Gets the offset, in bits, of the end of the class' last base class
* subobject, or zero if the class has no base classes.
*/
int baseClassEnd(Architecture arch) {
- if exists(getABaseClass()) then result = arch.baseClassSize(getADerivation()) else result = 0
+ if exists(this.getABaseClass())
+ then result = arch.baseClassSize(this.getADerivation())
+ else result = 0
}
/** Gets the bitfield at field index `index`, if that field is a bitfield. */
- private BitField bitFieldAt(int index) { fieldIndex(result) = index }
+ private BitField bitFieldAt(int index) { this.fieldIndex(result) = index }
/**
* Gets the 0-based offset, in bits, of the first free bit after
@@ -596,13 +601,13 @@ class PaddedType extends Class {
then
// Base case: No fields seen yet, so return the offset of the end of the
// base class subojects.
- result = baseClassEnd(arch)
+ result = this.baseClassEnd(arch)
else
- exists(Field f | index = fieldIndex(f) |
- exists(int fSize | fSize = fieldSize(f, arch) |
+ exists(Field f | index = this.fieldIndex(f) |
+ exists(int fSize | fSize = this.fieldSize(f, arch) |
// Recursive case: Take previous field's end point, pad and add
// this field's size
- exists(int firstFree | firstFree = fieldEnd(index - 1, arch) |
+ exists(int firstFree | firstFree = this.fieldEnd(index - 1, arch) |
if f instanceof BitField
then
// Bitfield packing:
@@ -629,9 +634,11 @@ class PaddedType extends Class {
// No additional restrictions, so just pack it in with no padding.
result = firstFree + fSize
) else (
- if exists(bitFieldAt(index - 1))
+ if exists(this.bitFieldAt(index - 1))
then
- exists(BitField previousBitField | previousBitField = bitFieldAt(index - 1) |
+ exists(BitField previousBitField |
+ previousBitField = this.bitFieldAt(index - 1)
+ |
// Previous field was a bitfield.
if
nextSizeofBoundary >= (firstFree + fSize) and
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll
index bc66d9b2dd0..5aebf07f2f1 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeSSA.qll
@@ -88,7 +88,7 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
ControlFlowNode getDefinition() { result = this }
/** Gets the basic block containing this definition. */
- BasicBlock getBasicBlock() { result.contains(getDefinition()) }
+ BasicBlock getBasicBlock() { result.contains(this.getDefinition()) }
/** Whether this definition is a phi node for variable `v`. */
predicate isPhiNode(StackVariable v) { exists(RangeSSA x | x.phi_node(v, this.(BasicBlock))) }
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
index 5ca9339ae01..0be94ed4e62 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
@@ -127,17 +127,22 @@ private string getValue(Expr e) {
private class UnsignedBitwiseAndExpr extends BitwiseAndExpr {
UnsignedBitwiseAndExpr() {
(
- getLeftOperand().getFullyConverted().getType().getUnderlyingType().(IntegralType).isUnsigned() or
- getValue(getLeftOperand().getFullyConverted()).toInt() >= 0
- ) and
- (
- getRightOperand()
+ this.getLeftOperand()
.getFullyConverted()
.getType()
.getUnderlyingType()
.(IntegralType)
.isUnsigned() or
- getValue(getRightOperand().getFullyConverted()).toInt() >= 0
+ getValue(this.getLeftOperand().getFullyConverted()).toInt() >= 0
+ ) and
+ (
+ this.getRightOperand()
+ .getFullyConverted()
+ .getType()
+ .getUnderlyingType()
+ .(IntegralType)
+ .isUnsigned() or
+ getValue(this.getRightOperand().getFullyConverted()).toInt() >= 0
)
}
}
@@ -1586,6 +1591,15 @@ private module SimpleRangeAnalysisCached {
result = min([max(getTruncatedUpperBounds(expr)), getGuardedUpperBound(expr)])
}
+ /** Holds if the upper bound of `expr` may have been widened. This means the the upper bound is in practice likely to be overly wide. */
+ cached
+ predicate upperBoundMayBeWidened(Expr e) {
+ isRecursiveExpr(e) and
+ // Widening is not a problem if the post-analysis in `getGuardedUpperBound` has overridden the widening.
+ // Note that the RHS of `<` may be multi-valued.
+ not getGuardedUpperBound(e) < getTruncatedUpperBounds(e)
+ }
+
/**
* Holds if `expr` has a provably empty range. For example:
*
diff --git a/cpp/ql/lib/semmle/code/cpp/security/BufferWrite.qll b/cpp/ql/lib/semmle/code/cpp/security/BufferWrite.qll
index 2726b2eca00..61845654721 100644
--- a/cpp/ql/lib/semmle/code/cpp/security/BufferWrite.qll
+++ b/cpp/ql/lib/semmle/code/cpp/security/BufferWrite.qll
@@ -77,21 +77,21 @@ abstract class BufferWrite extends Expr {
* much smaller (8 bytes) than their true maximum length. This can be
* helpful in determining the cause of a buffer overflow issue.
*/
- int getMaxDataLimited() { result = getMaxData() }
+ int getMaxDataLimited() { result = this.getMaxData() }
/**
* Gets the size of a single character of the type this
* operation works with, in bytes.
*/
int getCharSize() {
- result = getBufferType().(PointerType).getBaseType().getSize() or
- result = getBufferType().(ArrayType).getBaseType().getSize()
+ result = this.getBufferType().(PointerType).getBaseType().getSize() or
+ result = this.getBufferType().(ArrayType).getBaseType().getSize()
}
/**
* Gets a description of this buffer write.
*/
- string getBWDesc() { result = toString() }
+ string getBWDesc() { result = this.toString() }
}
/**
@@ -109,7 +109,7 @@ abstract class BufferWriteCall extends BufferWrite, FunctionCall { }
class StrCopyBW extends BufferWriteCall {
StrcpyFunction f;
- StrCopyBW() { getTarget() = f.(TopLevelFunction) }
+ StrCopyBW() { this.getTarget() = f.(TopLevelFunction) }
/**
* Gets the index of the parameter that is the maximum size of the copy (in characters).
@@ -122,21 +122,22 @@ class StrCopyBW extends BufferWriteCall {
int getParamSrc() { result = f.getParamSrc() }
override Type getBufferType() {
- result = this.getTarget().getParameter(getParamSrc()).getUnspecifiedType()
+ result = this.getTarget().getParameter(this.getParamSrc()).getUnspecifiedType()
}
- override Expr getASource() { result = getArgument(getParamSrc()) }
+ override Expr getASource() { result = this.getArgument(this.getParamSrc()) }
- override Expr getDest() { result = getArgument(f.getParamDest()) }
+ override Expr getDest() { result = this.getArgument(f.getParamDest()) }
- override predicate hasExplicitLimit() { exists(getParamSize()) }
+ override predicate hasExplicitLimit() { exists(this.getParamSize()) }
override int getExplicitLimit() {
- result = getArgument(getParamSize()).getValue().toInt() * getCharSize()
+ result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
}
override int getMaxData() {
- result = getArgument(getParamSrc()).(AnalysedString).getMaxLength() * getCharSize()
+ result =
+ this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
}
}
@@ -146,7 +147,7 @@ class StrCopyBW extends BufferWriteCall {
class StrCatBW extends BufferWriteCall {
StrcatFunction f;
- StrCatBW() { getTarget() = f.(TopLevelFunction) }
+ StrCatBW() { this.getTarget() = f.(TopLevelFunction) }
/**
* Gets the index of the parameter that is the maximum size of the copy (in characters).
@@ -159,21 +160,22 @@ class StrCatBW extends BufferWriteCall {
int getParamSrc() { result = f.getParamSrc() }
override Type getBufferType() {
- result = this.getTarget().getParameter(getParamSrc()).getUnspecifiedType()
+ result = this.getTarget().getParameter(this.getParamSrc()).getUnspecifiedType()
}
- override Expr getASource() { result = getArgument(getParamSrc()) }
+ override Expr getASource() { result = this.getArgument(this.getParamSrc()) }
- override Expr getDest() { result = getArgument(f.getParamDest()) }
+ override Expr getDest() { result = this.getArgument(f.getParamDest()) }
- override predicate hasExplicitLimit() { exists(getParamSize()) }
+ override predicate hasExplicitLimit() { exists(this.getParamSize()) }
override int getExplicitLimit() {
- result = getArgument(getParamSize()).getValue().toInt() * getCharSize()
+ result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
}
override int getMaxData() {
- result = getArgument(getParamSrc()).(AnalysedString).getMaxLength() * getCharSize()
+ result =
+ this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
}
}
@@ -184,7 +186,7 @@ class SprintfBW extends BufferWriteCall {
FormattingFunction f;
SprintfBW() {
- exists(string name | f = getTarget().(TopLevelFunction) and name = f.getName() |
+ exists(string name | f = this.getTarget().(TopLevelFunction) and name = f.getName() |
/*
* C sprintf variants:
*/
@@ -229,19 +231,19 @@ class SprintfBW extends BufferWriteCall {
result = this.(FormattingFunctionCall).getFormatArgument(_)
}
- override Expr getDest() { result = getArgument(f.getOutputParameterIndex(false)) }
+ override Expr getDest() { result = this.getArgument(f.getOutputParameterIndex(false)) }
override int getMaxData() {
exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and
- result = fl.getMaxConvertedLength() * getCharSize()
+ result = fl.getMaxConvertedLength() * this.getCharSize()
)
}
override int getMaxDataLimited() {
exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and
- result = fl.getMaxConvertedLengthLimited() * getCharSize()
+ result = fl.getMaxConvertedLengthLimited() * this.getCharSize()
)
}
}
@@ -251,7 +253,7 @@ class SprintfBW extends BufferWriteCall {
*/
class SnprintfBW extends BufferWriteCall {
SnprintfBW() {
- exists(TopLevelFunction fn, string name | fn = getTarget() and name = fn.getName() |
+ exists(TopLevelFunction fn, string name | fn = this.getTarget() and name = fn.getName() |
/*
* C snprintf variants:
*/
@@ -326,25 +328,25 @@ class SnprintfBW extends BufferWriteCall {
result = this.(FormattingFunctionCall).getFormatArgument(_)
}
- override Expr getDest() { result = getArgument(0) }
+ override Expr getDest() { result = this.getArgument(0) }
- override predicate hasExplicitLimit() { exists(getParamSize()) }
+ override predicate hasExplicitLimit() { exists(this.getParamSize()) }
override int getExplicitLimit() {
- result = getArgument(getParamSize()).getValue().toInt() * getCharSize()
+ result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
}
override int getMaxData() {
exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and
- result = fl.getMaxConvertedLength() * getCharSize()
+ result = fl.getMaxConvertedLength() * this.getCharSize()
)
}
override int getMaxDataLimited() {
exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and
- result = fl.getMaxConvertedLengthLimited() * getCharSize()
+ result = fl.getMaxConvertedLengthLimited() * this.getCharSize()
)
}
}
@@ -354,7 +356,7 @@ class SnprintfBW extends BufferWriteCall {
*/
class GetsBW extends BufferWriteCall {
GetsBW() {
- getTarget().(TopLevelFunction).getName() =
+ this.getTarget().(TopLevelFunction).getName() =
[
"gets", // gets(dst)
"fgets", // fgets(dst, max_amount, src_stream)
@@ -365,24 +367,24 @@ class GetsBW extends BufferWriteCall {
/**
* Gets the index of the parameter that is the maximum number of characters to be read.
*/
- int getParamSize() { if exists(getArgument(1)) then result = 1 else none() }
+ int getParamSize() { exists(this.getArgument(1)) and result = 1 }
override Type getBufferType() { result = this.getTarget().getParameter(0).getUnspecifiedType() }
override Expr getASource() {
- if exists(getArgument(2))
- then result = getArgument(2)
+ if exists(this.getArgument(2))
+ then result = this.getArgument(2)
else
// the source is input inside the 'gets' call itself
result = this
}
- override Expr getDest() { result = getArgument(0) }
+ override Expr getDest() { result = this.getArgument(0) }
- override predicate hasExplicitLimit() { exists(getParamSize()) }
+ override predicate hasExplicitLimit() { exists(this.getParamSize()) }
override int getExplicitLimit() {
- result = getArgument(getParamSize()).getValue().toInt() * getCharSize()
+ result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
}
}
@@ -438,7 +440,7 @@ class ScanfBW extends BufferWrite {
exists(ScanfFunctionCall fc, ScanfFormatLiteral fl, int arg |
this = fc.getArgument(arg) and
fl = fc.getFormat() and
- result = (fl.getMaxConvertedLength(arg - getParamArgs()) + 1) * getCharSize() // +1 is for the terminating null
+ result = (fl.getMaxConvertedLength(arg - this.getParamArgs()) + 1) * this.getCharSize() // +1 is for the terminating null
)
}
@@ -463,14 +465,14 @@ private int path_max() {
class RealpathBW extends BufferWriteCall {
RealpathBW() {
exists(path_max()) and // Ignore realpath() calls if PATH_MAX cannot be determined
- getTarget().hasGlobalName("realpath") // realpath(path, resolved_path);
+ this.getTarget().hasGlobalName("realpath") // realpath(path, resolved_path);
}
override Type getBufferType() { result = this.getTarget().getParameter(0).getUnspecifiedType() }
- override Expr getDest() { result = getArgument(1) }
+ override Expr getDest() { result = this.getArgument(1) }
- override Expr getASource() { result = getArgument(0) }
+ override Expr getASource() { result = this.getArgument(0) }
override int getMaxData() {
result = path_max() and
diff --git a/cpp/ql/lib/semmle/code/cpp/security/CommandExecution.qll b/cpp/ql/lib/semmle/code/cpp/security/CommandExecution.qll
index d9bb701be58..063c7300031 100644
--- a/cpp/ql/lib/semmle/code/cpp/security/CommandExecution.qll
+++ b/cpp/ql/lib/semmle/code/cpp/security/CommandExecution.qll
@@ -4,42 +4,20 @@ import cpp
import semmle.code.cpp.security.FunctionWithWrappers
import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.Alias
+import semmle.code.cpp.models.interfaces.CommandExecution
/**
* A function for running a command using a command interpreter.
*/
-class SystemFunction extends FunctionWithWrappers, ArrayFunction, AliasFunction, SideEffectFunction {
- SystemFunction() {
- hasGlobalOrStdName("system") or // system(command)
- hasGlobalName("popen") or // popen(command, mode)
- // Windows variants
- hasGlobalName("_popen") or // _popen(command, mode)
- hasGlobalName("_wpopen") or // _wpopen(command, mode)
- hasGlobalName("_wsystem") // _wsystem(command)
- }
-
- override predicate interestingArg(int arg) { arg = 0 }
-
- override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 or bufParam = 1 }
-
- override predicate hasArrayInput(int bufParam) { bufParam = 0 or bufParam = 1 }
-
- override predicate parameterNeverEscapes(int index) { index = 0 or index = 1 }
-
- override predicate parameterEscapesOnlyViaReturn(int index) { none() }
-
- override predicate parameterIsAlwaysReturned(int index) { none() }
-
- override predicate hasOnlySpecificReadSideEffects() { any() }
-
- override predicate hasOnlySpecificWriteSideEffects() {
- hasGlobalOrStdName("system") or
- hasGlobalName("_wsystem")
- }
-
- override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
- (i = 0 or i = 1) and
- buffer = true
+class SystemFunction extends FunctionWithWrappers instanceof CommandExecutionFunction {
+ override predicate interestingArg(int arg) {
+ exists(FunctionInput input |
+ this.(CommandExecutionFunction).hasCommandArgument(input) and
+ (
+ input.isParameterDerefOrQualifierObject(arg) or
+ input.isParameterOrQualifierAddress(arg)
+ )
+ )
}
}
@@ -50,35 +28,19 @@ class SystemFunction extends FunctionWithWrappers, ArrayFunction, AliasFunction,
*/
class VarargsExecFunctionCall extends FunctionCall {
VarargsExecFunctionCall() {
- getTarget().hasGlobalName("execl") or
- getTarget().hasGlobalName("execle") or
- getTarget().hasGlobalName("execlp") or
- // Windows
- getTarget().hasGlobalName("_execl") or
- getTarget().hasGlobalName("_execle") or
- getTarget().hasGlobalName("_execlp") or
- getTarget().hasGlobalName("_execlpe") or
- getTarget().hasGlobalName("_spawnl") or
- getTarget().hasGlobalName("_spawnle") or
- getTarget().hasGlobalName("_spawnlp") or
- getTarget().hasGlobalName("_spawnlpe") or
- getTarget().hasGlobalName("_wexecl") or
- getTarget().hasGlobalName("_wexecle") or
- getTarget().hasGlobalName("_wexeclp") or
- getTarget().hasGlobalName("_wexeclpe") or
- getTarget().hasGlobalName("_wspawnl") or
- getTarget().hasGlobalName("_wspawnle") or
- getTarget().hasGlobalName("_wspawnlp") or
- getTarget().hasGlobalName("_wspawnlpe")
+ getTarget()
+ .hasGlobalName([
+ "execl", "execle", "execlp",
+ // Windows
+ "_execl", "_execle", "_execlp", "_execlpe", "_spawnl", "_spawnle", "_spawnlp",
+ "_spawnlpe", "_wexecl", "_wexecle", "_wexeclp", "_wexeclpe", "_wspawnl", "_wspawnle",
+ "_wspawnlp", "_wspawnlpe"
+ ])
}
/** Whether the last argument to the function is an environment pointer */
predicate hasEnvironmentArgument() {
- getTarget().hasGlobalName("execle") or
- getTarget().hasGlobalName("_execle") or
- getTarget().hasGlobalName("_execlpe") or
- getTarget().hasGlobalName("_wexecle") or
- getTarget().hasGlobalName("_wexeclpe")
+ getTarget().hasGlobalName(["execle", "_execle", "_execlpe", "_wexecle", "_wexeclpe"])
}
/**
@@ -105,11 +67,7 @@ class VarargsExecFunctionCall extends FunctionCall {
* all the other ones start with the command.
*/
private int getCommandIdx() {
- if
- getTarget().getName().matches("\\_spawn%") or
- getTarget().getName().matches("\\_wspawn%")
- then result = 1
- else result = 0
+ if getTarget().getName().matches(["\\_spawn%", "\\_wspawn%"]) then result = 1 else result = 0
}
}
@@ -120,28 +78,14 @@ class VarargsExecFunctionCall extends FunctionCall {
*/
class ArrayExecFunctionCall extends FunctionCall {
ArrayExecFunctionCall() {
- getTarget().hasGlobalName("execv") or
- getTarget().hasGlobalName("execvp") or
- getTarget().hasGlobalName("execvpe") or
- getTarget().hasGlobalName("execve") or
- getTarget().hasGlobalName("fexecve") or
- // Windows variants
- getTarget().hasGlobalName("_execv") or
- getTarget().hasGlobalName("_execve") or
- getTarget().hasGlobalName("_execvp") or
- getTarget().hasGlobalName("_execvpe") or
- getTarget().hasGlobalName("_spawnv") or
- getTarget().hasGlobalName("_spawnve") or
- getTarget().hasGlobalName("_spawnvp") or
- getTarget().hasGlobalName("_spawnvpe") or
- getTarget().hasGlobalName("_wexecv") or
- getTarget().hasGlobalName("_wexecve") or
- getTarget().hasGlobalName("_wexecvp") or
- getTarget().hasGlobalName("_wexecvpe") or
- getTarget().hasGlobalName("_wspawnv") or
- getTarget().hasGlobalName("_wspawnve") or
- getTarget().hasGlobalName("_wspawnvp") or
- getTarget().hasGlobalName("_wspawnvpe")
+ getTarget()
+ .hasGlobalName([
+ "execv", "execvp", "execvpe", "execve", "fexecve",
+ // Windows variants
+ "_execv", "_execve", "_execvp", "_execvpe", "_spawnv", "_spawnve", "_spawnvp",
+ "_spawnvpe", "_wexecv", "_wexecve", "_wexecvp", "_wexecvpe", "_wspawnv", "_wspawnve",
+ "_wspawnvp", "_wspawnvpe"
+ ])
}
/** The argument with the array of command arguments */
@@ -155,11 +99,7 @@ class ArrayExecFunctionCall extends FunctionCall {
* all the other ones start with the command.
*/
private int getCommandIdx() {
- if
- getTarget().getName().matches("\\_spawn%") or
- getTarget().getName().matches("\\_wspawn%")
- then result = 1
- else result = 0
+ if getTarget().getName().matches(["\\_spawn%", "\\_wspawn%"]) then result = 1 else result = 0
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/security/FileWrite.qll b/cpp/ql/lib/semmle/code/cpp/security/FileWrite.qll
index 7c3d893b471..36f8b58d812 100644
--- a/cpp/ql/lib/semmle/code/cpp/security/FileWrite.qll
+++ b/cpp/ql/lib/semmle/code/cpp/security/FileWrite.qll
@@ -52,9 +52,9 @@ class BasicOStreamClass extends Type {
*/
class BasicOStreamCall extends FunctionCall {
BasicOStreamCall() {
- if getTarget() instanceof MemberFunction
- then getQualifier().getType() instanceof BasicOStreamClass
- else getArgument(0).getType() instanceof BasicOStreamClass
+ if this.getTarget() instanceof MemberFunction
+ then this.getQualifier().getType() instanceof BasicOStreamClass
+ else this.getArgument(0).getType() instanceof BasicOStreamClass
}
}
@@ -77,10 +77,10 @@ abstract class ChainedOutputCall extends BasicOStreamCall {
*/
Expr getEndDest() {
// recurse into the destination
- result = getDest().(ChainedOutputCall).getEndDest()
+ result = this.getDest().(ChainedOutputCall).getEndDest()
or
// or return something other than a ChainedOutputCall
- result = getDest() and
+ result = this.getDest() and
not result instanceof ChainedOutputCall
}
}
@@ -89,18 +89,18 @@ abstract class ChainedOutputCall extends BasicOStreamCall {
* A call to `operator<<` on an output stream.
*/
class OperatorLShiftCall extends ChainedOutputCall {
- OperatorLShiftCall() { getTarget().(Operator).hasName("operator<<") }
+ OperatorLShiftCall() { this.getTarget().(Operator).hasName("operator<<") }
override Expr getSource() {
- if getTarget() instanceof MemberFunction
- then result = getArgument(0)
- else result = getArgument(1)
+ if this.getTarget() instanceof MemberFunction
+ then result = this.getArgument(0)
+ else result = this.getArgument(1)
}
override Expr getDest() {
- if getTarget() instanceof MemberFunction
- then result = getQualifier()
- else result = getArgument(0)
+ if this.getTarget() instanceof MemberFunction
+ then result = this.getQualifier()
+ else result = this.getArgument(0)
}
}
@@ -108,22 +108,22 @@ class OperatorLShiftCall extends ChainedOutputCall {
* A call to 'put'.
*/
class PutFunctionCall extends ChainedOutputCall {
- PutFunctionCall() { getTarget().(MemberFunction).hasName("put") }
+ PutFunctionCall() { this.getTarget().(MemberFunction).hasName("put") }
- override Expr getSource() { result = getArgument(0) }
+ override Expr getSource() { result = this.getArgument(0) }
- override Expr getDest() { result = getQualifier() }
+ override Expr getDest() { result = this.getQualifier() }
}
/**
* A call to 'write'.
*/
class WriteFunctionCall extends ChainedOutputCall {
- WriteFunctionCall() { getTarget().(MemberFunction).hasName("write") }
+ WriteFunctionCall() { this.getTarget().(MemberFunction).hasName("write") }
- override Expr getSource() { result = getArgument(0) }
+ override Expr getSource() { result = this.getArgument(0) }
- override Expr getDest() { result = getQualifier() }
+ override Expr getDest() { result = this.getQualifier() }
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll b/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll
index b080651951f..d2c90a38075 100644
--- a/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll
+++ b/cpp/ql/lib/semmle/code/cpp/security/FlowSources.qll
@@ -24,7 +24,7 @@ private class RemoteReturnSource extends RemoteFlowSource {
RemoteReturnSource() {
exists(RemoteFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
- asInstruction() = instr and
+ this.asInstruction() = instr and
instr.getStaticCallTarget() = func and
func.hasRemoteFlowSource(output, sourceType) and
(
@@ -43,7 +43,7 @@ private class RemoteParameterSource extends RemoteFlowSource {
RemoteParameterSource() {
exists(RemoteFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
- asInstruction() = instr and
+ this.asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
func.hasRemoteFlowSource(output, sourceType) and
output.isParameterDerefOrQualifierObject(instr.getIndex())
@@ -58,7 +58,7 @@ private class LocalReturnSource extends LocalFlowSource {
LocalReturnSource() {
exists(LocalFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
- asInstruction() = instr and
+ this.asInstruction() = instr and
instr.getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and
(
@@ -77,7 +77,7 @@ private class LocalParameterSource extends LocalFlowSource {
LocalParameterSource() {
exists(LocalFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
- asInstruction() = instr and
+ this.asInstruction() = instr and
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
func.hasLocalFlowSource(output, sourceType) and
output.isParameterDerefOrQualifierObject(instr.getIndex())
diff --git a/cpp/ql/lib/semmle/code/cpp/security/FunctionWithWrappers.qll b/cpp/ql/lib/semmle/code/cpp/security/FunctionWithWrappers.qll
index 5451011b351..b7a7a95a427 100644
--- a/cpp/ql/lib/semmle/code/cpp/security/FunctionWithWrappers.qll
+++ b/cpp/ql/lib/semmle/code/cpp/security/FunctionWithWrappers.qll
@@ -17,7 +17,7 @@
import cpp
import PrintfLike
-private import TaintTracking
+private import semmle.code.cpp.ir.dataflow.ResolveCall
bindingset[index]
private string toCause(Function func, int index) {
@@ -77,7 +77,7 @@ abstract class FunctionWithWrappers extends Function {
) {
// base case
func = this and
- interestingArg(paramIndex) and
+ this.interestingArg(paramIndex) and
callChain = toCause(func, paramIndex) and
depth = 0
or
@@ -101,7 +101,7 @@ abstract class FunctionWithWrappers extends Function {
private predicate wrapperFunctionAnyDepth(Function func, int paramIndex, string cause) {
// base case
func = this and
- interestingArg(paramIndex) and
+ this.interestingArg(paramIndex) and
cause = toCause(func, paramIndex)
or
// recursive step
@@ -147,7 +147,7 @@ abstract class FunctionWithWrappers extends Function {
)
or
not this.wrapperFunctionLimitedDepth(func, paramIndex, _, _) and
- cause = wrapperFunctionAnyDepthUnique(func, paramIndex)
+ cause = this.wrapperFunctionAnyDepthUnique(func, paramIndex)
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/security/OutputWrite.qll b/cpp/ql/lib/semmle/code/cpp/security/OutputWrite.qll
index 9ed22aa970f..affb9954926 100644
--- a/cpp/ql/lib/semmle/code/cpp/security/OutputWrite.qll
+++ b/cpp/ql/lib/semmle/code/cpp/security/OutputWrite.qll
@@ -21,14 +21,12 @@ class OutputWrite extends Expr {
* A standard output or standard error variable.
*/
private predicate outputVariable(Variable v) {
- // standard output
- v.hasName("cout") or
- v.hasName("wcout") or
- // standard error
- v.hasName("cerr") or
- v.hasName("clog") or
- v.hasName("wcerr") or
- v.hasName("wclog")
+ v.hasName([
+ // standard output
+ "cout", "wcout",
+ // standard error
+ "cerr", "clog", "wcerr", "wclog"
+ ])
}
/**
@@ -64,10 +62,7 @@ private predicate outputWrite(Expr write, Expr source) {
arg >= f.(FormattingFunction).getFormatParameterIndex()
or
// puts, putchar
- (
- f.hasGlobalOrStdName("puts") or
- f.hasGlobalOrStdName("putchar")
- ) and
+ f.hasGlobalOrStdName(["puts", "putchar"]) and
arg = 0
or
exists(Call wrappedCall, Expr wrappedSource |
diff --git a/cpp/ql/lib/semmle/code/cpp/security/Security.qll b/cpp/ql/lib/semmle/code/cpp/security/Security.qll
index da808592b3e..7a73144f5fa 100644
--- a/cpp/ql/lib/semmle/code/cpp/security/Security.qll
+++ b/cpp/ql/lib/semmle/code/cpp/security/Security.qll
@@ -78,7 +78,7 @@ class SecurityOptions extends string {
functionCall.getTarget().getName() = fname and
(
fname = ["fgets", "gets"] or
- userInputReturn(fname)
+ this.userInputReturn(fname)
)
)
or
diff --git a/cpp/ql/lib/semmle/code/cpp/security/SensitiveExprs.qll b/cpp/ql/lib/semmle/code/cpp/security/SensitiveExprs.qll
index 22e0ee71b66..389129835cb 100644
--- a/cpp/ql/lib/semmle/code/cpp/security/SensitiveExprs.qll
+++ b/cpp/ql/lib/semmle/code/cpp/security/SensitiveExprs.qll
@@ -11,17 +11,8 @@ import cpp
*/
bindingset[s]
private predicate suspicious(string s) {
- (
- s.matches("%password%") or
- s.matches("%passwd%") or
- s.matches("%trusted%")
- ) and
- not (
- s.matches("%hash%") or
- s.matches("%crypt%") or
- s.matches("%file%") or
- s.matches("%path%")
- )
+ s.matches(["%password%", "%passwd%", "%trusted%"]) and
+ not s.matches(["%hash%", "%crypt%", "%file%", "%path%"])
}
/**
@@ -29,7 +20,7 @@ private predicate suspicious(string s) {
*/
class SensitiveVariable extends Variable {
SensitiveVariable() {
- suspicious(getName().toLowerCase()) and
+ suspicious(this.getName().toLowerCase()) and
not this.getUnspecifiedType() instanceof IntegralType
}
}
@@ -39,7 +30,7 @@ class SensitiveVariable extends Variable {
*/
class SensitiveFunction extends Function {
SensitiveFunction() {
- suspicious(getName().toLowerCase()) and
+ suspicious(this.getName().toLowerCase()) and
not this.getUnspecifiedType() instanceof IntegralType
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll b/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll
index e113d5e5745..c9d6b6613d8 100644
--- a/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll
+++ b/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll
@@ -113,7 +113,7 @@ module BoostorgAsio {
result.getName() = "tls_server"
)
or
- result = getASslv23ProtocolConstant()
+ result = this.getASslv23ProtocolConstant()
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/stmts/Block.qll b/cpp/ql/lib/semmle/code/cpp/stmts/Block.qll
index 3bebc660456..5fe8798cebb 100644
--- a/cpp/ql/lib/semmle/code/cpp/stmts/Block.qll
+++ b/cpp/ql/lib/semmle/code/cpp/stmts/Block.qll
@@ -76,9 +76,9 @@ class BlockStmt extends Stmt, @stmt_block {
* the result is the expression statement `a = b`.
*/
Stmt getLastStmtIn() {
- if getLastStmt() instanceof BlockStmt
- then result = getLastStmt().(BlockStmt).getLastStmtIn()
- else result = getLastStmt()
+ if this.getLastStmt() instanceof BlockStmt
+ then result = this.getLastStmt().(BlockStmt).getLastStmtIn()
+ else result = this.getLastStmt()
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll
index ed1fb4fbb50..af68daf025c 100644
--- a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll
+++ b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll
@@ -27,10 +27,10 @@ class Stmt extends StmtParent, @stmt {
*/
BlockStmt getEnclosingBlock() {
if
- getParentStmt() instanceof BlockStmt and
- not getParentStmt().(BlockStmt).getLocation() instanceof UnknownLocation
- then result = getParentStmt()
- else result = getParentStmt().getEnclosingBlock()
+ this.getParentStmt() instanceof BlockStmt and
+ not this.getParentStmt().(BlockStmt).getLocation() instanceof UnknownLocation
+ then result = this.getParentStmt()
+ else result = this.getParentStmt().getEnclosingBlock()
}
/** Gets a child of this statement. */
@@ -438,7 +438,7 @@ class WhileStmt extends Loop, @stmt_while {
* while(1) { ...; if(b) break; ...; }
* ```
*/
- predicate conditionAlwaysTrue() { conditionAlwaysTrue(getCondition()) }
+ predicate conditionAlwaysTrue() { conditionAlwaysTrue(this.getCondition()) }
/**
* Holds if the loop condition is provably `false`.
@@ -448,7 +448,7 @@ class WhileStmt extends Loop, @stmt_while {
* while(0) { ...; }
* ```
*/
- predicate conditionAlwaysFalse() { conditionAlwaysFalse(getCondition()) }
+ predicate conditionAlwaysFalse() { conditionAlwaysFalse(this.getCondition()) }
/**
* Holds if the loop condition is provably `true` upon entry,
@@ -857,7 +857,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
* ```
* the result is `int x`.
*/
- LocalVariable getVariable() { result = getChild(4).(DeclStmt).getADeclaration() }
+ LocalVariable getVariable() { result = this.getChild(4).(DeclStmt).getADeclaration() }
/**
* Gets the expression giving the range to iterate over.
@@ -868,10 +868,10 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
* ```
* the result is `xs`.
*/
- Expr getRange() { result = getRangeVariable().getInitializer().getExpr() }
+ Expr getRange() { result = this.getRangeVariable().getInitializer().getExpr() }
/** Gets the compiler-generated `__range` variable after desugaring. */
- LocalVariable getRangeVariable() { result = getChild(0).(DeclStmt).getADeclaration() }
+ LocalVariable getRangeVariable() { result = this.getChild(0).(DeclStmt).getADeclaration() }
/**
* Gets the compiler-generated `__begin != __end` which is the
@@ -891,10 +891,10 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
DeclStmt getBeginEndDeclaration() { result = this.getChild(1) }
/** Gets the compiler-generated `__begin` variable after desugaring. */
- LocalVariable getBeginVariable() { result = getBeginEndDeclaration().getDeclaration(0) }
+ LocalVariable getBeginVariable() { result = this.getBeginEndDeclaration().getDeclaration(0) }
/** Gets the compiler-generated `__end` variable after desugaring. */
- LocalVariable getEndVariable() { result = getBeginEndDeclaration().getDeclaration(1) }
+ LocalVariable getEndVariable() { result = this.getBeginEndDeclaration().getDeclaration(1) }
/**
* Gets the compiler-generated `++__begin` which is the update
@@ -905,7 +905,7 @@ class RangeBasedForStmt extends Loop, @stmt_range_based_for {
Expr getUpdate() { result = this.getChild(3) }
/** Gets the compiler-generated `__begin` variable after desugaring. */
- LocalVariable getAnIterationVariable() { result = getBeginVariable() }
+ LocalVariable getAnIterationVariable() { result = this.getBeginVariable() }
}
/**
@@ -1067,7 +1067,7 @@ class ForStmt extends Loop, @stmt_for {
* for(x = 0; 1; ++x) { sum += x; }
* ```
*/
- predicate conditionAlwaysTrue() { conditionAlwaysTrue(getCondition()) }
+ predicate conditionAlwaysTrue() { conditionAlwaysTrue(this.getCondition()) }
/**
* Holds if the loop condition is provably `false`.
@@ -1077,7 +1077,7 @@ class ForStmt extends Loop, @stmt_for {
* for(x = 0; 0; ++x) { sum += x; }
* ```
*/
- predicate conditionAlwaysFalse() { conditionAlwaysFalse(getCondition()) }
+ predicate conditionAlwaysFalse() { conditionAlwaysFalse(this.getCondition()) }
/**
* Holds if the loop condition is provably `true` upon entry,
@@ -1723,10 +1723,10 @@ class Handler extends Stmt, @stmt_handler {
/**
* Gets the block containing the implementation of this handler.
*/
- CatchBlock getBlock() { result = getChild(0) }
+ CatchBlock getBlock() { result = this.getChild(0) }
/** Gets the 'try' statement corresponding to this 'catch block'. */
- TryStmt getTryStmt() { result = getParent() }
+ TryStmt getTryStmt() { result = this.getParent() }
/**
* Gets the parameter introduced by this 'catch block', if any.
@@ -1734,7 +1734,7 @@ class Handler extends Stmt, @stmt_handler {
* For example, `catch(std::exception& e)` introduces a
* parameter `e`, whereas `catch(...)` does not introduce a parameter.
*/
- Parameter getParameter() { result = getBlock().getParameter() }
+ Parameter getParameter() { result = this.getBlock().getParameter() }
override predicate mayBeImpure() { none() }
@@ -1921,15 +1921,15 @@ class MicrosoftTryStmt extends Stmt, @stmt_microsoft_try {
* This is a Microsoft C/C++ extension.
*/
class MicrosoftTryExceptStmt extends MicrosoftTryStmt {
- MicrosoftTryExceptStmt() { getChild(1) instanceof Expr }
+ MicrosoftTryExceptStmt() { this.getChild(1) instanceof Expr }
override string toString() { result = "__try { ... } __except( ... ) { ... }" }
/** Gets the expression guarding the `__except` statement. */
- Expr getCondition() { result = getChild(1) }
+ Expr getCondition() { result = this.getChild(1) }
/** Gets the `__except` statement (usually a `BlockStmt`). */
- Stmt getExcept() { result = getChild(2) }
+ Stmt getExcept() { result = this.getChild(2) }
override string getAPrimaryQlClass() { result = "MicrosoftTryExceptStmt" }
}
@@ -1948,12 +1948,12 @@ class MicrosoftTryExceptStmt extends MicrosoftTryStmt {
* This is a Microsoft C/C++ extension.
*/
class MicrosoftTryFinallyStmt extends MicrosoftTryStmt {
- MicrosoftTryFinallyStmt() { not getChild(1) instanceof Expr }
+ MicrosoftTryFinallyStmt() { not this.getChild(1) instanceof Expr }
override string toString() { result = "__try { ... } __finally { ... }" }
/** Gets the `__finally` statement (usually a `BlockStmt`). */
- Stmt getFinally() { result = getChild(1) }
+ Stmt getFinally() { result = this.getChild(1) }
override string getAPrimaryQlClass() { result = "MicrosoftTryFinallyStmt" }
}
diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme
index 7806a11dd7a..018f430097e 100644
--- a/cpp/ql/lib/semmlecode.cpp.dbscheme
+++ b/cpp/ql/lib/semmlecode.cpp.dbscheme
@@ -245,7 +245,7 @@ svnchurn(
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `file`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
locations_default(
/** The location of an element that is not an expression or a statement. */
@@ -262,7 +262,7 @@ locations_default(
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `file`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
locations_stmt(
/** The location of a statement. */
@@ -279,7 +279,7 @@ locations_stmt(
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `file`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
locations_expr(
/** The location of an expression. */
diff --git a/cpp/ql/lib/tutorial.qll b/cpp/ql/lib/tutorial.qll
new file mode 100644
index 00000000000..8cb1797a532
--- /dev/null
+++ b/cpp/ql/lib/tutorial.qll
@@ -0,0 +1,1207 @@
+/**
+ * This library is used in the QL detective tutorials.
+ *
+ * Note: Data is usually stored in a separate database and the QL libraries only contain predicates,
+ * but for this tutorial both the data and the predicates are stored in the library.
+ */
+class Person extends string {
+ Person() {
+ this = "Ronil" or
+ this = "Dina" or
+ this = "Ravi" or
+ this = "Bruce" or
+ this = "Jo" or
+ this = "Aida" or
+ this = "Esme" or
+ this = "Charlie" or
+ this = "Fred" or
+ this = "Meera" or
+ this = "Maya" or
+ this = "Chad" or
+ this = "Tiana" or
+ this = "Laura" or
+ this = "George" or
+ this = "Will" or
+ this = "Mary" or
+ this = "Almira" or
+ this = "Susannah" or
+ this = "Rhoda" or
+ this = "Cynthia" or
+ this = "Eunice" or
+ this = "Olive" or
+ this = "Virginia" or
+ this = "Angeline" or
+ this = "Helen" or
+ this = "Cornelia" or
+ this = "Harriet" or
+ this = "Mahala" or
+ this = "Abby" or
+ this = "Margaret" or
+ this = "Deb" or
+ this = "Minerva" or
+ this = "Severus" or
+ this = "Lavina" or
+ this = "Adeline" or
+ this = "Cath" or
+ this = "Elisa" or
+ this = "Lucretia" or
+ this = "Anne" or
+ this = "Eleanor" or
+ this = "Joanna" or
+ this = "Adam" or
+ this = "Agnes" or
+ this = "Rosanna" or
+ this = "Clara" or
+ this = "Melissa" or
+ this = "Amy" or
+ this = "Isabel" or
+ this = "Jemima" or
+ this = "Cordelia" or
+ this = "Melinda" or
+ this = "Delila" or
+ this = "Jeremiah" or
+ this = "Elijah" or
+ this = "Hester" or
+ this = "Walter" or
+ this = "Oliver" or
+ this = "Hugh" or
+ this = "Aaron" or
+ this = "Reuben" or
+ this = "Eli" or
+ this = "Amos" or
+ this = "Augustus" or
+ this = "Theodore" or
+ this = "Ira" or
+ this = "Timothy" or
+ this = "Cyrus" or
+ this = "Horace" or
+ this = "Simon" or
+ this = "Asa" or
+ this = "Frank" or
+ this = "Nelson" or
+ this = "Leonard" or
+ this = "Harrison" or
+ this = "Anthony" or
+ this = "Louis" or
+ this = "Milton" or
+ this = "Noah" or
+ this = "Cornelius" or
+ this = "Abdul" or
+ this = "Warren" or
+ this = "Harvey" or
+ this = "Dennis" or
+ this = "Wesley" or
+ this = "Sylvester" or
+ this = "Gilbert" or
+ this = "Sullivan" or
+ this = "Edmund" or
+ this = "Wilson" or
+ this = "Perry" or
+ this = "Matthew" or
+ this = "Simba" or
+ this = "Nala" or
+ this = "Rafiki" or
+ this = "Shenzi" or
+ this = "Ernest" or
+ this = "Gertrude" or
+ this = "Oscar" or
+ this = "Lilian" or
+ this = "Raymond" or
+ this = "Elgar" or
+ this = "Elmer" or
+ this = "Herbert" or
+ this = "Maude" or
+ this = "Mae" or
+ this = "Otto" or
+ this = "Edwin" or
+ this = "Ophelia" or
+ this = "Parsley" or
+ this = "Sage" or
+ this = "Rosemary" or
+ this = "Thyme" or
+ this = "Garfunkel" or
+ this = "King Basil" or
+ this = "Stephen"
+ }
+
+ /** Gets the hair color of the person. If the person is bald, there is no result. */
+ string getHairColor() {
+ this = "Ronil" and result = "black"
+ or
+ this = "Dina" and result = "black"
+ or
+ this = "Ravi" and result = "black"
+ or
+ this = "Bruce" and result = "brown"
+ or
+ this = "Jo" and result = "red"
+ or
+ this = "Aida" and result = "blond"
+ or
+ this = "Esme" and result = "blond"
+ or
+ this = "Fred" and result = "gray"
+ or
+ this = "Meera" and result = "brown"
+ or
+ this = "Maya" and result = "brown"
+ or
+ this = "Chad" and result = "brown"
+ or
+ this = "Tiana" and result = "black"
+ or
+ this = "Laura" and result = "blond"
+ or
+ this = "George" and result = "blond"
+ or
+ this = "Will" and result = "blond"
+ or
+ this = "Mary" and result = "blond"
+ or
+ this = "Almira" and result = "black"
+ or
+ this = "Susannah" and result = "blond"
+ or
+ this = "Rhoda" and result = "blond"
+ or
+ this = "Cynthia" and result = "gray"
+ or
+ this = "Eunice" and result = "white"
+ or
+ this = "Olive" and result = "brown"
+ or
+ this = "Virginia" and result = "brown"
+ or
+ this = "Angeline" and result = "red"
+ or
+ this = "Helen" and result = "white"
+ or
+ this = "Cornelia" and result = "gray"
+ or
+ this = "Harriet" and result = "white"
+ or
+ this = "Mahala" and result = "black"
+ or
+ this = "Abby" and result = "red"
+ or
+ this = "Margaret" and result = "brown"
+ or
+ this = "Deb" and result = "brown"
+ or
+ this = "Minerva" and result = "brown"
+ or
+ this = "Severus" and result = "black"
+ or
+ this = "Lavina" and result = "brown"
+ or
+ this = "Adeline" and result = "brown"
+ or
+ this = "Cath" and result = "brown"
+ or
+ this = "Elisa" and result = "brown"
+ or
+ this = "Lucretia" and result = "gray"
+ or
+ this = "Anne" and result = "black"
+ or
+ this = "Eleanor" and result = "brown"
+ or
+ this = "Joanna" and result = "brown"
+ or
+ this = "Adam" and result = "black"
+ or
+ this = "Agnes" and result = "black"
+ or
+ this = "Rosanna" and result = "gray"
+ or
+ this = "Clara" and result = "blond"
+ or
+ this = "Melissa" and result = "brown"
+ or
+ this = "Amy" and result = "brown"
+ or
+ this = "Isabel" and result = "black"
+ or
+ this = "Jemima" and result = "red"
+ or
+ this = "Cordelia" and result = "red"
+ or
+ this = "Melinda" and result = "gray"
+ or
+ this = "Delila" and result = "white"
+ or
+ this = "Jeremiah" and result = "gray"
+ or
+ this = "Hester" and result = "black"
+ or
+ this = "Walter" and result = "black"
+ or
+ this = "Aaron" and result = "gray"
+ or
+ this = "Reuben" and result = "gray"
+ or
+ this = "Eli" and result = "gray"
+ or
+ this = "Amos" and result = "white"
+ or
+ this = "Augustus" and result = "white"
+ or
+ this = "Theodore" and result = "white"
+ or
+ this = "Timothy" and result = "brown"
+ or
+ this = "Cyrus" and result = "brown"
+ or
+ this = "Horace" and result = "brown"
+ or
+ this = "Simon" and result = "brown"
+ or
+ this = "Asa" and result = "brown"
+ or
+ this = "Frank" and result = "brown"
+ or
+ this = "Nelson" and result = "black"
+ or
+ this = "Leonard" and result = "black"
+ or
+ this = "Harrison" and result = "black"
+ or
+ this = "Anthony" and result = "black"
+ or
+ this = "Louis" and result = "black"
+ or
+ this = "Milton" and result = "blond"
+ or
+ this = "Noah" and result = "blond"
+ or
+ this = "Cornelius" and result = "red"
+ or
+ this = "Abdul" and result = "brown"
+ or
+ this = "Warren" and result = "red"
+ or
+ this = "Harvey" and result = "blond"
+ or
+ this = "Dennis" and result = "blond"
+ or
+ this = "Wesley" and result = "brown"
+ or
+ this = "Sylvester" and result = "brown"
+ or
+ this = "Gilbert" and result = "brown"
+ or
+ this = "Sullivan" and result = "brown"
+ or
+ this = "Edmund" and result = "brown"
+ or
+ this = "Wilson" and result = "blond"
+ or
+ this = "Perry" and result = "black"
+ or
+ this = "Simba" and result = "brown"
+ or
+ this = "Nala" and result = "brown"
+ or
+ this = "Rafiki" and result = "red"
+ or
+ this = "Shenzi" and result = "gray"
+ or
+ this = "Ernest" and result = "blond"
+ or
+ this = "Gertrude" and result = "brown"
+ or
+ this = "Oscar" and result = "blond"
+ or
+ this = "Lilian" and result = "brown"
+ or
+ this = "Raymond" and result = "brown"
+ or
+ this = "Elgar" and result = "brown"
+ or
+ this = "Elmer" and result = "brown"
+ or
+ this = "Herbert" and result = "brown"
+ or
+ this = "Maude" and result = "brown"
+ or
+ this = "Mae" and result = "brown"
+ or
+ this = "Otto" and result = "black"
+ or
+ this = "Edwin" and result = "black"
+ or
+ this = "Ophelia" and result = "brown"
+ or
+ this = "Parsley" and result = "brown"
+ or
+ this = "Sage" and result = "brown"
+ or
+ this = "Rosemary" and result = "brown"
+ or
+ this = "Thyme" and result = "brown"
+ or
+ this = "Garfunkel" and result = "brown"
+ or
+ this = "King Basil" and result = "brown"
+ or
+ this = "Stephen" and result = "black"
+ or
+ this = "Stephen" and result = "gray"
+ }
+
+ /** Gets the age of the person (in years). If the person is deceased, there is no result. */
+ int getAge() {
+ this = "Ronil" and result = 21
+ or
+ this = "Dina" and result = 53
+ or
+ this = "Ravi" and result = 16
+ or
+ this = "Bruce" and result = 35
+ or
+ this = "Jo" and result = 47
+ or
+ this = "Aida" and result = 26
+ or
+ this = "Esme" and result = 25
+ or
+ this = "Charlie" and result = 31
+ or
+ this = "Fred" and result = 68
+ or
+ this = "Meera" and result = 62
+ or
+ this = "Maya" and result = 29
+ or
+ this = "Chad" and result = 49
+ or
+ this = "Tiana" and result = 18
+ or
+ this = "Laura" and result = 2
+ or
+ this = "George" and result = 3
+ or
+ this = "Will" and result = 41
+ or
+ this = "Mary" and result = 51
+ or
+ this = "Almira" and result = 1
+ or
+ this = "Susannah" and result = 97
+ or
+ this = "Rhoda" and result = 39
+ or
+ this = "Cynthia" and result = 89
+ or
+ this = "Eunice" and result = 83
+ or
+ this = "Olive" and result = 25
+ or
+ this = "Virginia" and result = 52
+ or
+ this = "Angeline" and result = 22
+ or
+ this = "Helen" and result = 79
+ or
+ this = "Cornelia" and result = 59
+ or
+ this = "Harriet" and result = 57
+ or
+ this = "Mahala" and result = 61
+ or
+ this = "Abby" and result = 24
+ or
+ this = "Margaret" and result = 59
+ or
+ this = "Deb" and result = 31
+ or
+ this = "Minerva" and result = 72
+ or
+ this = "Severus" and result = 61
+ or
+ this = "Lavina" and result = 33
+ or
+ this = "Adeline" and result = 17
+ or
+ this = "Cath" and result = 22
+ or
+ this = "Elisa" and result = 9
+ or
+ this = "Lucretia" and result = 56
+ or
+ this = "Anne" and result = 11
+ or
+ this = "Eleanor" and result = 80
+ or
+ this = "Joanna" and result = 43
+ or
+ this = "Adam" and result = 37
+ or
+ this = "Agnes" and result = 47
+ or
+ this = "Rosanna" and result = 61
+ or
+ this = "Clara" and result = 31
+ or
+ this = "Melissa" and result = 37
+ or
+ this = "Amy" and result = 12
+ or
+ this = "Isabel" and result = 6
+ or
+ this = "Jemima" and result = 16
+ or
+ this = "Cordelia" and result = 21
+ or
+ this = "Melinda" and result = 55
+ or
+ this = "Delila" and result = 66
+ or
+ this = "Jeremiah" and result = 54
+ or
+ this = "Elijah" and result = 42
+ or
+ this = "Hester" and result = 68
+ or
+ this = "Walter" and result = 66
+ or
+ this = "Oliver" and result = 33
+ or
+ this = "Hugh" and result = 51
+ or
+ this = "Aaron" and result = 49
+ or
+ this = "Reuben" and result = 58
+ or
+ this = "Eli" and result = 70
+ or
+ this = "Amos" and result = 65
+ or
+ this = "Augustus" and result = 56
+ or
+ this = "Theodore" and result = 69
+ or
+ this = "Ira" and result = 1
+ or
+ this = "Timothy" and result = 54
+ or
+ this = "Cyrus" and result = 78
+ or
+ this = "Horace" and result = 34
+ or
+ this = "Simon" and result = 23
+ or
+ this = "Asa" and result = 28
+ or
+ this = "Frank" and result = 59
+ or
+ this = "Nelson" and result = 38
+ or
+ this = "Leonard" and result = 58
+ or
+ this = "Harrison" and result = 7
+ or
+ this = "Anthony" and result = 2
+ or
+ this = "Louis" and result = 34
+ or
+ this = "Milton" and result = 36
+ or
+ this = "Noah" and result = 48
+ or
+ this = "Cornelius" and result = 41
+ or
+ this = "Abdul" and result = 67
+ or
+ this = "Warren" and result = 47
+ or
+ this = "Harvey" and result = 31
+ or
+ this = "Dennis" and result = 39
+ or
+ this = "Wesley" and result = 13
+ or
+ this = "Sylvester" and result = 19
+ or
+ this = "Gilbert" and result = 16
+ or
+ this = "Sullivan" and result = 17
+ or
+ this = "Edmund" and result = 29
+ or
+ this = "Wilson" and result = 27
+ or
+ this = "Perry" and result = 31
+ or
+ this = "Matthew" and result = 55
+ or
+ this = "Simba" and result = 8
+ or
+ this = "Nala" and result = 7
+ or
+ this = "Rafiki" and result = 76
+ or
+ this = "Shenzi" and result = 67
+ }
+
+ /** Gets the height of the person (in cm). If the person is deceased, there is no result. */
+ float getHeight() {
+ this = "Ronil" and result = 183.0
+ or
+ this = "Dina" and result = 155.1
+ or
+ this = "Ravi" and result = 175.2
+ or
+ this = "Bruce" and result = 191.3
+ or
+ this = "Jo" and result = 163.4
+ or
+ this = "Aida" and result = 182.6
+ or
+ this = "Esme" and result = 176.9
+ or
+ this = "Charlie" and result = 189.7
+ or
+ this = "Fred" and result = 179.4
+ or
+ this = "Meera" and result = 160.1
+ or
+ this = "Maya" and result = 153.0
+ or
+ this = "Chad" and result = 168.5
+ or
+ this = "Tiana" and result = 149.7
+ or
+ this = "Laura" and result = 87.5
+ or
+ this = "George" and result = 96.4
+ or
+ this = "Will" and result = 167.1
+ or
+ this = "Mary" and result = 159.8
+ or
+ this = "Almira" and result = 62.1
+ or
+ this = "Susannah" and result = 145.8
+ or
+ this = "Rhoda" and result = 180.1
+ or
+ this = "Cynthia" and result = 161.8
+ or
+ this = "Eunice" and result = 153.2
+ or
+ this = "Olive" and result = 179.9
+ or
+ this = "Virginia" and result = 165.1
+ or
+ this = "Angeline" and result = 172.3
+ or
+ this = "Helen" and result = 163.1
+ or
+ this = "Cornelia" and result = 160.8
+ or
+ this = "Harriet" and result = 163.2
+ or
+ this = "Mahala" and result = 157.7
+ or
+ this = "Abby" and result = 174.5
+ or
+ this = "Margaret" and result = 165.6
+ or
+ this = "Deb" and result = 171.6
+ or
+ this = "Minerva" and result = 168.7
+ or
+ this = "Severus" and result = 188.8
+ or
+ this = "Lavina" and result = 155.1
+ or
+ this = "Adeline" and result = 165.5
+ or
+ this = "Cath" and result = 147.8
+ or
+ this = "Elisa" and result = 129.4
+ or
+ this = "Lucretia" and result = 153.6
+ or
+ this = "Anne" and result = 140.4
+ or
+ this = "Eleanor" and result = 151.1
+ or
+ this = "Joanna" and result = 167.2
+ or
+ this = "Adam" and result = 155.5
+ or
+ this = "Agnes" and result = 156.8
+ or
+ this = "Rosanna" and result = 162.4
+ or
+ this = "Clara" and result = 158.6
+ or
+ this = "Melissa" and result = 182.3
+ or
+ this = "Amy" and result = 147.1
+ or
+ this = "Isabel" and result = 121.4
+ or
+ this = "Jemima" and result = 149.8
+ or
+ this = "Cordelia" and result = 151.7
+ or
+ this = "Melinda" and result = 154.4
+ or
+ this = "Delila" and result = 163.4
+ or
+ this = "Jeremiah" and result = 167.5
+ or
+ this = "Elijah" and result = 184.5
+ or
+ this = "Hester" and result = 152.7
+ or
+ this = "Walter" and result = 159.6
+ or
+ this = "Oliver" and result = 192.4
+ or
+ this = "Hugh" and result = 173.1
+ or
+ this = "Aaron" and result = 176.6
+ or
+ this = "Reuben" and result = 169.9
+ or
+ this = "Eli" and result = 180.4
+ or
+ this = "Amos" and result = 167.4
+ or
+ this = "Augustus" and result = 156.5
+ or
+ this = "Theodore" and result = 176.6
+ or
+ this = "Ira" and result = 54.1
+ or
+ this = "Timothy" and result = 172.2
+ or
+ this = "Cyrus" and result = 157.9
+ or
+ this = "Horace" and result = 169.3
+ or
+ this = "Simon" and result = 157.1
+ or
+ this = "Asa" and result = 149.4
+ or
+ this = "Frank" and result = 167.2
+ or
+ this = "Nelson" and result = 173.0
+ or
+ this = "Leonard" and result = 172.0
+ or
+ this = "Harrison" and result = 126.0
+ or
+ this = "Anthony" and result = 98.4
+ or
+ this = "Louis" and result = 186.8
+ or
+ this = "Milton" and result = 157.8
+ or
+ this = "Noah" and result = 190.5
+ or
+ this = "Cornelius" and result = 183.1
+ or
+ this = "Abdul" and result = 182.0
+ or
+ this = "Warren" and result = 175.0
+ or
+ this = "Harvey" and result = 169.3
+ or
+ this = "Dennis" and result = 160.4
+ or
+ this = "Wesley" and result = 139.8
+ or
+ this = "Sylvester" and result = 188.2
+ or
+ this = "Gilbert" and result = 177.6
+ or
+ this = "Sullivan" and result = 168.3
+ or
+ this = "Edmund" and result = 159.2
+ or
+ this = "Wilson" and result = 167.6
+ or
+ this = "Perry" and result = 189.1
+ or
+ this = "Matthew" and result = 167.2
+ or
+ this = "Simba" and result = 140.1
+ or
+ this = "Nala" and result = 138.0
+ or
+ this = "Rafiki" and result = 139.3
+ or
+ this = "Shenzi" and result = 171.1
+ }
+
+ /** Gets the location of the person's home ("north", "south", "east", or "west"). If the person is deceased, there is no result. */
+ string getLocation() {
+ this = "Ronil" and result = "north"
+ or
+ this = "Dina" and result = "north"
+ or
+ this = "Ravi" and result = "north"
+ or
+ this = "Bruce" and result = "south"
+ or
+ this = "Jo" and result = "west"
+ or
+ this = "Aida" and result = "east"
+ or
+ this = "Esme" and result = "east"
+ or
+ this = "Charlie" and result = "south"
+ or
+ this = "Fred" and result = "west"
+ or
+ this = "Meera" and result = "south"
+ or
+ this = "Maya" and result = "south"
+ or
+ this = "Chad" and result = "south"
+ or
+ this = "Tiana" and result = "west"
+ or
+ this = "Laura" and result = "south"
+ or
+ this = "George" and result = "south"
+ or
+ this = "Will" and result = "south"
+ or
+ this = "Mary" and result = "south"
+ or
+ this = "Almira" and result = "south"
+ or
+ this = "Susannah" and result = "north"
+ or
+ this = "Rhoda" and result = "north"
+ or
+ this = "Cynthia" and result = "north"
+ or
+ this = "Eunice" and result = "north"
+ or
+ this = "Olive" and result = "west"
+ or
+ this = "Virginia" and result = "west"
+ or
+ this = "Angeline" and result = "west"
+ or
+ this = "Helen" and result = "west"
+ or
+ this = "Cornelia" and result = "east"
+ or
+ this = "Harriet" and result = "east"
+ or
+ this = "Mahala" and result = "east"
+ or
+ this = "Abby" and result = "east"
+ or
+ this = "Margaret" and result = "east"
+ or
+ this = "Deb" and result = "east"
+ or
+ this = "Minerva" and result = "south"
+ or
+ this = "Severus" and result = "north"
+ or
+ this = "Lavina" and result = "east"
+ or
+ this = "Adeline" and result = "west"
+ or
+ this = "Cath" and result = "east"
+ or
+ this = "Elisa" and result = "east"
+ or
+ this = "Lucretia" and result = "north"
+ or
+ this = "Anne" and result = "north"
+ or
+ this = "Eleanor" and result = "south"
+ or
+ this = "Joanna" and result = "south"
+ or
+ this = "Adam" and result = "east"
+ or
+ this = "Agnes" and result = "east"
+ or
+ this = "Rosanna" and result = "east"
+ or
+ this = "Clara" and result = "east"
+ or
+ this = "Melissa" and result = "west"
+ or
+ this = "Amy" and result = "west"
+ or
+ this = "Isabel" and result = "west"
+ or
+ this = "Jemima" and result = "west"
+ or
+ this = "Cordelia" and result = "west"
+ or
+ this = "Melinda" and result = "west"
+ or
+ this = "Delila" and result = "south"
+ or
+ this = "Jeremiah" and result = "north"
+ or
+ this = "Elijah" and result = "north"
+ or
+ this = "Hester" and result = "east"
+ or
+ this = "Walter" and result = "east"
+ or
+ this = "Oliver" and result = "east"
+ or
+ this = "Hugh" and result = "south"
+ or
+ this = "Aaron" and result = "south"
+ or
+ this = "Reuben" and result = "west"
+ or
+ this = "Eli" and result = "west"
+ or
+ this = "Amos" and result = "east"
+ or
+ this = "Augustus" and result = "south"
+ or
+ this = "Theodore" and result = "west"
+ or
+ this = "Ira" and result = "south"
+ or
+ this = "Timothy" and result = "north"
+ or
+ this = "Cyrus" and result = "north"
+ or
+ this = "Horace" and result = "east"
+ or
+ this = "Simon" and result = "east"
+ or
+ this = "Asa" and result = "east"
+ or
+ this = "Frank" and result = "west"
+ or
+ this = "Nelson" and result = "west"
+ or
+ this = "Leonard" and result = "west"
+ or
+ this = "Harrison" and result = "north"
+ or
+ this = "Anthony" and result = "north"
+ or
+ this = "Louis" and result = "north"
+ or
+ this = "Milton" and result = "south"
+ or
+ this = "Noah" and result = "south"
+ or
+ this = "Cornelius" and result = "east"
+ or
+ this = "Abdul" and result = "east"
+ or
+ this = "Warren" and result = "west"
+ or
+ this = "Harvey" and result = "west"
+ or
+ this = "Dennis" and result = "west"
+ or
+ this = "Wesley" and result = "west"
+ or
+ this = "Sylvester" and result = "south"
+ or
+ this = "Gilbert" and result = "east"
+ or
+ this = "Sullivan" and result = "east"
+ or
+ this = "Edmund" and result = "north"
+ or
+ this = "Wilson" and result = "north"
+ or
+ this = "Perry" and result = "west"
+ or
+ this = "Matthew" and result = "east"
+ or
+ this = "Simba" and result = "south"
+ or
+ this = "Nala" and result = "south"
+ or
+ this = "Rafiki" and result = "north"
+ or
+ this = "Shenzi" and result = "west"
+ }
+
+ /** Holds if the person is deceased. */
+ predicate isDeceased() {
+ this = "Ernest" or
+ this = "Gertrude" or
+ this = "Oscar" or
+ this = "Lilian" or
+ this = "Edwin" or
+ this = "Raymond" or
+ this = "Elgar" or
+ this = "Elmer" or
+ this = "Herbert" or
+ this = "Maude" or
+ this = "Mae" or
+ this = "Otto" or
+ this = "Ophelia" or
+ this = "Parsley" or
+ this = "Sage" or
+ this = "Rosemary" or
+ this = "Thyme" or
+ this = "Garfunkel" or
+ this = "King Basil"
+ }
+
+ /** Gets a parent of the person (alive or deceased). */
+ Person getAParent() {
+ this = "Stephen" and result = "Edmund"
+ or
+ this = "Edmund" and result = "Augustus"
+ or
+ this = "Augustus" and result = "Stephen"
+ or
+ this = "Abby" and result = "Cornelia"
+ or
+ this = "Abby" and result = "Amos"
+ or
+ this = "Abdul" and result = "Susannah"
+ or
+ this = "Adam" and result = "Amos"
+ or
+ this = "Adeline" and result = "Melinda"
+ or
+ this = "Adeline" and result = "Frank"
+ or
+ this = "Agnes" and result = "Abdul"
+ or
+ this = "Aida" and result = "Agnes"
+ or
+ this = "Almira" and result = "Sylvester"
+ or
+ this = "Amos" and result = "Eunice"
+ or
+ this = "Amy" and result = "Noah"
+ or
+ this = "Amy" and result = "Chad"
+ or
+ this = "Angeline" and result = "Reuben"
+ or
+ this = "Angeline" and result = "Lucretia"
+ or
+ this = "Anne" and result = "Rhoda"
+ or
+ this = "Anne" and result = "Louis"
+ or
+ this = "Anthony" and result = "Lavina"
+ or
+ this = "Anthony" and result = "Asa"
+ or
+ this = "Asa" and result = "Cornelia"
+ or
+ this = "Cath" and result = "Harriet"
+ or
+ this = "Charlie" and result = "Matthew"
+ or
+ this = "Clara" and result = "Ernest"
+ or
+ this = "Cornelia" and result = "Cynthia"
+ or
+ this = "Cornelius" and result = "Eli"
+ or
+ this = "Deb" and result = "Margaret"
+ or
+ this = "Dennis" and result = "Fred"
+ or
+ this = "Eli" and result = "Susannah"
+ or
+ this = "Elijah" and result = "Delila"
+ or
+ this = "Elisa" and result = "Deb"
+ or
+ this = "Elisa" and result = "Horace"
+ or
+ this = "Esme" and result = "Margaret"
+ or
+ this = "Frank" and result = "Eleanor"
+ or
+ this = "Frank" and result = "Cyrus"
+ or
+ this = "George" and result = "Maya"
+ or
+ this = "George" and result = "Wilson"
+ or
+ this = "Gilbert" and result = "Cornelius"
+ or
+ this = "Harriet" and result = "Cynthia"
+ or
+ this = "Harrison" and result = "Louis"
+ or
+ this = "Harvey" and result = "Fred"
+ or
+ this = "Helen" and result = "Susannah"
+ or
+ this = "Hester" and result = "Edwin"
+ or
+ this = "Hugh" and result = "Cyrus"
+ or
+ this = "Hugh" and result = "Helen"
+ or
+ this = "Ira" and result = "Maya"
+ or
+ this = "Ira" and result = "Wilson"
+ or
+ this = "Isabel" and result = "Perry"
+ or
+ this = "Isabel" and result = "Harvey"
+ or
+ this = "Jemima" and result = "Melinda"
+ or
+ this = "Jemima" and result = "Frank"
+ or
+ this = "Ernest" and result = "Lilian"
+ or
+ this = "Ernest" and result = "Oscar"
+ or
+ this = "Gertrude" and result = "Ophelia"
+ or
+ this = "Gertrude" and result = "Raymond"
+ or
+ this = "Lilian" and result = "Elgar"
+ or
+ this = "Lilian" and result = "Mae"
+ or
+ this = "Raymond" and result = "Elgar"
+ or
+ this = "Raymond" and result = "Mae"
+ or
+ this = "Elmer" and result = "Ophelia"
+ or
+ this = "Elmer" and result = "Raymond"
+ or
+ this = "Herbert" and result = "Ophelia"
+ or
+ this = "Herbert" and result = "Raymond"
+ or
+ this = "Maude" and result = "Ophelia"
+ or
+ this = "Maude" and result = "Raymond"
+ or
+ this = "Otto" and result = "Elgar"
+ or
+ this = "Otto" and result = "Mae"
+ or
+ this = "Edwin" and result = "Otto"
+ or
+ this = "Parsley" and result = "Simon"
+ or
+ this = "Parsley" and result = "Garfunkel"
+ or
+ this = "Sage" and result = "Simon"
+ or
+ this = "Sage" and result = "Garfunkel"
+ or
+ this = "Rosemary" and result = "Simon"
+ or
+ this = "Rosemary" and result = "Garfunkel"
+ or
+ this = "Thyme" and result = "Simon"
+ or
+ this = "Thyme" and result = "Garfunkel"
+ or
+ this = "King Basil" and result = "Ophelia"
+ or
+ this = "King Basil" and result = "Raymond"
+ or
+ this = "Jo" and result = "Theodore"
+ or
+ this = "Joanna" and result = "Shenzi"
+ or
+ this = "Laura" and result = "Maya"
+ or
+ this = "Laura" and result = "Wilson"
+ or
+ this = "Lavina" and result = "Mahala"
+ or
+ this = "Lavina" and result = "Walter"
+ or
+ this = "Leonard" and result = "Cyrus"
+ or
+ this = "Leonard" and result = "Helen"
+ or
+ this = "Lucretia" and result = "Eleanor"
+ or
+ this = "Lucretia" and result = "Cyrus"
+ or
+ this = "Mahala" and result = "Eunice"
+ or
+ this = "Margaret" and result = "Cynthia"
+ or
+ this = "Matthew" and result = "Cyrus"
+ or
+ this = "Matthew" and result = "Helen"
+ or
+ this = "Maya" and result = "Meera"
+ or
+ this = "Melinda" and result = "Rafiki"
+ or
+ this = "Melissa" and result = "Mahala"
+ or
+ this = "Melissa" and result = "Walter"
+ or
+ this = "Nala" and result = "Bruce"
+ or
+ this = "Nelson" and result = "Mahala"
+ or
+ this = "Nelson" and result = "Walter"
+ or
+ this = "Noah" and result = "Eli"
+ or
+ this = "Olive" and result = "Reuben"
+ or
+ this = "Olive" and result = "Lucretia"
+ or
+ this = "Oliver" and result = "Matthew"
+ or
+ this = "Perry" and result = "Leonard"
+ or
+ this = "Ravi" and result = "Dina"
+ or
+ this = "Simba" and result = "Will"
+ or
+ this = "Simon" and result = "Margaret"
+ or
+ this = "Sullivan" and result = "Cornelius"
+ or
+ this = "Sylvester" and result = "Timothy"
+ or
+ this = "Theodore" and result = "Susannah"
+ or
+ this = "Tiana" and result = "Jo"
+ or
+ this = "Virginia" and result = "Helen"
+ or
+ this = "Warren" and result = "Shenzi"
+ or
+ this = "Wesley" and result = "Warren"
+ or
+ this = "Wesley" and result = "Jo"
+ or
+ this = "Will" and result = "Eli"
+ }
+
+ /** Holds if the person is allowed in the region. Initially, all villagers are allowed in every region. */
+ predicate isAllowedIn(string region) {
+ region = "north" or
+ region = "south" or
+ region = "east" or
+ region = "west"
+ }
+}
+
+/** Returns a parent of the person. */
+Person parentOf(Person p) { result = p.getAParent() }
diff --git a/cpp/ql/src/AlertSuppression.ql b/cpp/ql/src/AlertSuppression.ql
index 6258e8f7818..9a3983ed515 100644
--- a/cpp/ql/src/AlertSuppression.ql
+++ b/cpp/ql/src/AlertSuppression.ql
@@ -60,20 +60,18 @@ class SuppressionComment extends Comment {
/**
* The scope of an alert suppression comment.
*/
-class SuppressionScope extends ElementBase {
- SuppressionScope() { this instanceof SuppressionComment }
-
+class SuppressionScope extends ElementBase instanceof SuppressionComment {
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
- this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn)
+ super.covers(filepath, startline, startcolumn, endline, endcolumn)
}
}
diff --git a/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyFields.ql b/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyFields.ql
index 5f11a9e0830..d2c69ba5fff 100644
--- a/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyFields.ql
+++ b/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyFields.ql
@@ -68,12 +68,12 @@ class VariableDeclarationLine extends TVariableDeclarationInfo {
/**
* Gets the start column of the first `VariableDeclarationEntry` on this line.
*/
- int getStartColumn() { result = min(getAVDE().getLocation().getStartColumn()) }
+ int getStartColumn() { result = min(this.getAVDE().getLocation().getStartColumn()) }
/**
* Gets the end column of the last `VariableDeclarationEntry` on this line.
*/
- int getEndColumn() { result = max(getAVDE().getLocation().getEndColumn()) }
+ int getEndColumn() { result = max(this.getAVDE().getLocation().getEndColumn()) }
/**
* Gets the rank of this `VariableDeclarationLine` in its file and class
@@ -89,14 +89,14 @@ class VariableDeclarationLine extends TVariableDeclarationInfo {
*/
VariableDeclarationLine getNext() {
result = TVariableDeclarationLine(c, f, _) and
- result.getRank() = getRank() + 1
+ result.getRank() = this.getRank() + 1
}
/**
* Gets the `VariableDeclarationLine` following this one, if it is nearby.
*/
VariableDeclarationLine getProximateNext() {
- result = getNext() and
+ result = this.getNext() and
result.getLine() <= this.getLine() + 3
}
@@ -114,14 +114,14 @@ class VariableDeclarationGroup extends VariableDeclarationLine {
// there is no `VariableDeclarationLine` within three lines previously
not any(VariableDeclarationLine prev).getProximateNext() = this and
// `end` is the last transitively proximate line
- end = getProximateNext*() and
+ end = this.getProximateNext*() and
not exists(end.getProximateNext())
}
predicate hasLocationInfo(string path, int startline, int startcol, int endline, int endcol) {
path = f.getAbsolutePath() and
- startline = getLine() and
- startcol = getStartColumn() and
+ startline = this.getLine() and
+ startcol = this.getStartColumn() and
endline = end.getLine() and
endcol = end.getEndColumn()
}
@@ -132,18 +132,18 @@ class VariableDeclarationGroup extends VariableDeclarationLine {
int getCount() {
result =
count(VariableDeclarationLine l |
- l = getProximateNext*()
+ l = this.getProximateNext*()
|
l.getAVDE().getVariable().getName()
)
}
override string toString() {
- getCount() = 1 and
- result = "declaration of " + getAVDE().getVariable().getName()
+ this.getCount() = 1 and
+ result = "declaration of " + this.getAVDE().getVariable().getName()
or
- getCount() > 1 and
- result = "group of " + getCount() + " fields here"
+ this.getCount() > 1 and
+ result = "group of " + this.getCount() + " fields here"
}
}
diff --git a/cpp/ql/src/Best Practices/Magic Constants/MagicConstants.qll b/cpp/ql/src/Best Practices/Magic Constants/MagicConstants.qll
index 587b64b60b3..fce3d286a5f 100644
--- a/cpp/ql/src/Best Practices/Magic Constants/MagicConstants.qll
+++ b/cpp/ql/src/Best Practices/Magic Constants/MagicConstants.qll
@@ -58,15 +58,7 @@ predicate intTrivial(Literal lit) { exists(string v | trivialIntValue(v) and v =
predicate longTrivial(Literal lit) { exists(string v | trivialLongValue(v) and v = lit.getValue()) }
predicate powerOfTen(float f) {
- f = 10 or
- f = 100 or
- f = 1000 or
- f = 10000 or
- f = 100000 or
- f = 1000000 or
- f = 10000000 or
- f = 100000000 or
- f = 1000000000
+ f = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]
}
predicate floatTrivial(Literal lit) {
diff --git a/cpp/ql/src/Critical/OverflowStatic.ql b/cpp/ql/src/Critical/OverflowStatic.ql
index 7c447c12323..8b09931cd4a 100644
--- a/cpp/ql/src/Critical/OverflowStatic.ql
+++ b/cpp/ql/src/Critical/OverflowStatic.ql
@@ -5,7 +5,7 @@
* @kind problem
* @problem.severity warning
* @security-severity 9.3
- * @precision medium
+ * @precision high
* @id cpp/static-buffer-overflow
* @tags reliability
* security
@@ -55,6 +55,8 @@ predicate overflowOffsetInLoop(BufferAccess bufaccess, string msg) {
loop.counter().getAnAccess() = bufaccess.getArrayOffset() and
// Ensure that we don't have an upper bound on the array index that's less than the buffer size.
not upperBound(bufaccess.getArrayOffset().getFullyConverted()) < bufaccess.bufferSize() and
+ // The upper bounds analysis must not have been widended
+ not upperBoundMayBeWidened(bufaccess.getArrayOffset().getFullyConverted()) and
msg =
"Potential buffer-overflow: counter '" + loop.counter().toString() + "' <= " +
loop.limit().toString() + " but '" + bufaccess.buffer().getName() + "' has " +
@@ -130,11 +132,13 @@ predicate outOfBounds(BufferAccess bufaccess, string msg) {
(
access > size
or
- access = size and not exists(AddressOfExpr addof | bufaccess = addof.getOperand())
+ access = size and
+ not exists(AddressOfExpr addof | bufaccess = addof.getOperand()) and
+ not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild() = bufaccess)
) and
msg =
"Potential buffer-overflow: '" + buf + "' has size " + size.toString() + " but '" + buf + "[" +
- access.toString() + "]' is accessed here."
+ access.toString() + "]' may be accessed here."
)
}
diff --git a/cpp/ql/src/Diagnostics/ExtractionErrors.ql b/cpp/ql/src/Diagnostics/ExtractionErrors.ql
deleted file mode 100644
index a445c3bc0c4..00000000000
--- a/cpp/ql/src/Diagnostics/ExtractionErrors.ql
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * @name Extraction errors
- * @description List all extraction errors for files in the source code directory.
- * @kind diagnostic
- * @id cpp/diagnostics/extraction-errors
- */
-
-import cpp
-import ExtractionErrors
-
-from ExtractionError error
-where
- error instanceof ExtractionUnknownError or
- exists(error.getFile().getRelativePath())
-select error, "Extraction failed in " + error.getFile() + " with error " + error.getErrorMessage(),
- error.getSeverity()
diff --git a/cpp/ql/src/Diagnostics/ExtractionErrors.qll b/cpp/ql/src/Diagnostics/ExtractionProblems.qll
similarity index 50%
rename from cpp/ql/src/Diagnostics/ExtractionErrors.qll
rename to cpp/ql/src/Diagnostics/ExtractionProblems.qll
index 4cf6f8145f8..c96e2e926e8 100644
--- a/cpp/ql/src/Diagnostics/ExtractionErrors.qll
+++ b/cpp/ql/src/Diagnostics/ExtractionProblems.qll
@@ -1,12 +1,12 @@
/**
- * Provides a common hierarchy of all types of errors that can occur during extraction.
+ * Provides a common hierarchy of all types of problems that can occur during extraction.
*/
import cpp
/*
* A note about how the C/C++ extractor emits diagnostics:
- * When the extractor frontend encounters an error, it emits a diagnostic message,
+ * When the extractor frontend encounters a problem, it emits a diagnostic message,
* that includes a message, location and severity.
* However, that process is best-effort and may fail (e.g. due to lack of memory).
* Thus, if the extractor emitted at least one diagnostic of severity discretionary
@@ -15,17 +15,17 @@ import cpp
* In the common case, this means that a compilation during which one or more errors happened also gets
* the catch-all diagnostic.
* This diagnostic has the empty string as file path.
- * We filter out these useless diagnostics if there is at least one error-level diagnostic
+ * We filter out these useless diagnostics if there is at least one warning-level diagnostic
* for the affected compilation in the database.
* Otherwise, we show it to indicate that something went wrong and that we
* don't know what exactly happened.
*/
/**
- * An error that, if present, leads to a file being marked as non-successfully extracted.
+ * A problem with a file that, if present, leads to a file being marked as non-successfully extracted.
*/
-class ReportableError extends Diagnostic {
- ReportableError() {
+class ReportableWarning extends Diagnostic {
+ ReportableWarning() {
(
this instanceof CompilerDiscretionaryError or
this instanceof CompilerError or
@@ -36,39 +36,35 @@ class ReportableError extends Diagnostic {
}
}
-private newtype TExtractionError =
- TReportableError(ReportableError err) or
+private newtype TExtractionProblem =
+ TReportableWarning(ReportableWarning err) or
TCompilationFailed(Compilation c, File f) {
f = c.getAFileCompiled() and not c.normalTermination()
} or
// Show the catch-all diagnostic (see note above) only if we haven't seen any other error-level diagnostic
// for that compilation
- TUnknownError(CompilerError err) {
- not exists(ReportableError e | e.getCompilation() = err.getCompilation())
+ TUnknownProblem(CompilerError err) {
+ not exists(ReportableWarning e | e.getCompilation() = err.getCompilation())
}
/**
- * Superclass for the extraction error hierarchy.
+ * Superclass for the extraction problem hierarchy.
*/
-class ExtractionError extends TExtractionError {
- /** Gets the string representation of the error. */
+class ExtractionProblem extends TExtractionProblem {
+ /** Gets the string representation of the problem. */
string toString() { none() }
- /** Gets the error message for this error. */
- string getErrorMessage() { none() }
+ /** Gets the problem message for this problem. */
+ string getProblemMessage() { none() }
- /** Gets the file this error occured in. */
+ /** Gets the file this problem occured in. */
File getFile() { none() }
- /** Gets the location this error occured in. */
+ /** Gets the location this problem occured in. */
Location getLocation() { none() }
- /** Gets the SARIF severity of this error. */
- int getSeverity() {
- // Unfortunately, we can't distinguish between errors and fatal errors in SARIF,
- // so all errors have severity 2.
- result = 2
- }
+ /** Gets the SARIF severity of this problem. */
+ int getSeverity() { none() }
}
/**
@@ -79,7 +75,7 @@ class ExtractionError extends TExtractionError {
* - stack overflow
* - out of memory
*/
-class ExtractionUnrecoverableError extends ExtractionError, TCompilationFailed {
+class ExtractionUnrecoverableError extends ExtractionProblem, TCompilationFailed {
Compilation c;
File f;
@@ -89,49 +85,67 @@ class ExtractionUnrecoverableError extends ExtractionError, TCompilationFailed {
result = "Unrecoverable extraction error while compiling " + f.toString()
}
- override string getErrorMessage() { result = "unrecoverable compilation failure." }
+ override string getProblemMessage() { result = "unrecoverable compilation failure." }
override File getFile() { result = f }
override Location getLocation() { result = f.getLocation() }
+
+ override int getSeverity() {
+ // These extractor errors break the analysis, so we mark them in SARIF as
+ // [errors](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#_Toc10541338).
+ result = 2
+ }
}
/**
- * A recoverable extraction error.
+ * A recoverable extraction warning.
* These are compiler errors from the frontend.
* Upon encountering one of these, we still continue extraction, but the
* database will be incomplete for that file.
*/
-class ExtractionRecoverableError extends ExtractionError, TReportableError {
- ReportableError err;
+class ExtractionRecoverableWarning extends ExtractionProblem, TReportableWarning {
+ ReportableWarning err;
- ExtractionRecoverableError() { this = TReportableError(err) }
+ ExtractionRecoverableWarning() { this = TReportableWarning(err) }
override string toString() { result = "Recoverable extraction error: " + err }
- override string getErrorMessage() { result = err.getFullMessage() }
+ override string getProblemMessage() { result = err.getFullMessage() }
override File getFile() { result = err.getFile() }
override Location getLocation() { result = err.getLocation() }
+
+ override int getSeverity() {
+ // Recoverable extraction problems don't tend to break the analysis, so we mark them in SARIF as
+ // [warnings](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#_Toc10541338).
+ result = 1
+ }
}
/**
- * An unknown error happened during extraction.
- * These are only displayed if we know that we encountered an error during extraction,
+ * An unknown problem happened during extraction.
+ * These are only displayed if we know that we encountered an problem during extraction,
* but, for some reason, failed to emit a proper diagnostic with location information
- * and error message.
+ * and problem message.
*/
-class ExtractionUnknownError extends ExtractionError, TUnknownError {
+class ExtractionUnknownProblem extends ExtractionProblem, TUnknownProblem {
CompilerError err;
- ExtractionUnknownError() { this = TUnknownError(err) }
+ ExtractionUnknownProblem() { this = TUnknownProblem(err) }
- override string toString() { result = "Unknown extraction error: " + err }
+ override string toString() { result = "Unknown extraction problem: " + err }
- override string getErrorMessage() { result = err.getFullMessage() }
+ override string getProblemMessage() { result = err.getFullMessage() }
override File getFile() { result = err.getFile() }
override Location getLocation() { result = err.getLocation() }
+
+ override int getSeverity() {
+ // Unknown extraction problems don't tend to break the analysis, so we mark them in SARIF as
+ // [warnings](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#_Toc10541338).
+ result = 1
+ }
}
diff --git a/cpp/ql/src/Diagnostics/ExtractionWarnings.ql b/cpp/ql/src/Diagnostics/ExtractionWarnings.ql
new file mode 100644
index 00000000000..dcfb599bbeb
--- /dev/null
+++ b/cpp/ql/src/Diagnostics/ExtractionWarnings.ql
@@ -0,0 +1,18 @@
+/**
+ * @name Extraction warnings
+ * @description List all extraction warnings for files in the source code directory.
+ * @kind diagnostic
+ * @id cpp/diagnostics/extraction-warnings
+ */
+
+import cpp
+import ExtractionProblems
+
+from ExtractionProblem warning
+where
+ warning instanceof ExtractionRecoverableWarning and exists(warning.getFile().getRelativePath())
+ or
+ warning instanceof ExtractionUnknownProblem
+select warning,
+ "Extraction failed in " + warning.getFile() + " with warning " + warning.getProblemMessage(),
+ warning.getSeverity()
diff --git a/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql b/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql
index 8672d674d2d..fdc02f12135 100644
--- a/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql
+++ b/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql
@@ -13,6 +13,9 @@ string describe(Compilation c) {
else result = "extractor invocation " + concat(int i | | c.getArgument(i), " " order by i)
}
+/** Gets the SARIF severity level that indicates an error. */
+private int getErrorSeverity() { result = 2 }
+
from Compilation c
where not c.normalTermination()
-select "Extraction aborted for " + describe(c)
+select "Extraction aborted for " + describe(c), getErrorSeverity()
diff --git a/cpp/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql b/cpp/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql
index a920af8e767..3e9fb12d935 100644
--- a/cpp/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql
+++ b/cpp/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql
@@ -1,15 +1,15 @@
/**
* @name Successfully extracted files
- * @description Lists all files in the source code directory that were extracted without encountering an error in the file.
+ * @description Lists all files in the source code directory that were extracted without encountering a problem in the file.
* @kind diagnostic
* @id cpp/diagnostics/successfully-extracted-files
*/
import cpp
-import ExtractionErrors
+import ExtractionProblems
from File f
where
- not exists(ExtractionError e | e.getFile() = f) and
+ not exists(ExtractionProblem e | e.getFile() = f) and
exists(f.getRelativePath())
-select f, ""
+select f, "File successfully extracted"
diff --git a/cpp/ql/src/Documentation/CommentedOutCode.qll b/cpp/ql/src/Documentation/CommentedOutCode.qll
index 172474bbe29..a4e5b948630 100644
--- a/cpp/ql/src/Documentation/CommentedOutCode.qll
+++ b/cpp/ql/src/Documentation/CommentedOutCode.qll
@@ -198,7 +198,7 @@ class CommentBlock extends Comment {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/cpp/ql/src/JPL_C/LOC-2/Rule 09/Semaphores.qll b/cpp/ql/src/JPL_C/LOC-2/Rule 09/Semaphores.qll
index 0b60a3b9877..543c516e4bf 100644
--- a/cpp/ql/src/JPL_C/LOC-2/Rule 09/Semaphores.qll
+++ b/cpp/ql/src/JPL_C/LOC-2/Rule 09/Semaphores.qll
@@ -50,7 +50,7 @@ class SemaphoreTake extends LockOperation {
result.(SemaphoreGive).getLocked() = this.getLocked()
}
- override string say() { result = "semaphore take of " + getLocked().getName() }
+ override string say() { result = "semaphore take of " + this.getLocked().getName() }
}
class SemaphoreGive extends UnlockOperation {
@@ -76,13 +76,13 @@ class LockingPrimitive extends FunctionCall, LockOperation {
this.getTarget().getName().replaceAll("Lock", "Unlock")
}
- override string say() { result = "call to " + getLocked().getName() }
+ override string say() { result = "call to " + this.getLocked().getName() }
}
class UnlockingPrimitive extends FunctionCall, UnlockOperation {
UnlockingPrimitive() { this.getTarget().getName() = ["taskUnlock", "intUnlock", "taskRtpUnlock"] }
- Function getLocked() { result = getMatchingLock().getLocked() }
+ Function getLocked() { result = this.getMatchingLock().getLocked() }
override LockOperation getMatchingLock() { this = result.getMatchingUnlock() }
}
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
index 03ad085b6d3..ba7a6b58aa0 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
@@ -166,6 +166,7 @@ class VarAnalyzableExpr extends AnalyzableExpr, VariableAccess {
* Holds if `t` is not an instance of `IntegralType`,
* or if `me` cannot be proven to not overflow
*/
+pragma[inline]
predicate overflows(MulExpr me, Type t) {
t instanceof IntegralType
implies
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql
index 94a6c403937..e2fe02be867 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql
@@ -50,10 +50,7 @@ where
// If either of the operands is constant, then don't include it.
(
if cmp.getLeftOperand().isConstant()
- then
- if cmp.getRightOperand().isConstant()
- then none() // Both operands are constant so don't create a message.
- else reason = rightReason
+ then not cmp.getRightOperand().isConstant() and reason = rightReason
else
if cmp.getRightOperand().isConstant()
then reason = leftReason
diff --git a/cpp/ql/src/Likely Bugs/Conversion/NonzeroValueCastToPointer.ql b/cpp/ql/src/Likely Bugs/Conversion/NonzeroValueCastToPointer.ql
index 87f52198b0d..47842118874 100644
--- a/cpp/ql/src/Likely Bugs/Conversion/NonzeroValueCastToPointer.ql
+++ b/cpp/ql/src/Likely Bugs/Conversion/NonzeroValueCastToPointer.ql
@@ -13,14 +13,15 @@
import cpp
predicate commonErrorCode(string value) {
- value = "0" or
- value = "1" or
- value = "-1" or
- value = "18446744073709551615" or // 2^64-1, i.e. -1 as an unsigned int64
- value = "4294967295" or // 2^32-1, i.e. -1 as an unsigned int32
- value = "3735928559" or // 0xdeadbeef
- value = "3735929054" or // 0xdeadc0de
- value = "3405691582" // 0xcafebabe
+ value =
+ [
+ "0", "1", "-1", // common error codes
+ "18446744073709551615", // 2^64-1, i.e. -1 as an unsigned int64
+ "4294967295", // 2^32-1, i.e. -1 as an unsigned int32
+ "3735928559", // 0xdeadbeef
+ "3735929054", // 0xdeadc0de
+ "3405691582" // 0xcafebabe
+ ]
}
from Expr e
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ImproperNullTermination.ql b/cpp/ql/src/Likely Bugs/Memory Management/ImproperNullTermination.ql
index 2e643070a19..ed378dce60a 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/ImproperNullTermination.ql
+++ b/cpp/ql/src/Likely Bugs/Memory Management/ImproperNullTermination.ql
@@ -53,6 +53,7 @@ class ImproperNullTerminationReachability extends StackVariableReachabilityWithR
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
exprDefinition(v, node, _) or
mayAddNullTerminator(node, v.getAnAccess()) or
+ node.(AddressOfExpr).getOperand() = v.getAnAccess() or // address taken
isSinkActual(node, v) // only report first use
}
}
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll
index 9606fb968ec..37d5a5e5c1b 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll
+++ b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll
@@ -126,13 +126,7 @@ class MallocSizeExpr extends BufferAccess, FunctionCall {
}
class NetworkFunctionCall extends FunctionCall {
- NetworkFunctionCall() {
- getTarget().hasName("ntohd") or
- getTarget().hasName("ntohf") or
- getTarget().hasName("ntohl") or
- getTarget().hasName("ntohll") or
- getTarget().hasName("ntohs")
- }
+ NetworkFunctionCall() { getTarget().hasName(["ntohd", "ntohf", "ntohl", "ntohll", "ntohs"]) }
}
class NetworkToBufferSizeConfiguration extends DataFlow::Configuration {
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.ql b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.ql
index 8e7bc5bfcf4..f7eca2304b3 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.ql
+++ b/cpp/ql/src/Likely Bugs/Memory Management/StrncpyFlippedArgs.ql
@@ -43,23 +43,25 @@ predicate isSizePlus(Expr e, BufferSizeExpr baseSize, int plus) {
predicate strncpyFunction(Function f, int argDest, int argSrc, int argLimit) {
exists(string name | name = f.getName() |
- (
- name = "strcpy_s" or // strcpy_s(dst, max_amount, src)
- name = "wcscpy_s" or // wcscpy_s(dst, max_amount, src)
- name = "_mbscpy_s" // _mbscpy_s(dst, max_amount, src)
- ) and
+ name =
+ [
+ "strcpy_s", // strcpy_s(dst, max_amount, src)
+ "wcscpy_s", // wcscpy_s(dst, max_amount, src)
+ "_mbscpy_s" // _mbscpy_s(dst, max_amount, src)
+ ] and
argDest = 0 and
argSrc = 2 and
argLimit = 1
or
- (
- name = "strncpy" or // strncpy(dst, src, max_amount)
- name = "strncpy_l" or // strncpy_l(dst, src, max_amount, locale)
- name = "wcsncpy" or // wcsncpy(dst, src, max_amount)
- name = "_wcsncpy_l" or // _wcsncpy_l(dst, src, max_amount, locale)
- name = "_mbsncpy" or // _mbsncpy(dst, src, max_amount)
- name = "_mbsncpy_l" // _mbsncpy_l(dst, src, max_amount, locale)
- ) and
+ name =
+ [
+ "strncpy", // strncpy(dst, src, max_amount)
+ "strncpy_l", // strncpy_l(dst, src, max_amount, locale)
+ "wcsncpy", // wcsncpy(dst, src, max_amount)
+ "_wcsncpy_l", // _wcsncpy_l(dst, src, max_amount, locale)
+ "_mbsncpy", // _mbsncpy(dst, src, max_amount)
+ "_mbsncpy_l" // _mbsncpy_l(dst, src, max_amount, locale)
+ ] and
argDest = 0 and
argSrc = 1 and
argLimit = 2
diff --git a/cpp/ql/src/Metrics/Internal/CallableExtents.ql b/cpp/ql/src/Metrics/Internal/CallableExtents.ql
index 80c798b19ff..7a376c6da72 100644
--- a/cpp/ql/src/Metrics/Internal/CallableExtents.ql
+++ b/cpp/ql/src/Metrics/Internal/CallableExtents.ql
@@ -18,7 +18,7 @@ class RangeFunction extends Function {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
super.getLocation().hasLocationInfo(path, sl, sc, _, _) and
diff --git a/cpp/ql/src/Power of 10/Rule 1/UseOfJmp.ql b/cpp/ql/src/Power of 10/Rule 1/UseOfJmp.ql
index 9a6d143bfb6..0a98eafc70f 100644
--- a/cpp/ql/src/Power of 10/Rule 1/UseOfJmp.ql
+++ b/cpp/ql/src/Power of 10/Rule 1/UseOfJmp.ql
@@ -15,10 +15,7 @@ import cpp
class ForbiddenFunction extends Function {
ForbiddenFunction() {
exists(string name | name = this.getName() |
- name = "setjmp" or
- name = "longjmp" or
- name = "sigsetjmp" or
- name = "siglongjmp"
+ name = ["setjmp", "longjmp", "sigsetjmp", "siglongjmp"]
)
}
}
diff --git a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql
index 5e22506d03a..fc8023053b0 100644
--- a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql
+++ b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql
@@ -26,12 +26,8 @@ import TaintedWithPath
class FileFunction extends FunctionWithWrappers {
FileFunction() {
exists(string nme | this.hasGlobalName(nme) |
- nme = "fopen" or
- nme = "_fopen" or
- nme = "_wfopen" or
- nme = "open" or
- nme = "_open" or
- nme = "_wopen" or
+ nme = ["fopen", "_fopen", "_wfopen", "open", "_open", "_wopen"]
+ or
// create file function on windows
nme.matches("CreateFile%")
)
@@ -40,10 +36,7 @@ class FileFunction extends FunctionWithWrappers {
or
// on any of the fstream classes, or filebuf
exists(string nme | this.getDeclaringType().hasQualifiedName("std", nme) |
- nme = "basic_fstream" or
- nme = "basic_ifstream" or
- nme = "basic_ofstream" or
- nme = "basic_filebuf"
+ nme = ["basic_fstream", "basic_ifstream", "basic_ofstream", "basic_filebuf"]
) and
// we look for either the open method or the constructor
(this.getName() = "open" or this instanceof Constructor)
diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.c b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.c
index da5950c5fe5..c61adeee651 100644
--- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.c
+++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.c
@@ -9,7 +9,7 @@ int main(int argc, char** argv) {
system(command1);
}
- {
+ {
// GOOD: the user string is encoded by a library routine.
char userNameQuoted[1000] = {0};
encodeShellString(userNameQuoted, 1000, userName);
diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql
index 5f516eec83b..26652d9c1da 100644
--- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql
+++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql
@@ -3,10 +3,10 @@
* @description Using user-supplied data in an OS command, without
* neutralizing special elements, can make code vulnerable
* to command injection.
- * @kind problem
+ * @kind path-problem
* @problem.severity error
* @security-severity 9.8
- * @precision low
+ * @precision high
* @id cpp/command-line-injection
* @tags security
* external/cwe/cwe-078
@@ -16,13 +16,204 @@
import cpp
import semmle.code.cpp.security.CommandExecution
import semmle.code.cpp.security.Security
-import semmle.code.cpp.security.TaintTracking
+import semmle.code.cpp.valuenumbering.GlobalValueNumbering
+import semmle.code.cpp.ir.IR
+import semmle.code.cpp.ir.dataflow.TaintTracking
+import semmle.code.cpp.ir.dataflow.TaintTracking2
+import semmle.code.cpp.security.FlowSources
+import semmle.code.cpp.models.implementations.Strcat
-from Expr taintedArg, Expr taintSource, string taintCause, string callChain
+Expr sinkAsArgumentIndirection(DataFlow::Node sink) {
+ result =
+ sink.asOperand()
+ .(SideEffectOperand)
+ .getAddressOperand()
+ .getAnyDef()
+ .getUnconvertedResultExpression()
+}
+
+/**
+ * Holds if `fst` is a string that is used in a format or concatenation function resulting in `snd`,
+ * and is *not* placed at the start of the resulting string. This indicates that the author did not
+ * expect `fst` to control what program is run if the resulting string is eventually interpreted as
+ * a command line, for example as an argument to `system`.
+ */
+predicate interestingConcatenation(DataFlow::Node fst, DataFlow::Node snd) {
+ exists(FormattingFunctionCall call, int index, FormatLiteral literal |
+ sinkAsArgumentIndirection(fst) = call.getConversionArgument(index) and
+ snd.asDefiningArgument() = call.getOutputArgument(false) and
+ literal = call.getFormat() and
+ not literal.getConvSpecOffset(index) = 0 and
+ literal.getConversionChar(index) = ["s", "S"]
+ )
+ or
+ // strcat and friends
+ exists(StrcatFunction strcatFunc, CallInstruction call, ReadSideEffectInstruction rse |
+ call.getStaticCallTarget() = strcatFunc and
+ rse.getArgumentDef() = call.getArgument(strcatFunc.getParamSrc()) and
+ fst.asOperand() = rse.getSideEffectOperand() and
+ snd.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() =
+ call.getArgument(strcatFunc.getParamDest())
+ )
+ or
+ exists(CallInstruction call, Operator op, ReadSideEffectInstruction rse |
+ call.getStaticCallTarget() = op and
+ op.hasQualifiedName("std", "operator+") and
+ op.getType().(UserType).hasQualifiedName("std", "basic_string") and
+ call.getArgument(1) = rse.getArgumentOperand().getAnyDef() and // left operand
+ fst.asOperand() = rse.getSideEffectOperand() and
+ call = snd.asInstruction()
+ )
+}
+
+class TaintToConcatenationConfiguration extends TaintTracking::Configuration {
+ TaintToConcatenationConfiguration() { this = "TaintToConcatenationConfiguration" }
+
+ override predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
+
+ override predicate isSink(DataFlow::Node sink) { interestingConcatenation(sink, _) }
+
+ override predicate isSanitizer(DataFlow::Node node) {
+ node.asInstruction().getResultType() instanceof IntegralType
+ or
+ node.asInstruction().getResultType() instanceof FloatingPointType
+ }
+}
+
+class ExecTaintConfiguration extends TaintTracking2::Configuration {
+ ExecTaintConfiguration() { this = "ExecTaintConfiguration" }
+
+ override predicate isSource(DataFlow::Node source) {
+ exists(DataFlow::Node prevSink, TaintToConcatenationConfiguration conf |
+ conf.hasFlow(_, prevSink) and
+ interestingConcatenation(prevSink, source)
+ )
+ }
+
+ override predicate isSink(DataFlow::Node sink) {
+ shellCommand(sinkAsArgumentIndirection(sink), _)
+ }
+
+ override predicate isSanitizerOut(DataFlow::Node node) {
+ isSink(node) // Prevent duplicates along a call chain, since `shellCommand` will include wrappers
+ }
+}
+
+module StitchedPathGraph {
+ // There's a different PathNode class for each DataFlowImplN.qll, so we can't simply combine the
+ // PathGraph predicates directly. Instead, we use a newtype so there's a single type that
+ // contains both sets of PathNodes.
+ newtype TMergedPathNode =
+ TPathNode1(DataFlow::PathNode node) or
+ TPathNode2(DataFlow2::PathNode node)
+
+ // this wraps the toString and location predicates so we can use the merged node type in a
+ // selection
+ class MergedPathNode extends TMergedPathNode {
+ string toString() {
+ exists(DataFlow::PathNode n |
+ this = TPathNode1(n) and
+ result = n.toString()
+ )
+ or
+ exists(DataFlow2::PathNode n |
+ this = TPathNode2(n) and
+ result = n.toString()
+ )
+ }
+
+ DataFlow::Node getNode() {
+ exists(DataFlow::PathNode n |
+ this = TPathNode1(n) and
+ result = n.getNode()
+ )
+ or
+ exists(DataFlow2::PathNode n |
+ this = TPathNode2(n) and
+ result = n.getNode()
+ )
+ }
+
+ DataFlow::PathNode getPathNode1() { this = TPathNode1(result) }
+
+ DataFlow2::PathNode getPathNode2() { this = TPathNode2(result) }
+
+ predicate hasLocationInfo(
+ string filepath, int startline, int startcolumn, int endline, int endcolumn
+ ) {
+ exists(DataFlow::PathNode n |
+ this = TPathNode1(n) and
+ n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
+ )
+ or
+ exists(DataFlow2::PathNode n |
+ this = TPathNode2(n) and
+ n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
+ )
+ }
+ }
+
+ query predicate edges(MergedPathNode a, MergedPathNode b) {
+ exists(DataFlow::PathNode an, DataFlow::PathNode bn |
+ a = TPathNode1(an) and
+ b = TPathNode1(bn) and
+ DataFlow::PathGraph::edges(an, bn)
+ )
+ or
+ exists(DataFlow2::PathNode an, DataFlow2::PathNode bn |
+ a = TPathNode2(an) and
+ b = TPathNode2(bn) and
+ DataFlow2::PathGraph::edges(an, bn)
+ )
+ or
+ // This is where paths from the two configurations are connected. `interestingConcatenation`
+ // is the only thing in this module that's actually specific to the query - everything else is
+ // just using types and predicates from the DataFlow library.
+ interestingConcatenation(a.getNode(), b.getNode()) and
+ a instanceof TPathNode1 and
+ b instanceof TPathNode2
+ }
+
+ query predicate nodes(MergedPathNode mpn, string key, string val) {
+ // here we just need the union of the underlying `nodes` predicates
+ exists(DataFlow::PathNode n |
+ mpn = TPathNode1(n) and
+ DataFlow::PathGraph::nodes(n, key, val)
+ )
+ or
+ exists(DataFlow2::PathNode n |
+ mpn = TPathNode2(n) and
+ DataFlow2::PathGraph::nodes(n, key, val)
+ )
+ }
+
+ query predicate subpaths(
+ MergedPathNode arg, MergedPathNode par, MergedPathNode ret, MergedPathNode out
+ ) {
+ // just forward subpaths from the underlying libraries. This might be slightly awkward when
+ // the concatenation is deep in a call chain.
+ DataFlow::PathGraph::subpaths(arg.getPathNode1(), par.getPathNode1(), ret.getPathNode1(),
+ out.getPathNode1())
+ or
+ DataFlow2::PathGraph::subpaths(arg.getPathNode2(), par.getPathNode2(), ret.getPathNode2(),
+ out.getPathNode2())
+ }
+}
+
+import StitchedPathGraph
+
+from
+ DataFlow::PathNode sourceNode, DataFlow::PathNode concatSink, DataFlow2::PathNode concatSource,
+ DataFlow2::PathNode sinkNode, string taintCause, string callChain,
+ TaintToConcatenationConfiguration conf1, ExecTaintConfiguration conf2
where
- shellCommand(taintedArg, callChain) and
- tainted(taintSource, taintedArg) and
- isUserInput(taintSource, taintCause)
-select taintedArg,
- "This argument to an OS command is derived from $@ and then passed to " + callChain, taintSource,
- "user input (" + taintCause + ")"
+ taintCause = sourceNode.getNode().(FlowSource).getSourceType() and
+ conf1.hasFlowPath(sourceNode, concatSink) and
+ interestingConcatenation(concatSink.getNode(), concatSource.getNode()) and // this loses call context
+ conf2.hasFlowPath(concatSource, sinkNode) and
+ shellCommand(sinkAsArgumentIndirection(sinkNode.getNode()), callChain)
+select sinkAsArgumentIndirection(sinkNode.getNode()), TPathNode1(sourceNode).(MergedPathNode),
+ TPathNode2(sinkNode).(MergedPathNode),
+ "This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to "
+ + callChain, sourceNode, "user input (" + taintCause + ")", concatSource,
+ concatSource.toString()
diff --git a/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql b/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql
index b2844c319ba..3b0e3f5198d 100644
--- a/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql
+++ b/cpp/ql/src/Security/CWE/CWE-170/ImproperNullTerminationTainted.ql
@@ -21,11 +21,7 @@ class TaintSource extends VariableAccess {
this.getTarget() instanceof SemanticStackVariable and
x.isUserInput(this, cause)
|
- cause = "read" or
- cause = "fread" or
- cause = "recv" or
- cause = "recvfrom" or
- cause = "recvmsg"
+ cause = ["read", "fread", "recv", "recvfrom", "recvmsg"]
)
}
diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextStorage.inc.qhelp b/cpp/ql/src/Security/CWE/CWE-311/CleartextStorage.inc.qhelp
index eb9a6f8adce..f5e978e05cb 100644
--- a/cpp/ql/src/Security/CWE/CWE-311/CleartextStorage.inc.qhelp
+++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextStorage.inc.qhelp
@@ -9,7 +9,7 @@ storage.
-
Ensure that sensitive information is always encrypted before being stored, especially before writing to a file.
+
Ensure that sensitive information is always encrypted before being stored to a file or transmitted over the network.
It may be wise to encrypt information before it is put into a buffer that may be readable in memory.
In general, decrypt sensitive information only at the point where it is necessary for it to be used in
diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.qhelp b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.qhelp
new file mode 100644
index 00000000000..d715abca84c
--- /dev/null
+++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.qhelp
@@ -0,0 +1,5 @@
+
+
+
diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql
new file mode 100644
index 00000000000..d7e5343d6dc
--- /dev/null
+++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql
@@ -0,0 +1,124 @@
+/**
+ * @name Cleartext transmission of sensitive information
+ * @description Transmitting sensitive information across a network in
+ * cleartext can expose it to an attacker.
+ * @kind path-problem
+ * @problem.severity warning
+ * @security-severity 7.5
+ * @precision medium
+ * @id cpp/cleartext-transmission
+ * @tags security
+ * external/cwe/cwe-319
+ */
+
+import cpp
+import semmle.code.cpp.security.SensitiveExprs
+import semmle.code.cpp.dataflow.TaintTracking
+import semmle.code.cpp.models.interfaces.FlowSource
+import DataFlow::PathGraph
+
+/**
+ * A function call that sends or receives data over a network.
+ */
+abstract class NetworkSendRecv extends FunctionCall {
+ /**
+ * Gets the expression for the socket or similar object used for sending or
+ * receiving data (if any).
+ */
+ abstract Expr getSocketExpr();
+
+ /**
+ * Gets the expression for the buffer to be sent from / received into.
+ */
+ abstract Expr getDataExpr();
+}
+
+/**
+ * A function call that sends data over a network.
+ *
+ * note: functions such as `write` may be writing to a network source or a file. We could attempt to determine which, and sort results into `cpp/cleartext-transmission` and perhaps `cpp/cleartext-storage-file`. In practice it usually isn't very important which query reports a result as long as its reported exactly once.
+ */
+class NetworkSend extends NetworkSendRecv {
+ RemoteFlowSinkFunction target;
+
+ NetworkSend() { target = this.getTarget() }
+
+ override Expr getSocketExpr() {
+ exists(FunctionInput input, int arg |
+ target.hasSocketInput(input) and
+ input.isParameter(arg) and
+ result = this.getArgument(arg)
+ )
+ }
+
+ override Expr getDataExpr() {
+ exists(FunctionInput input, int arg |
+ target.hasRemoteFlowSink(input, _) and
+ input.isParameterDeref(arg) and
+ result = this.getArgument(arg)
+ )
+ }
+}
+
+/**
+ * A function call that receives data over a network.
+ */
+class NetworkRecv extends NetworkSendRecv {
+ RemoteFlowSourceFunction target;
+
+ NetworkRecv() { target = this.getTarget() }
+
+ override Expr getSocketExpr() {
+ exists(FunctionInput input, int arg |
+ target.hasSocketInput(input) and
+ input.isParameter(arg) and
+ result = this.getArgument(arg)
+ )
+ }
+
+ override Expr getDataExpr() {
+ exists(FunctionOutput output, int arg |
+ target.hasRemoteFlowSource(output, _) and
+ output.isParameterDeref(arg) and
+ result = this.getArgument(arg)
+ )
+ }
+}
+
+/**
+ * Taint flow from a sensitive expression to a network operation with data
+ * tainted by that expression.
+ */
+class SensitiveSendRecvConfiguration extends TaintTracking::Configuration {
+ SensitiveSendRecvConfiguration() { this = "SensitiveSendRecvConfiguration" }
+
+ override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof SensitiveExpr }
+
+ override predicate isSink(DataFlow::Node sink) {
+ exists(NetworkSendRecv transmission |
+ sink.asExpr() = transmission.getDataExpr() and
+ // a zero socket descriptor is standard input, which is not interesting for this query.
+ not exists(Zero zero |
+ DataFlow::localFlow(DataFlow::exprNode(zero),
+ DataFlow::exprNode(transmission.getSocketExpr()))
+ )
+ )
+ }
+}
+
+from
+ SensitiveSendRecvConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink,
+ NetworkSendRecv transmission, string msg
+where
+ config.hasFlowPath(source, sink) and
+ sink.getNode().asExpr() = transmission.getDataExpr() and
+ if transmission instanceof NetworkSend
+ then
+ msg =
+ "This operation transmits '" + sink.toString() +
+ "', which may contain unencrypted sensitive data from $@"
+ else
+ msg =
+ "This operation receives into '" + sink.toString() +
+ "', which may put unencrypted sensitive data into $@"
+select transmission, source, sink, msg, source, source.getNode().asExpr().toString()
diff --git a/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScalingCommon.qll b/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScalingCommon.qll
index 4854c1dc38e..9978d9ece0b 100644
--- a/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScalingCommon.qll
+++ b/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScalingCommon.qll
@@ -121,16 +121,14 @@ predicate exprSourceType(Expr use, Type sourceType, Location sourceLoc) {
else
if use instanceof CrementOperation
then exprSourceType(use.(CrementOperation).getOperand(), sourceType, sourceLoc)
- else
+ else (
// Conversions are not in the AST, so ignore them.
- if use instanceof Conversion
- then none()
- else (
- // Source expressions
- sourceType = use.getUnspecifiedType() and
- isPointerType(sourceType) and
- sourceLoc = use.getLocation()
- )
+ not use instanceof Conversion and
+ // Source expressions
+ sourceType = use.getUnspecifiedType() and
+ isPointerType(sourceType) and
+ sourceLoc = use.getLocation()
+ )
}
/**
diff --git a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql
index bbe3b0805e1..8d016751f39 100644
--- a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql
+++ b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql
@@ -103,12 +103,7 @@ private predicate posixSystemInfo(FunctionCall source, Element use) {
// - various filesystem parameters
// int uname(struct utsname *buf)
// - OS name and version
- (
- source.getTarget().hasName("confstr") or
- source.getTarget().hasName("statvfs") or
- source.getTarget().hasName("fstatvfs") or
- source.getTarget().hasName("uname")
- ) and
+ source.getTarget().hasName(["confstr", "statvfs", "fstatvfs", "uname"]) and
use = source.getArgument(1)
}
@@ -128,14 +123,9 @@ private predicate posixPWInfo(FunctionCall source, Element use) {
// struct group *getgrnam(const char *name);
// struct group *getgrgid(gid_t);
// struct group *getgrent(void);
- (
- source.getTarget().hasName("getpwnam") or
- source.getTarget().hasName("getpwuid") or
- source.getTarget().hasName("getpwent") or
- source.getTarget().hasName("getgrnam") or
- source.getTarget().hasName("getgrgid") or
- source.getTarget().hasName("getgrent")
- ) and
+ source
+ .getTarget()
+ .hasName(["getpwnam", "getpwuid", "getpwent", "getgrnam", "getgrgid", "getgrent"]) and
use = source
or
// int getpwnam_r(const char *name, struct passwd *pwd,
@@ -146,31 +136,15 @@ private predicate posixPWInfo(FunctionCall source, Element use) {
// char *buf, size_t buflen, struct group **result);
// int getgrnam_r(const char *name, struct group *grp,
// char *buf, size_t buflen, struct group **result);
- (
- source.getTarget().hasName("getpwnam_r") or
- source.getTarget().hasName("getpwuid_r") or
- source.getTarget().hasName("getgrgid_r") or
- source.getTarget().hasName("getgrnam_r")
- ) and
- (
- use = source.getArgument(1) or
- use = source.getArgument(2) or
- use = source.getArgument(4)
- )
+ source.getTarget().hasName(["getpwnam_r", "getpwuid_r", "getgrgid_r", "getgrnam_r"]) and
+ use = source.getArgument([1, 2, 4])
or
// int getpwent_r(struct passwd *pwd, char *buffer, size_t bufsize,
// struct passwd **result);
// int getgrent_r(struct group *gbuf, char *buf,
// size_t buflen, struct group **gbufp);
- (
- source.getTarget().hasName("getpwent_r") or
- source.getTarget().hasName("getgrent_r")
- ) and
- (
- use = source.getArgument(0) or
- use = source.getArgument(1) or
- use = source.getArgument(3)
- )
+ source.getTarget().hasName(["getpwent_r", "getgrent_r"]) and
+ use = source.getArgument([0, 1, 3])
}
/**
@@ -190,13 +164,11 @@ private predicate windowsSystemInfo(FunctionCall source, Element use) {
// BOOL WINAPI GetVersionEx(_Inout_ LPOSVERSIONINFO lpVersionInfo);
// void WINAPI GetSystemInfo(_Out_ LPSYSTEM_INFO lpSystemInfo);
// void WINAPI GetNativeSystemInfo(_Out_ LPSYSTEM_INFO lpSystemInfo);
- (
- source.getTarget().hasGlobalName("GetVersionEx") or
- source.getTarget().hasGlobalName("GetVersionExA") or
- source.getTarget().hasGlobalName("GetVersionExW") or
- source.getTarget().hasGlobalName("GetSystemInfo") or
- source.getTarget().hasGlobalName("GetNativeSystemInfo")
- ) and
+ source
+ .getTarget()
+ .hasGlobalName([
+ "GetVersionEx", "GetVersionExA", "GetVersionExW", "GetSystemInfo", "GetNativeSystemInfo"
+ ]) and
use = source.getArgument(0)
}
@@ -216,11 +188,11 @@ private predicate windowsFolderPath(FunctionCall source, Element use) {
// _In_ int csidl,
// _In_ BOOL fCreate
// );
- (
- source.getTarget().hasGlobalName("SHGetSpecialFolderPath") or
- source.getTarget().hasGlobalName("SHGetSpecialFolderPathA") or
- source.getTarget().hasGlobalName("SHGetSpecialFolderPathW")
- ) and
+ source
+ .getTarget()
+ .hasGlobalName([
+ "SHGetSpecialFolderPath", "SHGetSpecialFolderPathA", "SHGetSpecialFolderPathW"
+ ]) and
use = source.getArgument(1)
or
// HRESULT SHGetKnownFolderPath(
@@ -239,11 +211,7 @@ private predicate windowsFolderPath(FunctionCall source, Element use) {
// _In_ DWORD dwFlags,
// _Out_ LPTSTR pszPath
// );
- (
- source.getTarget().hasGlobalName("SHGetFolderPath") or
- source.getTarget().hasGlobalName("SHGetFolderPathA") or
- source.getTarget().hasGlobalName("SHGetFolderPathW")
- ) and
+ source.getTarget().hasGlobalName(["SHGetFolderPath", "SHGetFolderPathA", "SHGetFolderPathW"]) and
use = source.getArgument(4)
or
// HRESULT SHGetFolderPathAndSubDir(
@@ -254,11 +222,11 @@ private predicate windowsFolderPath(FunctionCall source, Element use) {
// _In_ LPCTSTR pszSubDir,
// _Out_ LPTSTR pszPath
// );
- (
- source.getTarget().hasGlobalName("SHGetFolderPathAndSubDir") or
- source.getTarget().hasGlobalName("SHGetFolderPathAndSubDirA") or
- source.getTarget().hasGlobalName("SHGetFolderPathAndSubDirW")
- ) and
+ source
+ .getTarget()
+ .hasGlobalName([
+ "SHGetFolderPathAndSubDir", "SHGetFolderPathAndSubDirA", "SHGetFolderPathAndSubDirW"
+ ]) and
use = source.getArgument(5)
}
@@ -273,11 +241,7 @@ class WindowsFolderPath extends SystemData {
}
private predicate logonUser(FunctionCall source, VariableAccess use) {
- (
- source.getTarget().hasGlobalName("LogonUser") or
- source.getTarget().hasGlobalName("LogonUserW") or
- source.getTarget().hasGlobalName("LogonUserA")
- ) and
+ source.getTarget().hasGlobalName(["LogonUser", "LogonUserW", "LogonUserA"]) and
use = source.getAnArgument()
}
@@ -297,11 +261,7 @@ private predicate regQuery(FunctionCall source, VariableAccess use) {
// _Out_opt_ LPTSTR lpValue,
// _Inout_opt_ PLONG lpcbValue
// );
- (
- source.getTarget().hasGlobalName("RegQueryValue") or
- source.getTarget().hasGlobalName("RegQueryValueA") or
- source.getTarget().hasGlobalName("RegQueryValueW")
- ) and
+ source.getTarget().hasGlobalName(["RegQueryValue", "RegQueryValueA", "RegQueryValueW"]) and
use = source.getArgument(2)
or
// LONG WINAPI RegQueryMultipleValues(
@@ -311,11 +271,11 @@ private predicate regQuery(FunctionCall source, VariableAccess use) {
// _Out_opt_ LPTSTR lpValueBuf,
// _Inout_opt_ LPDWORD ldwTotsize
// );
- (
- source.getTarget().hasGlobalName("RegQueryMultipleValues") or
- source.getTarget().hasGlobalName("RegQueryMultipleValuesA") or
- source.getTarget().hasGlobalName("RegQueryMultipleValuesW")
- ) and
+ source
+ .getTarget()
+ .hasGlobalName([
+ "RegQueryMultipleValues", "RegQueryMultipleValuesA", "RegQueryMultipleValuesW"
+ ]) and
use = source.getArgument(3)
or
// LONG WINAPI RegQueryValueEx(
@@ -326,11 +286,7 @@ private predicate regQuery(FunctionCall source, VariableAccess use) {
// _Out_opt_ LPBYTE lpData,
// _Inout_opt_ LPDWORD lpcbData
// );
- (
- source.getTarget().hasGlobalName("RegQueryValueEx") or
- source.getTarget().hasGlobalName("RegQueryValueExA") or
- source.getTarget().hasGlobalName("RegQueryValueExW")
- ) and
+ source.getTarget().hasGlobalName(["RegQueryValueEx", "RegQueryValueExA", "RegQueryValueExW"]) and
use = source.getArgument(4)
or
// LONG WINAPI RegGetValue(
@@ -342,11 +298,7 @@ private predicate regQuery(FunctionCall source, VariableAccess use) {
// _Out_opt_ PVOID pvData,
// _Inout_opt_ LPDWORD pcbData
// );
- (
- source.getTarget().hasGlobalName("RegGetValue") or
- source.getTarget().hasGlobalName("RegGetValueA") or
- source.getTarget().hasGlobalName("RegGetValueW")
- ) and
+ source.getTarget().hasGlobalName(["RegGetValue", "RegGetValueA", "RegGetValueW"]) and
use = source.getArgument(5)
}
@@ -408,12 +360,7 @@ private predicate socketOutput(FunctionCall call, Expr data) {
// const struct sockaddr *dest_addr, socklen_t addrlen);
// ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
// int write(int handle, void *buffer, int nbyte);
- (
- call.getTarget().hasGlobalName("send") or
- call.getTarget().hasGlobalName("sendto") or
- call.getTarget().hasGlobalName("sendmsg") or
- call.getTarget().hasGlobalName("write")
- ) and
+ call.getTarget().hasGlobalName(["send", "sendto", "sendmsg", "write"]) and
data = call.getArgument(1) and
socketFileDescriptor(call.getArgument(0))
)
diff --git a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql
index 28e7295dcdc..357e6375570 100644
--- a/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql
+++ b/cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.ql
@@ -4,10 +4,13 @@
* @kind problem
* @id cpp/incorrect-allocation-error-handling
* @problem.severity warning
+ * @security-severity 7.5
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-570
+ * external/cwe/cwe-252
+ * external/cwe/cwe-755
*/
import cpp
diff --git a/cpp/ql/src/definitions.qll b/cpp/ql/src/definitions.qll
index eac03ce7082..cb229d66ef1 100644
--- a/cpp/ql/src/definitions.qll
+++ b/cpp/ql/src/definitions.qll
@@ -24,7 +24,7 @@ class Top extends Element {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
pragma[noopt]
final predicate hasLocationInfo(
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.cpp
new file mode 100644
index 00000000000..a04107bbadf
--- /dev/null
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.cpp
@@ -0,0 +1,18 @@
+...
+int myFclose(FILE * fmy)
+{
+ if(!fclose(fmy)) {
+ fmy = NULL;
+ return 0;
+ }
+ return -1;
+}
+...
+ fe = fopen("myFile.txt", "wt");
+ ...
+ fclose(fe); // BAD
+...
+ fe = fopen("myFile.txt", "wt");
+ ...
+ myFclose(fe); // GOOD
+...
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.qhelp
new file mode 100644
index 00000000000..cc8519a3410
--- /dev/null
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.qhelp
@@ -0,0 +1,23 @@
+
+
+
+
The presence of a shell function with additional check indicates the possible risks of the call. Use this check everywhere.
+
+
+
+
+
The following example demonstrates fallacious and fixed methods of using wrapper functions.
+
+
+
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.ql b/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.ql
new file mode 100644
index 00000000000..4b147fa3612
--- /dev/null
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.ql
@@ -0,0 +1,141 @@
+/**
+ * @name Missed opportunity to call wrapper function
+ * @description If a wrapper function is defined for a given function, any call to the given function should be via the wrapper function.
+ * @kind problem
+ * @id cpp/call-to-function-without-wrapper
+ * @problem.severity warning
+ * @precision medium
+ * @tags correctness
+ * maintainability
+ * security
+ * external/cwe/cwe-1041
+ */
+
+import cpp
+import semmle.code.cpp.valuenumbering.GlobalValueNumbering
+import semmle.code.cpp.commons.Assertions
+
+/**
+ * A function call that is used in error situations (logging, throwing an exception, abnormal termination).
+ */
+class CallUsedToHandleErrors extends FunctionCall {
+ CallUsedToHandleErrors() {
+ // call that is known to not return
+ not exists(this.(ControlFlowNode).getASuccessor())
+ or
+ // call throwing an exception
+ exists(ThrowExpr tex | tex = this.(ControlFlowNode).getASuccessor())
+ or
+ // call logging a message, possibly an error
+ exists(FormattingFunction ff | ff = this.(ControlFlowNode).getASuccessor())
+ or
+ // enabling recursive search
+ exists(CallUsedToHandleErrors fr | getTarget() = fr.getEnclosingFunction())
+ }
+}
+
+/** Holds if the conditions for a call outside the wrapper function are met. */
+predicate conditionsOutsideWrapper(FunctionCall fcp) {
+ fcp.getNumberOfArguments() > 0 and
+ not exists(ConditionalStmt cdtmp | fcp.getEnclosingStmt().getParentStmt*() = cdtmp) and
+ not exists(Loop lptmp | fcp.getEnclosingStmt().getParentStmt*() = lptmp) and
+ not exists(ReturnStmt rttmp | fcp.getEnclosingStmt().getParentStmt*() = rttmp) and
+ not exists(FunctionCall fctmp2 | fcp = fctmp2.getAnArgument().getAChild*()) and
+ not exists(Assignment astmp | fcp = astmp.getRValue().getAChild*()) and
+ not exists(Initializer intmp | fcp = intmp.getExpr().getAChild*()) and
+ not exists(Assertion astmp | fcp = astmp.getAsserted().getAChild*()) and
+ not exists(Operation optmp | fcp = optmp.getAChild*()) and
+ not exists(ArrayExpr aetmp | fcp = aetmp.getAChild*()) and
+ not exists(ExprCall ectmp | fcp = ectmp.getAnArgument().getAChild*())
+}
+
+/** Holds if the conditions for calling `fcp` inside the `fnp` wrapper function are met. */
+pragma[inline]
+predicate conditionsInsideWrapper(FunctionCall fcp, Function fnp) {
+ not exists(FunctionCall fctmp2 |
+ fctmp2.getEnclosingFunction() = fnp and fcp = fctmp2.getAnArgument().getAChild*()
+ ) and
+ not fcp instanceof CallUsedToHandleErrors and
+ not fcp.getAnArgument().isConstant() and
+ fcp.getEnclosingFunction() = fnp and
+ fnp.getNumberOfParameters() > 0 and
+ // the call arguments must be passed through the arguments of the wrapper function
+ forall(int i | i in [0 .. fcp.getNumberOfArguments() - 1] |
+ globalValueNumber(fcp.getArgument(i)) = globalValueNumber(fnp.getAParameter().getAnAccess())
+ ) and
+ // there should be no more than one required call inside the wrapper function
+ not exists(FunctionCall fctmp |
+ fctmp.getTarget() = fcp.getTarget() and
+ fctmp.getFile() = fcp.getFile() and
+ fctmp != fcp and
+ fctmp.getEnclosingFunction() = fnp
+ ) and
+ // inside the wrapper function there should be no calls without paths to the desired function
+ not exists(FunctionCall fctmp |
+ fctmp.getEnclosingFunction() = fnp and
+ fctmp.getFile() = fcp.getFile() and
+ fctmp != fcp and
+ (
+ fctmp = fcp.getAPredecessor+()
+ or
+ not exists(FunctionCall fctmp1 |
+ fctmp1 = fcp and
+ (
+ fctmp.getASuccessor+() = fctmp1 or
+ fctmp.getAPredecessor+() = fctmp1
+ )
+ )
+ )
+ )
+}
+
+/** Holds if the conditions for the wrapper function are met. */
+pragma[inline]
+predicate conditionsForWrapper(FunctionCall fcp, Function fnp) {
+ not exists(ExprCall ectmp | fnp = ectmp.getEnclosingFunction()) and
+ not exists(Loop lp | lp.getEnclosingFunction() = fnp) and
+ not exists(SwitchStmt sw | sw.getEnclosingFunction() = fnp) and
+ not fnp instanceof Operator and
+ // inside the wrapper function there should be checks of arguments or the result,
+ // perhaps by means of passing the latter as an argument to some function
+ (
+ exists(IfStmt ifs |
+ ifs.getEnclosingFunction() = fnp and
+ (
+ globalValueNumber(ifs.getCondition().getAChild*()) = globalValueNumber(fcp.getAnArgument()) and
+ ifs.getASuccessor*() = fcp
+ or
+ ifs.getCondition().getAChild() = fcp
+ )
+ )
+ or
+ exists(FunctionCall fctmp |
+ fctmp.getEnclosingFunction() = fnp and
+ globalValueNumber(fctmp.getAnArgument().getAChild*()) = globalValueNumber(fcp)
+ )
+ ) and
+ // inside the wrapper function there must be a function call to handle the error
+ exists(CallUsedToHandleErrors fctmp |
+ fctmp.getEnclosingFunction() = fnp and
+ forall(int i | i in [0 .. fnp.getNumberOfParameters() - 1] |
+ fnp.getParameter(i).getAnAccess().getTarget() =
+ fcp.getAnArgument().(VariableAccess).getTarget() or
+ fnp.getParameter(i).getUnspecifiedType() instanceof Class or
+ fnp.getParameter(i).getUnspecifiedType().(ReferenceType).getBaseType() instanceof Class or
+ fnp.getParameter(i).getAnAccess().getTarget() =
+ fctmp.getAnArgument().(VariableAccess).getTarget()
+ )
+ )
+}
+
+from FunctionCall fc, Function fn
+where
+ exists(FunctionCall fctmp |
+ conditionsInsideWrapper(fctmp, fn) and
+ conditionsForWrapper(fctmp, fn) and
+ conditionsOutsideWrapper(fc) and
+ fctmp.getTarget() = fc.getTarget() and
+ fc.getEnclosingFunction() != fn and
+ fc.getEnclosingFunction().getMetrics().getNumberOfCalls() > fn.getMetrics().getNumberOfCalls()
+ )
+select fc, "Consider changing the call to $@", fn, fn.getName()
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-273/PrivilegeDroppingOutoforder.ql b/cpp/ql/src/experimental/Security/CWE/CWE-273/PrivilegeDroppingOutoforder.ql
index 7798203205a..9d2faf793c5 100644
--- a/cpp/ql/src/experimental/Security/CWE/CWE-273/PrivilegeDroppingOutoforder.ql
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-273/PrivilegeDroppingOutoforder.ql
@@ -44,14 +44,13 @@ class SetuidLikeWrapperCall extends FunctionCall {
class CallBeforeSetuidFunctionCall extends FunctionCall {
CallBeforeSetuidFunctionCall() {
- (
- getTarget().hasGlobalName("setgid") or
- getTarget().hasGlobalName("setresgid") or
- // Compatibility may require skipping initgroups and setgroups return checks.
- // A stricter best practice is to check the result and errnor for EPERM.
- getTarget().hasGlobalName("initgroups") or
- getTarget().hasGlobalName("setgroups")
- ) and
+ getTarget()
+ .hasGlobalName([
+ "setgid", "setresgid",
+ // Compatibility may require skipping initgroups and setgroups return checks.
+ // A stricter best practice is to check the result and errnor for EPERM.
+ "initgroups", "setgroups"
+ ]) and
// setgid/setresgid/etc with the root group are false positives.
not argumentMayBeRoot(getArgument(0))
}
diff --git a/cpp/ql/src/external/CodeDuplication.qll b/cpp/ql/src/external/CodeDuplication.qll
index 8cc56d12e19..2656378bf62 100644
--- a/cpp/ql/src/external/CodeDuplication.qll
+++ b/cpp/ql/src/external/CodeDuplication.qll
@@ -38,10 +38,10 @@ class Copy extends @duplication_or_similarity {
int sourceStartColumn() { tokens(this, 0, _, result, _, _) }
/** Gets the line on which the last token in this block ends. */
- int sourceEndLine() { tokens(this, lastToken(), _, _, result, _) }
+ int sourceEndLine() { tokens(this, this.lastToken(), _, _, result, _) }
/** Gets the column on which the last token in this block ends. */
- int sourceEndColumn() { tokens(this, lastToken(), _, _, _, result) }
+ int sourceEndColumn() { tokens(this, this.lastToken(), _, _, _, result) }
/** Gets the number of lines containing at least (part of) one token in this block. */
int sourceLines() { result = this.sourceEndLine() + 1 - this.sourceStartLine() }
@@ -61,16 +61,16 @@ class Copy extends @duplication_or_similarity {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
- sourceFile().getAbsolutePath() = filepath and
- startline = sourceStartLine() and
- startcolumn = sourceStartColumn() and
- endline = sourceEndLine() and
- endcolumn = sourceEndColumn()
+ this.sourceFile().getAbsolutePath() = filepath and
+ startline = this.sourceStartLine() and
+ startcolumn = this.sourceStartColumn() and
+ endline = this.sourceEndLine() and
+ endcolumn = this.sourceEndColumn()
}
/** Gets a textual representation of this element. */
@@ -79,13 +79,15 @@ class Copy extends @duplication_or_similarity {
/** A block of duplicated code. */
class DuplicateBlock extends Copy, @duplication {
- override string toString() { result = "Duplicate code: " + sourceLines() + " duplicated lines." }
+ override string toString() {
+ result = "Duplicate code: " + this.sourceLines() + " duplicated lines."
+ }
}
/** A block of similar code. */
class SimilarBlock extends Copy, @similarity {
override string toString() {
- result = "Similar code: " + sourceLines() + " almost duplicated lines."
+ result = "Similar code: " + this.sourceLines() + " almost duplicated lines."
}
}
diff --git a/cpp/ql/src/external/DefectFilter.qll b/cpp/ql/src/external/DefectFilter.qll
index 675f3b25faa..b932ffd0470 100644
--- a/cpp/ql/src/external/DefectFilter.qll
+++ b/cpp/ql/src/external/DefectFilter.qll
@@ -8,7 +8,7 @@ import cpp
* column `startcolumn` of line `startline` to column `endcolumn` of line `endline`
* in file `filepath`.
*
- * For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
external predicate defectResults(
int id, string queryPath, string file, int startline, int startcol, int endline, int endcol,
diff --git a/cpp/ql/src/external/MetricFilter.qll b/cpp/ql/src/external/MetricFilter.qll
index dd9cece78ce..0315cd23c8d 100644
--- a/cpp/ql/src/external/MetricFilter.qll
+++ b/cpp/ql/src/external/MetricFilter.qll
@@ -8,7 +8,7 @@ import cpp
* column `startcolumn` of line `startline` to column `endcolumn` of line `endline`
* in file `filepath`.
*
- * For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
external predicate metricResults(
int id, string queryPath, string file, int startline, int startcol, int endline, int endcol,
@@ -67,7 +67,7 @@ class MetricResult extends int {
/** Gets the URL corresponding to the location of this query result. */
string getURL() {
result =
- "file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" +
- getEndLine() + ":" + getEndColumn()
+ "file://" + this.getFile().getAbsolutePath() + ":" + this.getStartLine() + ":" +
+ this.getStartColumn() + ":" + this.getEndLine() + ":" + this.getEndColumn()
}
}
diff --git a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql
index 608374b241c..91b5e4e8b98 100644
--- a/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql
+++ b/cpp/ql/src/jsf/4.09 Style/AV Rule 53.1.ql
@@ -14,12 +14,5 @@ import cpp
from Include i, string name
where
name = i.getIncludeText() and
- (
- name.matches("%'%") or
- name.matches("%\\\\%") or
- name.matches("%/*%") or
- name.matches("%//%") or
- name.matches("%\"%\"%\"%") or
- name.matches("%<%\"%>%")
- )
+ name.matches(["%'%", "%\\\\%", "%/*%", "%//%", "%\"%\"%\"%", "%<%\"%>%"])
select i, "AV Rule 53.1: Invalid character sequence in header file name '" + name + "'"
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
index 3ae7bc65b45..adeb54746df 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
@@ -230,13 +230,13 @@ predicate leakedInSameMethod(Resource r, Expr acquire) {
)
)
)
- or
- exists(FunctionAccess fa, string kind |
- // the address of a function that releases `r` is taken (and likely
- // used to release `r` at some point).
- r.acquisitionWithRequiredKind(acquire, kind) and
- fa.getTarget() = r.getAReleaseExpr(kind).getEnclosingFunction()
- )
+ )
+ or
+ exists(FunctionAccess fa, string kind |
+ // the address of a function that releases `r` is taken (and likely
+ // used to release `r` at some point).
+ r.acquisitionWithRequiredKind(acquire, kind) and
+ fa.getTarget() = r.getAReleaseExpr(kind).getEnclosingFunction()
)
}
diff --git a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql
index b881c5ed601..64a130f46e0 100644
--- a/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql
+++ b/cpp/ql/src/jsf/4.28 Portable Code/AV Rule 209.ql
@@ -15,13 +15,7 @@ import cpp
from Element u, ArithmeticType at
where
- (
- at.hasName("int") or
- at.hasName("short") or
- at.hasName("long") or
- at.hasName("float") or
- at.hasName("double")
- ) and
+ at.hasName(["int", "short", "long", "float", "double"]) and
u = at.getATypeNameUse() and
not at instanceof WideCharType
select u, "AV Rule 209: The basic types of int, short, long, float and double shall not be used."
diff --git a/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll b/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll
index d351bac89a8..52a790cca28 100644
--- a/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll
+++ b/cpp/ql/test/TestUtilities/InlineExpectationsTest.qll
@@ -4,7 +4,7 @@
* (in that the `.expected` file should always be empty).
*
* To add this framework to a new language:
- * - Add a file `InlineExpectationsTestPrivate.qll` that defines a `LineComment` class. This class
+ * - Add a file `InlineExpectationsTestPrivate.qll` that defines a `ExpectationComment` class. This class
* must support a `getContents` method that returns the contents of the given comment, _excluding_
* the comment indicator itself. It should also define `toString` and `getLocation` as usual.
*
@@ -60,8 +60,8 @@
*
* Example:
* ```cpp
- * int i = x + 5; // $const=5
- * int j = y + (7 - 3) // $const=7 const=3 const=4 // The result of the subtraction is a constant.
+ * int i = x + 5; // $ const=5
+ * int j = y + (7 - 3) // $ const=7 const=3 const=4 // The result of the subtraction is a constant.
* ```
*
* For tests that contain known missing and spurious results, it is possible to further
@@ -194,7 +194,7 @@ private int getEndOfColumnPosition(int start, string content) {
}
private predicate getAnExpectation(
- LineComment comment, TColumn column, string expectation, string tags, string value
+ ExpectationComment comment, TColumn column, string expectation, string tags, string value
) {
exists(string content |
content = comment.getContents().regexpCapture(expectationCommentPattern(), 1) and
@@ -247,14 +247,14 @@ private newtype TFailureLocatable =
) {
test.hasActualResult(location, element, tag, value)
} or
- TValidExpectation(LineComment comment, string tag, string value, string knownFailure) {
+ TValidExpectation(ExpectationComment comment, string tag, string value, string knownFailure) {
exists(TColumn column, string tags |
getAnExpectation(comment, column, _, tags, value) and
tag = tags.splitAt(",") and
knownFailure = getColumnString(column)
)
} or
- TInvalidExpectation(LineComment comment, string expectation) {
+ TInvalidExpectation(ExpectationComment comment, string expectation) {
getAnExpectation(comment, _, expectation, _, _) and
not expectation.regexpMatch(expectationPattern())
}
@@ -292,7 +292,7 @@ class ActualResult extends FailureLocatable, TActualResult {
}
abstract private class Expectation extends FailureLocatable {
- LineComment comment;
+ ExpectationComment comment;
override string toString() { result = comment.toString() }
diff --git a/cpp/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll b/cpp/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll
index f3aae029eb4..adad4238095 100644
--- a/cpp/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll
+++ b/cpp/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll
@@ -1,16 +1,16 @@
import cpp
-private newtype TLineComment = MkLineComment(CppStyleComment c)
+private newtype TExpectationComment = MkExpectationComment(CppStyleComment c)
/**
* Represents a line comment in the CPP style.
* Unlike the `CppStyleComment` class, however, the string returned by `getContents` does _not_
* include the preceding comment marker (`//`).
*/
-class LineComment extends TLineComment {
+class ExpectationComment extends TExpectationComment {
CppStyleComment comment;
- LineComment() { this = MkLineComment(comment) }
+ ExpectationComment() { this = MkExpectationComment(comment) }
/** Returns the contents of the given comment, _without_ the preceding comment marker (`//`). */
string getContents() { result = comment.getContents().suffix(2) }
diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-1041/semmle/tests/FindWrapperFunctions.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-1041/semmle/tests/FindWrapperFunctions.expected
new file mode 100644
index 00000000000..b8152734e2d
--- /dev/null
+++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-1041/semmle/tests/FindWrapperFunctions.expected
@@ -0,0 +1 @@
+| test.cpp:23:3:23:8 | call to fclose | Consider changing the call to $@ | test.cpp:9:6:9:13 | myFclose | myFclose |
diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-1041/semmle/tests/FindWrapperFunctions.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-1041/semmle/tests/FindWrapperFunctions.qlref
new file mode 100644
index 00000000000..22dae13892f
--- /dev/null
+++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-1041/semmle/tests/FindWrapperFunctions.qlref
@@ -0,0 +1 @@
+experimental/Security/CWE/CWE-1041/FindWrapperFunctions.ql
diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-1041/semmle/tests/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-1041/semmle/tests/test.cpp
new file mode 100644
index 00000000000..4f862a324e5
--- /dev/null
+++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-1041/semmle/tests/test.cpp
@@ -0,0 +1,27 @@
+#define NULL (0)
+typedef int FILE;
+FILE *fopen(const char *filename, const char *mode);
+int fclose(FILE *stream);
+extern FILE * fe;
+extern int printf(const char *fmt, ...);
+void exit(int status);
+
+void myFclose(FILE * fmy)
+{
+ int i;
+ if(fmy) {
+ i = fclose(fmy);
+ fmy = NULL;
+ printf("close end is code %d",i);
+ if(i!=0) exit(1);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ fe = fopen("myFile.txt", "wt");
+ fclose(fe); // BAD
+ fe = fopen("myFile.txt", "wt");
+ myFclose(fe); // GOOD
+ return 0;
+}
diff --git a/cpp/ql/test/include/iterator.h b/cpp/ql/test/include/iterator.h
new file mode 100644
index 00000000000..77758bfa8da
--- /dev/null
+++ b/cpp/ql/test/include/iterator.h
@@ -0,0 +1,97 @@
+#if !defined(CODEQL_ITERATOR_H)
+#define CODEQL_ITERATOR_H
+
+typedef unsigned long size_t;
+
+#include "type_traits.h"
+
+namespace std {
+ struct ptrdiff_t;
+
+ template struct iterator_traits;
+
+ template
+ struct iterator {
+ typedef Category iterator_category;
+
+ iterator();
+ iterator(iterator > const &other); // non-const -> const conversion constructor
+
+ iterator &operator++();
+ iterator operator++(int);
+ iterator &operator--();
+ iterator operator--(int);
+ bool operator==(iterator other) const;
+ bool operator!=(iterator other) const;
+ reference_type operator*() const;
+ pointer_type operator->() const;
+ iterator operator+(int);
+ iterator operator-(int);
+ iterator &operator+=(int);
+ iterator &operator-=(int);
+ int operator-(iterator);
+ reference_type operator[](int);
+ };
+
+ struct input_iterator_tag {};
+ struct forward_iterator_tag : public input_iterator_tag {};
+ struct bidirectional_iterator_tag : public forward_iterator_tag {};
+ struct random_access_iterator_tag : public bidirectional_iterator_tag {};
+
+ struct output_iterator_tag {};
+
+ template
+ class back_insert_iterator {
+ protected:
+ Container* container = nullptr;
+ public:
+ using iterator_category = output_iterator_tag;
+ using value_type = void;
+ using difference_type = ptrdiff_t;
+ using pointer = void;
+ using reference = void;
+ using container_type = Container;
+ constexpr back_insert_iterator() noexcept = default;
+ constexpr explicit back_insert_iterator(Container& x);
+ back_insert_iterator& operator=(const typename Container::value_type& value);
+ back_insert_iterator& operator=(typename Container::value_type&& value);
+ back_insert_iterator& operator*();
+ back_insert_iterator& operator++();
+ back_insert_iterator operator++(int);
+ };
+
+ template
+ constexpr back_insert_iterator back_inserter(Container& x) {
+ return back_insert_iterator(x);
+ }
+
+ template
+ class front_insert_iterator {
+ protected:
+ Container* container = nullptr;
+ public:
+ using iterator_category = output_iterator_tag;
+ using value_type = void;
+ using difference_type = ptrdiff_t;
+ using pointer = void;
+ using reference = void;
+ using container_type = Container;
+ constexpr front_insert_iterator() noexcept = default;
+ constexpr explicit front_insert_iterator(Container& x);
+ constexpr front_insert_iterator& operator=(const typename Container::value_type& value);
+ constexpr front_insert_iterator& operator=(typename Container::value_type&& value);
+ constexpr front_insert_iterator& operator*();
+ constexpr front_insert_iterator& operator++();
+ constexpr front_insert_iterator operator++(int);
+ };
+ template
+ constexpr front_insert_iterator front_inserter(Container& x) {
+ return front_insert_iterator(x);
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/cpp/ql/test/include/string.h b/cpp/ql/test/include/string.h
new file mode 100644
index 00000000000..8d577c350f9
--- /dev/null
+++ b/cpp/ql/test/include/string.h
@@ -0,0 +1,85 @@
+#if !defined(CODEQL_STRING_H)
+#define CODEQL_STRING_H
+
+#include "iterator.h"
+
+namespace std
+{
+ template struct char_traits;
+
+ typedef size_t streamsize;
+
+ template class allocator {
+ public:
+ allocator() throw();
+ typedef size_t size_type;
+ };
+
+ template, class Allocator = allocator >
+ class basic_string {
+ public:
+ using value_type = charT;
+ using reference = value_type&;
+ using const_reference = const value_type&;
+ typedef typename Allocator::size_type size_type;
+ static const size_type npos = -1;
+
+ explicit basic_string(const Allocator& a = Allocator());
+ basic_string(const charT* s, const Allocator& a = Allocator());
+ template basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
+
+ const charT* c_str() const;
+ charT* data() noexcept;
+ size_t length() const;
+
+ typedef std::iterator iterator;
+ typedef std::iterator const_iterator;
+
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+ const_iterator cbegin() const;
+ const_iterator cend() const;
+
+ void push_back(charT c);
+
+ const charT& front() const;
+ charT& front();
+ const charT& back() const;
+ charT& back();
+
+ const_reference operator[](size_type pos) const;
+ reference operator[](size_type pos);
+ const_reference at(size_type n) const;
+ reference at(size_type n);
+ template basic_string& operator+=(const T& t);
+ basic_string& operator+=(const charT* s);
+ basic_string& append(const basic_string& str);
+ basic_string& append(const charT* s);
+ basic_string& append(size_type n, charT c);
+ template basic_string& append(InputIterator first, InputIterator last);
+ basic_string& assign(const basic_string& str);
+ basic_string& assign(size_type n, charT c);
+ template basic_string& assign(InputIterator first, InputIterator last);
+ basic_string& insert(size_type pos, const basic_string& str);
+ basic_string& insert(size_type pos, size_type n, charT c);
+ basic_string& insert(size_type pos, const charT* s);
+ iterator insert(const_iterator p, size_type n, charT c);
+ template iterator insert(const_iterator p, InputIterator first, InputIterator last);
+ basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
+ basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c);
+ size_type copy(charT* s, size_type n, size_type pos = 0) const;
+ void clear() noexcept;
+ basic_string substr(size_type pos = 0, size_type n = npos) const;
+ void swap(basic_string& s) noexcept/*(allocator_traits::propagate_on_container_swap::value || allocator_traits::is_always_equal::value)*/;
+ };
+
+ template basic_string operator+(const basic_string& lhs, const basic_string& rhs);
+ template basic_string operator+(const basic_string& lhs, const charT* rhs);
+ template basic_string operator+(const charT* lhs, const basic_string& rhs);
+
+ typedef basic_string string;
+}
+
+#endif
\ No newline at end of file
diff --git a/cpp/ql/test/include/type_traits.h b/cpp/ql/test/include/type_traits.h
index 19bdd46906b..dba04f36cad 100644
--- a/cpp/ql/test/include/type_traits.h
+++ b/cpp/ql/test/include/type_traits.h
@@ -1,21 +1,44 @@
#if !defined(CODEQL_TYPE_TRAITS_H)
#define CODEQL_TYPE_TRAITS_H
+typedef unsigned long size_t;
+
namespace std {
- template
- struct remove_reference {
+ template
+ struct remove_const { typedef T type; };
+
+ template
+ struct remove_const { typedef T type; };
+
+ // `remove_const_t` removes any `const` specifier from `T`
+ template
+ using remove_const_t = typename remove_const::type;
+
+ template
+ struct remove_reference { typedef T type; };
+
+ template
+ struct remove_reference { typedef T type; };
+
+ template
+ struct remove_reference { typedef T type; };
+
+ // `remove_reference_t` removes any `&` from `T`
+ template
+ using remove_reference_t = typename remove_reference::type;
+
+ template
+ struct decay_impl {
typedef T type;
};
- template
- struct remove_reference {
- typedef T type;
+ template
+ struct decay_impl {
+ typedef T* type;
};
- template
- struct remove_reference {
- typedef T type;
- };
+ template
+ using decay_t = typename decay_impl>::type;
}
#endif
diff --git a/cpp/ql/test/library-tests/access/noPublic/noPublic.ql b/cpp/ql/test/library-tests/access/noPublic/noPublic.ql
index e6d78dcfd5a..c249ea45d74 100644
--- a/cpp/ql/test/library-tests/access/noPublic/noPublic.ql
+++ b/cpp/ql/test/library-tests/access/noPublic/noPublic.ql
@@ -3,5 +3,5 @@ import cpp
from AccessSpecifier spec
// There is no way to create "protected" access without writing the keyword
// `protected` in the source, so we don't need to test for that.
-where spec.hasName("private") or spec.hasName("public")
+where spec.hasName(["private", "public"])
select spec
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/copyableclass_declonly.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/copyableclass_declonly.cpp
index f8169db1128..307e1ecaa76 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/copyableclass_declonly.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/copyableclass_declonly.cpp
@@ -64,6 +64,6 @@ void test_copyableclass_declonly()
sink(s1); // $ ast,ir
sink(s2); // $ ast,ir
- sink(s3 = source()); // $ ast MISSING: ir
+ sink(s3 = source()); // $ ast,ir
}
}
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
index aabd898830e..4e85a6b9aa3 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
@@ -415,10 +415,10 @@ void test_unordered_map()
sink(m30["abc"]);
sink(m31.try_emplace("abc", source(), 2)); // $ ast,ir
sink(m31); // $ ast,ir
- sink(m31["abc"]); // $ ast MISSING: ir
+ sink(m31["abc"]); // $ ast,ir
sink(m32.try_emplace("abc", 1, source())); // $ ast,ir
sink(m32); // $ ast,ir
- sink(m32["abc"]); // $ ast MISSING: ir
+ sink(m32["abc"]); // $ ast,ir
// additional emplace test cases
std::unordered_map m33;
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp
index 0e29d314887..9ce653c654a 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp
@@ -30,20 +30,20 @@ void test_string()
sink(b);
sink(c); // $ ast,ir
sink(b.c_str());
- sink(c.c_str()); // $ ast MISSING: ir
+ sink(c.c_str()); // $ ast,ir
}
void test_strings2()
{
string path1 = user_input();
- sink(path1.c_str(), "r"); // $ ast MISSING: ir
+ sink(path1.c_str(), "r"); // $ ast,ir
string path2;
path2 = user_input();
- sink(path2.c_str(), "r"); // $ ast MISSING: ir
+ sink(path2.c_str(), "r"); // $ ast,ir
string path3(user_input());
- sink(path3.c_str(), "r"); // $ ast MISSING: ir
+ sink(path3.c_str(), "r"); // $ ast,ir
}
void test_string3()
@@ -67,7 +67,7 @@ void test_string4()
// convert back std::string -> char *
cs = ss.c_str();
- sink(cs); // $ ast MISSING: ir
+ sink(cs); // $ ast,ir
sink(ss); // $ ast,ir
}
@@ -159,12 +159,12 @@ void test_string_append() {
sink(s5); // $ ast,ir
s6 = s3;
- sink(s6 += s4); // $ ast MISSING: ir
+ sink(s6 += s4); // $ ast,ir
sink(s6); // $ ast,ir
s7 = s3;
- sink(s7 += source()); // $ ast MISSING: ir
- sink(s7 += " "); // $ ast MISSING: ir
+ sink(s7 += source()); // $ ast,ir
+ sink(s7 += " "); // $ ast,ir
sink(s7); // $ ast,ir
s8 = s3;
@@ -196,10 +196,10 @@ void test_string_assign() {
sink(s3.assign(s1));
sink(s3);
- sink(s4.assign(s2)); // $ ast MISSING: ir
+ sink(s4.assign(s2)); // $ ast,ir
sink(s4); // $ ast,ir
- sink(s5.assign(10, c)); // $ ast MISSING: ir
+ sink(s5.assign(10, c)); // $ ast,ir
sink(s5); // $ ast,ir
sink(s6.assign(s1));
@@ -217,15 +217,15 @@ void test_string_insert() {
sink(s3);
s4 = s2;
- sink(s4.insert(0, s1)); // $ ast MISSING: ir
+ sink(s4.insert(0, s1)); // $ ast,ir
sink(s4); // $ ast,ir
s5 = s1;
- sink(s5.insert(0, s2)); // $ ast MISSING: ir
+ sink(s5.insert(0, s2)); // $ ast,ir
sink(s5); // $ ast,ir
s6 = s1;
- sink(s6.insert(0, 10, c)); // $ ast MISSING: ir
+ sink(s6.insert(0, 10, c)); // $ ast,ir
sink(s6); // $ ast,ir
}
@@ -240,15 +240,15 @@ void test_string_replace() {
sink(s3);
s4 = s2;
- sink(s4.replace(1, 2, s1)); // $ ast MISSING: ir
+ sink(s4.replace(1, 2, s1)); // $ ast,ir
sink(s4); // $ ast,ir
s5 = s1;
- sink(s5.replace(1, 2, s2)); // $ ast MISSING: ir
+ sink(s5.replace(1, 2, s2)); // $ ast,ir
sink(s5); // $ ast,ir
s6 = s1;
- sink(s6.replace(1, 2, 10, c)); // $ ast MISSING: ir
+ sink(s6.replace(1, 2, 10, c)); // $ ast,ir
sink(s6); // $ ast,ir
}
@@ -309,7 +309,7 @@ void test_string_data()
std::string b(source());
sink(a.data());
- sink(b.data()); // $ ast MISSING: ir
+ sink(b.data()); // $ ast,ir
sink(a.length());
sink(b.length());
}
@@ -360,7 +360,7 @@ void test_string_iterators() {
std::string s4("world");
sink(s1);
- sink(s1.append(s2.begin(), s2.end())); // $ ast MISSING: ir
+ sink(s1.append(s2.begin(), s2.end())); // $ ast,ir
sink(s1); // $ ast,ir
sink(s3);
@@ -433,7 +433,7 @@ void test_string_insert_more()
sink(s1.insert(0, cs1));
sink(s1);
- sink(s2.insert(0, cs2)); // $ ast MISSING: ir
+ sink(s2.insert(0, cs2)); // $ ast,ir
sink(s2); // $ ast,ir
}
@@ -446,7 +446,7 @@ void test_string_iterator_methods()
sink(a.insert(a.begin(), 10, 'x'));
sink(a);
- sink(b.insert(b.begin(), 10, ns_char::source())); // $ ast MISSING: ir
+ sink(b.insert(b.begin(), 10, ns_char::source())); // $ ast,ir
sink(b); // $ ast,ir
}
@@ -459,10 +459,10 @@ void test_string_iterator_methods()
sink(c.insert(c.end(), s1.begin(), s1.end()));
sink(c);
- sink(d.insert(d.end(), s2.begin(), s2.end())); // $ ast MISSING: ir
+ sink(d.insert(d.end(), s2.begin(), s2.end())); // $ ast,ir
sink(d); // $ ast,ir
- sink(s2.insert(s2.end(), s1.begin(), s1.end())); // $ ast MISSING: ir
+ sink(s2.insert(s2.end(), s1.begin(), s1.end())); // $ ast,ir
sink(s2); // $ ast,ir
}
@@ -475,10 +475,10 @@ void test_string_iterator_methods()
sink(e.append(s3.begin(), s3.end()));
sink(e);
- sink(f.append(s4.begin(), s4.end())); // $ ast MISSING: ir
+ sink(f.append(s4.begin(), s4.end())); // $ ast,ir
sink(f); // $ ast,ir
- sink(s4.append(s3.begin(), s3.end())); // $ ast MISSING: ir
+ sink(s4.append(s3.begin(), s3.end())); // $ ast,ir
sink(s4); // $ ast,ir
}
@@ -491,7 +491,7 @@ void test_string_iterator_methods()
sink(g.assign(s5.cbegin(), s5.cend()));
sink(g);
- sink(h.assign(s6.cbegin(), s6.cend())); // $ ast MISSING: ir
+ sink(h.assign(s6.cbegin(), s6.cend())); // $ ast,ir
sink(h); // $ ast,ir
sink(s6.assign(s5.cbegin(), s5.cend()));
@@ -519,8 +519,8 @@ void test_string_front_back() {
sink(a.front());
sink(a.back());
a.push_back(ns_char::source());
- sink(a.front()); // $ SPURIOUS: ast
- sink(a.back()); // $ ast MISSING: ir
+ sink(a.front()); // $ SPURIOUS: ast,ir
+ sink(a.back()); // $ ast,ir
}
void test_string_return_assign() {
@@ -533,12 +533,12 @@ void test_string_return_assign() {
std::string f("ff");
sink( a += (b += "bb") );
- sink( c += (d += source()) ); // $ ast MISSING: ir
- sink( (e += "ee") += source() ); // $ ast MISSING: ir
- sink( (f += source()) += "ff" ); // $ ast MISSING: ir
+ sink( c += (d += source()) ); // $ ast,ir
+ sink( (e += "ee") += source() ); // $ ast,ir
+ sink( (f += source()) += "ff" ); // $ ast,ir
sink(a);
sink(b);
- sink(c); // $ ast MISSING: ir
+ sink(c); // $ ast,ir
sink(d); // $ ast,ir
sink(e); // $ ast MISSING: ir
sink(f); // $ ast,ir
@@ -553,12 +553,12 @@ void test_string_return_assign() {
std::string f("ff");
sink( a.assign(b.assign("bb")) );
- sink( c.assign(d.assign(source())) ); // $ ast MISSING: ir
- sink( e.assign("ee").assign(source()) ); // $ ast MISSING: ir
+ sink( c.assign(d.assign(source())) ); // $ ast,ir
+ sink( e.assign("ee").assign(source()) ); // $ ast,ir
sink( f.assign(source()).assign("ff") );
sink(a);
sink(b);
- sink(c); // $ ast MISSING: ir
+ sink(c); // $ ast,ir
sink(d); // $ ast,ir
sink(e); // $ ast MISSING: ir
sink(f); // $ SPURIOUS: ast,ir
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp
index fab96fc878d..249c8ac21bf 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp
@@ -53,15 +53,15 @@ void test_stringstream_string(int amount)
sink(ss7); // $ SPURIOUS: ast,ir
sink(ss8.put('a'));
- sink(ss9.put(ns_char::source())); // $ ast MISSING: ir
- sink(ss10.put('a').put(ns_char::source()).put('z')); // $ ast MISSING: ir
+ sink(ss9.put(ns_char::source())); // $ ast,ir
+ sink(ss10.put('a').put(ns_char::source()).put('z')); // $ ast,ir
sink(ss8);
sink(ss9); // $ ast,ir
sink(ss10); // $ ast MISSING: ir
sink(ss11.write("begin", 5));
- sink(ss12.write(source(), 5)); // $ ast MISSING: ir
- sink(ss13.write("begin", 5).write(source(), amount).write("end", 3)); // $ ast MISSING: ir
+ sink(ss12.write(source(), 5)); // $ ast,ir
+ sink(ss13.write("begin", 5).write(source(), amount).write("end", 3)); // $ ast,ir
sink(ss11);
sink(ss12); // $ ast,ir
sink(ss13); // $ ast MISSING: ir
@@ -73,7 +73,7 @@ void test_stringstream_int(int source)
int v1 = 0, v2 = 0;
sink(ss1 << 1234);
- sink(ss2 << source); // $ ast MISSING: ir
+ sink(ss2 << source); // $ ast,ir
sink(ss1 >> v1);
sink(ss2 >> v2); // $ ast,ir
@@ -97,7 +97,7 @@ void test_stringstream_constructors()
std::stringstream ss6;
sink(ss5 = std::stringstream("abc"));
- sink(ss6 = std::stringstream(source())); // $ ast MISSING: ir
+ sink(ss6 = std::stringstream(source())); // $ ast,ir
sink(ss1);
sink(ss2); // $ ast,ir
@@ -193,7 +193,7 @@ void test_stringstream_putback()
sink(ss.get());
sink(ss.putback('b'));
sink(ss.get());
- sink(ss.putback(ns_char::source())); // $ ast MISSING: ir
+ sink(ss.putback(ns_char::source())); // $ ast,ir
sink(ss.get()); // $ ast,ir
}
@@ -263,6 +263,6 @@ void test_chaining()
sink(b1); // $ ast,ir
sink(b2); // $ ast,ir
- sink(ss2.write("abc", 3).flush().write(source(), 3).flush().write("xyz", 3)); // $ ast MISSING: ir
+ sink(ss2.write("abc", 3).flush().write(source(), 3).flush().write("xyz", 3)); // $ ast,ir
sink(ss2); // $ ast MISSING: ir
}
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp
index 9434dbe52ae..92a44f2950c 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp
@@ -466,7 +466,7 @@ void test_qualifiers()
sink(d.getString());
d.setString(strings::source());
sink(d); // $ ast,ir
- sink(d.getString()); // $ ast MISSING: ir
+ sink(d.getString()); // $ ast,ir
}
// --- non-standard swap ---
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
index 4f0c8fab414..aacef1f4a5b 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
@@ -68,8 +68,8 @@ void test_element_taint(int x) {
v5.push_back(source());
sink(v5); // $ ast,ir
- sink(v5.front()); // $ SPURIOUS: ast
- sink(v5.back()); // $ ast MISSING: ir
+ sink(v5.front()); // $ SPURIOUS: ast,ir
+ sink(v5.back()); // $ ast,ir
v6.data()[2] = source();
sink(v6); // $ ast MISSING: ir
@@ -81,8 +81,8 @@ void test_element_taint(int x) {
v7.insert(it, source());
}
sink(v7); // $ ast,ir
- sink(v7.front()); // $ ast MISSING: ir
- sink(v7.back()); // $ SPURIOUS: ast
+ sink(v7.front()); // $ ast,ir
+ sink(v7.back()); // $ SPURIOUS: ast,ir
{
const std::vector &v8c = v8;
@@ -283,8 +283,8 @@ void test_data_more() {
v1.push_back(source());
sink(v1); // $ ast,ir
- sink(v1.data()); // $ ast MISSING: ir
- sink(v1.data()[2]); // $ ast MISSING: ir
+ sink(v1.data()); // $ ast,ir
+ sink(v1.data()[2]); // $ ast,ir
*(v2.data()) = ns_int::source();
sink(v2); // $ ast MISSING: ir
@@ -305,10 +305,10 @@ void test_vector_insert() {
sink(a.insert(a.end(), b.begin(), b.end()));
sink(a);
- sink(c.insert(c.end(), d.begin(), d.end())); // $ ast MISSING: ir
+ sink(c.insert(c.end(), d.begin(), d.end())); // $ ast,ir
sink(c); // $ ast,ir
- sink(d.insert(d.end(), a.begin(), a.end())); // $ ast MISSING: ir
+ sink(d.insert(d.end(), a.begin(), a.end())); // $ ast,ir
sink(d); // $ ast,ir
}
diff --git a/cpp/ql/test/library-tests/ir/points_to/points_to.ql b/cpp/ql/test/library-tests/ir/points_to/points_to.ql
index da090c5552e..b639a235ee8 100644
--- a/cpp/ql/test/library-tests/ir/points_to/points_to.ql
+++ b/cpp/ql/test/library-tests/ir/points_to/points_to.ql
@@ -3,12 +3,7 @@ private import TestUtilities.InlineExpectationsTest
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
private predicate ignoreAllocation(string name) {
- name = "i" or
- name = "p" or
- name = "q" or
- name = "s" or
- name = "t" or
- name = "?{AllAliased}"
+ name = ["i", "p", "q", "s", "t", "?{AllAliased}"]
}
private predicate ignoreFile(File file) {
diff --git a/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected b/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected
index 9ecfb2303db..0e5bbee7d73 100644
--- a/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected
+++ b/cpp/ql/test/query-tests/Critical/OverflowStatic/OverflowStatic.expected
@@ -5,14 +5,10 @@
| test2.c:33:26:33:27 | 46 | Potential buffer-overflow: 'buffer' has size 40 not 46. |
| test2.c:34:22:34:23 | 47 | Potential buffer-overflow: 'buffer' has size 40 not 47. |
| test2.c:35:23:35:24 | 48 | Potential buffer-overflow: 'buffer' has size 40 not 48. |
-| test.c:14:9:14:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[5]' is accessed here. |
-| test.c:15:9:15:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[6]' is accessed here. |
-| test.c:20:9:20:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[5]' is accessed here. |
-| test.c:21:9:21:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[6]' is accessed here. |
-| test.c:47:3:47:18 | access to array | Potential buffer-overflow: 'ptr' has size 8 but 'ptr[8]' is accessed here. |
-| test.c:54:3:54:26 | access to array | Potential buffer-overflow: 'ptr' has size 8 but 'ptr[8]' is accessed here. |
-| test.c:61:3:61:18 | access to array | Potential buffer-overflow: 'ptr' has size 8 but 'ptr[8]' is accessed here. |
-| test.c:72:3:72:11 | access to array | Potential buffer-overflow: 'buf' has size 1 but 'buf[1]' is accessed here. |
+| test.c:14:9:14:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[5]' may be accessed here. |
+| test.c:15:9:15:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[6]' may be accessed here. |
+| test.c:20:9:20:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[5]' may be accessed here. |
+| test.c:21:9:21:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[6]' may be accessed here. |
| test.cpp:19:3:19:12 | access to array | Potential buffer-overflow: counter 'i' <= 3 but 'buffer1' has 3 elements. |
| test.cpp:20:3:20:12 | access to array | Potential buffer-overflow: counter 'i' <= 3 but 'buffer2' has 3 elements. |
| test.cpp:24:27:24:27 | 4 | Potential buffer-overflow: 'buffer1' has size 3 not 4. |
diff --git a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.c b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.c
index 4da951a3139..3c726a452b9 100644
--- a/cpp/ql/test/query-tests/Critical/OverflowStatic/test.c
+++ b/cpp/ql/test/query-tests/Critical/OverflowStatic/test.c
@@ -44,21 +44,21 @@ void union_test() {
union u u;
u.ptr[0] = 0; // GOOD
u.ptr[sizeof(u)-1] = 0; // GOOD
- u.ptr[sizeof(u)] = 0; // BAD
+ u.ptr[sizeof(u)] = 0; // BAD [NOT DETECTED]
}
void test_struct_union() {
struct { union u u; } v;
v.u.ptr[0] = 0; // GOOD
v.u.ptr[sizeof(union u)-1] = 0; // GOOD
- v.u.ptr[sizeof(union u)] = 0; // BAD
+ v.u.ptr[sizeof(union u)] = 0; // BAD [NOT DETECTED]
}
void union_test2() {
union { char ptr[1]; unsigned long value; } u;
u.ptr[0] = 0; // GOOD
u.ptr[sizeof(u)-1] = 0; // GOOD
- u.ptr[sizeof(u)] = 0; // BAD
+ u.ptr[sizeof(u)] = 0; // BAD [NOT DETECTED]
}
typedef struct {
@@ -69,5 +69,5 @@ typedef struct {
void test_alloc() {
// Special case of taking sizeof without any addition or multiplications
var_buf *b = malloc(sizeof(var_buf));
- b->buf[1] = 0; // BAD
+ b->buf[1] = 0; // BAD [NOT DETECTED]
}
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTermination.expected b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTermination.expected
index c83205ef49f..19edbd28c6a 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTermination.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTermination.expected
@@ -1,27 +1,29 @@
-| test.cpp:25:10:25:16 | buffer1 | Variable $@ may not be null terminated. | test.cpp:22:8:22:14 | buffer1 | buffer1 |
-| test.cpp:26:10:26:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:23:8:23:14 | buffer2 | buffer2 |
-| test.cpp:39:10:39:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:35:8:35:14 | buffer2 | buffer2 |
-| test.cpp:59:10:59:13 | ptr1 | Variable $@ may not be null terminated. | test.cpp:56:9:56:12 | ptr1 | ptr1 |
-| test.cpp:69:10:69:16 | buffer1 | Variable $@ may not be null terminated. | test.cpp:64:8:64:14 | buffer1 | buffer1 |
-| test.cpp:70:10:70:12 | ptr | Variable $@ may not be null terminated. | test.cpp:64:8:64:14 | buffer1 | buffer1 |
-| test.cpp:81:10:81:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:65:8:65:14 | buffer2 | buffer2 |
-| test.cpp:82:10:82:12 | ptr | Variable $@ may not be null terminated. | test.cpp:65:8:65:14 | buffer2 | buffer2 |
-| test.cpp:93:10:93:15 | buffer | Variable $@ may not be null terminated. | test.cpp:86:8:86:13 | buffer | buffer |
-| test.cpp:116:10:116:15 | buffer | Variable $@ may not be null terminated. | test.cpp:109:8:109:13 | buffer | buffer |
-| test.cpp:130:14:130:19 | buffer | Variable $@ may not be null terminated. | test.cpp:127:7:127:12 | buffer | buffer |
-| test.cpp:139:10:139:15 | buffer | Variable $@ may not be null terminated. | test.cpp:136:8:136:13 | buffer | buffer |
-| test.cpp:147:14:147:19 | buffer | Variable $@ may not be null terminated. | test.cpp:143:8:143:13 | buffer | buffer |
-| test.cpp:182:10:182:15 | buffer | Variable $@ may not be null terminated. | test.cpp:178:8:178:13 | buffer | buffer |
-| test.cpp:234:10:234:15 | buffer | Variable $@ may not be null terminated. | test.cpp:232:8:232:13 | buffer | buffer |
-| test.cpp:262:10:262:15 | buffer | Variable $@ may not be null terminated. | test.cpp:259:8:259:13 | buffer | buffer |
-| test.cpp:283:10:283:15 | buffer | Variable $@ may not be null terminated. | test.cpp:280:8:280:13 | buffer | buffer |
-| test.cpp:300:10:300:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:295:8:295:14 | buffer2 | buffer2 |
-| test.cpp:312:10:312:15 | buffer | Variable $@ may not be null terminated. | test.cpp:308:8:308:13 | buffer | buffer |
-| test.cpp:327:18:327:23 | buffer | Variable $@ may not be null terminated. | test.cpp:326:8:326:13 | buffer | buffer |
-| test.cpp:346:11:346:16 | buffer | Variable $@ may not be null terminated. | test.cpp:341:8:341:13 | buffer | buffer |
+| test.cpp:26:10:26:16 | buffer1 | Variable $@ may not be null terminated. | test.cpp:23:8:23:14 | buffer1 | buffer1 |
+| test.cpp:27:10:27:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:24:8:24:14 | buffer2 | buffer2 |
+| test.cpp:40:10:40:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:36:8:36:14 | buffer2 | buffer2 |
+| test.cpp:60:10:60:13 | ptr1 | Variable $@ may not be null terminated. | test.cpp:57:9:57:12 | ptr1 | ptr1 |
+| test.cpp:70:10:70:16 | buffer1 | Variable $@ may not be null terminated. | test.cpp:65:8:65:14 | buffer1 | buffer1 |
+| test.cpp:71:10:71:12 | ptr | Variable $@ may not be null terminated. | test.cpp:65:8:65:14 | buffer1 | buffer1 |
+| test.cpp:82:10:82:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:66:8:66:14 | buffer2 | buffer2 |
+| test.cpp:83:10:83:12 | ptr | Variable $@ may not be null terminated. | test.cpp:66:8:66:14 | buffer2 | buffer2 |
+| test.cpp:94:10:94:15 | buffer | Variable $@ may not be null terminated. | test.cpp:87:8:87:13 | buffer | buffer |
+| test.cpp:117:10:117:15 | buffer | Variable $@ may not be null terminated. | test.cpp:110:8:110:13 | buffer | buffer |
+| test.cpp:131:14:131:19 | buffer | Variable $@ may not be null terminated. | test.cpp:128:7:128:12 | buffer | buffer |
+| test.cpp:140:10:140:15 | buffer | Variable $@ may not be null terminated. | test.cpp:137:8:137:13 | buffer | buffer |
+| test.cpp:148:14:148:19 | buffer | Variable $@ may not be null terminated. | test.cpp:144:8:144:13 | buffer | buffer |
+| test.cpp:183:10:183:15 | buffer | Variable $@ may not be null terminated. | test.cpp:179:8:179:13 | buffer | buffer |
+| test.cpp:236:10:236:15 | buffer | Variable $@ may not be null terminated. | test.cpp:234:8:234:13 | buffer | buffer |
+| test.cpp:264:10:264:15 | buffer | Variable $@ may not be null terminated. | test.cpp:261:8:261:13 | buffer | buffer |
+| test.cpp:285:10:285:15 | buffer | Variable $@ may not be null terminated. | test.cpp:282:8:282:13 | buffer | buffer |
+| test.cpp:302:10:302:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:297:8:297:14 | buffer2 | buffer2 |
+| test.cpp:314:10:314:15 | buffer | Variable $@ may not be null terminated. | test.cpp:310:8:310:13 | buffer | buffer |
+| test.cpp:336:18:336:23 | buffer | Variable $@ may not be null terminated. | test.cpp:335:8:335:13 | buffer | buffer |
| test.cpp:355:11:355:16 | buffer | Variable $@ may not be null terminated. | test.cpp:350:8:350:13 | buffer | buffer |
-| test.cpp:365:19:365:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:363:8:363:14 | buffer2 | buffer2 |
-| test.cpp:392:17:392:22 | buffer | Variable $@ may not be null terminated. | test.cpp:390:8:390:13 | buffer | buffer |
-| test.cpp:398:18:398:23 | buffer | Variable $@ may not be null terminated. | test.cpp:396:8:396:13 | buffer | buffer |
-| test.cpp:444:10:444:15 | buffer | Variable $@ may not be null terminated. | test.cpp:442:8:442:13 | buffer | buffer |
-| test.cpp:450:16:450:21 | buffer | Variable $@ may not be null terminated. | test.cpp:448:8:448:13 | buffer | buffer |
+| test.cpp:364:11:364:16 | buffer | Variable $@ may not be null terminated. | test.cpp:359:8:359:13 | buffer | buffer |
+| test.cpp:392:11:392:16 | buffer | Variable $@ may not be null terminated. | test.cpp:381:8:381:13 | buffer | buffer |
+| test.cpp:410:11:410:16 | buffer | Variable $@ may not be null terminated. | test.cpp:397:8:397:13 | buffer | buffer |
+| test.cpp:421:19:421:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:419:8:419:14 | buffer2 | buffer2 |
+| test.cpp:448:17:448:22 | buffer | Variable $@ may not be null terminated. | test.cpp:446:8:446:13 | buffer | buffer |
+| test.cpp:454:18:454:23 | buffer | Variable $@ may not be null terminated. | test.cpp:452:8:452:13 | buffer | buffer |
+| test.cpp:513:10:513:15 | buffer | Variable $@ may not be null terminated. | test.cpp:511:8:511:13 | buffer | buffer |
+| test.cpp:519:16:519:21 | buffer | Variable $@ may not be null terminated. | test.cpp:517:8:517:13 | buffer | buffer |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTerminationTainted.expected b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTerminationTainted.expected
index 3bf8c4d3652..b0a0d6cbb66 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTerminationTainted.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/ImproperNullTerminationTainted.expected
@@ -1,2 +1,2 @@
-| test.cpp:410:10:410:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:409:18:409:23 | buffer | User-provided value |
-| test.cpp:425:10:425:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:424:9:424:14 | buffer | User-provided value |
+| test.cpp:466:10:466:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:465:18:465:23 | buffer | User-provided value |
+| test.cpp:481:10:481:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:480:9:480:14 | buffer | User-provided value |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/test.cpp
index 45410c15ebf..9adf409af4a 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/test.cpp
+++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ImproperNullTermination/test.cpp
@@ -6,6 +6,7 @@ size_t strlen(const char *s);
char *strcpy(char *s1, const char *s2);
char *strcat(char *s1, const char *s2);
char *strdup(const char *s1);
+long int strtol(const char* nptr, char** endptr, int base);
void *malloc(size_t size);
void *memset(void *s, int c, size_t n);
void *memcpy(void *s1, const void *s2, size_t n);
@@ -225,6 +226,7 @@ void test_readlink(int fd, const char *path, size_t sz)
void doNothing(char *data) { };
void doNothing2(const char *data);
void clearBuffer(char *data, size_t size);
+char *id(char *data) { return data; }
void test_strcat()
{
@@ -318,6 +320,13 @@ void test_strcat()
clearBuffer(buffer, 1024);
strcat(buffer, "content"); // GOOD
}
+
+ {
+ char buffer[1024];
+
+ clearBuffer(id(buffer), 1024);
+ strcat(buffer, "content"); // GOOD
+ }
}
void test_strlen(bool cond1, bool cond2)
@@ -354,6 +363,53 @@ void test_strlen(bool cond1, bool cond2)
if (cond2)
strlen(buffer); // BAD
}
+
+ {
+ char buffer[1024];
+
+ if (cond1)
+ {
+ buffer[0] = 0;
+ } else {
+ buffer[0] = 0;
+ }
+
+ strlen(buffer); // GOOD
+ }
+
+ {
+ char buffer[1024];
+ int init = 0;
+
+ if (cond1)
+ {
+ buffer[0] = 0;
+ init = 1;
+ }
+
+ if (init != 0)
+ {
+ strlen(buffer); // GOOD [FALSE POSITIVE]
+ }
+ }
+
+ {
+ char buffer[1024];
+ int init = 0;
+
+ if (cond1)
+ {
+ buffer[0] = 0;
+ init = 1;
+ }
+
+ if (init == 0)
+ {
+ // ...
+ } else {
+ strlen(buffer); // GOOD [FALSE POSITIVE]
+ }
+ }
}
void test_strcpy()
@@ -434,6 +490,19 @@ void test_read_fread(int read_src, FILE *s)
}
}
+void test_strtol()
+{
+ {
+ char buffer[100];
+ char *after_ptr;
+ long int num;
+
+ strcpy(buffer, "123abc");
+ num = strtol("123abc", &after_ptr, 10);
+ strlen(after_ptr); // GOOD
+ }
+}
+
int printf(const char *format, ...);
void test_printf(char *str)
@@ -466,3 +535,4 @@ void test_printf(char *str)
printf("%s", copied_str); // GOOD
}
}
+
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.expected
index 6f011708465..51c8906abb5 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/SAMATE/ExecTainted/ExecTainted.expected
@@ -1 +1,17 @@
-| tests.cpp:53:16:53:19 | data | This argument to an OS command is derived from $@ and then passed to system(string) | tests.cpp:33:34:33:39 | call to getenv | user input (getenv) |
+edges
+| tests.cpp:33:34:33:39 | call to getenv | tests.cpp:38:39:38:49 | environment indirection |
+| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:42:5:42:16 | Phi |
+| tests.cpp:38:39:38:49 | environment indirection | tests.cpp:38:25:38:36 | strncat output argument |
+| tests.cpp:38:39:38:49 | environment indirection | tests.cpp:38:25:38:36 | strncat output argument |
+| tests.cpp:42:5:42:16 | Phi | tests.cpp:51:22:51:25 | badSource output argument |
+| tests.cpp:51:22:51:25 | badSource output argument | tests.cpp:53:16:53:19 | data indirection |
+nodes
+| tests.cpp:33:34:33:39 | call to getenv | semmle.label | call to getenv |
+| tests.cpp:38:25:38:36 | strncat output argument | semmle.label | strncat output argument |
+| tests.cpp:38:39:38:49 | environment indirection | semmle.label | environment indirection |
+| tests.cpp:42:5:42:16 | Phi | semmle.label | Phi |
+| tests.cpp:51:22:51:25 | badSource output argument | semmle.label | badSource output argument |
+| tests.cpp:53:16:53:19 | data indirection | semmle.label | data indirection |
+subpaths
+#select
+| tests.cpp:53:16:53:19 | data | tests.cpp:33:34:33:39 | call to getenv | tests.cpp:53:16:53:19 | data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | tests.cpp:33:34:33:39 | call to getenv | user input (an environment variable) | tests.cpp:38:25:38:36 | strncat output argument | strncat output argument |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected
index a78a7a99d90..4b1b5a61ace 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected
@@ -1 +1,85 @@
-| test.c:21:12:21:19 | command1 | This argument to an OS command is derived from $@ and then passed to system(string) | test.c:14:20:14:23 | argv | user input (argv) |
+edges
+| test.cpp:16:20:16:23 | argv | test.cpp:22:45:22:52 | userName indirection |
+| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection |
+| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
+| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
+| test.cpp:47:21:47:26 | call to getenv | test.cpp:50:35:50:43 | envCflags indirection |
+| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | command indirection |
+| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument |
+| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument |
+| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | filename indirection |
+| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | command indirection |
+| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument |
+| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument |
+| test.cpp:82:9:82:16 | fread output argument | test.cpp:84:20:84:27 | filename indirection |
+| test.cpp:84:11:84:17 | strncat output argument | test.cpp:85:32:85:38 | command indirection |
+| test.cpp:84:20:84:27 | filename indirection | test.cpp:84:11:84:17 | strncat output argument |
+| test.cpp:84:20:84:27 | filename indirection | test.cpp:84:11:84:17 | strncat output argument |
+| test.cpp:91:9:91:16 | fread output argument | test.cpp:93:17:93:24 | filename indirection |
+| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | path indirection |
+| test.cpp:93:17:93:24 | filename indirection | test.cpp:93:11:93:14 | strncat output argument |
+| test.cpp:93:17:93:24 | filename indirection | test.cpp:93:11:93:14 | strncat output argument |
+| test.cpp:106:20:106:25 | call to getenv | test.cpp:107:33:107:36 | path indirection |
+| test.cpp:107:31:107:31 | call to operator+ | test.cpp:108:18:108:22 | call to c_str indirection |
+| test.cpp:107:33:107:36 | path indirection | test.cpp:107:31:107:31 | call to operator+ |
+| test.cpp:107:33:107:36 | path indirection | test.cpp:107:31:107:31 | call to operator+ |
+| test.cpp:113:20:113:25 | call to getenv | test.cpp:114:19:114:22 | path indirection |
+| test.cpp:114:17:114:17 | Call | test.cpp:114:25:114:29 | call to c_str indirection |
+| test.cpp:114:19:114:22 | path indirection | test.cpp:114:17:114:17 | Call |
+| test.cpp:114:19:114:22 | path indirection | test.cpp:114:17:114:17 | Call |
+| test.cpp:119:20:119:25 | call to getenv | test.cpp:120:19:120:22 | path indirection |
+| test.cpp:120:17:120:17 | Call | test.cpp:120:10:120:30 | call to data indirection |
+| test.cpp:120:19:120:22 | path indirection | test.cpp:120:17:120:17 | Call |
+| test.cpp:120:19:120:22 | path indirection | test.cpp:120:17:120:17 | Call |
+| test.cpp:140:9:140:11 | fread output argument | test.cpp:142:31:142:33 | str indirection |
+| test.cpp:142:11:142:17 | sprintf output argument | test.cpp:143:10:143:16 | command indirection |
+| test.cpp:142:31:142:33 | str indirection | test.cpp:142:11:142:17 | sprintf output argument |
+| test.cpp:142:31:142:33 | str indirection | test.cpp:142:11:142:17 | sprintf output argument |
+nodes
+| test.cpp:16:20:16:23 | argv | semmle.label | argv |
+| test.cpp:22:13:22:20 | sprintf output argument | semmle.label | sprintf output argument |
+| test.cpp:22:45:22:52 | userName indirection | semmle.label | userName indirection |
+| test.cpp:23:12:23:19 | command1 indirection | semmle.label | command1 indirection |
+| test.cpp:47:21:47:26 | call to getenv | semmle.label | call to getenv |
+| test.cpp:50:11:50:17 | sprintf output argument | semmle.label | sprintf output argument |
+| test.cpp:50:35:50:43 | envCflags indirection | semmle.label | envCflags indirection |
+| test.cpp:51:10:51:16 | command indirection | semmle.label | command indirection |
+| test.cpp:62:9:62:16 | fread output argument | semmle.label | fread output argument |
+| test.cpp:64:11:64:17 | strncat output argument | semmle.label | strncat output argument |
+| test.cpp:64:20:64:27 | filename indirection | semmle.label | filename indirection |
+| test.cpp:65:10:65:16 | command indirection | semmle.label | command indirection |
+| test.cpp:82:9:82:16 | fread output argument | semmle.label | fread output argument |
+| test.cpp:84:11:84:17 | strncat output argument | semmle.label | strncat output argument |
+| test.cpp:84:20:84:27 | filename indirection | semmle.label | filename indirection |
+| test.cpp:85:32:85:38 | command indirection | semmle.label | command indirection |
+| test.cpp:91:9:91:16 | fread output argument | semmle.label | fread output argument |
+| test.cpp:93:11:93:14 | strncat output argument | semmle.label | strncat output argument |
+| test.cpp:93:17:93:24 | filename indirection | semmle.label | filename indirection |
+| test.cpp:94:45:94:48 | path indirection | semmle.label | path indirection |
+| test.cpp:106:20:106:25 | call to getenv | semmle.label | call to getenv |
+| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ |
+| test.cpp:107:33:107:36 | path indirection | semmle.label | path indirection |
+| test.cpp:108:18:108:22 | call to c_str indirection | semmle.label | call to c_str indirection |
+| test.cpp:113:20:113:25 | call to getenv | semmle.label | call to getenv |
+| test.cpp:114:17:114:17 | Call | semmle.label | Call |
+| test.cpp:114:19:114:22 | path indirection | semmle.label | path indirection |
+| test.cpp:114:25:114:29 | call to c_str indirection | semmle.label | call to c_str indirection |
+| test.cpp:119:20:119:25 | call to getenv | semmle.label | call to getenv |
+| test.cpp:120:10:120:30 | call to data indirection | semmle.label | call to data indirection |
+| test.cpp:120:17:120:17 | Call | semmle.label | Call |
+| test.cpp:120:19:120:22 | path indirection | semmle.label | path indirection |
+| test.cpp:140:9:140:11 | fread output argument | semmle.label | fread output argument |
+| test.cpp:142:11:142:17 | sprintf output argument | semmle.label | sprintf output argument |
+| test.cpp:142:31:142:33 | str indirection | semmle.label | str indirection |
+| test.cpp:143:10:143:16 | command indirection | semmle.label | command indirection |
+subpaths
+#select
+| test.cpp:23:12:23:19 | command1 | test.cpp:16:20:16:23 | argv | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:16:20:16:23 | argv | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
+| test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | call to getenv | test.cpp:51:10:51:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:47:21:47:26 | call to getenv | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument |
+| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:62:9:62:16 | fread output argument | user input (String read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument |
+| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl | test.cpp:82:9:82:16 | fread output argument | user input (String read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument |
+| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | path indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl | test.cpp:91:9:91:16 | fread output argument | user input (String read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument |
+| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:25 | call to getenv | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:106:20:106:25 | call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ |
+| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:25 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:113:20:113:25 | call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | Call | Call |
+| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:25 | call to getenv | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:119:20:119:25 | call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | Call | Call |
+| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string) | test.cpp:140:9:140:11 | fread output argument | user input (String read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.c
deleted file mode 100644
index c3155787368..00000000000
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.c
+++ /dev/null
@@ -1,33 +0,0 @@
-// Semmle test case for rule ExecTainted.ql (Uncontrolled data used in OS command)
-// Associated with CWE-078: OS Command Injection. http://cwe.mitre.org/data/definitions/78.html
-
-///// Library routines /////
-
-int sprintf(char *s, const char *format, ...);
-int system(const char *string);
-
-extern void encodeShellString(char *shellStr, int maxChars, const char* cStr);
-
-///// Test code /////
-
-int main(int argc, char** argv) {
- char *userName = argv[2];
-
- {
- // BAD: a string from the user is injected directly into
- // a command.
- char command1[1000] = {0};
- sprintf(command1, "userinfo -v \"%s\"", userName);
- system(command1);
- }
-
- {
- // GOOD: the user string is encoded by a library routine.
- char userNameQuoted[1000] = {0};
- encodeShellString(userNameQuoted, 1000, userName);
- char command2[1000] = {0};
- sprintf(command2, "userinfo -v %s", userNameQuoted);
- system(command2);
- }
-}
-
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp
new file mode 100644
index 00000000000..8407ffb68da
--- /dev/null
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/test.cpp
@@ -0,0 +1,174 @@
+// Semmle test case for rule ExecTainted.ql (Uncontrolled data used in OS command)
+// Associated with CWE-078: OS Command Injection. http://cwe.mitre.org/data/definitions/78.html
+
+///// Library routines /////
+
+int sprintf(char *s, const char *format, ...);
+int system(const char *string);
+
+char *getenv(char *var);
+
+extern void encodeShellString(char *shellStr, int maxChars, const char* cStr);
+#include "../../../../../../include/string.h"
+///// Test code /////
+
+int main(int argc, char** argv) {
+ char *userName = argv[2];
+
+ {
+ // BAD: a string from the user is injected directly into
+ // a command.
+ char command1[1000] = {0};
+ sprintf(command1, "userinfo -v \"%s\"", userName);
+ system(command1);
+ }
+
+ {
+ // GOOD: the user string is encoded by a library routine.
+ char userNameQuoted[1000] = {0};
+ encodeShellString(userNameQuoted, 1000, userName);
+ char command2[1000] = {0};
+ sprintf(command2, "userinfo -v %s", userNameQuoted);
+ system(command2);
+ }
+}
+
+void test2(char* arg2) {
+ // GOOD?: the user string is the *first* part of the command, like $CC in many environments
+ char *envCC = getenv("CC");
+
+ char command[1000];
+ sprintf("%s %s", envCC, arg2);
+ system(command);
+}
+
+void test3(char* arg1) {
+ // GOOD?: the user string is a `$CFLAGS` environment variable
+ char *envCflags = getenv("CFLAGS");
+
+ char command[1000];
+ sprintf(command, "%s %s", arg1, envCflags);
+ system(command);
+}
+
+typedef unsigned long size_t;
+typedef void FILE;
+size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+char *strncat(char *s1, const char *s2, size_t n);
+
+void test4(FILE *f) {
+ // BAD: the user string is injected directly into a command
+ char command[1000] = "mv ", filename[1000];
+ fread(filename, 1, 1000, f);
+
+ strncat(command, filename, 1000);
+ system(command);
+}
+
+void test5(FILE *f) {
+ // GOOD?: the user string is the start of a command
+ char command[1000], filename[1000] = " test.txt";
+ fread(command, 1, 1000, f);
+
+ strncat(command, filename, 1000);
+ system(command);
+}
+
+int execl(char *path, char *arg1, ...);
+
+void test6(FILE *f) {
+ // BAD: the user string is injected directly into a command
+ char command[1000] = "mv ", filename[1000];
+ fread(filename, 1, 1000, f);
+
+ strncat(command, filename, 1000);
+ execl("/bin/sh", "sh", "-c", command);
+}
+
+void test7(FILE *f) {
+ // GOOD [FALSE POSITIVE]: the user string is a positional argument to a shell script
+ char path[1000] = "/home/me/", filename[1000];
+ fread(filename, 1, 1000, f);
+
+ strncat(path, filename, 1000);
+ execl("/bin/sh", "sh", "-c", "script.sh", path);
+}
+
+void test8(char *arg2) {
+ // GOOD?: the user string is the *first* part of the command, like $CC in many environments
+ std::string envCC(getenv("CC"));
+ std::string command = envCC + arg2;
+ system(command.c_str());
+}
+
+void test9(FILE *f) {
+ // BAD: the user string is injected directly into a command
+ std::string path(getenv("something"));
+ std::string command = "mv " + path;
+ system(command.c_str());
+}
+
+void test10(FILE *f) {
+ // BAD: the user string is injected directly into a command
+ std::string path(getenv("something"));
+ system(("mv " + path).c_str());
+}
+
+void test11(FILE *f) {
+ // BAD: the user string is injected directly into a command
+ std::string path(getenv("something"));
+ system(("mv " + path).data());
+}
+
+int atoi(char *);
+
+void test12(FILE *f) {
+ char temp[10];
+ char command[1000];
+
+ fread(temp, 1, 10, f);
+
+ int x = atoi(temp);
+ sprintf(command, "tail -n %d foo.log", x);
+ system(command); // GOOD: the user string was converted to an integer and back
+}
+
+void test13(FILE *f) {
+ char str[1000];
+ char command[1000];
+
+ fread(str, 1, 1000, f);
+
+ sprintf(command, "echo %s", str);
+ system(command); // BAD: the user string was printed into the command with the %s specifier
+}
+
+void test14(FILE *f) {
+ char str[1000];
+ char command[1000];
+
+ fread(str, 1, 1000, f);
+
+ sprintf(command, "echo %p", str);
+ system(command); // GOOD: the user string's address was printed into the command with the %p specifier
+}
+
+void test15(FILE *f) {
+ char temp[10];
+ char command[1000];
+
+ fread(temp, 1, 10, f);
+
+ int x = atoi(temp);
+
+ char temp2[10];
+ sprintf(temp2, "%d", x);
+ sprintf(command, "tail -n %s foo.log", temp2);
+
+ system(command); // GOOD: the user string was converted to an integer and back
+}
+
+
+// TODO: test for call context sensitivity at concatenation site
+
+// open question: do we want to report certain sources even when they're the start of the string?
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowBuffer.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowBuffer.expected
index 77751b66d4e..795d83587c3 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowBuffer.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowBuffer.expected
@@ -72,12 +72,9 @@
| unions.cpp:30:2:30:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:15:7:15:11 | small | destination buffer |
| unions.cpp:34:2:34:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:16:7:16:11 | large | destination buffer |
| unions.cpp:34:2:34:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:34:14:34:18 | large | destination buffer |
-| var_size_struct.cpp:54:5:54:14 | access to array | This array indexing operation accesses byte offset 1 but the $@ is only 1 byte. | var_size_struct.cpp:32:8:32:10 | str | array |
-| var_size_struct.cpp:55:5:55:14 | access to array | This array indexing operation accesses byte offset 1 but the $@ is only 1 byte. | var_size_struct.cpp:38:8:38:10 | str | array |
| var_size_struct.cpp:71:3:71:8 | call to memset | This 'memset' operation accesses 1025 bytes but the $@ is only 1024 bytes. | var_size_struct.cpp:63:8:63:11 | data | destination buffer |
| var_size_struct.cpp:73:3:73:9 | call to strncpy | This 'strncpy' operation may access 1025 bytes but the $@ is only 1024 bytes. | var_size_struct.cpp:63:8:63:11 | data | destination buffer |
| var_size_struct.cpp:87:3:87:19 | access to array | This array indexing operation accesses byte offset 67 but the $@ is only 64 bytes. | var_size_struct.cpp:78:7:78:14 | elements | array |
| var_size_struct.cpp:99:3:99:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
| var_size_struct.cpp:101:3:101:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
| var_size_struct.cpp:103:3:103:9 | call to strncpy | This 'strncpy' operation may access 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
-| var_size_struct.cpp:169:3:169:8 | call to memset | This 'memset' operation accesses 100 bytes but the $@ is only 1 byte. | var_size_struct.cpp:125:17:125:19 | arr | destination buffer |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowStatic.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowStatic.expected
index ef334a73a2c..ac44bbf028d 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowStatic.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowStatic.expected
@@ -3,8 +3,6 @@
| tests.cpp:163:3:163:11 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. |
| tests.cpp:164:8:164:16 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. |
| tests.cpp:245:42:245:42 | 6 | Potential buffer-overflow: 'global_array_5' has size 5 not 6. |
-| tests.cpp:349:2:349:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' is accessed here. |
-| tests.cpp:350:17:350:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' is accessed here. |
-| var_size_struct.cpp:54:5:54:14 | access to array | Potential buffer-overflow: 'str' has size 1 but 'str[1]' is accessed here. |
-| var_size_struct.cpp:55:5:55:14 | access to array | Potential buffer-overflow: 'str' has size 1 but 'str[1]' is accessed here. |
+| tests.cpp:349:2:349:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
+| tests.cpp:350:17:350:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
| var_size_struct.cpp:103:39:103:41 | 129 | Potential buffer-overflow: 'str' has size 128 not 129. |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/var_size_struct.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/var_size_struct.cpp
index c006c35fe9b..a514135f348 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/var_size_struct.cpp
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/var_size_struct.cpp
@@ -51,8 +51,8 @@ void testVarString(int n) {
s1->str[1] = '?'; // GOOD
s2->str[1] = '?'; // GOOD
s3->str[1] = '?'; // GOOD
- s4->str[1] = '?'; // BAD
- s5->str[1] = '?'; // BAD
+ s4->str[1] = '?'; // BAD [NOT DETECTED]
+ s5->str[1] = '?'; // BAD [NOT DETECTED]
}
}
@@ -166,7 +166,7 @@ void useVarStruct34(varStruct5 *vs5) {
void testVarStruct34(varStruct3 *vs3, varStruct4 *vs4, varStruct5 *vs5, varStruct6 *vs6, varStruct7 *vs7, varStruct8 *vs8, varStruct9 *vs9) {
memset(vs3->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag
- memset(vs4->arr, 'x', 100); // BAD: it's not variable size, so this is a buffer overflow
+ memset(vs4->arr, 'x', 100); // BAD: [NOT DETECTED] it's not variable size, so this is a buffer overflow
memset(vs5->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag
memset(vs6->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag
memset(vs7->arr, 'x', 100); // GOOD: it's variable size, we don't know how big so shouldn't flag
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/varsize.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/varsize.expected
index d9e9effde62..79406c3eaef 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/varsize.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/varsize.expected
@@ -1,12 +1,17 @@
| var_size_struct.cpp:13:8:13:17 | VarString1 | var_size_struct.cpp:15:8:15:10 | str |
| var_size_struct.cpp:18:8:18:17 | VarString2 | var_size_struct.cpp:20:8:20:10 | str |
| var_size_struct.cpp:24:8:24:17 | VarString3 | var_size_struct.cpp:26:8:26:10 | str |
+| var_size_struct.cpp:30:8:30:17 | VarString4 | var_size_struct.cpp:32:8:32:10 | str |
+| var_size_struct.cpp:36:8:36:17 | VarString5 | var_size_struct.cpp:38:8:38:10 | str |
| var_size_struct.cpp:36:8:36:17 | VarString5 | var_size_struct.cpp:39:8:39:11 | str2 |
| var_size_struct.cpp:61:8:61:17 | varStruct1 | var_size_struct.cpp:63:8:63:11 | data |
| var_size_struct.cpp:76:8:76:17 | varStruct2 | var_size_struct.cpp:78:7:78:14 | elements |
+| var_size_struct.cpp:106:8:106:20 | notVarStruct2 | var_size_struct.cpp:107:8:107:10 | str |
| var_size_struct.cpp:119:8:119:17 | varStruct3 | var_size_struct.cpp:121:17:121:19 | arr |
+| var_size_struct.cpp:123:8:123:17 | varStruct4 | var_size_struct.cpp:125:17:125:19 | arr |
| var_size_struct.cpp:127:8:127:17 | varStruct5 | var_size_struct.cpp:129:17:129:19 | arr |
| var_size_struct.cpp:131:8:131:17 | varStruct6 | var_size_struct.cpp:133:17:133:19 | arr |
| var_size_struct.cpp:135:8:135:17 | varStruct7 | var_size_struct.cpp:137:17:137:19 | arr |
| var_size_struct.cpp:139:8:139:17 | varStruct8 | var_size_struct.cpp:141:9:141:11 | arr |
| var_size_struct.cpp:143:8:143:17 | varStruct9 | var_size_struct.cpp:145:17:145:19 | arr |
+| var_size_struct.cpp:181:8:181:18 | PseudoUnion | var_size_struct.cpp:183:7:183:10 | data |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected
new file mode 100644
index 00000000000..3534c2c7cad
--- /dev/null
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.expected
@@ -0,0 +1,49 @@
+edges
+| test3.cpp:68:21:68:29 | password1 | test3.cpp:70:15:70:17 | ptr |
+| test3.cpp:75:15:75:22 | password | test3.cpp:77:15:77:17 | ptr |
+| test3.cpp:106:20:106:25 | buffer | test3.cpp:108:14:108:19 | buffer |
+| test3.cpp:111:28:111:33 | buffer | test3.cpp:113:9:113:14 | buffer |
+| test3.cpp:120:9:120:23 | global_password | test3.cpp:138:16:138:29 | call to get_global_str |
+| test3.cpp:128:11:128:18 | password | test3.cpp:106:20:106:25 | buffer |
+| test3.cpp:132:21:132:22 | call to id | test3.cpp:134:15:134:17 | ptr |
+| test3.cpp:132:24:132:32 | password1 | test3.cpp:111:28:111:33 | buffer |
+| test3.cpp:132:24:132:32 | password1 | test3.cpp:132:21:132:22 | call to id |
+| test3.cpp:138:16:138:29 | call to get_global_str | test3.cpp:140:15:140:18 | data |
+| test3.cpp:151:19:151:26 | password | test3.cpp:153:15:153:20 | buffer |
+nodes
+| test3.cpp:20:15:20:23 | password1 | semmle.label | password1 |
+| test3.cpp:24:15:24:23 | password2 | semmle.label | password2 |
+| test3.cpp:41:15:41:22 | password | semmle.label | password |
+| test3.cpp:49:15:49:22 | password | semmle.label | password |
+| test3.cpp:68:21:68:29 | password1 | semmle.label | password1 |
+| test3.cpp:70:15:70:17 | ptr | semmle.label | ptr |
+| test3.cpp:75:15:75:22 | password | semmle.label | password |
+| test3.cpp:77:15:77:17 | ptr | semmle.label | ptr |
+| test3.cpp:95:12:95:19 | password | semmle.label | password |
+| test3.cpp:106:20:106:25 | buffer | semmle.label | buffer |
+| test3.cpp:108:14:108:19 | buffer | semmle.label | buffer |
+| test3.cpp:111:28:111:33 | buffer | semmle.label | buffer |
+| test3.cpp:113:9:113:14 | buffer | semmle.label | buffer |
+| test3.cpp:120:9:120:23 | global_password | semmle.label | global_password |
+| test3.cpp:128:11:128:18 | password | semmle.label | password |
+| test3.cpp:132:21:132:22 | call to id | semmle.label | call to id |
+| test3.cpp:132:24:132:32 | password1 | semmle.label | password1 |
+| test3.cpp:134:15:134:17 | ptr | semmle.label | ptr |
+| test3.cpp:138:16:138:29 | call to get_global_str | semmle.label | call to get_global_str |
+| test3.cpp:140:15:140:18 | data | semmle.label | data |
+| test3.cpp:151:19:151:26 | password | semmle.label | password |
+| test3.cpp:153:15:153:20 | buffer | semmle.label | buffer |
+subpaths
+| test3.cpp:132:24:132:32 | password1 | test3.cpp:111:28:111:33 | buffer | test3.cpp:113:9:113:14 | buffer | test3.cpp:132:21:132:22 | call to id |
+#select
+| test3.cpp:20:3:20:6 | call to send | test3.cpp:20:15:20:23 | password1 | test3.cpp:20:15:20:23 | password1 | This operation transmits 'password1', which may contain unencrypted sensitive data from $@ | test3.cpp:20:15:20:23 | password1 | password1 |
+| test3.cpp:24:3:24:6 | call to send | test3.cpp:24:15:24:23 | password2 | test3.cpp:24:15:24:23 | password2 | This operation transmits 'password2', which may contain unencrypted sensitive data from $@ | test3.cpp:24:15:24:23 | password2 | password2 |
+| test3.cpp:41:3:41:6 | call to recv | test3.cpp:41:15:41:22 | password | test3.cpp:41:15:41:22 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:41:15:41:22 | password | password |
+| test3.cpp:49:3:49:6 | call to recv | test3.cpp:49:15:49:22 | password | test3.cpp:49:15:49:22 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:49:15:49:22 | password | password |
+| test3.cpp:70:3:70:6 | call to send | test3.cpp:68:21:68:29 | password1 | test3.cpp:70:15:70:17 | ptr | This operation transmits 'ptr', which may contain unencrypted sensitive data from $@ | test3.cpp:68:21:68:29 | password1 | password1 |
+| test3.cpp:77:3:77:6 | call to recv | test3.cpp:75:15:75:22 | password | test3.cpp:77:15:77:17 | ptr | This operation receives into 'ptr', which may put unencrypted sensitive data into $@ | test3.cpp:75:15:75:22 | password | password |
+| test3.cpp:95:3:95:6 | call to read | test3.cpp:95:12:95:19 | password | test3.cpp:95:12:95:19 | password | This operation receives into 'password', which may put unencrypted sensitive data into $@ | test3.cpp:95:12:95:19 | password | password |
+| test3.cpp:108:2:108:5 | call to recv | test3.cpp:128:11:128:18 | password | test3.cpp:108:14:108:19 | buffer | This operation receives into 'buffer', which may put unencrypted sensitive data into $@ | test3.cpp:128:11:128:18 | password | password |
+| test3.cpp:134:3:134:6 | call to send | test3.cpp:132:24:132:32 | password1 | test3.cpp:134:15:134:17 | ptr | This operation transmits 'ptr', which may contain unencrypted sensitive data from $@ | test3.cpp:132:24:132:32 | password1 | password1 |
+| test3.cpp:140:3:140:6 | call to send | test3.cpp:120:9:120:23 | global_password | test3.cpp:140:15:140:18 | data | This operation transmits 'data', which may contain unencrypted sensitive data from $@ | test3.cpp:120:9:120:23 | global_password | global_password |
+| test3.cpp:153:3:153:6 | call to send | test3.cpp:151:19:151:26 | password | test3.cpp:153:15:153:20 | buffer | This operation transmits 'buffer', which may contain unencrypted sensitive data from $@ | test3.cpp:151:19:151:26 | password | password |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.qlref
new file mode 100644
index 00000000000..bb3fc66f1f1
--- /dev/null
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextTransmission.qlref
@@ -0,0 +1 @@
+Security/CWE/CWE-311/CleartextTransmission.ql
\ No newline at end of file
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp
new file mode 100644
index 00000000000..010ed2c8062
--- /dev/null
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test3.cpp
@@ -0,0 +1,155 @@
+
+typedef unsigned long size_t;
+#define STDIN_FILENO (0)
+
+size_t strlen(const char *s);
+
+void send(int fd, const void *buf, size_t bufLen, int d);
+void recv(int fd, void *buf, size_t bufLen, int d);
+void read(int fd, void *buf, size_t bufLen);
+
+void LogonUserA(int a, int b, const char *password, int d, int e, int f);
+
+int val();
+
+void test_send(const char *password1, const char *password2, const char *password_hash, const char *message)
+{
+ {
+ LogonUserA(val(), val(), password1, val(), val(), val()); // proof `password1` is plaintext
+
+ send(val(), password1, strlen(password1), val()); // BAD: `password1` is sent plaintext (certainly)
+ }
+
+ {
+ send(val(), password2, strlen(password2), val()); // BAD: `password2` is sent plaintext (probably)
+ }
+
+ {
+ send(val(), password_hash, strlen(password_hash), val()); // GOOD: `password_hash` is sent encrypted
+ }
+
+ {
+ send(val(), message, strlen(message), val()); // GOOD: `message` is not a password
+ }
+}
+
+void test_receive()
+{
+ {
+ char password[256];
+
+ recv(val(), password, 256, val()); // BAD: `password` is received plaintext (certainly)
+
+ LogonUserA(val(), val(), password, val(), val(), val()); // (proof `password` is plaintext)
+ }
+
+ {
+ char password[256];
+
+ recv(val(), password, 256, val()); // BAD: `password` is received plaintext (probably)
+ }
+
+ {
+ char password_hash[256];
+
+ recv(val(), password_hash, 256, val()); // GOOD: `password` is received encrypted
+ }
+
+ {
+ char message[256];
+
+ recv(val(), message, 256, val()); // GOOD: `message` is not a password
+ }
+}
+
+void test_dataflow(const char *password1)
+{
+ {
+ const char *ptr = password1;
+
+ send(val(), ptr, strlen(ptr), val()); // BAD: `password` is sent plaintext
+ }
+
+ {
+ char password[256];
+ char *ptr = password;
+
+ recv(val(), ptr, 256, val()); // BAD: `password` is received plaintext
+ }
+
+ {
+ char buffer[256];
+
+ recv(val(), buffer, 256, val()); // BAD: `password` is received plaintext [NOT DETECTED]
+
+ char *password = buffer;
+ }
+}
+
+void test_read()
+{
+ {
+ char password[256];
+ int fd = val();
+
+ read(fd, password, 256); // BAD: `password` is received plaintext
+ }
+
+ {
+ char password[256];
+ int fd = STDIN_FILENO;
+
+ read(fd, password, 256); // GOOD: `password` is received from stdin, not a network socket
+ }
+}
+
+void my_recv(char *buffer, size_t bufferSize)
+{
+ recv(val(), buffer, bufferSize, val());
+}
+
+const char *id(const char *buffer)
+{
+ return buffer;
+}
+
+char *global_password;
+
+char *get_global_str()
+{
+ return global_password;
+}
+
+void test_interprocedural(const char *password1)
+{
+ {
+ char password[256];
+
+ my_recv(password, 256); // BAD: `password` is received plaintext [detected on line 108]
+ }
+
+ {
+ const char *ptr = id(password1);
+
+ send(val(), ptr, strlen(ptr), val()); // BAD: `password1` is sent plaintext
+ }
+
+ {
+ char *data = get_global_str();
+
+ send(val(), data, strlen(data), val()); // BAD: `global_password` is sent plaintext
+ }
+}
+
+char *strncpy(char *s1, const char *s2, size_t n);
+
+void test_taint(const char *password)
+{
+ {
+ char buffer[16];
+
+ strncpy(buffer, password, 16);
+ buffer[15] = 0;
+ send(val(), buffer, 16, val()); // BAD: `password` is (partially) sent plaintext
+ }
+}
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-367/semmle/TOCTOUFilesystemRace.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-367/semmle/TOCTOUFilesystemRace.expected
index f0f7aaaefee..413d3dbccf9 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-367/semmle/TOCTOUFilesystemRace.expected
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-367/semmle/TOCTOUFilesystemRace.expected
@@ -5,9 +5,13 @@
| test2.cpp:130:7:130:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:130:13:130:16 | path | filename | test2.cpp:128:21:128:27 | buf_ptr | checked |
| test2.cpp:157:7:157:10 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:157:12:157:15 | path | filename | test2.cpp:155:6:155:9 | call to stat | checked |
| test2.cpp:170:7:170:10 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:170:12:170:15 | path | filename | test2.cpp:168:6:168:10 | call to lstat | checked |
-| test2.cpp:245:3:245:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:245:9:245:12 | path | filename | test2.cpp:238:6:238:10 | call to fopen | checked |
-| test2.cpp:277:7:277:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:277:13:277:16 | path | filename | test2.cpp:275:6:275:11 | call to access | checked |
-| test2.cpp:303:7:303:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:303:13:303:16 | path | filename | test2.cpp:301:7:301:12 | call to access | checked |
-| test2.cpp:317:7:317:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:317:13:317:16 | path | filename | test2.cpp:313:6:313:11 | call to access | checked |
-| test2.cpp:348:3:348:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:348:9:348:12 | path | filename | test2.cpp:341:6:341:10 | call to fopen | checked |
-| test2.cpp:356:3:356:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:356:9:356:13 | path2 | filename | test2.cpp:354:7:354:12 | call to rename | checked |
+| test2.cpp:209:7:209:10 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:209:12:209:15 | path | filename | test2.cpp:207:6:207:9 | call to stat | checked |
+| test2.cpp:228:8:228:11 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:228:13:228:16 | path | filename | test2.cpp:224:6:224:9 | call to stat | checked |
+| test2.cpp:228:8:228:11 | call to open | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:228:13:228:16 | path | filename | test2.cpp:226:7:226:9 | buf | checked |
+| test2.cpp:249:6:249:10 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:249:12:249:15 | path | filename | test2.cpp:244:6:244:9 | call to stat | checked |
+| test2.cpp:297:3:297:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:297:9:297:12 | path | filename | test2.cpp:290:6:290:10 | call to fopen | checked |
+| test2.cpp:329:7:329:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:329:13:329:16 | path | filename | test2.cpp:327:6:327:11 | call to access | checked |
+| test2.cpp:355:7:355:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:355:13:355:16 | path | filename | test2.cpp:353:7:353:12 | call to access | checked |
+| test2.cpp:369:7:369:11 | call to fopen | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:369:13:369:16 | path | filename | test2.cpp:365:6:365:11 | call to access | checked |
+| test2.cpp:400:3:400:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:400:9:400:12 | path | filename | test2.cpp:393:6:393:10 | call to fopen | checked |
+| test2.cpp:408:3:408:7 | call to chmod | The $@ being operated upon was previously $@, but the underlying file may have been changed since then. | test2.cpp:408:9:408:13 | path2 | filename | test2.cpp:406:7:406:12 | call to rename | checked |
diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-367/semmle/test2.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-367/semmle/test2.cpp
index e1317e9a9ca..14875b9d367 100644
--- a/cpp/ql/test/query-tests/Security/CWE/CWE-367/semmle/test2.cpp
+++ b/cpp/ql/test/query-tests/Security/CWE/CWE-367/semmle/test2.cpp
@@ -199,6 +199,58 @@ void test2_10(int dir, const char *path, int arg)
// ...
}
+void test2_11(const char *path, int arg)
+{
+ stat_data buf;
+ int f;
+
+ if (stat(path, &buf))
+ {
+ f = open(path, arg); // GOOD (here stat is just a redundant check that the file exists / path is valid, confirmed by the return value of open) [FALSE POSITIVE]
+ if (f == -1)
+ {
+ // handle error
+ }
+
+ // ...
+ }
+}
+
+void test2_12(const char *path, int arg)
+{
+ stat_data buf;
+ int f;
+
+ if (stat(path, &buf))
+ {
+ if (buf.foo == 11) // check a property of the file
+ {
+ f = open(path, arg); // BAD
+ if (f == -1)
+ {
+ // handle error
+ }
+ }
+
+ // ...
+ }
+}
+
+void test2_13(const char *path, int arg)
+{
+ stat_data buf;
+ FILE *f;
+
+ if (stat(path, &buf)) // check the file does *not* exist
+ {
+ return;
+ }
+
+ f = fopen(path, "wt"); // BAD
+
+ // ...
+}
+
// --- open -> stat ---
void test3_1(const char *path, int arg)
diff --git a/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/old.dbscheme b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/old.dbscheme
new file mode 100644
index 00000000000..7806a11dd7a
--- /dev/null
+++ b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/old.dbscheme
@@ -0,0 +1,2136 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The date of the snapshot.
+ */
+snapshotDate(unique date snapshotDate : date ref);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Data used by the 'duplicate code' detection.
+ */
+duplicateCode(
+ unique int id : @duplication,
+ string relativePath : string ref,
+ int equivClass : int ref
+);
+
+/**
+ * Data used by the 'similar code' detection.
+ */
+similarCode(
+ unique int id : @similarity,
+ string relativePath : string ref,
+ int equivClass : int ref
+);
+
+/**
+ * Data used by the 'duplicate code' and 'similar code' detection.
+ */
+@duplication_or_similarity = @duplication | @similarity
+
+/**
+ * Data used by the 'duplicate code' and 'similar code' detection.
+ */
+#keyset[id, offset]
+tokens(
+ int id : @duplication_or_similarity ref,
+ int offset : int ref,
+ int beginLine : int ref,
+ int beginColumn : int ref,
+ int endLine : int ref,
+ int endColumn : int ref
+);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+/*
+ case @macroinvocations.kind of
+ 1 = macro expansion
+ | 2 = other macro reference
+ ;
+*/
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+ case @function.kind of
+ 1 = normal
+ | 2 = constructor
+ | 3 = destructor
+ | 4 = conversion
+ | 5 = operator
+ | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk
+ ;
+*/
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(int id: @function ref, unique int entry_point: @stmt ref);
+
+function_return_type(int id: @function ref, int return_type: @type ref);
+
+/** If `function` is a coroutine, then this gives the
+ std::experimental::resumable_traits instance associated with it,
+ and the variables representing the `handle` and `promise` for it. */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref,
+ int handle: @variable ref,
+ int promise: @variable ref
+);
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+member_function_this_type(unique int id: @function ref, int this_type: @type ref);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @functionorblock ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(int new: @function ref, int old: @function ref);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/*
+ Built-in types are the fundamental types, e.g., integral, floating, and void.
+
+ case @builtintype.kind of
+ 1 = error
+ | 2 = unknown
+ | 3 = void
+ | 4 = boolean
+ | 5 = char
+ | 6 = unsigned_char
+ | 7 = signed_char
+ | 8 = short
+ | 9 = unsigned_short
+ | 10 = signed_short
+ | 11 = int
+ | 12 = unsigned_int
+ | 13 = signed_int
+ | 14 = long
+ | 15 = unsigned_long
+ | 16 = signed_long
+ | 17 = long_long
+ | 18 = unsigned_long_long
+ | 19 = signed_long_long
+ | 20 = __int8 // Microsoft-specific
+ | 21 = __int16 // Microsoft-specific
+ | 22 = __int32 // Microsoft-specific
+ | 23 = __int64 // Microsoft-specific
+ | 24 = float
+ | 25 = double
+ | 26 = long_double
+ | 27 = _Complex_float // C99-specific
+ | 28 = _Complex_double // C99-specific
+ | 29 = _Complex_long double // C99-specific
+ | 30 = _Imaginary_float // C99-specific
+ | 31 = _Imaginary_double // C99-specific
+ | 32 = _Imaginary_long_double // C99-specific
+ | 33 = wchar_t // Microsoft-specific
+ | 34 = decltype_nullptr // C++11
+ | 35 = __int128
+ | 36 = unsigned___int128
+ | 37 = signed___int128
+ | 38 = __float128
+ | 39 = _Complex___float128
+ | 40 = _Decimal32
+ | 41 = _Decimal64
+ | 42 = _Decimal128
+ | 43 = char16_t
+ | 44 = char32_t
+ | 45 = _Float32
+ | 46 = _Float32x
+ | 47 = _Float64
+ | 48 = _Float64x
+ | 49 = _Float128
+ | 50 = _Float128x
+ | 51 = char8_t
+ ;
+*/
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/*
+ Derived types are types that are directly derived from existing types and
+ point to, refer to, transform type data to return a new type.
+
+ case @derivedtype.kind of
+ 1 = pointer
+ | 2 = reference
+ | 3 = type_with_specifiers
+ | 4 = array
+ | 5 = gnu_vector
+ | 6 = routineptr
+ | 7 = routinereference
+ | 8 = rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+ | 10 = block
+ ;
+*/
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * would change the semantics of this decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+ case @usertype.kind of
+ 1 = struct
+ | 2 = class
+ | 3 = union
+ | 4 = enum
+ | 5 = typedef // classic C: typedef typedef type name
+ | 6 = template
+ | 7 = template_parameter
+ | 8 = template_template_parameter
+ | 9 = proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+ | 13 = scoped_enum
+ | 14 = using_alias // a using name = type style typedef
+ ;
+*/
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ unique string uuid: string ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ unique int templ_param_id: @usertype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+/*
+ Fixed point types
+ precision(1) = short, precision(2) = default, precision(3) = long
+ is_unsigned(1) = unsigned is_unsigned(2) = signed
+ is_fract_type(1) = declared with _Fract
+ saturating(1) = declared with _Sat
+*/
+/* TODO
+fixedpointtypes(
+ unique int id: @fixedpointtype,
+ int precision: int ref,
+ int is_unsigned: int ref,
+ int is_fract_type: int ref,
+ int saturating: int ref);
+*/
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ /* TODO | @fixedpointtype */
+ | @routinetype
+ | @ptrtomember
+ | @decltype;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(unique int caller: @funbindexpr ref, int kind: int ref);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ | @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr
+
+@assign_expr = @assignexpr | @assign_op_expr
+
+/*
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 3 = size_and_alignment
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ ;
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union.
+ */
+#keyset[aggregate, field]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array.
+ */
+#keyset[aggregate, element_index]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof;
+
+sizeof_bind(
+ unique int expr: @runtime_sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+for_initialization(
+ unique int for_stmt: @stmt_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@functionorblock = @function | @stmt_block;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @functionorblock ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ unique int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* XML Files */
+
+xmlEncoding(unique int id: @file ref, string encoding: string ref);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters
+ | @xmlelement
+ | @xmlcomment
+ | @xmlattribute
+ | @xmldtd
+ | @file
+ | @xmlnamespace;
diff --git a/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/semmlecode.cpp.dbscheme b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/semmlecode.cpp.dbscheme
new file mode 100644
index 00000000000..018f430097e
--- /dev/null
+++ b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/semmlecode.cpp.dbscheme
@@ -0,0 +1,2136 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The date of the snapshot.
+ */
+snapshotDate(unique date snapshotDate : date ref);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Data used by the 'duplicate code' detection.
+ */
+duplicateCode(
+ unique int id : @duplication,
+ string relativePath : string ref,
+ int equivClass : int ref
+);
+
+/**
+ * Data used by the 'similar code' detection.
+ */
+similarCode(
+ unique int id : @similarity,
+ string relativePath : string ref,
+ int equivClass : int ref
+);
+
+/**
+ * Data used by the 'duplicate code' and 'similar code' detection.
+ */
+@duplication_or_similarity = @duplication | @similarity
+
+/**
+ * Data used by the 'duplicate code' and 'similar code' detection.
+ */
+#keyset[id, offset]
+tokens(
+ int id : @duplication_or_similarity ref,
+ int offset : int ref,
+ int beginLine : int ref,
+ int beginColumn : int ref,
+ int endLine : int ref,
+ int endColumn : int ref
+);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+/*
+ case @macroinvocations.kind of
+ 1 = macro expansion
+ | 2 = other macro reference
+ ;
+*/
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+ case @function.kind of
+ 1 = normal
+ | 2 = constructor
+ | 3 = destructor
+ | 4 = conversion
+ | 5 = operator
+ | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk
+ ;
+*/
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(int id: @function ref, unique int entry_point: @stmt ref);
+
+function_return_type(int id: @function ref, int return_type: @type ref);
+
+/** If `function` is a coroutine, then this gives the
+ std::experimental::resumable_traits instance associated with it,
+ and the variables representing the `handle` and `promise` for it. */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref,
+ int handle: @variable ref,
+ int promise: @variable ref
+);
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+member_function_this_type(unique int id: @function ref, int this_type: @type ref);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @functionorblock ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(int new: @function ref, int old: @function ref);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/*
+ Built-in types are the fundamental types, e.g., integral, floating, and void.
+
+ case @builtintype.kind of
+ 1 = error
+ | 2 = unknown
+ | 3 = void
+ | 4 = boolean
+ | 5 = char
+ | 6 = unsigned_char
+ | 7 = signed_char
+ | 8 = short
+ | 9 = unsigned_short
+ | 10 = signed_short
+ | 11 = int
+ | 12 = unsigned_int
+ | 13 = signed_int
+ | 14 = long
+ | 15 = unsigned_long
+ | 16 = signed_long
+ | 17 = long_long
+ | 18 = unsigned_long_long
+ | 19 = signed_long_long
+ | 20 = __int8 // Microsoft-specific
+ | 21 = __int16 // Microsoft-specific
+ | 22 = __int32 // Microsoft-specific
+ | 23 = __int64 // Microsoft-specific
+ | 24 = float
+ | 25 = double
+ | 26 = long_double
+ | 27 = _Complex_float // C99-specific
+ | 28 = _Complex_double // C99-specific
+ | 29 = _Complex_long double // C99-specific
+ | 30 = _Imaginary_float // C99-specific
+ | 31 = _Imaginary_double // C99-specific
+ | 32 = _Imaginary_long_double // C99-specific
+ | 33 = wchar_t // Microsoft-specific
+ | 34 = decltype_nullptr // C++11
+ | 35 = __int128
+ | 36 = unsigned___int128
+ | 37 = signed___int128
+ | 38 = __float128
+ | 39 = _Complex___float128
+ | 40 = _Decimal32
+ | 41 = _Decimal64
+ | 42 = _Decimal128
+ | 43 = char16_t
+ | 44 = char32_t
+ | 45 = _Float32
+ | 46 = _Float32x
+ | 47 = _Float64
+ | 48 = _Float64x
+ | 49 = _Float128
+ | 50 = _Float128x
+ | 51 = char8_t
+ ;
+*/
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/*
+ Derived types are types that are directly derived from existing types and
+ point to, refer to, transform type data to return a new type.
+
+ case @derivedtype.kind of
+ 1 = pointer
+ | 2 = reference
+ | 3 = type_with_specifiers
+ | 4 = array
+ | 5 = gnu_vector
+ | 6 = routineptr
+ | 7 = routinereference
+ | 8 = rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+ | 10 = block
+ ;
+*/
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * would change the semantics of this decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+ case @usertype.kind of
+ 1 = struct
+ | 2 = class
+ | 3 = union
+ | 4 = enum
+ | 5 = typedef // classic C: typedef typedef type name
+ | 6 = template
+ | 7 = template_parameter
+ | 8 = template_template_parameter
+ | 9 = proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+ | 13 = scoped_enum
+ | 14 = using_alias // a using name = type style typedef
+ ;
+*/
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ unique string uuid: string ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ unique int templ_param_id: @usertype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+/*
+ Fixed point types
+ precision(1) = short, precision(2) = default, precision(3) = long
+ is_unsigned(1) = unsigned is_unsigned(2) = signed
+ is_fract_type(1) = declared with _Fract
+ saturating(1) = declared with _Sat
+*/
+/* TODO
+fixedpointtypes(
+ unique int id: @fixedpointtype,
+ int precision: int ref,
+ int is_unsigned: int ref,
+ int is_fract_type: int ref,
+ int saturating: int ref);
+*/
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ /* TODO | @fixedpointtype */
+ | @routinetype
+ | @ptrtomember
+ | @decltype;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(unique int caller: @funbindexpr ref, int kind: int ref);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ | @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr
+
+@assign_expr = @assignexpr | @assign_op_expr
+
+/*
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 3 = size_and_alignment
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ ;
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union.
+ */
+#keyset[aggregate, field]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array.
+ */
+#keyset[aggregate, element_index]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof;
+
+sizeof_bind(
+ unique int expr: @runtime_sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+for_initialization(
+ unique int for_stmt: @stmt_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@functionorblock = @function | @stmt_block;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @functionorblock ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ unique int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* XML Files */
+
+xmlEncoding(unique int id: @file ref, string encoding: string ref);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters
+ | @xmlelement
+ | @xmlcomment
+ | @xmlattribute
+ | @xmldtd
+ | @file
+ | @xmlnamespace;
diff --git a/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/upgrade.properties b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/upgrade.properties
new file mode 100644
index 00000000000..63872bd6f10
--- /dev/null
+++ b/cpp/upgrades/7806a11dd7ab6611c4245b2e96b8ed13cb5c6056/upgrade.properties
@@ -0,0 +1,2 @@
+description: Non-functional change to dbscheme comments
+compatibility: full
diff --git a/cpp/upgrades/qlpack.yml b/cpp/upgrades/qlpack.yml
index acc305bb6a2..7f18cb54c8e 100644
--- a/cpp/upgrades/qlpack.yml
+++ b/cpp/upgrades/qlpack.yml
@@ -1,3 +1,4 @@
name: codeql/cpp-upgrades
upgrades: .
version: 0.0.2
+library: true
diff --git a/csharp/change-notes/2021-10-04-constand-condition.md b/csharp/change-notes/2021-10-04-constand-condition.md
new file mode 100644
index 00000000000..70ad5b5ea75
--- /dev/null
+++ b/csharp/change-notes/2021-10-04-constand-condition.md
@@ -0,0 +1,2 @@
+lgtm,codescanning
+* Discards in tuple patterns, for example `(_, string s)`, are no longer flagged by the query "Constant condition".
\ No newline at end of file
diff --git a/csharp/change-notes/2021-10-04-dead-store-of-local.md b/csharp/change-notes/2021-10-04-dead-store-of-local.md
new file mode 100644
index 00000000000..307f10af654
--- /dev/null
+++ b/csharp/change-notes/2021-10-04-dead-store-of-local.md
@@ -0,0 +1,2 @@
+lgtm,codescanning
+* `using` declarations are no longer flagged by the query "Useless assignment to local variable".
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs
index a478047ac7b..123bc315bfa 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs
@@ -178,7 +178,13 @@ namespace Semmle.Extraction.CSharp.Entities
var defaultValue = parameter.ExplicitDefaultValue;
- if (parameter.Type is INamedTypeSymbol nt && nt.EnumUnderlyingType is not null)
+ var type = parameter.Type;
+ if (type.IsBoundNullable() && type is INamedTypeSymbol named)
+ {
+ type = named.TypeArguments[0];
+ }
+
+ if (type is INamedTypeSymbol nt && nt.EnumUnderlyingType is not null)
{
// = (MyEnum)1, = MyEnum.Value1, = default(MyEnum), = new MyEnum()
// we're generating a (MyEnum)value cast expression:
@@ -194,7 +200,7 @@ namespace Semmle.Extraction.CSharp.Entities
return Default.CreateGenerated(cx, parent, childIndex, location, parameter.Type.IsReferenceType ? ValueAsString(null) : null);
}
- if (parameter.Type.SpecialType == SpecialType.System_Object)
+ if (parameter.Type.SpecialType is SpecialType.System_Object)
{
// this can happen in VB.NET
cx.ExtractionError($"Extracting default argument value 'object {parameter.Name} = default' instead of 'object {parameter.Name} = {defaultValue}'. The latter is not supported in C#.",
@@ -205,7 +211,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
// const literal:
- return Literal.CreateGenerated(cx, parent, childIndex, parameter.Type, defaultValue, location);
+ return Literal.CreateGenerated(cx, parent, childIndex, type, defaultValue, location);
}
///
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs
index 63389822cad..a92715c4e1c 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs
@@ -14,7 +14,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
{
if (info.Node is null)
{
- info.Context.ModelError("Attempt to create a null expression");
+ info.Context.ModelError(info.Location, "Attempt to create a null expression");
return new Unknown(info);
}
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Literal.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Literal.cs
index bac257e9e34..387e8074f5f 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Literal.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Literal.cs
@@ -32,10 +32,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
var type = info.Type?.Symbol;
- return GetExprKind(type, info.Node, info.Context);
+ return GetExprKind(type, info.Node, info.Location, info.Context);
}
- private static ExprKind GetExprKind(ITypeSymbol? type, ExpressionSyntax? expr, Context context)
+ private static ExprKind GetExprKind(ITypeSymbol? type, ExpressionSyntax? expr, Extraction.Entities.Location loc, Context context)
{
switch (type?.SpecialType)
{
@@ -75,10 +75,11 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
case null:
default:
+ var kind = type?.SpecialType.ToString() ?? "null";
if (expr is not null)
- context.ModelError(expr, "Unhandled literal type");
+ context.ModelError(expr, $"Unhandled literal type {kind}");
else
- context.ModelError("Unhandled literal type");
+ context.ModelError(loc, $"Unhandled literal type {kind}");
return ExprKind.UNKNOWN;
}
}
@@ -86,11 +87,12 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, ITypeSymbol type, object? value,
Extraction.Entities.Location location)
{
+ var kind = value is null ? ExprKind.NULL_LITERAL : GetExprKind(type, null, location, cx);
var info = new ExpressionInfo(
cx,
AnnotatedTypeSymbol.CreateNotAnnotated(type),
location,
- GetExprKind(type, null, cx),
+ kind,
parent,
childIndex,
true,
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs
index d01a3f37ac8..3140815d323 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Extractor.cs
@@ -492,8 +492,18 @@ namespace Semmle.Extraction.CSharp
///
/// Gets a list of all `csharp.{hash}.txt` files currently written to the log directory.
///
- public static IEnumerable GetCSharpArgsLogs() =>
- Directory.EnumerateFiles(GetCSharpLogDirectory(), "csharp.*.txt");
+ public static IEnumerable GetCSharpArgsLogs()
+ {
+ try
+ {
+ return Directory.EnumerateFiles(GetCSharpLogDirectory(), "csharp.*.txt");
+ }
+ catch (DirectoryNotFoundException)
+ {
+ // If the directory does not exist, there are no log files
+ return Enumerable.Empty();
+ }
+ }
private static string GetCSharpLogDirectory()
{
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs
index 6116c3511a1..be53e48f319 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs
@@ -59,8 +59,15 @@ namespace Semmle.Extraction.CSharp.Populators
return;
}
- var entryPoint = Cx.Compilation.GetEntryPoint(System.Threading.CancellationToken.None)!;
+ var entryPoint = Cx.Compilation.GetEntryPoint(System.Threading.CancellationToken.None);
var entryMethod = Method.Create(Cx, entryPoint);
+ if (entryMethod is null)
+ {
+ Cx.ExtractionError("No entry method found. Skipping the extraction of global statements.",
+ null, Cx.CreateLocation(globalStatements[0].GetLocation()), null, Severity.Info);
+ return;
+ }
+
var block = GlobalStatementsBlock.Create(Cx, entryMethod);
for (var i = 0; i < globalStatements.Count; i++)
diff --git a/csharp/extractor/Semmle.Extraction/Context.cs b/csharp/extractor/Semmle.Extraction/Context.cs
index abbabcdd198..99da916d294 100644
--- a/csharp/extractor/Semmle.Extraction/Context.cs
+++ b/csharp/extractor/Semmle.Extraction/Context.cs
@@ -426,6 +426,16 @@ namespace Semmle.Extraction
ReportError(new InternalError(symbol, msg));
}
+ ///
+ /// Signal an error in the program model.
+ ///
+ /// The location of the error.
+ /// The error message.
+ public void ModelError(Entities.Location loc, string msg)
+ {
+ ReportError(new InternalError(loc.ReportingLocation, msg));
+ }
+
///
/// Signal an error in the program model.
///
diff --git a/csharp/extractor/Semmle.Extraction/InternalError.cs b/csharp/extractor/Semmle.Extraction/InternalError.cs
index a90685e068f..fe9701488c7 100644
--- a/csharp/extractor/Semmle.Extraction/InternalError.cs
+++ b/csharp/extractor/Semmle.Extraction/InternalError.cs
@@ -23,6 +23,13 @@ namespace Semmle.Extraction
Location = node.GetLocation();
}
+ public InternalError(Location? loc, string msg)
+ {
+ Text = msg;
+ EntityText = "";
+ Location = loc;
+ }
+
public InternalError(string msg)
{
Text = msg;
diff --git a/csharp/ql/examples/qlpack.yml b/csharp/ql/examples/qlpack.yml
index 573e7a673d0..fd3bccb2005 100644
--- a/csharp/ql/examples/qlpack.yml
+++ b/csharp/ql/examples/qlpack.yml
@@ -1,4 +1,4 @@
-name: codeql-csharp-examples
+name: codeql/csharp-examples
version: 0.0.2
dependencies:
codeql/csharp-all: "*"
diff --git a/csharp/ql/lib/semmle/code/asp/WebConfig.qll b/csharp/ql/lib/semmle/code/asp/WebConfig.qll
index ed0f9aef451..16d5393afc2 100644
--- a/csharp/ql/lib/semmle/code/asp/WebConfig.qll
+++ b/csharp/ql/lib/semmle/code/asp/WebConfig.qll
@@ -8,7 +8,7 @@ import csharp
* A `Web.config` file.
*/
class WebConfigXML extends XMLFile {
- WebConfigXML() { getName().matches("%Web.config") }
+ WebConfigXML() { this.getName().matches("%Web.config") }
}
/** A `` tag in an ASP.NET configuration file. */
@@ -73,12 +73,14 @@ class FormsElement extends XMLElement {
/**
* Gets attribute's `requireSSL` value.
*/
- string getRequireSSL() { result = getAttribute("requireSSL").getValue().trim().toLowerCase() }
+ string getRequireSSL() {
+ result = this.getAttribute("requireSSL").getValue().trim().toLowerCase()
+ }
/**
* Holds if `requireSSL` value is true.
*/
- predicate isRequireSSL() { getRequireSSL() = "true" }
+ predicate isRequireSSL() { this.getRequireSSL() = "true" }
}
/** A `` tag in an ASP.NET configuration file. */
@@ -89,26 +91,28 @@ class HttpCookiesElement extends XMLElement {
* Gets attribute's `httpOnlyCookies` value.
*/
string getHttpOnlyCookies() {
- result = getAttribute("httpOnlyCookies").getValue().trim().toLowerCase()
+ result = this.getAttribute("httpOnlyCookies").getValue().trim().toLowerCase()
}
/**
* Holds if there is any chance that `httpOnlyCookies` is set to `true`.
*/
- predicate isHttpOnlyCookies() { getHttpOnlyCookies() = "true" }
+ predicate isHttpOnlyCookies() { this.getHttpOnlyCookies() = "true" }
/**
* Gets attribute's `requireSSL` value.
*/
- string getRequireSSL() { result = getAttribute("requireSSL").getValue().trim().toLowerCase() }
+ string getRequireSSL() {
+ result = this.getAttribute("requireSSL").getValue().trim().toLowerCase()
+ }
/**
* Holds if there is any chance that `requireSSL` is set to `true` either globally or for Forms.
*/
predicate isRequireSSL() {
- getRequireSSL() = "true"
+ this.getRequireSSL() = "true"
or
- not getRequireSSL() = "false" and // not set all, i.e. default
- exists(FormsElement forms | forms.getFile() = getFile() | forms.isRequireSSL())
+ not this.getRequireSSL() = "false" and // not set all, i.e. default
+ exists(FormsElement forms | forms.getFile() = this.getFile() | forms.isRequireSSL())
}
}
diff --git a/csharp/ql/lib/semmle/code/cil/Access.qll b/csharp/ql/lib/semmle/code/cil/Access.qll
index 6d72a48ff1b..5fecd8acb10 100644
--- a/csharp/ql/lib/semmle/code/cil/Access.qll
+++ b/csharp/ql/lib/semmle/code/cil/Access.qll
@@ -20,7 +20,7 @@ class VariableAccess extends Access, @cil_access { }
/** An instruction that reads a variable. */
class ReadAccess extends VariableAccess, Expr, @cil_read_access {
- override Type getType() { result = getTarget().getType() }
+ override Type getType() { result = this.getTarget().getType() }
}
/** An instruction yielding an address. */
@@ -49,7 +49,7 @@ class ParameterReadAccess extends ParameterAccess, ReadAccess {
class ParameterWriteAccess extends ParameterAccess, WriteAccess {
override int getPopCount() { result = 1 }
- override Expr getExpr() { result = getOperand(0) }
+ override Expr getExpr() { result = this.getOperand(0) }
}
/** An access to the `this` parameter. */
@@ -71,9 +71,9 @@ class LocalVariableAccess extends StackVariableAccess, @cil_local_access {
class LocalVariableWriteAccess extends LocalVariableAccess, WriteAccess {
override int getPopCount() { result = 1 }
- override Expr getExpr() { result = getOperand(0) }
+ override Expr getExpr() { result = this.getOperand(0) }
- override string getExtra() { result = "L" + getTarget().getIndex() }
+ override string getExtra() { result = "L" + this.getTarget().getIndex() }
}
/** An instruction that reads a local variable. */
@@ -85,7 +85,7 @@ class LocalVariableReadAccess extends LocalVariableAccess, ReadAccess {
class FieldAccess extends VariableAccess, @cil_field_access {
override Field getTarget() { result = VariableAccess.super.getTarget() }
- override string getExtra() { result = getTarget().getName() }
+ override string getExtra() { result = this.getTarget().getName() }
/** Gets the qualifier of the access, if any. */
abstract Expr getQualifier();
diff --git a/csharp/ql/lib/semmle/code/cil/BasicBlock.qll b/csharp/ql/lib/semmle/code/cil/BasicBlock.qll
index 0c9c0b8ad07..2680cb0a769 100644
--- a/csharp/ql/lib/semmle/code/cil/BasicBlock.qll
+++ b/csharp/ql/lib/semmle/code/cil/BasicBlock.qll
@@ -10,7 +10,7 @@ private import CIL
*/
class BasicBlock extends Cached::TBasicBlockStart {
/** Gets an immediate successor of this basic block, if any. */
- BasicBlock getASuccessor() { result.getFirstNode() = getLastNode().getASuccessor() }
+ BasicBlock getASuccessor() { result.getFirstNode() = this.getLastNode().getASuccessor() }
/** Gets an immediate predecessor of this basic block, if any. */
BasicBlock getAPredecessor() { result.getASuccessor() = this }
@@ -31,7 +31,7 @@ class BasicBlock extends Cached::TBasicBlockStart {
* The basic block on line 2 is an immediate `true` successor of the
* basic block on line 1.
*/
- BasicBlock getATrueSuccessor() { result.getFirstNode() = getLastNode().getTrueSuccessor() }
+ BasicBlock getATrueSuccessor() { result.getFirstNode() = this.getLastNode().getTrueSuccessor() }
/**
* Gets an immediate `false` successor, if any.
@@ -49,22 +49,22 @@ class BasicBlock extends Cached::TBasicBlockStart {
* The basic block on line 2 is an immediate `false` successor of the
* basic block on line 1.
*/
- BasicBlock getAFalseSuccessor() { result.getFirstNode() = getLastNode().getFalseSuccessor() }
+ BasicBlock getAFalseSuccessor() { result.getFirstNode() = this.getLastNode().getFalseSuccessor() }
/** Gets the control flow node at a specific (zero-indexed) position in this basic block. */
- ControlFlowNode getNode(int pos) { Cached::bbIndex(getFirstNode(), result, pos) }
+ ControlFlowNode getNode(int pos) { Cached::bbIndex(this.getFirstNode(), result, pos) }
/** Gets a control flow node in this basic block. */
- ControlFlowNode getANode() { result = getNode(_) }
+ ControlFlowNode getANode() { result = this.getNode(_) }
/** Gets the first control flow node in this basic block. */
ControlFlowNode getFirstNode() { this = Cached::TBasicBlockStart(result) }
/** Gets the last control flow node in this basic block. */
- ControlFlowNode getLastNode() { result = getNode(length() - 1) }
+ ControlFlowNode getLastNode() { result = this.getNode(this.length() - 1) }
/** Gets the length of this basic block. */
- int length() { result = strictcount(getANode()) }
+ int length() { result = strictcount(this.getANode()) }
/**
* Holds if this basic block strictly dominates basic block `bb`.
@@ -114,7 +114,7 @@ class BasicBlock extends Cached::TBasicBlockStart {
*/
predicate dominates(BasicBlock bb) {
bb = this or
- strictlyDominates(bb)
+ this.strictlyDominates(bb)
}
/**
@@ -140,14 +140,14 @@ class BasicBlock extends Cached::TBasicBlockStart {
* does not dominate the basic block on line 6.
*/
predicate inDominanceFrontier(BasicBlock df) {
- dominatesPredecessor(df) and
- not strictlyDominates(df)
+ this.dominatesPredecessor(df) and
+ not this.strictlyDominates(df)
}
/**
* Holds if this basic block dominates a predecessor of `df`.
*/
- private predicate dominatesPredecessor(BasicBlock df) { dominates(df.getAPredecessor()) }
+ private predicate dominatesPredecessor(BasicBlock df) { this.dominates(df.getAPredecessor()) }
/**
* Gets the basic block that immediately dominates this basic block, if any.
@@ -226,7 +226,7 @@ class BasicBlock extends Cached::TBasicBlockStart {
* post-dominates itself.
*/
predicate postDominates(BasicBlock bb) {
- strictlyPostDominates(bb) or
+ this.strictlyPostDominates(bb) or
this = bb
}
@@ -239,7 +239,7 @@ class BasicBlock extends Cached::TBasicBlockStart {
predicate inLoop() { this.getASuccessor+() = this }
/** Gets a textual representation of this basic block. */
- string toString() { result = getFirstNode().toString() }
+ string toString() { result = this.getFirstNode().toString() }
/** Gets the location of this basic block. */
Location getLocation() { result = this.getFirstNode().getLocation() }
@@ -325,16 +325,16 @@ private predicate exitBB(BasicBlock bb) { not exists(bb.getLastNode().getASucces
* A basic block with more than one predecessor.
*/
class JoinBlock extends BasicBlock {
- JoinBlock() { getFirstNode().isJoin() }
+ JoinBlock() { this.getFirstNode().isJoin() }
}
/** A basic block that terminates in a condition, splitting the subsequent control flow. */
class ConditionBlock extends BasicBlock {
ConditionBlock() {
exists(BasicBlock succ |
- succ = getATrueSuccessor()
+ succ = this.getATrueSuccessor()
or
- succ = getAFalseSuccessor()
+ succ = this.getAFalseSuccessor()
)
}
@@ -380,16 +380,16 @@ class ConditionBlock extends BasicBlock {
*/
exists(BasicBlock succ |
- isCandidateSuccessor(succ, testIsTrue) and
+ this.isCandidateSuccessor(succ, testIsTrue) and
succ.dominates(controlled)
)
}
private predicate isCandidateSuccessor(BasicBlock succ, boolean testIsTrue) {
(
- testIsTrue = true and succ = getATrueSuccessor()
+ testIsTrue = true and succ = this.getATrueSuccessor()
or
- testIsTrue = false and succ = getAFalseSuccessor()
+ testIsTrue = false and succ = this.getAFalseSuccessor()
) and
forall(BasicBlock pred | pred = succ.getAPredecessor() and pred != this | succ.dominates(pred))
}
diff --git a/csharp/ql/lib/semmle/code/cil/ConsistencyChecks.qll b/csharp/ql/lib/semmle/code/cil/ConsistencyChecks.qll
index 02cfd149886..262bb58ab9c 100644
--- a/csharp/ql/lib/semmle/code/cil/ConsistencyChecks.qll
+++ b/csharp/ql/lib/semmle/code/cil/ConsistencyChecks.qll
@@ -62,7 +62,7 @@ abstract class InstructionViolation extends CfgViolation, CfgCheck {
override string toString() {
result =
instruction.getImplementation().getMethod().toStringWithTypes() + ": " +
- instruction.toString() + ", " + getInstructionsUpTo()
+ instruction.toString() + ", " + this.getInstructionsUpTo()
}
}
@@ -126,7 +126,7 @@ class MissingOperand extends InstructionViolation {
}
override string getMessage() {
- result = "This instruction is missing operand " + getMissingOperand()
+ result = "This instruction is missing operand " + this.getMissingOperand()
}
}
@@ -364,7 +364,7 @@ class TypeViolation extends ConsistencyViolation, TypeCheck {
/** Gets the type containing the violation. */
Type getType() { this = TypeCheck(result) }
- override string toString() { result = getType().toString() }
+ override string toString() { result = this.getType().toString() }
abstract override string getMessage();
}
@@ -374,7 +374,7 @@ class TypeViolation extends ConsistencyViolation, TypeCheck {
*/
class TypeIsBothConstructedAndUnbound extends TypeViolation {
TypeIsBothConstructedAndUnbound() {
- getType() instanceof ConstructedGeneric and getType() instanceof UnboundGeneric
+ this.getType() instanceof ConstructedGeneric and this.getType() instanceof UnboundGeneric
}
override string getMessage() { result = "Type is both constructed and unbound" }
@@ -397,16 +397,16 @@ class InconsistentTypeLocation extends TypeViolation {
*/
class TypeParameterMismatch extends TypeViolation {
TypeParameterMismatch() {
- getType().(ConstructedGeneric).getNumberOfTypeArguments() !=
- getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters()
+ this.getType().(ConstructedGeneric).getNumberOfTypeArguments() !=
+ this.getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters()
}
override string getMessage() {
result =
- "Constructed type (" + getType().toStringWithTypes() + ") has " +
- getType().(ConstructedGeneric).getNumberOfTypeArguments() +
- " type arguments and unbound type (" + getType().getUnboundType().toStringWithTypes() +
- ") has " + getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters() +
+ "Constructed type (" + this.getType().toStringWithTypes() + ") has " +
+ this.getType().(ConstructedGeneric).getNumberOfTypeArguments() +
+ " type arguments and unbound type (" + this.getType().getUnboundType().toStringWithTypes() +
+ ") has " + this.getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters() +
" type parameters"
}
}
@@ -418,7 +418,7 @@ class MethodViolation extends ConsistencyViolation, DeclarationCheck {
/** Gets the method containing the violation. */
Method getMethod() { this = DeclarationCheck(result) }
- override string toString() { result = getMethod().toString() }
+ override string toString() { result = this.getMethod().toString() }
override string getMessage() { none() }
}
@@ -440,14 +440,15 @@ class InconsistentMethodLocation extends MethodViolation {
*/
class ConstructedMethodTypeParams extends MethodViolation {
ConstructedMethodTypeParams() {
- getMethod().(ConstructedGeneric).getNumberOfTypeArguments() !=
- getMethod().getUnboundDeclaration().(UnboundGeneric).getNumberOfTypeParameters()
+ this.getMethod().(ConstructedGeneric).getNumberOfTypeArguments() !=
+ this.getMethod().getUnboundDeclaration().(UnboundGeneric).getNumberOfTypeParameters()
}
override string getMessage() {
result =
- "The constructed method " + getMethod().toStringWithTypes() +
- " does not match unbound method " + getMethod().getUnboundDeclaration().toStringWithTypes()
+ "The constructed method " + this.getMethod().toStringWithTypes() +
+ " does not match unbound method " +
+ this.getMethod().getUnboundDeclaration().toStringWithTypes()
}
}
@@ -477,8 +478,8 @@ class InvalidOverride extends MethodViolation {
private Method base;
InvalidOverride() {
- base = getMethod().getOverriddenMethod() and
- not getMethod().getDeclaringType().getABaseType+() = base.getDeclaringType() and
+ base = this.getMethod().getOverriddenMethod() and
+ not this.getMethod().getDeclaringType().getABaseType+() = base.getDeclaringType() and
base.getDeclaringType().isUnboundDeclaration() // Bases classes of constructed types aren't extracted properly.
}
@@ -493,7 +494,9 @@ class InvalidOverride extends MethodViolation {
* A pointer type that does not have a pointee type.
*/
class InvalidPointerType extends TypeViolation {
- InvalidPointerType() { exists(PointerType p | p = getType() | count(p.getReferentType()) != 1) }
+ InvalidPointerType() {
+ exists(PointerType p | p = this.getType() | count(p.getReferentType()) != 1)
+ }
override string getMessage() { result = "Invalid Pointertype.getPointeeType()" }
}
@@ -502,7 +505,9 @@ class InvalidPointerType extends TypeViolation {
* An array with an invalid `getElementType`.
*/
class ArrayTypeMissingElement extends TypeViolation {
- ArrayTypeMissingElement() { exists(ArrayType t | t = getType() | count(t.getElementType()) != 1) }
+ ArrayTypeMissingElement() {
+ exists(ArrayType t | t = this.getType() | count(t.getElementType()) != 1)
+ }
override string getMessage() { result = "Invalid ArrayType.getElementType()" }
}
@@ -511,7 +516,7 @@ class ArrayTypeMissingElement extends TypeViolation {
* An array with an invalid `getRank`.
*/
class ArrayTypeInvalidRank extends TypeViolation {
- ArrayTypeInvalidRank() { exists(ArrayType t | t = getType() | not t.getRank() > 0) }
+ ArrayTypeInvalidRank() { exists(ArrayType t | t = this.getType() | not t.getRank() > 0) }
override string getMessage() { result = "Invalid ArrayType.getRank()" }
}
@@ -564,7 +569,7 @@ abstract class DeclarationViolation extends ConsistencyViolation, DeclarationChe
/** Gets the member containing the potential violation. */
Declaration getDeclaration() { this = DeclarationCheck(result) }
- override string toString() { result = getDeclaration().toString() }
+ override string toString() { result = this.getDeclaration().toString() }
}
/**
@@ -572,7 +577,7 @@ abstract class DeclarationViolation extends ConsistencyViolation, DeclarationChe
*/
class PropertyWithNoAccessors extends DeclarationViolation {
PropertyWithNoAccessors() {
- exists(Property p | p = getDeclaration() | not exists(p.getAnAccessor()))
+ exists(Property p | p = this.getDeclaration() | not exists(p.getAnAccessor()))
}
override string getMessage() { result = "Property has no accessors" }
@@ -646,7 +651,7 @@ class TypeMultiplyDefined extends TypeViolation, DisabledCheck {
override string getMessage() {
result =
- "This type (" + getType().toStringWithTypes() + ") has " +
+ "This type (" + this.getType().toStringWithTypes() + ") has " +
count(Type t |
not t instanceof ConstructedGeneric and
t.toStringWithTypes() = this.getType().toStringWithTypes()
@@ -669,11 +674,11 @@ class MissingCilDeclaration extends ConsistencyViolation, MissingCSharpCheck {
override string getMessage() {
result =
- "Cannot locate CIL for " + getDeclaration().toStringWithTypes() + " of class " +
- getDeclaration().getPrimaryQlClasses()
+ "Cannot locate CIL for " + this.getDeclaration().toStringWithTypes() + " of class " +
+ this.getDeclaration().getPrimaryQlClasses()
}
- override string toString() { result = getDeclaration().toStringWithTypes() }
+ override string toString() { result = this.getDeclaration().toStringWithTypes() }
}
/**
@@ -717,21 +722,23 @@ private predicate expectedCilDeclaration(CS::Declaration decl) {
/** A member with an invalid name. */
class MemberWithInvalidName extends DeclarationViolation {
MemberWithInvalidName() {
- exists(string name | name = getDeclaration().(Member).getName() |
+ exists(string name | name = this.getDeclaration().(Member).getName() |
exists(name.indexOf(".")) and
not name = ".ctor" and
not name = ".cctor"
)
}
- override string getMessage() { result = "Invalid name " + getDeclaration().(Member).getName() }
+ override string getMessage() {
+ result = "Invalid name " + this.getDeclaration().(Member).getName()
+ }
}
class ConstructedSourceDeclarationMethod extends MethodViolation {
Method method;
ConstructedSourceDeclarationMethod() {
- method = getMethod() and
+ method = this.getMethod() and
method = method.getUnboundDeclaration() and
(
method instanceof ConstructedGeneric or
@@ -751,7 +758,7 @@ class DeclarationWithMultipleLabels extends DeclarationViolation {
}
override string getMessage() {
- result = "Multiple labels " + concat(getDeclaration().getLabel(), ", ")
+ result = "Multiple labels " + concat(this.getDeclaration().getLabel(), ", ")
}
}
diff --git a/csharp/ql/lib/semmle/code/cil/ControlFlow.qll b/csharp/ql/lib/semmle/code/cil/ControlFlow.qll
index 52a2ddc3376..8b6d6c70a05 100644
--- a/csharp/ql/lib/semmle/code/cil/ControlFlow.qll
+++ b/csharp/ql/lib/semmle/code/cil/ControlFlow.qll
@@ -23,13 +23,13 @@ class ControlFlowNode extends @cil_controlflow_node {
int getPopCount() { result = 0 }
/** Gets a successor of this node, if any. */
- final Instruction getASuccessor() { result = getASuccessorType(_) }
+ final Instruction getASuccessor() { result = this.getASuccessorType(_) }
/** Gets a true successor of this node, if any. */
- final Instruction getTrueSuccessor() { result = getASuccessorType(any(TrueFlow f)) }
+ final Instruction getTrueSuccessor() { result = this.getASuccessorType(any(TrueFlow f)) }
/** Gets a false successor of this node, if any. */
- final Instruction getFalseSuccessor() { result = getASuccessorType(any(FalseFlow f)) }
+ final Instruction getFalseSuccessor() { result = this.getASuccessorType(any(FalseFlow f)) }
/** Gets a successor to this node, of type `type`, if any. */
cached
@@ -57,7 +57,7 @@ class ControlFlowNode extends @cil_controlflow_node {
}
/** Gets an operand of this instruction, if any. */
- ControlFlowNode getAnOperand() { result = getOperand(_) }
+ ControlFlowNode getAnOperand() { result = this.getOperand(_) }
/** Gets an expression that consumes the output of this instruction on the stack. */
Instruction getParentExpr() { this = result.getAnOperand() }
@@ -86,17 +86,17 @@ class ControlFlowNode extends @cil_controlflow_node {
)
}
- private int getStackDelta() { result = getPushCount() - getPopCount() }
+ private int getStackDelta() { result = this.getPushCount() - this.getPopCount() }
/** Gets the stack size before this instruction. */
- int getStackSizeBefore() { result = getAPredecessor().getStackSizeAfter() }
+ int getStackSizeBefore() { result = this.getAPredecessor().getStackSizeAfter() }
/** Gets the stack size after this instruction. */
final int getStackSizeAfter() {
// This is a guard to prevent ill formed programs
// and other logic errors going into an infinite loop.
- result in [0 .. getImplementation().getStackSize()] and
- result = getStackSizeBefore() + getStackDelta()
+ result in [0 .. this.getImplementation().getStackSize()] and
+ result = this.getStackSizeBefore() + this.getStackDelta()
}
/** Gets the method containing this control flow node. */
diff --git a/csharp/ql/lib/semmle/code/cil/Declaration.qll b/csharp/ql/lib/semmle/code/cil/Declaration.qll
index a747d4a6d80..178b5c9966e 100644
--- a/csharp/ql/lib/semmle/code/cil/Declaration.qll
+++ b/csharp/ql/lib/semmle/code/cil/Declaration.qll
@@ -68,7 +68,7 @@ class Member extends DotNet::Member, Declaration, @cil_member {
/** Holds if this member has a security attribute. */
predicate hasSecurity() { cil_security(this) }
- override Location getLocation() { result = getDeclaringType().getLocation() }
+ override Location getLocation() { result = this.getDeclaringType().getLocation() }
}
/** A property. */
@@ -87,24 +87,25 @@ class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_pr
override Setter getSetter() { this = result.getProperty() }
/** Gets an accessor of this property. */
- Accessor getAnAccessor() { result = getGetter() or result = getSetter() }
+ Accessor getAnAccessor() { result = this.getGetter() or result = this.getSetter() }
- override string toString() { result = "property " + getName() }
+ override string toString() { result = "property " + this.getName() }
override string toStringWithTypes() {
result =
- getType().toStringWithTypes() + " " + getDeclaringType().toStringWithTypes() + "." + getName()
+ this.getType().toStringWithTypes() + " " + this.getDeclaringType().toStringWithTypes() + "." +
+ this.getName()
}
}
/** A property that is trivial (wraps a field). */
class TrivialProperty extends Property {
TrivialProperty() {
- getGetter().(TrivialGetter).getField() = getSetter().(TrivialSetter).getField()
+ this.getGetter().(TrivialGetter).getField() = this.getSetter().(TrivialSetter).getField()
}
/** Gets the underlying field of this property. */
- Field getField() { result = getGetter().(TrivialGetter).getField() }
+ Field getField() { result = this.getGetter().(TrivialGetter).getField() }
}
/** An event. */
@@ -125,9 +126,9 @@ class Event extends DotNet::Event, Member, @cil_event {
/** Gets the raiser. */
Method getRaiser() { cil_raiser(this, result) }
- override string toString() { result = "event " + getName() }
+ override string toString() { result = "event " + this.getName() }
override string toStringWithTypes() {
- result = getDeclaringType().toStringWithTypes() + "." + getName()
+ result = this.getDeclaringType().toStringWithTypes() + "." + this.getName()
}
}
diff --git a/csharp/ql/lib/semmle/code/cil/Generics.qll b/csharp/ql/lib/semmle/code/cil/Generics.qll
index a742a142cc4..2e702e68ffe 100644
--- a/csharp/ql/lib/semmle/code/cil/Generics.qll
+++ b/csharp/ql/lib/semmle/code/cil/Generics.qll
@@ -45,5 +45,5 @@ class ConstructedType extends ConstructedGeneric, Type {
/** A constructed generic method. */
class ConstructedMethod extends ConstructedGeneric, Method {
- final override UnboundGenericMethod getUnboundGeneric() { result = getUnboundMethod() }
+ final override UnboundGenericMethod getUnboundGeneric() { result = this.getUnboundMethod() }
}
diff --git a/csharp/ql/lib/semmle/code/cil/Instruction.qll b/csharp/ql/lib/semmle/code/cil/Instruction.qll
index 3e620031264..fa9753e1f0c 100644
--- a/csharp/ql/lib/semmle/code/cil/Instruction.qll
+++ b/csharp/ql/lib/semmle/code/cil/Instruction.qll
@@ -4,15 +4,17 @@ private import CIL
/** An instruction. */
class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instruction {
- override string toString() { result = getOpcodeName() }
+ override string toString() { result = this.getOpcodeName() }
/** Gets a more verbose textual representation of this instruction. */
- string toStringExtra() { result = getIndex() + ": " + getOpcodeName() + getExtraStr() }
+ string toStringExtra() {
+ result = this.getIndex() + ": " + this.getOpcodeName() + this.getExtraStr()
+ }
/** Gets the method containing this instruction. */
override MethodImplementation getImplementation() { cil_instruction(this, _, _, result) }
- override Method getMethod() { result = getImplementation().getMethod() }
+ override Method getMethod() { result = this.getImplementation().getMethod() }
/**
* Gets the index of this instruction.
@@ -30,7 +32,7 @@ class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instructi
string getExtra() { none() }
private string getExtraStr() {
- if exists(getExtra()) then result = " " + getExtra() else result = ""
+ if exists(this.getExtra()) then result = " " + this.getExtra() else result = ""
}
/** Gets the declaration accessed by this instruction, if any. */
@@ -39,8 +41,8 @@ class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instructi
/** Gets a successor instruction to this instruction. */
override Instruction getASuccessorType(FlowType t) {
t instanceof NormalFlow and
- canFlowNext() and
- result = this.getImplementation().getInstruction(getIndex() + 1)
+ this.canFlowNext() and
+ result = this.getImplementation().getInstruction(this.getIndex() + 1)
}
/** Holds if this instruction passes control flow into the next instruction. */
@@ -61,7 +63,7 @@ class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instructi
override Location getALocation() {
cil_instruction_location(this, result) // The source code, if available
or
- result = getImplementation().getLocation() // The containing assembly
+ result = this.getImplementation().getLocation() // The containing assembly
}
override Location getLocation() { result = Element.super.getLocation() }
diff --git a/csharp/ql/lib/semmle/code/cil/InstructionGroups.qll b/csharp/ql/lib/semmle/code/cil/InstructionGroups.qll
index e4aeb05a839..5dac4bf7291 100644
--- a/csharp/ql/lib/semmle/code/cil/InstructionGroups.qll
+++ b/csharp/ql/lib/semmle/code/cil/InstructionGroups.qll
@@ -14,7 +14,7 @@ class Expr extends DotNet::Expr, Instruction, @cil_expr {
override Type getType() { result = Instruction.super.getType() }
- override Method getEnclosingCallable() { result = getImplementation().getMethod() }
+ override Method getEnclosingCallable() { result = this.getImplementation().getMethod() }
/**
* The "parent" of a CIL expression is taken to be the instruction
@@ -28,13 +28,13 @@ class Branch extends Instruction, @cil_jump {
/** Gets the instruction that is jumped to. */
Instruction getTarget() { cil_jump(this, result) }
- override string getExtra() { result = getTarget().getIndex() + ":" }
+ override string getExtra() { result = this.getTarget().getIndex() + ":" }
}
/** An instruction that unconditionally jumps to another instruction. */
class UnconditionalBranch extends Branch, @cil_unconditional_jump {
override Instruction getASuccessorType(FlowType t) {
- t instanceof NormalFlow and result = getTarget()
+ t instanceof NormalFlow and result = this.getTarget()
}
override predicate canFlowNext() { none() }
@@ -43,9 +43,9 @@ class UnconditionalBranch extends Branch, @cil_unconditional_jump {
/** An instruction that jumps to a target based on a condition. */
class ConditionalBranch extends Branch, @cil_conditional_jump {
override Instruction getASuccessorType(FlowType t) {
- t instanceof TrueFlow and result = getTarget()
+ t instanceof TrueFlow and result = this.getTarget()
or
- t instanceof FalseFlow and result = getImplementation().getInstruction(getIndex() + 1)
+ t instanceof FalseFlow and result = this.getImplementation().getInstruction(this.getIndex() + 1)
}
override int getPushCount() { result = 0 }
@@ -61,7 +61,7 @@ class UnaryExpr extends Expr, @cil_unary_expr {
override int getPopCount() { result = 1 }
/** Gets the operand of this unary expression. */
- Expr getOperand() { result = getOperand(0) }
+ Expr getOperand() { result = this.getOperand(0) }
}
/** A binary expression that compares two values. */
@@ -73,8 +73,8 @@ class ComparisonOperation extends BinaryExpr, @cil_comparison_operation {
class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation {
override Type getType() {
exists(Type t0, Type t1 |
- t0 = getOperand(0).getType().getUnderlyingType() and
- t1 = getOperand(1).getType().getUnderlyingType()
+ t0 = this.getOperand(0).getType().getUnderlyingType() and
+ t1 = this.getOperand(1).getType().getUnderlyingType()
|
t0 = t1 and result = t0
or
@@ -100,7 +100,7 @@ class UnaryBitwiseOperation extends UnaryExpr, @cil_unary_bitwise_operation {
/** A unary expression that converts a value from one primitive type to another. */
class Conversion extends UnaryExpr, @cil_conversion_operation {
/** Gets the expression being converted. */
- Expr getExpr() { result = getOperand(0) }
+ Expr getExpr() { result = this.getOperand(0) }
}
/** A branch that leaves the scope of a `Handler`. */
@@ -111,7 +111,7 @@ class Literal extends DotNet::Literal, Expr, @cil_literal {
/** Gets the pushed value. */
override string getValue() { cil_value(this, result) }
- override string getExtra() { result = getValue() }
+ override string getExtra() { result = this.getValue() }
}
/** An integer literal. */
@@ -149,44 +149,44 @@ class Call extends Expr, DotNet::Call, @cil_call_any {
/** Gets the method that is called. */
override Method getTarget() { cil_access(this, result) }
- override Method getARuntimeTarget() { result = getTarget().getAnOverrider*() }
+ override Method getARuntimeTarget() { result = this.getTarget().getAnOverrider*() }
- override string getExtra() { result = getTarget().getQualifiedName() }
+ override string getExtra() { result = this.getTarget().getQualifiedName() }
/**
* Gets the return type of the call. Methods that do not return a value
* return the `void` type, `System.Void`, although the value of `getPushCount` is
* 0 in this case.
*/
- override Type getType() { result = getTarget().getReturnType() }
+ override Type getType() { result = this.getTarget().getReturnType() }
// The number of items popped/pushed from the stack
// depends on the target of the call.
- override int getPopCount() { result = getTarget().getCallPopCount() }
+ override int getPopCount() { result = this.getTarget().getCallPopCount() }
- override int getPushCount() { result = getTarget().getCallPushCount() }
+ override int getPushCount() { result = this.getTarget().getCallPushCount() }
/**
* Holds if this is a "tail call", meaning that control does not return to the
* calling method.
*/
predicate isTailCall() {
- getImplementation().getInstruction(getIndex() - 1) instanceof Opcodes::Tail
+ this.getImplementation().getInstruction(this.getIndex() - 1) instanceof Opcodes::Tail
}
/** Holds if this call is virtual and could go to an overriding method. */
predicate isVirtual() { none() }
- override Expr getRawArgument(int i) { result = getOperand(getPopCount() - i - 1) }
+ override Expr getRawArgument(int i) { result = this.getOperand(this.getPopCount() - i - 1) }
/** Gets the qualifier of this call, if any. */
- Expr getQualifier() { result = getRawArgument(0) and not getTarget().isStatic() }
+ Expr getQualifier() { result = this.getRawArgument(0) and not this.getTarget().isStatic() }
override Expr getArgument(int i) {
- if getTarget().isStatic()
- then result = getRawArgument(i)
+ if this.getTarget().isStatic()
+ then result = this.getRawArgument(i)
else (
- result = getRawArgument(i + 1) and i >= 0
+ result = this.getRawArgument(i + 1) and i >= 0
)
}
@@ -217,10 +217,10 @@ class VirtualCall extends Call {
/** A read of an array element. */
class ReadArrayElement extends BinaryExpr, @cil_read_array {
/** Gets the array being read. */
- Expr getArray() { result = getOperand(1) }
+ Expr getArray() { result = this.getOperand(1) }
/** Gets the index into the array. */
- Expr getArrayIndex() { result = getOperand(0) }
+ Expr getArrayIndex() { result = this.getOperand(0) }
}
/** A write of an array element. */
@@ -233,14 +233,14 @@ class WriteArrayElement extends Instruction, @cil_write_array {
/** A `return` statement. */
class Return extends Instruction, @cil_ret {
/** Gets the expression being returned, if any. */
- Expr getExpr() { result = getOperand(0) }
+ Expr getExpr() { result = this.getOperand(0) }
override predicate canFlowNext() { none() }
}
/** A `throw` statement. */
class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
- override Expr getExpr() { result = getOperand(0) }
+ override Expr getExpr() { result = this.getOperand(0) }
override predicate canFlowNext() { none() }
}
@@ -250,10 +250,10 @@ class StoreIndirect extends Instruction, @cil_stind {
override int getPopCount() { result = 2 }
/** Gets the location to store the value at. */
- Expr getAddress() { result = getOperand(1) }
+ Expr getAddress() { result = this.getOperand(1) }
/** Gets the value to store. */
- Expr getExpr() { result = getOperand(0) }
+ Expr getExpr() { result = this.getOperand(0) }
}
/** Loads a value from an address/location. */
diff --git a/csharp/ql/lib/semmle/code/cil/Instructions.qll b/csharp/ql/lib/semmle/code/cil/Instructions.qll
index e385ceced31..5752ae45b20 100644
--- a/csharp/ql/lib/semmle/code/cil/Instructions.qll
+++ b/csharp/ql/lib/semmle/code/cil/Instructions.qll
@@ -83,21 +83,21 @@ module Opcodes {
class Ldc_i4 extends IntLiteral, @cil_ldc_i4 {
override string getOpcodeName() { result = "ldc.i4" }
- override string getExtra() { result = getValue() }
+ override string getExtra() { result = this.getValue() }
}
/** An `ldc.i8` instruction. */
class Ldc_i8 extends IntLiteral, @cil_ldc_i8 {
override string getOpcodeName() { result = "ldc.i8" }
- override string getExtra() { result = getValue() }
+ override string getExtra() { result = this.getValue() }
}
/** An `ldc.i4.s` instruction. */
class Ldc_i4_s extends IntLiteral, @cil_ldc_i4_s {
override string getOpcodeName() { result = "ldc.i4.s" }
- override string getExtra() { result = getValue() }
+ override string getExtra() { result = this.getValue() }
}
/** An `ldnull` instruction. */
@@ -115,7 +115,7 @@ module Opcodes {
class Ldc_r4 extends FloatLiteral, @cil_ldc_r4 {
override string getOpcodeName() { result = "ldc.r4" }
- override string getExtra() { result = getValue() }
+ override string getExtra() { result = this.getValue() }
override Type getType() { result instanceof FloatType }
}
@@ -124,7 +124,7 @@ module Opcodes {
class Ldc_r8 extends FloatLiteral, @cil_ldc_r8 {
override string getOpcodeName() { result = "ldc.r8" }
- override string getExtra() { result = getValue() }
+ override string getExtra() { result = this.getValue() }
override Type getType() { result instanceof DoubleType }
}
@@ -199,9 +199,9 @@ module Opcodes {
override string getOpcodeName() { result = "neg" }
override NumericType getType() {
- result = getOperand().getType()
+ result = this.getOperand().getType()
or
- getOperand().getType() instanceof Enum and result instanceof IntType
+ this.getOperand().getType() instanceof Enum and result instanceof IntType
}
}
@@ -260,7 +260,7 @@ module Opcodes {
override int getPushCount() { result = 2 } // This is the only instruction that pushes 2 items
- override Type getType() { result = getOperand(0).getType() }
+ override Type getType() { result = this.getOperand(0).getType() }
}
/** A `ret` instruction. */
@@ -270,7 +270,7 @@ module Opcodes {
override predicate canFlowNext() { none() }
override int getPopCount() {
- if getImplementation().getMethod().returnsVoid() then result = 0 else result = 1
+ if this.getImplementation().getMethod().returnsVoid() then result = 0 else result = 1
}
}
@@ -283,7 +283,7 @@ module Opcodes {
class Ldstr extends StringLiteral, @cil_ldstr {
override string getOpcodeName() { result = "ldstr" }
- override string getExtra() { result = "\"" + getValue() + "\"" }
+ override string getExtra() { result = "\"" + this.getValue() + "\"" }
override Type getType() { result instanceof StringType }
}
@@ -427,11 +427,14 @@ module Opcodes {
override Instruction getASuccessorType(FlowType t) {
t instanceof NormalFlow and
- (result = getTarget(_) or result = getImplementation().getInstruction(getIndex() + 1))
+ (
+ result = this.getTarget(_) or
+ result = this.getImplementation().getInstruction(this.getIndex() + 1)
+ )
}
override string getExtra() {
- result = concat(int n | exists(getTarget(n)) | getTarget(n).getIndex() + ":", " ")
+ result = concat(int n | exists(this.getTarget(n)) | this.getTarget(n).getIndex() + ":", " ")
}
}
@@ -493,9 +496,9 @@ module Opcodes {
// The number of items popped/pushed from the stack depends on the target of
// the call. Also, we need to pop the function pointer itself too.
- override int getPopCount() { result = getTargetType().getCallPopCount() + 1 }
+ override int getPopCount() { result = this.getTargetType().getCallPopCount() + 1 }
- override int getPushCount() { result = getTargetType().getCallPushCount() }
+ override int getPushCount() { result = this.getTargetType().getCallPushCount() }
}
/** A `callvirt` instruction. */
@@ -524,49 +527,49 @@ module Opcodes {
override BoolType getType() { exists(result) }
/** Gets the type that is being tested against. */
- Type getTestedType() { result = getAccess() }
+ Type getTestedType() { result = this.getAccess() }
- override string getExtra() { result = getTestedType().getQualifiedName() }
+ override string getExtra() { result = this.getTestedType().getQualifiedName() }
}
/** A `castclass` instruction. */
class Castclass extends UnaryExpr, @cil_castclass {
override string getOpcodeName() { result = "castclass" }
- override Type getType() { result = getAccess() }
+ override Type getType() { result = this.getAccess() }
/** Gets the type that is being cast to. */
- Type getTestedType() { result = getAccess() }
+ Type getTestedType() { result = this.getAccess() }
- override string getExtra() { result = getTestedType().getQualifiedName() }
+ override string getExtra() { result = this.getTestedType().getQualifiedName() }
}
/** An `stloc.0` instruction. */
class Stloc_0 extends LocalVariableWriteAccess, @cil_stloc_0 {
override string getOpcodeName() { result = "stloc.0" }
- override LocalVariable getTarget() { result = getImplementation().getLocalVariable(0) }
+ override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(0) }
}
/** An `stloc.1` instruction. */
class Stloc_1 extends LocalVariableWriteAccess, @cil_stloc_1 {
override string getOpcodeName() { result = "stloc.1" }
- override LocalVariable getTarget() { result = getImplementation().getLocalVariable(1) }
+ override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(1) }
}
/** An `stloc.2` instruction. */
class Stloc_2 extends LocalVariableWriteAccess, @cil_stloc_2 {
override string getOpcodeName() { result = "stloc.2" }
- override LocalVariable getTarget() { result = getImplementation().getLocalVariable(2) }
+ override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(2) }
}
/** An `stloc.3` instruction. */
class Stloc_3 extends LocalVariableWriteAccess, @cil_stloc_3 {
override string getOpcodeName() { result = "stloc.3" }
- override LocalVariable getTarget() { result = getImplementation().getLocalVariable(3) }
+ override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(3) }
}
/** An `stloc.s` instruction. */
@@ -587,28 +590,28 @@ module Opcodes {
class Ldloc_0 extends LocalVariableReadAccess, @cil_ldloc_0 {
override string getOpcodeName() { result = "ldloc.0" }
- override LocalVariable getTarget() { result = getImplementation().getLocalVariable(0) }
+ override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(0) }
}
/** An `ldloc.1` instruction. */
class Ldloc_1 extends LocalVariableReadAccess, @cil_ldloc_1 {
override string getOpcodeName() { result = "ldloc.1" }
- override LocalVariable getTarget() { result = getImplementation().getLocalVariable(1) }
+ override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(1) }
}
/** An `ldloc.2` instruction. */
class Ldloc_2 extends LocalVariableReadAccess, @cil_ldloc_2 {
override string getOpcodeName() { result = "ldloc.2" }
- override LocalVariable getTarget() { result = getImplementation().getLocalVariable(2) }
+ override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(2) }
}
/** An `ldloc.3` instruction. */
class Ldloc_3 extends LocalVariableReadAccess, @cil_ldloc_3 {
override string getOpcodeName() { result = "ldloc.3" }
- override LocalVariable getTarget() { result = getImplementation().getLocalVariable(3) }
+ override LocalVariable getTarget() { result = this.getImplementation().getLocalVariable(3) }
}
/** An `ldloc.s` instruction. */
@@ -617,7 +620,7 @@ module Opcodes {
override LocalVariable getTarget() { cil_access(this, result) }
- override string getExtra() { result = "L" + getTarget().getIndex() }
+ override string getExtra() { result = "L" + this.getTarget().getIndex() }
}
/** An `ldloca.s` instruction. */
@@ -626,7 +629,7 @@ module Opcodes {
override LocalVariable getTarget() { cil_access(this, result) }
- override string getExtra() { result = "L" + getTarget().getIndex() }
+ override string getExtra() { result = "L" + this.getTarget().getIndex() }
}
/** An `ldloc` instruction. */
@@ -635,7 +638,7 @@ module Opcodes {
override LocalVariable getTarget() { cil_access(this, result) }
- override string getExtra() { result = "L" + getTarget().getIndex() }
+ override string getExtra() { result = "L" + this.getTarget().getIndex() }
}
/** An `ldarg.0` instruction. */
@@ -643,7 +646,7 @@ module Opcodes {
override string getOpcodeName() { result = "ldarg.0" }
override MethodParameter getTarget() {
- result = getImplementation().getMethod().getRawParameter(0)
+ result = this.getImplementation().getMethod().getRawParameter(0)
}
}
@@ -652,7 +655,7 @@ module Opcodes {
override string getOpcodeName() { result = "ldarg.1" }
override MethodParameter getTarget() {
- result = getImplementation().getMethod().getRawParameter(1)
+ result = this.getImplementation().getMethod().getRawParameter(1)
}
}
@@ -661,7 +664,7 @@ module Opcodes {
override string getOpcodeName() { result = "ldarg.2" }
override MethodParameter getTarget() {
- result = getImplementation().getMethod().getRawParameter(2)
+ result = this.getImplementation().getMethod().getRawParameter(2)
}
}
@@ -670,7 +673,7 @@ module Opcodes {
override string getOpcodeName() { result = "ldarg.3" }
override MethodParameter getTarget() {
- result = getImplementation().getMethod().getRawParameter(3)
+ result = this.getImplementation().getMethod().getRawParameter(3)
}
}
@@ -710,7 +713,7 @@ module Opcodes {
override int getPopCount() { result = 1 }
- override Expr getQualifier() { result = getOperand(0) }
+ override Expr getQualifier() { result = this.getOperand(0) }
}
/** An `ldflda` instruction. */
@@ -719,7 +722,7 @@ module Opcodes {
override int getPopCount() { result = 1 }
- override Expr getQualifier() { result = getOperand(0) }
+ override Expr getQualifier() { result = this.getOperand(0) }
}
/** An `ldsfld` instruction. */
@@ -746,9 +749,9 @@ module Opcodes {
override int getPopCount() { result = 2 }
- override Expr getQualifier() { result = getOperand(1) }
+ override Expr getQualifier() { result = this.getOperand(1) }
- override Expr getExpr() { result = getOperand(0) }
+ override Expr getExpr() { result = this.getOperand(0) }
}
/** An `stsfld` instruction. */
@@ -759,7 +762,7 @@ module Opcodes {
override Expr getQualifier() { none() }
- override Expr getExpr() { result = getOperand(0) }
+ override Expr getExpr() { result = this.getOperand(0) }
}
/** A `newobj` instruction. */
@@ -772,7 +775,7 @@ module Opcodes {
override Type getType() { result = this.getTarget().getDeclaringType() }
- override Expr getArgument(int i) { result = getRawArgument(i) }
+ override Expr getArgument(int i) { result = this.getRawArgument(i) }
pragma[noinline]
private Parameter getARawTargetParameter() { result = this.getTarget().getARawParameter() }
@@ -796,21 +799,21 @@ module Opcodes {
class Box extends UnaryExpr, @cil_box {
override string getOpcodeName() { result = "box" }
- override Type getType() { result = getAccess() }
+ override Type getType() { result = this.getAccess() }
}
/** An `unbox.any` instruction. */
class Unbox_any extends UnaryExpr, @cil_unbox_any {
override string getOpcodeName() { result = "unbox.any" }
- override Type getType() { result = getAccess() }
+ override Type getType() { result = this.getAccess() }
}
/** An `unbox` instruction. */
class Unbox extends UnaryExpr, @cil_unbox {
override string getOpcodeName() { result = "unbox" }
- override Type getType() { result = getAccess() }
+ override Type getType() { result = this.getAccess() }
}
/** An `ldobj` instruction. */
@@ -820,7 +823,7 @@ module Opcodes {
/** Gets the type of the object. */
Type getTarget() { cil_access(this, result) }
- override Type getType() { result = getAccess() }
+ override Type getType() { result = this.getAccess() }
}
/** An `ldtoken` instruction. */
@@ -867,31 +870,31 @@ module Opcodes {
// Note that this is technically wrong - it should be
// result.(ArrayType).getElementType() = getAccess()
// However the (ArrayType) may not be in the database.
- result = getAccess()
+ result = this.getAccess()
}
- override string getExtra() { result = getType().getQualifiedName() }
+ override string getExtra() { result = this.getType().getQualifiedName() }
}
/** An `ldelem` instruction. */
class Ldelem extends ReadArrayElement, @cil_ldelem {
override string getOpcodeName() { result = "ldelem" }
- override Type getType() { result = getAccess() }
+ override Type getType() { result = this.getAccess() }
}
/** An `ldelem.ref` instruction. */
class Ldelem_ref extends ReadArrayElement, @cil_ldelem_ref {
override string getOpcodeName() { result = "ldelem.ref" }
- override Type getType() { result = getArray().getType() }
+ override Type getType() { result = this.getArray().getType() }
}
/** An `ldelema` instruction. */
class Ldelema extends ReadArrayElement, ReadRef, @cil_ldelema {
override string getOpcodeName() { result = "ldelema" }
- override Type getType() { result = getAccess() }
+ override Type getType() { result = this.getAccess() }
}
/** An `stelem.ref` instruction. */
@@ -1410,7 +1413,7 @@ module Opcodes {
override int getPopCount() { result = 1 }
- override Type getType() { result = getAccess() }
+ override Type getType() { result = this.getAccess() }
}
/** A `refanytype` instruction. */
diff --git a/csharp/ql/lib/semmle/code/cil/Method.qll b/csharp/ql/lib/semmle/code/cil/Method.qll
index 82bde17a477..461a020972b 100644
--- a/csharp/ql/lib/semmle/code/cil/Method.qll
+++ b/csharp/ql/lib/semmle/code/cil/Method.qll
@@ -28,13 +28,13 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation {
LocalVariable getLocalVariable(int n) { cil_local_variable(result, this, n, _) }
/** Gets a local variable of this implementation, if any. */
- LocalVariable getALocalVariable() { result = getLocalVariable(_) }
+ LocalVariable getALocalVariable() { result = this.getLocalVariable(_) }
/** Gets an instruction in this implementation, if any. */
- Instruction getAnInstruction() { result = getInstruction(_) }
+ Instruction getAnInstruction() { result = this.getInstruction(_) }
/** Gets the total number of instructions in this implementation. */
- int getNumberOfInstructions() { result = count(getAnInstruction()) }
+ int getNumberOfInstructions() { result = count(this.getAnInstruction()) }
/** Gets the `i`th handler in this implementation. */
Handler getHandler(int i) { result.getImplementation() = this and result.getIndex() = i }
@@ -49,7 +49,7 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation {
/** Gets the maximum stack size of this implementation. */
int getStackSize() { cil_method_stack_size(this, result) }
- override string toString() { result = getMethod().toString() }
+ override string toString() { result = this.getMethod().toString() }
/** Gets a string representing the disassembly of this implementation. */
string getDisassembly() {
@@ -75,13 +75,13 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
MethodImplementation getAnImplementation() { result.getMethod() = this }
/** Gets the "best" implementation of this method, if any. */
- BestImplementation getImplementation() { result = getAnImplementation() }
+ BestImplementation getImplementation() { result = this.getAnImplementation() }
override Method getMethod() { result = this }
override string getName() { cil_method(this, result, _, _) }
- override string getUndecoratedName() { result = getName() }
+ override string getUndecoratedName() { result = this.getName() }
override string toString() { result = this.getName() }
@@ -92,25 +92,29 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
override Location getALocation() { cil_method_location(this.getUnboundDeclaration(), result) }
override MethodParameter getParameter(int n) {
- if isStatic() then result = getRawParameter(n) else (result = getRawParameter(n + 1) and n >= 0)
+ if this.isStatic()
+ then result = this.getRawParameter(n)
+ else (
+ result = this.getRawParameter(n + 1) and n >= 0
+ )
}
- override Type getType() { result = getReturnType() }
+ override Type getType() { result = this.getReturnType() }
/** Gets the return type of this method. */
override Type getReturnType() { cil_method(this, _, _, result) }
/** Holds if the return type is `void`. */
- predicate returnsVoid() { getReturnType() instanceof VoidType }
+ predicate returnsVoid() { this.getReturnType() instanceof VoidType }
/** Gets the number of stack items pushed in a call to this method. */
- int getCallPushCount() { if returnsVoid() then result = 0 else result = 1 }
+ int getCallPushCount() { if this.returnsVoid() then result = 0 else result = 1 }
/** Gets the number of stack items popped in a call to this method. */
- int getCallPopCount() { result = count(getRawParameter(_)) }
+ int getCallPopCount() { result = count(this.getRawParameter(_)) }
/** Gets a method called by this method. */
- Method getACallee() { result = getImplementation().getAnInstruction().(Call).getTarget() }
+ Method getACallee() { result = this.getImplementation().getAnInstruction().(Call).getTarget() }
/** Holds if this method is `virtual`. */
predicate isVirtual() { cil_virtual(this) }
@@ -129,43 +133,45 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
/** Gets the unbound declaration of this method, or the method itself. */
Method getUnboundMethod() { cil_method_source_declaration(this, result) }
- override Method getUnboundDeclaration() { result = getUnboundMethod() }
+ override Method getUnboundDeclaration() { result = this.getUnboundMethod() }
/** Holds if this method is an instance constructor. */
- predicate isInstanceConstructor() { isSpecial() and getName() = ".ctor" }
+ predicate isInstanceConstructor() { this.isSpecial() and this.getName() = ".ctor" }
/** Holds if this method is a static class constructor. */
- predicate isStaticConstructor() { isSpecial() and getName() = ".cctor" }
+ predicate isStaticConstructor() { this.isSpecial() and this.getName() = ".cctor" }
/** Holds if this method is a constructor (static or instance). */
- predicate isConstructor() { isStaticConstructor() or isInstanceConstructor() }
+ predicate isConstructor() { this.isStaticConstructor() or this.isInstanceConstructor() }
/** Holds if this method is a destructor/finalizer. */
- predicate isFinalizer() { getOverriddenMethod*().getQualifiedName() = "System.Object.Finalize" }
+ predicate isFinalizer() {
+ this.getOverriddenMethod*().getQualifiedName() = "System.Object.Finalize"
+ }
/** Holds if this method is an operator. */
- predicate isOperator() { isSpecial() and getName().matches("op\\_%") }
+ predicate isOperator() { this.isSpecial() and this.getName().matches("op\\_%") }
/** Holds if this method is a getter. */
- predicate isGetter() { isSpecial() and getName().matches("get\\_%") }
+ predicate isGetter() { this.isSpecial() and this.getName().matches("get\\_%") }
/** Holds if this method is a setter. */
- predicate isSetter() { isSpecial() and getName().matches("set\\_%") }
+ predicate isSetter() { this.isSpecial() and this.getName().matches("set\\_%") }
/** Holds if this method is an adder/add event accessor. */
- predicate isAdder() { isSpecial() and getName().matches("add\\_%") }
+ predicate isAdder() { this.isSpecial() and this.getName().matches("add\\_%") }
/** Holds if this method is a remover/remove event accessor. */
- predicate isRemove() { isSpecial() and getName().matches("remove\\_%") }
+ predicate isRemove() { this.isSpecial() and this.getName().matches("remove\\_%") }
/** Holds if this method is an implicit conversion operator. */
- predicate isImplicitConversion() { isSpecial() and getName() = "op_Implicit" }
+ predicate isImplicitConversion() { this.isSpecial() and this.getName() = "op_Implicit" }
/** Holds if this method is an explicit conversion operator. */
- predicate isExplicitConversion() { isSpecial() and getName() = "op_Explicit" }
+ predicate isExplicitConversion() { this.isSpecial() and this.getName() = "op_Explicit" }
/** Holds if this method is a conversion operator. */
- predicate isConversion() { isImplicitConversion() or isExplicitConversion() }
+ predicate isConversion() { this.isImplicitConversion() or this.isExplicitConversion() }
/**
* Gets a method that is overridden, either in a base class
@@ -176,7 +182,7 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN
/** Gets a method that overrides this method, if any. */
final Method getAnOverrider() { result.getOverriddenMethod() = this }
- override predicate hasBody() { exists(getImplementation()) }
+ override predicate hasBody() { exists(this.getImplementation()) }
override predicate canReturn(DotNet::Expr expr) {
exists(Return ret | ret.getImplementation() = this.getImplementation() and expr = ret.getExpr())
@@ -206,7 +212,7 @@ class InstanceConstructor extends Constructor {
/** A method that always returns the `this` parameter. */
class ChainingMethod extends Method {
ChainingMethod() {
- forex(Return ret | ret = getImplementation().getAnInstruction() |
+ forex(Return ret | ret = this.getImplementation().getAnInstruction() |
ret.getExpr() instanceof ThisAccess
)
}
@@ -231,7 +237,7 @@ class Getter extends Accessor {
*/
class TrivialGetter extends Method {
TrivialGetter() {
- exists(MethodImplementation impl | impl = getAnImplementation() |
+ exists(MethodImplementation impl | impl = this.getAnImplementation() |
impl.getInstruction(0) instanceof ThisAccess and
impl.getInstruction(1) instanceof FieldReadAccess and
impl.getInstruction(2) instanceof Return
@@ -239,7 +245,9 @@ class TrivialGetter extends Method {
}
/** Gets the underlying field of this getter. */
- Field getField() { getImplementation().getAnInstruction().(FieldReadAccess).getTarget() = result }
+ Field getField() {
+ this.getImplementation().getAnInstruction().(FieldReadAccess).getTarget() = result
+ }
}
/** A setter. */
@@ -262,7 +270,7 @@ class Setter extends Accessor {
*/
class TrivialSetter extends Method {
TrivialSetter() {
- exists(MethodImplementation impl | impl = getImplementation() |
+ exists(MethodImplementation impl | impl = this.getImplementation() |
impl.getInstruction(0) instanceof ThisAccess and
impl.getInstruction(1).(ParameterReadAccess).getTarget().getIndex() = 1 and
impl.getInstruction(2) instanceof FieldWriteAccess
@@ -271,7 +279,7 @@ class TrivialSetter extends Method {
/** Gets the underlying field of this setter. */
Field getField() {
- result = getImplementation().getAnInstruction().(FieldWriteAccess).getTarget()
+ result = this.getImplementation().getAnInstruction().(FieldWriteAccess).getTarget()
}
}
@@ -283,5 +291,5 @@ class Operator extends Method {
Operator() { this.isOperator() }
/** Gets the name of the implementing method (for compatibility with C# data model). */
- string getFunctionName() { result = getName() }
+ string getFunctionName() { result = this.getName() }
}
diff --git a/csharp/ql/lib/semmle/code/cil/Type.qll b/csharp/ql/lib/semmle/code/cil/Type.qll
index a081d62b7ee..7aeaf9a6495 100644
--- a/csharp/ql/lib/semmle/code/cil/Type.qll
+++ b/csharp/ql/lib/semmle/code/cil/Type.qll
@@ -19,7 +19,7 @@ class TypeContainer extends DotNet::NamedElement, @cil_type_container {
/** A namespace. */
class Namespace extends DotNet::Namespace, TypeContainer, @namespace {
- override string toString() { result = getQualifiedName() }
+ override string toString() { result = this.getQualifiedName() }
override Namespace getParent() { result = this.getParentNamespace() }
@@ -39,7 +39,7 @@ class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type {
override string toString() { result = this.getName() }
/** Gets the containing type of this type, if any. */
- override Type getDeclaringType() { result = getParent() }
+ override Type getDeclaringType() { result = this.getParent() }
/** Gets a member of this type, if any. */
Member getAMember() { result.getDeclaringType() = this }
@@ -96,13 +96,13 @@ class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type {
Type getABaseInterface() { cil_base_interface(this, result) }
/** Gets an immediate base type of this type, if any. */
- Type getABaseType() { result = getBaseClass() or result = getABaseInterface() }
+ Type getABaseType() { result = this.getBaseClass() or result = this.getABaseInterface() }
/** Gets an immediate subtype of this type, if any. */
Type getASubtype() { result.getABaseType() = this }
/** Gets the namespace directly containing this type, if any. */
- Namespace getNamespace() { result = getParent() }
+ Namespace getNamespace() { result = this.getParent() }
/**
* Gets an index for implicit conversions. A type can be converted to another numeric type
diff --git a/csharp/ql/lib/semmle/code/cil/Types.qll b/csharp/ql/lib/semmle/code/cil/Types.qll
index d4d9342b73d..1dfaa0191a1 100644
--- a/csharp/ql/lib/semmle/code/cil/Types.qll
+++ b/csharp/ql/lib/semmle/code/cil/Types.qll
@@ -12,7 +12,7 @@ class TypeParameter extends DotNet::TypeParameter, Type, @cil_typeparameter {
/** Gets the generic type/method declaring this type parameter. */
TypeContainer getGeneric() { cil_type_parameter(result, _, this) }
- override Location getLocation() { result = getParent().getLocation() }
+ override Location getLocation() { result = this.getParent().getLocation() }
/** Holds if this type parameter has the `new` constraint. */
predicate isDefaultConstructible() { cil_typeparam_new(this) }
@@ -34,11 +34,11 @@ class TypeParameter extends DotNet::TypeParameter, Type, @cil_typeparameter {
/** A value or reference type. */
class ValueOrRefType extends DotNet::ValueOrRefType, Type, @cil_valueorreftype {
- override ValueOrRefType getDeclaringType() { result = getParent() }
+ override ValueOrRefType getDeclaringType() { result = this.getParent() }
override string getUndecoratedName() { cil_type(this, result, _, _, _) }
- override Namespace getDeclaringNamespace() { result = getNamespace() }
+ override Namespace getDeclaringNamespace() { result = this.getNamespace() }
override ValueOrRefType getABaseType() { result = Type.super.getABaseType() }
}
@@ -79,7 +79,7 @@ class ArrayType extends DotNet::ArrayType, Type, @cil_array_type {
override string toStringWithTypes() { result = DotNet::ArrayType.super.toStringWithTypes() }
- override Location getLocation() { result = getElementType().getLocation() }
+ override Location getLocation() { result = this.getElementType().getLocation() }
override ValueOrRefType getABaseType() { result = Type.super.getABaseType() }
}
@@ -92,7 +92,7 @@ class PointerType extends DotNet::PointerType, PrimitiveType, @cil_pointer_type
override string getName() { result = DotNet::PointerType.super.getName() }
- override Location getLocation() { result = getReferentType().getLocation() }
+ override Location getLocation() { result = this.getReferentType().getLocation() }
override string toString() { result = DotNet::PointerType.super.toString() }
@@ -312,13 +312,13 @@ class FunctionPointerType extends Type, CustomModifierReceiver, Parameterizable,
override string toString() { result = Type.super.toString() }
/** Holds if the return type is `void`. */
- predicate returnsVoid() { getReturnType() instanceof VoidType }
+ predicate returnsVoid() { this.getReturnType() instanceof VoidType }
/** Gets the number of stack items pushed in a call to this method. */
- int getCallPushCount() { if returnsVoid() then result = 0 else result = 1 }
+ int getCallPushCount() { if this.returnsVoid() then result = 0 else result = 1 }
/** Gets the number of stack items popped in a call to this method. */
- int getCallPopCount() { result = count(getRawParameter(_)) }
+ int getCallPopCount() { result = count(this.getRawParameter(_)) }
- override string getLabel() { result = getName() }
+ override string getLabel() { result = this.getName() }
}
diff --git a/csharp/ql/lib/semmle/code/cil/Variable.qll b/csharp/ql/lib/semmle/code/cil/Variable.qll
index 3a247e1f0d1..604f2c2b646 100644
--- a/csharp/ql/lib/semmle/code/cil/Variable.qll
+++ b/csharp/ql/lib/semmle/code/cil/Variable.qll
@@ -17,10 +17,10 @@ class Variable extends DotNet::Variable, Declaration, DataFlowNode, @cil_variabl
VariableAccess getAnAccess() { result.getTarget() = this }
/** Gets a read access to this variable, if any. */
- ReadAccess getARead() { result = getAnAccess() }
+ ReadAccess getARead() { result = this.getAnAccess() }
/** Gets a write access to this variable, if any. */
- WriteAccess getAWrite() { result = getAnAccess() }
+ WriteAccess getAWrite() { result = this.getAnAccess() }
override string toString() { result = Declaration.super.toString() }
@@ -40,20 +40,21 @@ class StackVariable extends Variable, @cil_stack_variable {
class LocalVariable extends StackVariable, @cil_local_variable {
override string toString() {
result =
- "Local variable " + getIndex() + " of method " + getImplementation().getMethod().getName()
+ "Local variable " + this.getIndex() + " of method " +
+ this.getImplementation().getMethod().getName()
}
/** Gets the method implementation defining this local variable. */
MethodImplementation getImplementation() { this = result.getALocalVariable() }
/** Gets the index number of this local variable. This is not usually significant. */
- int getIndex() { this = getImplementation().getLocalVariable(result) }
+ int getIndex() { this = this.getImplementation().getLocalVariable(result) }
override Type getType() { cil_local_variable(this, _, _, result) }
- override Location getLocation() { result = getImplementation().getLocation() }
+ override Location getLocation() { result = this.getImplementation().getLocation() }
- override Method getMethod() { result = getImplementation().getMethod() }
+ override Method getMethod() { result = this.getImplementation().getMethod() }
}
/** A parameter of a `Method` or `FunctionPointerType`. */
@@ -64,7 +65,7 @@ class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_paramete
int getIndex() { cil_parameter(this, _, result, _) }
override string toString() {
- result = "Parameter " + getIndex() + " of " + getDeclaringElement().getName()
+ result = "Parameter " + this.getIndex() + " of " + this.getDeclaringElement().getName()
}
override Type getType() { cil_parameter(this, _, _, result) }
@@ -82,23 +83,25 @@ class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_paramete
predicate hasInFlag() { cil_parameter_in(this) }
/** Holds if this parameter has C# `out` semantics. */
- override predicate isOut() { hasOutFlag() and not hasInFlag() }
+ override predicate isOut() { this.hasOutFlag() and not this.hasInFlag() }
/** Holds if this parameter has C# `ref` semantics. */
- override predicate isRef() { hasOutFlag() and hasInFlag() }
+ override predicate isRef() { this.hasOutFlag() and this.hasInFlag() }
- override string toStringWithTypes() { result = getPrefix() + getType().toStringWithTypes() }
+ override string toStringWithTypes() {
+ result = this.getPrefix() + this.getType().toStringWithTypes()
+ }
private string getPrefix() {
- if isOut()
+ if this.isOut()
then result = "out "
else
- if isRef()
+ if this.isRef()
then result = "ref "
else result = ""
}
- override Location getLocation() { result = getDeclaringElement().getLocation() }
+ override Location getLocation() { result = this.getDeclaringElement().getLocation() }
}
/** A method parameter. */
@@ -110,11 +113,11 @@ class MethodParameter extends Parameter, StackVariable {
/** Gets a parameter in an overridden method. */
MethodParameter getOverriddenParameter() {
- result = getMethod().getOverriddenMethod().getRawParameter(getRawPosition())
+ result = this.getMethod().getOverriddenMethod().getRawParameter(this.getRawPosition())
}
override MethodParameter getUnboundDeclaration() {
- result = getMethod().getUnboundDeclaration().getRawParameter(getRawPosition())
+ result = this.getMethod().getUnboundDeclaration().getRawParameter(this.getRawPosition())
}
override string toString() { result = Parameter.super.toString() }
@@ -136,10 +139,10 @@ class ThisParameter extends MethodParameter {
/** A field. */
class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @cil_field {
- override string toString() { result = getName() }
+ override string toString() { result = this.getName() }
override string toStringWithTypes() {
- result = getDeclaringType().toStringWithTypes() + "." + getName()
+ result = this.getDeclaringType().toStringWithTypes() + "." + this.getName()
}
override string getName() { cil_field(this, _, result, _) }
@@ -148,5 +151,5 @@ class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @ci
override ValueOrRefType getDeclaringType() { cil_field(this, result, _, _) }
- override Location getLocation() { result = getDeclaringType().getLocation() }
+ override Location getLocation() { result = this.getDeclaringType().getLocation() }
}
diff --git a/csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll b/csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll
index 884f4406d01..395cb5cb171 100644
--- a/csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll
+++ b/csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll
@@ -156,6 +156,7 @@ private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) {
}
/** Holds if `df` is in the dominance frontier of `bb`. */
+pragma[noinline]
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and
not strictlyDominates(bb, df)
diff --git a/csharp/ql/lib/semmle/code/csharp/AnnotatedType.qll b/csharp/ql/lib/semmle/code/csharp/AnnotatedType.qll
index 37aa2b23410..8afdbd0d4a3 100644
--- a/csharp/ql/lib/semmle/code/csharp/AnnotatedType.qll
+++ b/csharp/ql/lib/semmle/code/csharp/AnnotatedType.qll
@@ -67,7 +67,7 @@ private module Annotations {
Nullability() { this = TNullability(nullability) }
- override string toString() { result = getMemberString() + getSelfNullability() }
+ override string toString() { result = this.getMemberString() + this.getSelfNullability() }
language[monotonicAggregates]
private string getMemberString() {
@@ -125,7 +125,9 @@ private module Annotations {
}
/** Gets a textual representation of this type annotation. */
- string toString() { result = getTypePrefix() + getNullability() + getTypeSuffix() }
+ string toString() {
+ result = this.getTypePrefix() + this.getNullability() + this.getTypeSuffix()
+ }
private int getFlags() { this = TAnnotationFlags(result, _) }
@@ -136,7 +138,7 @@ private module Annotations {
/** Gets an annotation in this set of annotations. */
TypeAnnotation getAnAnnotation() {
- isSet(result.getBit())
+ this.isSet(result.getBit())
or
result = this.getNullability()
}
@@ -298,7 +300,7 @@ class AnnotatedType extends TAnnotatedType {
/** Gets a textual representation of this annotated type. */
string toString() {
result =
- annotations.getTypePrefix() + getUnderlyingType().toStringWithTypes() +
+ annotations.getTypePrefix() + this.getUnderlyingType().toStringWithTypes() +
annotations.getTypeSuffix()
}
@@ -327,7 +329,7 @@ class AnnotatedType extends TAnnotatedType {
/** Gets a type annotation of this annotated type. */
private Annotations::TypeAnnotation getAnAnnotation() {
- result = getAnnotations().getAnAnnotation()
+ result = this.getAnnotations().getAnAnnotation()
}
/** Holds if the type is a non-nullable reference, for example, `string` in a nullable-enabled context. */
@@ -376,7 +378,7 @@ class AnnotatedArrayType extends AnnotatedType {
private string getDimensionString(AnnotatedType elementType) {
exists(AnnotatedType et, string res |
- et = getElementType() and
+ et = this.getElementType() and
res = type.getArraySuffix() and
if et.getUnderlyingType() instanceof ArrayType and not et.isNullableRefType()
then result = res + et.(AnnotatedArrayType).getDimensionString(elementType)
diff --git a/csharp/ql/lib/semmle/code/csharp/Attribute.qll b/csharp/ql/lib/semmle/code/csharp/Attribute.qll
index 2085c4c650a..dae9f8a9fad 100644
--- a/csharp/ql/lib/semmle/code/csharp/Attribute.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Attribute.qll
@@ -25,7 +25,7 @@ class Attributable extends @attributable {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -89,7 +89,7 @@ class Attribute extends TopLevelExprParent, @attribute {
override Location getALocation() { attribute_location(this, result) }
override string toString() {
- exists(string type, string name | type = getType().getName() |
+ exists(string type, string name | type = this.getType().getName() |
(if type.matches("%Attribute") then name = type.prefix(type.length() - 9) else name = type) and
result = "[" + name + "(...)]"
)
diff --git a/csharp/ql/lib/semmle/code/csharp/Callable.qll b/csharp/ql/lib/semmle/code/csharp/Callable.qll
index 133ae86d551..41641a9d032 100644
--- a/csharp/ql/lib/semmle/code/csharp/Callable.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Callable.qll
@@ -117,7 +117,7 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
final BlockStmt getAStatementBody() { result = this.getStatementBody() }
/** Holds if this callable has a statement body. */
- final predicate hasStatementBody() { exists(getStatementBody()) }
+ final predicate hasStatementBody() { exists(this.getStatementBody()) }
/**
* Gets the expression body of this callable (if any), specified by `=>`.
@@ -157,7 +157,7 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
deprecated final Expr getAnExpressionBody() { result = this.getExpressionBody() }
/** Holds if this callable has an expression body. */
- final predicate hasExpressionBody() { exists(getExpressionBody()) }
+ final predicate hasExpressionBody() { exists(this.getExpressionBody()) }
/** Gets the entry point in the control graph for this callable. */
ControlFlow::Nodes::EntryNode getEntryPoint() { result.getCallable() = this }
@@ -218,7 +218,9 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
exists(YieldReturnStmt yield | yield.getEnclosingCallable() = this | e = yield.getExpr())
}
- override string toStringWithTypes() { result = getName() + "(" + parameterTypesToString() + ")" }
+ override string toStringWithTypes() {
+ result = this.getName() + "(" + this.parameterTypesToString() + ")"
+ }
/** Gets a `Call` that has this callable as a target. */
Call getACall() { this = result.getTarget() }
@@ -270,18 +272,18 @@ class Method extends Callable, Virtualizable, Attributable, @method {
override Location getALocation() { method_location(this, result) }
/** Holds if this method is an extension method. */
- predicate isExtensionMethod() { getParameter(0).hasExtensionMethodModifier() }
+ predicate isExtensionMethod() { this.getParameter(0).hasExtensionMethodModifier() }
/** Gets the type of the `params` parameter of this method, if any. */
Type getParamsType() {
- exists(Parameter last | last = getParameter(getNumberOfParameters() - 1) |
+ exists(Parameter last | last = this.getParameter(this.getNumberOfParameters() - 1) |
last.isParams() and
result = last.getType().(ArrayType).getElementType()
)
}
/** Holds if this method has a `params` parameter. */
- predicate hasParams() { exists(getParamsType()) }
+ predicate hasParams() { exists(this.getParamsType()) }
// Remove when `Callable.isOverridden()` is removed
override predicate isOverridden() { Virtualizable.super.isOverridden() }
@@ -316,7 +318,7 @@ class ExtensionMethod extends Method {
/** Gets the type being extended by this method. */
pragma[noinline]
- Type getExtendedType() { result = getParameter(0).getType() }
+ Type getExtendedType() { result = this.getParameter(0).getType() }
override string getAPrimaryQlClass() { result = "ExtensionMethod" }
}
@@ -355,7 +357,7 @@ class Constructor extends DotNet::Constructor, Callable, Member, Attributable, @
ConstructorInitializer getInitializer() { result = this.getChildExpr(-1) }
/** Holds if this constructor has an initializer. */
- predicate hasInitializer() { exists(getInitializer()) }
+ predicate hasInitializer() { exists(this.getInitializer()) }
override ValueOrRefType getDeclaringType() { constructors(this, _, result, _) }
@@ -467,7 +469,7 @@ class Operator extends Callable, Member, Attributable, @operator {
override string toString() { result = Callable.super.toString() }
- override Parameter getRawParameter(int i) { result = getParameter(i) }
+ override Parameter getRawParameter(int i) { result = this.getParameter(i) }
}
/** A clone method on a record. */
@@ -999,10 +1001,10 @@ class LocalFunction extends Callable, Modifiable, Attributable, @local_function
override Type getReturnType() { local_functions(this, _, result, _) }
- override Element getParent() { result = getStatement().getParent() }
+ override Element getParent() { result = this.getStatement().getParent() }
/** Gets the local function statement defining this function. */
- LocalFunctionStmt getStatement() { result.getLocalFunction() = getUnboundDeclaration() }
+ LocalFunctionStmt getStatement() { result.getLocalFunction() = this.getUnboundDeclaration() }
override Callable getEnclosingCallable() { result = this.getStatement().getEnclosingCallable() }
@@ -1011,9 +1013,9 @@ class LocalFunction extends Callable, Modifiable, Attributable, @local_function
name = this.getName()
}
- override Location getALocation() { result = getStatement().getALocation() }
+ override Location getALocation() { result = this.getStatement().getALocation() }
- override Parameter getRawParameter(int i) { result = getParameter(i) }
+ override Parameter getRawParameter(int i) { result = this.getParameter(i) }
override string getAPrimaryQlClass() { result = "LocalFunction" }
diff --git a/csharp/ql/lib/semmle/code/csharp/Comments.qll b/csharp/ql/lib/semmle/code/csharp/Comments.qll
index 41f4e5b0be8..9a611b851e8 100644
--- a/csharp/ql/lib/semmle/code/csharp/Comments.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Comments.qll
@@ -11,7 +11,7 @@ import Location
/**
* A single line of comment.
*
- * Either a single line comment (`SingleLineComment`), an XML comment (`XmlComment`),
+ * Either a single line comment (`SinglelineComment`), an XML comment (`XmlComment`),
* or a line in a multi-line comment (`MultilineComment`).
*/
class CommentLine extends @commentline {
diff --git a/csharp/ql/lib/semmle/code/csharp/Conversion.qll b/csharp/ql/lib/semmle/code/csharp/Conversion.qll
index 0c560d1d86f..d62055b6a17 100644
--- a/csharp/ql/lib/semmle/code/csharp/Conversion.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Conversion.qll
@@ -552,11 +552,16 @@ private predicate defaultDynamicConversion(Type fromType, Type toType) {
fromType instanceof RefType and toType instanceof DynamicType
}
+pragma[noinline]
+private predicate systemDelegateBaseType(RefType t) {
+ t = any(SystemDelegateClass c).getABaseType*()
+}
+
// This is a deliberate, small cartesian product, so we have manually lifted it to force the
// evaluator to evaluate it in its entirety, rather than trying to optimize it in context.
pragma[noinline]
private predicate defaultDelegateConversion(RefType fromType, RefType toType) {
- fromType instanceof DelegateType and toType = any(SystemDelegateClass c).getABaseType*()
+ fromType instanceof DelegateType and systemDelegateBaseType(toType)
}
private predicate convRefTypeRefType(RefType fromType, RefType toType) {
diff --git a/csharp/ql/lib/semmle/code/csharp/Element.qll b/csharp/ql/lib/semmle/code/csharp/Element.qll
index fbd96f6086d..390a7b16632 100644
--- a/csharp/ql/lib/semmle/code/csharp/Element.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Element.qll
@@ -31,7 +31,7 @@ class Element extends DotNet::Element, @element {
Element getParent() { result.getAChild() = this }
/** Gets a child of this element, if any. */
- Element getAChild() { result = getChild(_) }
+ Element getAChild() { result = this.getChild(_) }
/** Gets the `i`th child of this element (zero-based). */
Element getChild(int i) { none() }
diff --git a/csharp/ql/lib/semmle/code/csharp/Event.qll b/csharp/ql/lib/semmle/code/csharp/Event.qll
index 7cbfda76877..810cffa927a 100644
--- a/csharp/ql/lib/semmle/code/csharp/Event.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Event.qll
@@ -29,10 +29,10 @@ class Event extends DeclarationWithAccessors, @event {
EventAccessor getAnEventAccessor() { result.getDeclaration() = this }
/** Gets the `add` accessor of this event, if any. */
- AddEventAccessor getAddEventAccessor() { result = getAnEventAccessor() }
+ AddEventAccessor getAddEventAccessor() { result = this.getAnEventAccessor() }
/** Gets the `remove` accessor of this event, if any. */
- RemoveEventAccessor getRemoveEventAccessor() { result = getAnEventAccessor() }
+ RemoveEventAccessor getRemoveEventAccessor() { result = this.getAnEventAccessor() }
/**
* Holds if this event can be used like a field within its declaring type
@@ -111,9 +111,9 @@ class EventAccessor extends Accessor, @event_accessor {
* ```
*/
class AddEventAccessor extends EventAccessor, @add_event_accessor {
- override string getName() { result = "add" + "_" + getDeclaration().getName() }
+ override string getName() { result = "add" + "_" + this.getDeclaration().getName() }
- override string getUndecoratedName() { result = "add" + "_" + getDeclaration().getName() }
+ override string getUndecoratedName() { result = "add" + "_" + this.getDeclaration().getName() }
override string getAPrimaryQlClass() { result = "AddEventAccessor" }
}
@@ -132,9 +132,9 @@ class AddEventAccessor extends EventAccessor, @add_event_accessor {
* ```
*/
class RemoveEventAccessor extends EventAccessor, @remove_event_accessor {
- override string getName() { result = "remove" + "_" + getDeclaration().getName() }
+ override string getName() { result = "remove" + "_" + this.getDeclaration().getName() }
- override string getUndecoratedName() { result = "remove" + "_" + getDeclaration().getName() }
+ override string getUndecoratedName() { result = "remove" + "_" + this.getDeclaration().getName() }
override string getAPrimaryQlClass() { result = "RemoveEventAccessor" }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/File.qll b/csharp/ql/lib/semmle/code/csharp/File.qll
index 8ee61b29085..55fd2ccdc81 100644
--- a/csharp/ql/lib/semmle/code/csharp/File.qll
+++ b/csharp/ql/lib/semmle/code/csharp/File.qll
@@ -33,7 +33,7 @@ class Container extends @container {
/**
* Gets a URL representing the location of this container.
*
- * For more information see [Providing URLs](https://help.semmle.com/QL/learn-ql/ql/locations.html#providing-urls).
+ * For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls).
*/
string getURL() { none() }
@@ -47,7 +47,7 @@ class Container extends @container {
*/
string getRelativePath() {
exists(string absPath, string pref |
- absPath = getAbsolutePath() and sourceLocationPrefix(pref)
+ absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
|
absPath = pref and result = ""
or
@@ -74,7 +74,7 @@ class Container extends @container {
*
*/
string getBaseName() {
- result = getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
+ result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
}
/**
@@ -100,7 +100,9 @@ class Container extends @container {
*
"/tmp/x.tar.gz"
"gz"
*
*/
- string getExtension() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3) }
+ string getExtension() {
+ result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
+ }
/**
* Gets the stem of this container, that is, the prefix of its base name up to
@@ -119,7 +121,9 @@ class Container extends @container {
*
"/tmp/x.tar.gz"
"x.tar"
*
*/
- string getStem() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1) }
+ string getStem() {
+ result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
+ }
/** Gets the parent container of this file or folder, if any. */
Container getParentContainer() { containerparent(result, this) }
@@ -128,52 +132,52 @@ class Container extends @container {
Container getAChildContainer() { this = result.getParentContainer() }
/** Gets a file in this container. */
- File getAFile() { result = getAChildContainer() }
+ File getAFile() { result = this.getAChildContainer() }
/** Gets the file in this container that has the given `baseName`, if any. */
File getFile(string baseName) {
- result = getAFile() and
+ result = this.getAFile() and
result.getBaseName() = baseName
}
/** Gets a sub-folder in this container. */
- Folder getAFolder() { result = getAChildContainer() }
+ Folder getAFolder() { result = this.getAChildContainer() }
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
Folder getFolder(string baseName) {
- result = getAFolder() and
+ result = this.getAFolder() and
result.getBaseName() = baseName
}
/** Gets the file or sub-folder in this container that has the given `name`, if any. */
Container getChildContainer(string name) {
- result = getAChildContainer() and
+ result = this.getAChildContainer() and
result.getBaseName() = name
}
/** Gets the file in this container that has the given `stem` and `extension`, if any. */
File getFile(string stem, string extension) {
- result = getAChildContainer() and
+ result = this.getAChildContainer() and
result.getStem() = stem and
result.getExtension() = extension
}
/** Gets a sub-folder contained in this container. */
- Folder getASubFolder() { result = getAChildContainer() }
+ Folder getASubFolder() { result = this.getAChildContainer() }
/**
* Gets a textual representation of the path of this container.
*
* This is the absolute path of the container.
*/
- string toString() { result = getAbsolutePath() }
+ string toString() { result = this.getAbsolutePath() }
}
/** A folder. */
class Folder extends Container, @folder {
override string getAbsolutePath() { folders(this, result) }
- override string getURL() { result = "folder://" + getAbsolutePath() }
+ override string getURL() { result = "folder://" + this.getAbsolutePath() }
}
/** A file. */
diff --git a/csharp/ql/lib/semmle/code/csharp/Generics.qll b/csharp/ql/lib/semmle/code/csharp/Generics.qll
index 25a3679715b..9190523e3c0 100644
--- a/csharp/ql/lib/semmle/code/csharp/Generics.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Generics.qll
@@ -71,14 +71,14 @@ class ConstructedGeneric extends DotNet::ConstructedGeneric, Generic {
override UnboundGeneric getUnboundGeneric() { constructed_generic(this, result) }
override UnboundGeneric getUnboundDeclaration() {
- result = getUnboundGeneric().getUnboundDeclaration()
+ result = this.getUnboundGeneric().getUnboundDeclaration()
}
override int getNumberOfTypeArguments() { result = count(int i | type_arguments(_, i, this)) }
override Type getTypeArgument(int i) { none() }
- override Type getATypeArgument() { result = getTypeArgument(_) }
+ override Type getATypeArgument() { result = this.getTypeArgument(_) }
/** Gets the annotated type of type argument `i`. */
final AnnotatedType getAnnotatedTypeArgument(int i) { result.appliesToTypeArgument(this, i) }
@@ -141,7 +141,7 @@ class UnboundGenericType extends ValueOrRefType, UnboundGeneric {
result = ValueOrRefType.super.getUnboundDeclaration()
}
- final override Type getChild(int n) { result = getTypeParameter(n) }
+ final override Type getChild(int n) { result = this.getTypeParameter(n) }
override string toStringWithTypes() {
result = this.getUndecoratedName() + "<" + getTypeParametersToString(this) + ">"
@@ -173,7 +173,7 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
TypeParameterConstraints getConstraints() { result.getTypeParameter() = this }
override predicate isRefType() {
- exists(TypeParameterConstraints tpc | tpc = getConstraints() |
+ exists(TypeParameterConstraints tpc | tpc = this.getConstraints() |
tpc.hasRefTypeConstraint() or
tpc.getATypeConstraint() instanceof Class or
tpc.getATypeConstraint().(TypeParameter).isRefType()
@@ -182,7 +182,7 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
}
override predicate isValueType() {
- exists(TypeParameterConstraints tpc | tpc = getConstraints() |
+ exists(TypeParameterConstraints tpc | tpc = this.getConstraints() |
tpc.hasValueTypeConstraint() or
tpc.getATypeConstraint().(TypeParameter).isValueType()
)
@@ -219,9 +219,9 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
/** Gets a non-type-parameter type that was transitively supplied for this parameter. */
Type getAnUltimatelySuppliedType() {
- result = getASuppliedType() and not result instanceof TypeParameter
+ result = this.getASuppliedType() and not result instanceof TypeParameter
or
- result = getASuppliedType().(TypeParameter).getAnUltimatelySuppliedType()
+ result = this.getASuppliedType().(TypeParameter).getAnUltimatelySuppliedType()
}
override int getIndex() { type_parameters(this, result, _, _) }
@@ -376,8 +376,8 @@ class UnboundGenericDelegateType extends DelegateType, UnboundGenericType {
override string toStringWithTypes() {
result =
- getUndecoratedName() + "<" + getTypeParametersToString(this) + ">(" + parameterTypesToString()
- + ")"
+ this.getUndecoratedName() + "<" + getTypeParametersToString(this) + ">(" +
+ this.parameterTypesToString() + ")"
}
}
@@ -404,7 +404,7 @@ class ConstructedType extends ValueOrRefType, ConstructedGeneric {
override UnboundGenericType getUnboundGeneric() { constructed_generic(this, getTypeRef(result)) }
- final override Type getChild(int n) { result = getTypeArgument(n) }
+ final override Type getChild(int n) { result = this.getTypeArgument(n) }
final override string toStringWithTypes() {
result = this.getUndecoratedName() + "<" + getTypeArgumentsToString(this) + ">"
@@ -542,12 +542,12 @@ class UnboundGenericMethod extends Method, UnboundGeneric {
override string toStringWithTypes() {
result =
- getUndecoratedName() + "<" + getTypeParametersToString(this) + ">" + "(" +
- parameterTypesToString() + ")"
+ this.getUndecoratedName() + "<" + getTypeParametersToString(this) + ">" + "(" +
+ this.parameterTypesToString() + ")"
}
final override string getName() {
- result = getUndecoratedName() + "<" + getTypeParameterCommas(this) + ">"
+ result = this.getUndecoratedName() + "<" + getTypeParameterCommas(this) + ">"
}
final override string getUndecoratedName() { methods(this, result, _, _, _) }
@@ -580,8 +580,8 @@ class ConstructedMethod extends Method, ConstructedGeneric {
override string toStringWithTypes() {
result =
- getUndecoratedName() + "<" + getTypeArgumentsToString(this) + ">" + "(" +
- parameterTypesToString() + ")"
+ this.getUndecoratedName() + "<" + getTypeArgumentsToString(this) + ">" + "(" +
+ this.parameterTypesToString() + ")"
}
override UnboundGenericMethod getUnboundDeclaration() {
@@ -589,12 +589,12 @@ class ConstructedMethod extends Method, ConstructedGeneric {
}
final override string getName() {
- result = getUndecoratedName() + "<" + getTypeArgumentsNames(this) + ">"
+ result = this.getUndecoratedName() + "<" + getTypeArgumentsNames(this) + ">"
}
override predicate hasQualifiedName(string qualifier, string name) {
- qualifier = getDeclaringType().getQualifiedName() and
- name = getUndecoratedName() + "<" + getTypeArgumentsQualifiedNames(this) + ">"
+ qualifier = this.getDeclaringType().getQualifiedName() and
+ name = this.getUndecoratedName() + "<" + getTypeArgumentsQualifiedNames(this) + ">"
}
final override string getUndecoratedName() { methods(this, result, _, _, _) }
diff --git a/csharp/ql/lib/semmle/code/csharp/Implements.qll b/csharp/ql/lib/semmle/code/csharp/Implements.qll
index c2d33d102dd..cc821b52823 100644
--- a/csharp/ql/lib/semmle/code/csharp/Implements.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Implements.qll
@@ -398,6 +398,15 @@ private module Gvn {
)
}
+ pragma[noinline]
+ private predicate toStringPart(int i, int j) {
+ exists(Unification::GenericType t, int children |
+ t = this.getConstructedGenericDeclaringTypeAt(i) and
+ children = t.getNumberOfArgumentsSelf() and
+ if children = 0 then j = 0 else j in [0 .. 2 * children]
+ )
+ }
+
language[monotonicAggregates]
string toString() {
this.isFullyConstructed() and
@@ -406,11 +415,7 @@ private module Gvn {
or
result =
strictconcat(int i, int j |
- exists(Unification::GenericType t, int children |
- t = this.getConstructedGenericDeclaringTypeAt(i) and
- children = t.getNumberOfArgumentsSelf() and
- if children = 0 then j = 0 else j in [0 .. 2 * children]
- )
+ this.toStringPart(i, j)
|
this.toStringConstructedPart(i, j) order by i desc, j
)
diff --git a/csharp/ql/lib/semmle/code/csharp/Location.qll b/csharp/ql/lib/semmle/code/csharp/Location.qll
index 97f9302c474..22d87f42424 100644
--- a/csharp/ql/lib/semmle/code/csharp/Location.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Location.qll
@@ -28,7 +28,7 @@ class Location extends @location {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/csharp/ql/lib/semmle/code/csharp/Member.qll b/csharp/ql/lib/semmle/code/csharp/Member.qll
index 9f8408621fc..40b887f052a 100644
--- a/csharp/ql/lib/semmle/code/csharp/Member.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Member.qll
@@ -155,7 +155,9 @@ class Modifiable extends Declaration, @modifiable {
* Holds if this declaration is effectively `public`, meaning that it can be
* referenced outside the declaring assembly.
*/
- predicate isEffectivelyPublic() { not isEffectivelyPrivate() and not isEffectivelyInternal() }
+ predicate isEffectivelyPublic() {
+ not this.isEffectivelyPrivate() and not this.isEffectivelyInternal()
+ }
}
/** A declaration that is a member of a type. */
@@ -193,12 +195,12 @@ class Virtualizable extends Member, @virtualizable {
override predicate isPublic() {
Member.super.isPublic() or
- implementsExplicitInterface()
+ this.implementsExplicitInterface()
}
override predicate isPrivate() {
super.isPrivate() and
- not implementsExplicitInterface()
+ not this.implementsExplicitInterface()
}
/**
@@ -211,17 +213,17 @@ class Virtualizable extends Member, @virtualizable {
/**
* Holds if this member implements an interface member explicitly.
*/
- predicate implementsExplicitInterface() { exists(getExplicitlyImplementedInterface()) }
+ predicate implementsExplicitInterface() { exists(this.getExplicitlyImplementedInterface()) }
/** Holds if this member can be overridden or implemented. */
predicate isOverridableOrImplementable() {
- not isSealed() and
- not getDeclaringType().isSealed() and
+ not this.isSealed() and
+ not this.getDeclaringType().isSealed() and
(
- isVirtual() or
- isOverride() or
- isAbstract() or
- getDeclaringType() instanceof Interface
+ this.isVirtual() or
+ this.isOverride() or
+ this.isAbstract() or
+ this.getDeclaringType() instanceof Interface
)
}
@@ -243,10 +245,10 @@ class Virtualizable extends Member, @virtualizable {
Virtualizable getAnOverrider() { this = result.getOverridee() }
/** Holds if this member is overridden by some other member. */
- predicate isOverridden() { exists(getAnOverrider()) }
+ predicate isOverridden() { exists(this.getAnOverrider()) }
/** Holds if this member overrides another member. */
- predicate overrides() { exists(getOverridee()) }
+ predicate overrides() { exists(this.getOverridee()) }
/**
* Gets the interface member that is immediately implemented by this member, if any.
@@ -274,7 +276,7 @@ class Virtualizable extends Member, @virtualizable {
Virtualizable getImplementee(ValueOrRefType t) { implements(this, result, t) }
/** Gets the interface member that is immediately implemented by this member, if any. */
- Virtualizable getImplementee() { result = getImplementee(_) }
+ Virtualizable getImplementee() { result = this.getImplementee(_) }
/**
* Gets a member that immediately implements this interface member, if any.
@@ -338,8 +340,8 @@ class Virtualizable extends Member, @virtualizable {
|
this = implementation
or
- getOverridee+() = implementation and
- getDeclaringType().getABaseType+() = implementationType
+ this.getOverridee+() = implementation and
+ this.getDeclaringType().getABaseType+() = implementationType
)
}
@@ -355,10 +357,10 @@ class Virtualizable extends Member, @virtualizable {
Virtualizable getAnUltimateImplementor() { this = result.getAnUltimateImplementee() }
/** Holds if this interface member is implemented by some other member. */
- predicate isImplemented() { exists(getAnImplementor()) }
+ predicate isImplemented() { exists(this.getAnImplementor()) }
/** Holds if this member implements (transitively) an interface member. */
- predicate implements() { exists(getAnUltimateImplementee()) }
+ predicate implements() { exists(this.getAnUltimateImplementee()) }
/**
* Holds if this member overrides or implements (reflexively, transitively)
@@ -366,8 +368,8 @@ class Virtualizable extends Member, @virtualizable {
*/
predicate overridesOrImplementsOrEquals(Virtualizable that) {
this = that or
- getOverridee+() = that or
- getAnUltimateImplementee() = that
+ this.getOverridee+() = that or
+ this.getAnUltimateImplementee() = that
}
}
@@ -386,7 +388,7 @@ class Parameterizable extends DotNet::Parameterizable, Declaration, @parameteriz
*/
private string parameterTypeToString(int i) {
exists(Parameter p, string prefix |
- p = getParameter(i) and
+ p = this.getParameter(i) and
result = prefix + p.getType().toStringWithTypes()
|
if p.isOut()
@@ -407,6 +409,7 @@ class Parameterizable extends DotNet::Parameterizable, Declaration, @parameteriz
*/
language[monotonicAggregates]
string parameterTypesToString() {
- result = concat(int i | exists(getParameter(i)) | parameterTypeToString(i), ", " order by i)
+ result =
+ concat(int i | exists(this.getParameter(i)) | this.parameterTypeToString(i), ", " order by i)
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/Modifier.qll b/csharp/ql/lib/semmle/code/csharp/Modifier.qll
index 542598d204e..39652070af3 100644
--- a/csharp/ql/lib/semmle/code/csharp/Modifier.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Modifier.qll
@@ -19,10 +19,5 @@ class Modifier extends Element, @modifier {
* An access modifier: `public`, `private`, `internal` or `protected`.
*/
class AccessModifier extends Modifier {
- AccessModifier() {
- hasName("public") or
- hasName("private") or
- hasName("internal") or
- hasName("protected")
- }
+ AccessModifier() { this.hasName(["public", "private", "internal", "protected"]) }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/Preprocessor.qll b/csharp/ql/lib/semmle/code/csharp/Preprocessor.qll
index daf4978da53..3342dd5c59c 100644
--- a/csharp/ql/lib/semmle/code/csharp/Preprocessor.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Preprocessor.qll
@@ -289,7 +289,7 @@ class IfDirective extends ConditionalDirective, @directive_if {
}
/** Gets a sibling `#elif` or `#else` preprocessor directive. */
- BranchDirective getASiblingDirective() { result = getSiblingDirective(_) }
+ BranchDirective getASiblingDirective() { result = this.getSiblingDirective(_) }
override string toString() { result = "#if ..." }
diff --git a/csharp/ql/lib/semmle/code/csharp/PrintAst.qll b/csharp/ql/lib/semmle/code/csharp/PrintAst.qll
index a701c7bfbf3..a3d36fba69d 100644
--- a/csharp/ql/lib/semmle/code/csharp/PrintAst.qll
+++ b/csharp/ql/lib/semmle/code/csharp/PrintAst.qll
@@ -171,7 +171,7 @@ class PrintAstNode extends TPrintAstNode {
/**
* Gets a child of this node.
*/
- final PrintAstNode getAChild() { result = getChild(_) }
+ final PrintAstNode getAChild() { result = this.getChild(_) }
/**
* Gets the parent of this node, if any.
@@ -189,7 +189,7 @@ class PrintAstNode extends TPrintAstNode {
*/
string getProperty(string key) {
key = "semmle.label" and
- result = toString()
+ result = this.toString()
}
/**
@@ -198,7 +198,7 @@ class PrintAstNode extends TPrintAstNode {
* this.
*/
string getChildEdgeLabel(int childIndex) {
- exists(getChild(childIndex)) and
+ exists(this.getChild(childIndex)) and
result = childIndex.toString()
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/Property.qll b/csharp/ql/lib/semmle/code/csharp/Property.qll
index 5464142a085..a91ac6f13a4 100644
--- a/csharp/ql/lib/semmle/code/csharp/Property.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Property.qll
@@ -53,10 +53,10 @@ class DeclarationWithAccessors extends AssignableMember, Virtualizable, Attribut
class DeclarationWithGetSetAccessors extends DeclarationWithAccessors, TopLevelExprParent,
@assignable_with_accessors {
/** Gets the `get` accessor of this declaration, if any. */
- Getter getGetter() { result = getAnAccessor() }
+ Getter getGetter() { result = this.getAnAccessor() }
/** Gets the `set` accessor of this declaration, if any. */
- Setter getSetter() { result = getAnAccessor() }
+ Setter getSetter() { result = this.getAnAccessor() }
override DeclarationWithGetSetAccessors getOverridee() {
result = DeclarationWithAccessors.super.getOverridee()
@@ -182,10 +182,10 @@ class Property extends DotNet::Property, DeclarationWithGetSetAccessors, @proper
or
// For library types, we don't know about assignments in constructors. We instead assume that
// arguments passed to parameters of constructors with suitable names.
- getDeclaringType().fromLibrary() and
+ this.getDeclaringType().fromLibrary() and
exists(Parameter param, Constructor c, string propertyName |
- propertyName = getName() and
- c = getDeclaringType().getAConstructor() and
+ propertyName = this.getName() and
+ c = this.getDeclaringType().getAConstructor() and
param = c.getAParameter() and
// Find a constructor parameter with the same name, but with a lower case initial letter.
param.hasName(propertyName.charAt(0).toLowerCase() + propertyName.suffix(1))
@@ -256,7 +256,7 @@ class Indexer extends DeclarationWithGetSetAccessors, Parameterizable, @indexer
override string getUndecoratedName() { indexers(this, result, _, _, _) }
/** Gets the dimension of this indexer, that is, its number of parameters. */
- int getDimension() { result = getNumberOfParameters() }
+ int getDimension() { result = this.getNumberOfParameters() }
override ValueOrRefType getDeclaringType() { indexers(this, _, result, _, _) }
@@ -304,7 +304,9 @@ class Indexer extends DeclarationWithGetSetAccessors, Parameterizable, @indexer
override Location getALocation() { indexer_location(this, result) }
- override string toStringWithTypes() { result = getName() + "[" + parameterTypesToString() + "]" }
+ override string toStringWithTypes() {
+ result = this.getName() + "[" + this.parameterTypesToString() + "]"
+ }
override string getAPrimaryQlClass() { result = "Indexer" }
}
@@ -368,17 +370,17 @@ class Accessor extends Callable, Modifiable, Attributable, @callable_accessor {
* ```
*/
override Modifier getAModifier() {
- result = getAnAccessModifier()
+ result = this.getAnAccessModifier()
or
- result = getDeclaration().getAModifier() and
- not (result instanceof AccessModifier and exists(getAnAccessModifier()))
+ result = this.getDeclaration().getAModifier() and
+ not (result instanceof AccessModifier and exists(this.getAnAccessModifier()))
}
override Accessor getUnboundDeclaration() { accessors(this, _, _, _, result) }
override Location getALocation() { accessor_location(this, result) }
- override string toString() { result = getName() }
+ override string toString() { result = this.getName() }
}
/**
@@ -395,11 +397,11 @@ class Accessor extends Callable, Modifiable, Attributable, @callable_accessor {
* ```
*/
class Getter extends Accessor, @getter {
- override string getName() { result = "get" + "_" + getDeclaration().getName() }
+ override string getName() { result = "get" + "_" + this.getDeclaration().getName() }
- override string getUndecoratedName() { result = "get" + "_" + getDeclaration().getName() }
+ override string getUndecoratedName() { result = "get" + "_" + this.getDeclaration().getName() }
- override Type getReturnType() { result = getDeclaration().getType() }
+ override Type getReturnType() { result = this.getDeclaration().getType() }
/**
* Gets the field used in the trival implementation of this getter, if any.
@@ -417,8 +419,8 @@ class Getter extends Accessor, @getter {
*/
Field trivialGetterField() {
exists(ReturnStmt ret |
- getStatementBody().getNumberOfStmts() = 1 and
- getStatementBody().getAChild() = ret and
+ this.getStatementBody().getNumberOfStmts() = 1 and
+ this.getStatementBody().getAChild() = ret and
ret.getExpr() = result.getAnAccess()
)
}
@@ -444,9 +446,9 @@ class Getter extends Accessor, @getter {
* ```
*/
class Setter extends Accessor, @setter {
- override string getName() { result = "set" + "_" + getDeclaration().getName() }
+ override string getName() { result = "set" + "_" + this.getDeclaration().getName() }
- override string getUndecoratedName() { result = "set" + "_" + getDeclaration().getName() }
+ override string getUndecoratedName() { result = "set" + "_" + this.getDeclaration().getName() }
override Type getReturnType() {
exists(this) and // needed to avoid compiler warning
@@ -469,8 +471,8 @@ class Setter extends Accessor, @setter {
*/
Field trivialSetterField() {
exists(AssignExpr assign |
- getStatementBody().getNumberOfStmts() = 1 and
- assign.getParent() = getStatementBody().getAChild() and
+ this.getStatementBody().getNumberOfStmts() = 1 and
+ assign.getParent() = this.getStatementBody().getAChild() and
assign.getLValue() = result.getAnAccess() and
assign.getRValue() = accessToValue()
)
@@ -521,9 +523,9 @@ private ParameterAccess accessToValue() {
*/
class TrivialProperty extends Property {
TrivialProperty() {
- isAutoImplemented()
+ this.isAutoImplemented()
or
- getGetter().trivialGetterField() = getSetter().trivialSetterField()
+ this.getGetter().trivialGetterField() = this.getSetter().trivialSetterField()
or
exists(CIL::TrivialProperty prop | this.matchesHandle(prop))
}
diff --git a/csharp/ql/lib/semmle/code/csharp/Stmt.qll b/csharp/ql/lib/semmle/code/csharp/Stmt.qll
index 2ccd57078db..be074c176ba 100644
--- a/csharp/ql/lib/semmle/code/csharp/Stmt.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Stmt.qll
@@ -65,10 +65,10 @@ class BlockStmt extends Stmt, @block_stmt {
int getNumberOfStmts() { result = count(this.getAStmt()) }
/** Gets the first statement in this block, if any. */
- Stmt getFirstStmt() { result = getStmt(0) }
+ Stmt getFirstStmt() { result = this.getStmt(0) }
/** Gets the last statement in this block, if any. */
- Stmt getLastStmt() { result = getStmt(getNumberOfStmts() - 1) }
+ Stmt getLastStmt() { result = this.getStmt(this.getNumberOfStmts() - 1) }
/** Holds if this block is an empty block with no statements. */
predicate isEmpty() { not exists(this.getAStmt()) }
@@ -79,8 +79,8 @@ class BlockStmt extends Stmt, @block_stmt {
}
override Stmt stripSingletonBlocks() {
- if getNumberOfStmts() = 1
- then result = getAChildStmt().stripSingletonBlocks()
+ if this.getNumberOfStmts() = 1
+ then result = this.getAChildStmt().stripSingletonBlocks()
else result = this
}
@@ -420,7 +420,7 @@ class ForStmt extends LoopStmt, @for_stmt {
* }
* ```
*/
- Expr getAnInitializer() { result = getInitializer(_) }
+ Expr getAnInitializer() { result = this.getInitializer(_) }
/**
* Gets the `n`th initializer expression of this `for` loop
@@ -451,7 +451,7 @@ class ForStmt extends LoopStmt, @for_stmt {
* }
* ```
*/
- Expr getAnUpdate() { result = getUpdate(_) }
+ Expr getAnUpdate() { result = this.getUpdate(_) }
/**
* Gets the `n`th update expression of this `for` loop (starting at index 0).
@@ -519,7 +519,7 @@ class ForeachStmt extends LoopStmt, @foreach_stmt {
* ```
*/
LocalVariableDeclExpr getVariableDeclExpr(int i) {
- result = getVariableDeclTuple().getArgument(i)
+ result = this.getVariableDeclTuple().getArgument(i)
or
i = 0 and result = this.getChild(0)
}
@@ -547,7 +547,7 @@ class ForeachStmt extends LoopStmt, @foreach_stmt {
* }
* ```
*/
- LocalVariable getVariable(int i) { result = getVariableDeclExpr(i).getVariable() }
+ LocalVariable getVariable(int i) { result = this.getVariableDeclExpr(i).getVariable() }
/**
* Gets a local variable of this `foreach` loop.
@@ -560,7 +560,7 @@ class ForeachStmt extends LoopStmt, @foreach_stmt {
* }
* ```
*/
- LocalVariable getAVariable() { result = getVariable(_) }
+ LocalVariable getAVariable() { result = this.getVariable(_) }
/**
* Gets a local variable declaration of this `foreach` loop.
@@ -573,7 +573,7 @@ class ForeachStmt extends LoopStmt, @foreach_stmt {
* }
* ```
*/
- LocalVariableDeclExpr getAVariableDeclExpr() { result = getVariableDeclExpr(_) }
+ LocalVariableDeclExpr getAVariableDeclExpr() { result = this.getVariableDeclExpr(_) }
override Expr getCondition() { none() }
@@ -690,8 +690,8 @@ class GotoLabelStmt extends GotoStmt, @goto_stmt {
/** Gets the target statement that this `goto` statement jumps to. */
LabeledStmt getTarget() {
- result.getEnclosingCallable() = getEnclosingCallable() and
- result.getLabel() = getLabel()
+ result.getEnclosingCallable() = this.getEnclosingCallable() and
+ result.getLabel() = this.getLabel()
}
override string getAPrimaryQlClass() { result = "GotoLabelStmt" }
@@ -717,7 +717,7 @@ class GotoCaseStmt extends GotoStmt, @goto_case_stmt {
/** Gets the constant expression that this `goto case` statement jumps to. */
Expr getExpr() { result = this.getChild(0) }
- override string getLabel() { result = getExpr().getValue() }
+ override string getLabel() { result = this.getExpr().getValue() }
override string toString() { result = "goto case ...;" }
@@ -764,14 +764,14 @@ class ThrowStmt extends JumpStmt, ThrowElement, @throw_stmt {
override ExceptionClass getThrownExceptionType() {
result = ThrowElement.super.getThrownExceptionType()
or
- result = getRethrowParent().(CatchClause).getCaughtExceptionType()
+ result = this.getRethrowParent().(CatchClause).getCaughtExceptionType()
}
private ControlFlowElement getRethrowParent() {
- result = this and not exists(getExpr())
+ result = this and not exists(this.getExpr())
or
exists(ControlFlowElement mid |
- mid = getRethrowParent() and
+ mid = this.getRethrowParent() and
not mid instanceof CatchClause and
result = mid.getParent()
)
@@ -785,7 +785,7 @@ class ThrowStmt extends JumpStmt, ThrowElement, @throw_stmt {
* and may be thrown as an exception.
*/
class ExceptionClass extends Class {
- ExceptionClass() { getBaseClass*() instanceof SystemExceptionClass }
+ ExceptionClass() { this.getBaseClass*() instanceof SystemExceptionClass }
}
/**
@@ -897,13 +897,15 @@ class TryStmt extends Stmt, @try_stmt {
override string getAPrimaryQlClass() { result = "TryStmt" }
/** Gets the `catch` clause that handles an exception of type `ex`, if any. */
- CatchClause getAnExceptionHandler(ExceptionClass ex) { result = clauseHandlesException(ex, 0) }
+ CatchClause getAnExceptionHandler(ExceptionClass ex) {
+ result = this.clauseHandlesException(ex, 0)
+ }
/**
* Holds if catch clause `cc` definitely handles exceptions of type `ex`.
*/
predicate definitelyHandles(ExceptionClass ex, CatchClause cc) {
- cc = getACatchClause() and
+ cc = this.getACatchClause() and
not exists(cc.getFilterClause()) and
(
cc.getCaughtExceptionType() = ex.getBaseClass*()
@@ -913,22 +915,22 @@ class TryStmt extends Stmt, @try_stmt {
}
private predicate maybeHandles(ExceptionClass ex, CatchClause cc) {
- cc = getACatchClause() and
+ cc = this.getACatchClause() and
cc.getCaughtExceptionType().getBaseClass*() = ex
}
private CatchClause clauseHandlesException(ExceptionClass ex, int n) {
- exists(CatchClause clause | clause = getCatchClause(n) |
- if definitelyHandles(ex, clause)
+ exists(CatchClause clause | clause = this.getCatchClause(n) |
+ if this.definitelyHandles(ex, clause)
then result = clause
else
- if maybeHandles(ex, clause)
+ if this.maybeHandles(ex, clause)
then
result = clause or
- result = clauseHandlesException(ex, n + 1)
+ result = this.clauseHandlesException(ex, n + 1)
else
// Does not handle
- result = clauseHandlesException(ex, n + 1)
+ result = this.clauseHandlesException(ex, n + 1)
)
}
@@ -939,10 +941,10 @@ class TryStmt extends Stmt, @try_stmt {
* `try` statement.
*/
ControlFlowElement getATriedElement() {
- result = getBlock()
+ result = this.getBlock()
or
exists(ControlFlowElement mid |
- mid = getATriedElement() and
+ mid = this.getATriedElement() and
not mid instanceof TryStmt and
result = getAChild(mid, mid.getEnclosingCallable())
)
@@ -996,10 +998,10 @@ class CatchClause extends Stmt, @catch {
* }
* ```
*/
- Expr getFilterClause() { result = getChild(2) }
+ Expr getFilterClause() { result = this.getChild(2) }
/** Holds if this `catch` clause has a filter. */
- predicate hasFilterClause() { exists(getFilterClause()) }
+ predicate hasFilterClause() { exists(this.getFilterClause()) }
/** Holds if this is the last `catch` clause in the `try` statement that it belongs to. */
predicate isLast() {
@@ -1120,7 +1122,7 @@ class LockStmt extends Stmt, @lock_stmt {
override string toString() { result = "lock (...) {...}" }
/** Gets the variable being locked, if any. */
- Variable getLockVariable() { result.getAnAccess() = getExpr() }
+ Variable getLockVariable() { result.getAnAccess() = this.getExpr() }
/** Gets a statement in the scope of this `lock` statement. */
Stmt getALockedStmt() {
@@ -1128,14 +1130,14 @@ class LockStmt extends Stmt, @lock_stmt {
// delegates and lambdas
result.getParent() = this
or
- exists(Stmt mid | mid = getALockedStmt() and result.getParent() = mid)
+ exists(Stmt mid | mid = this.getALockedStmt() and result.getParent() = mid)
}
/** Holds if this statement is of the form `lock(this) { ... }`. */
- predicate isLockThis() { getExpr() instanceof ThisAccess }
+ predicate isLockThis() { this.getExpr() instanceof ThisAccess }
/** Gets the type `T` if this statement is of the form `lock(typeof(T)) { ... }`. */
- Type getLockTypeObject() { result = getExpr().(TypeofExpr).getTypeAccess().getTarget() }
+ Type getLockTypeObject() { result = this.getExpr().(TypeofExpr).getTypeAccess().getTarget() }
override string getAPrimaryQlClass() { result = "LockStmt" }
}
@@ -1453,7 +1455,7 @@ class LocalFunctionStmt extends Stmt, @local_function_stmt {
/** Gets the local function defined by this statement. */
LocalFunction getLocalFunction() { local_function_stmts(this, result) }
- override string toString() { result = getLocalFunction().getName() + "(...)" }
+ override string toString() { result = this.getLocalFunction().getName() + "(...)" }
override string getAPrimaryQlClass() { result = "LocalFunctionStmt" }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/Type.qll b/csharp/ql/lib/semmle/code/csharp/Type.qll
index d7a15000bbf..109c1df00c7 100644
--- a/csharp/ql/lib/semmle/code/csharp/Type.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Type.qll
@@ -37,7 +37,7 @@ class Type extends DotNet::Type, Member, TypeContainer, @type {
predicate containsTypeParameters() {
this instanceof TypeParameter
or
- not this instanceof UnboundGenericType and getAChild().containsTypeParameters()
+ not this instanceof UnboundGenericType and this.getAChild().containsTypeParameters()
}
/** Holds if this type is a reference type, or a type parameter that is a reference type. */
@@ -133,8 +133,8 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
/** Gets an immediate base type of this type, if any. */
override ValueOrRefType getABaseType() {
- result = getBaseClass() or
- result = getABaseInterface()
+ result = this.getBaseClass() or
+ result = this.getABaseInterface()
}
/** Gets an immediate subtype of this type, if any. */
@@ -200,9 +200,9 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
*/
pragma[inline]
predicate hasCallable(Callable c) {
- hasMethod(c)
+ this.hasMethod(c)
or
- hasMember(c.(Accessor).getDeclaration())
+ this.hasMember(c.(Accessor).getDeclaration())
}
/**
@@ -234,63 +234,63 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
or
hasNonOverriddenMember(this.getBaseClass+(), m)
or
- hasOverriddenMember(m)
+ this.hasOverriddenMember(m)
}
cached
private predicate hasOverriddenMember(Virtualizable v) {
v.isOverridden() and
- v = getAMember()
+ v = this.getAMember()
or
- getBaseClass().(ValueOrRefType).hasOverriddenMember(v) and
+ this.getBaseClass().(ValueOrRefType).hasOverriddenMember(v) and
not v.isPrivate() and
- not memberOverrides(v)
+ not this.memberOverrides(v)
}
// Predicate folding for proper join-order
pragma[noinline]
private predicate memberOverrides(Virtualizable v) {
- getAMember().(Virtualizable).getOverridee() = v
+ this.getAMember().(Virtualizable).getOverridee() = v
}
/** Gets a field (or member constant) with the given name. */
- Field getField(string name) { result = getAMember() and result.hasName(name) }
+ Field getField(string name) { result = this.getAMember() and result.hasName(name) }
/** Gets a field (or member constant) of this type, if any. */
Field getAField() { result = this.getField(_) }
/** Gets a member constant of this type, if any. */
- MemberConstant getAConstant() { result = getAMember() }
+ MemberConstant getAConstant() { result = this.getAMember() }
/** Gets a method of this type, if any. */
- Method getAMethod() { result = getAMember() }
+ Method getAMethod() { result = this.getAMember() }
/** Gets a method of this type with the given name. */
- Method getAMethod(string name) { result = getAMember() and result.hasName(name) }
+ Method getAMethod(string name) { result = this.getAMember() and result.hasName(name) }
/** Gets a property of this type, if any. */
- Property getAProperty() { result = getAMember() }
+ Property getAProperty() { result = this.getAMember() }
/** Gets a named property of this type. */
- Property getProperty(string name) { result = getAMember() and result.hasName(name) }
+ Property getProperty(string name) { result = this.getAMember() and result.hasName(name) }
/** Gets an indexer of this type, if any. */
- Indexer getAnIndexer() { result = getAMember() }
+ Indexer getAnIndexer() { result = this.getAMember() }
/** Gets an event of this type, if any. */
- Event getAnEvent() { result = getAMember() }
+ Event getAnEvent() { result = this.getAMember() }
/** Gets a user-defined operator of this type, if any. */
- Operator getAnOperator() { result = getAMember() }
+ Operator getAnOperator() { result = this.getAMember() }
/** Gets a static or instance constructor of this type, if any. */
- Constructor getAConstructor() { result = getAMember() }
+ Constructor getAConstructor() { result = this.getAMember() }
/** Gets the static constructor of this type, if any. */
- StaticConstructor getStaticConstructor() { result = getAMember() }
+ StaticConstructor getStaticConstructor() { result = this.getAMember() }
/** Gets a nested type of this type, if any. */
- NestedType getANestedType() { result = getAMember() }
+ NestedType getANestedType() { result = this.getAMember() }
/** Gets the number of types that directly depend on this type. */
int getAfferentCoupling() { afferentCoupling(this, result) }
@@ -675,10 +675,10 @@ class Enum extends ValueType, @enum_type {
*/
class Struct extends ValueType, @struct_type {
/** Holds if this `struct` has a `ref` modifier. */
- predicate isRef() { hasModifier("ref") }
+ predicate isRef() { this.hasModifier("ref") }
/** Holds if this `struct` has a `readonly` modifier. */
- predicate isReadonly() { hasModifier("readonly") }
+ predicate isReadonly() { this.hasModifier("readonly") }
override string getAPrimaryQlClass() { result = "Struct" }
}
@@ -695,7 +695,7 @@ class RefType extends ValueOrRefType, @ref_type {
/** Gets a member that overrides a non-abstract member in a super type, if any. */
private Virtualizable getAnOverrider() {
- getAMember() = result and
+ this.getAMember() = result and
exists(Virtualizable v | result.getOverridee() = v and not v.isAbstract())
}
@@ -897,14 +897,14 @@ class FunctionPointerType extends Type, Parameterizable, @function_pointer_type
}
/** Gets an unmanaged calling convention. */
- Type getAnUnmanagedCallingConvention() { result = getUnmanagedCallingConvention(_) }
+ Type getAnUnmanagedCallingConvention() { result = this.getUnmanagedCallingConvention(_) }
/** Gets the annotated return type of this function pointer type. */
AnnotatedType getAnnotatedReturnType() { result.appliesTo(this) }
override string getAPrimaryQlClass() { result = "FunctionPointerType" }
- override string getLabel() { result = getName() }
+ override string getLabel() { result = this.getName() }
}
/**
@@ -922,13 +922,15 @@ class NullableType extends ValueType, DotNet::ConstructedGeneric, @nullable_type
*/
Type getUnderlyingType() { nullable_underlying_type(this, getTypeRef(result)) }
- override string toStringWithTypes() { result = getUnderlyingType().toStringWithTypes() + "?" }
+ override string toStringWithTypes() {
+ result = this.getUnderlyingType().toStringWithTypes() + "?"
+ }
- override Type getChild(int n) { result = getUnderlyingType() and n = 0 }
+ override Type getChild(int n) { result = this.getUnderlyingType() and n = 0 }
- override Location getALocation() { result = getUnderlyingType().getALocation() }
+ override Location getALocation() { result = this.getUnderlyingType().getALocation() }
- override Type getTypeArgument(int p) { p = 0 and result = getUnderlyingType() }
+ override Type getTypeArgument(int p) { p = 0 and result = this.getUnderlyingType() }
override string getAPrimaryQlClass() { result = "NullableType" }
@@ -966,8 +968,8 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
/** Holds if this array type has the same shape (dimension and rank) as `that` array type. */
predicate hasSameShapeAs(ArrayType that) {
- getDimension() = that.getDimension() and
- getRank() = that.getRank()
+ this.getDimension() = that.getDimension() and
+ this.getRank() = that.getRank()
}
/**
@@ -981,7 +983,7 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
private string getDimensionString(Type elementType) {
exists(Type et, string res |
et = this.getElementType() and
- res = getArraySuffix() and
+ res = this.getArraySuffix() and
if et instanceof ArrayType
then result = res + et.(ArrayType).getDimensionString(elementType)
else (
@@ -996,7 +998,7 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
)
}
- override Type getChild(int n) { result = getElementType() and n = 0 }
+ override Type getChild(int n) { result = this.getElementType() and n = 0 }
override Location getALocation() {
type_location(this, result)
@@ -1021,13 +1023,15 @@ class PointerType extends DotNet::PointerType, Type, @pointer_type {
override string toStringWithTypes() { result = DotNet::PointerType.super.toStringWithTypes() }
- override Type getChild(int n) { result = getReferentType() and n = 0 }
+ override Type getChild(int n) { result = this.getReferentType() and n = 0 }
final override string getName() { types(this, _, result) }
- final override string getUndecoratedName() { result = getReferentType().getUndecoratedName() }
+ final override string getUndecoratedName() {
+ result = this.getReferentType().getUndecoratedName()
+ }
- override Location getALocation() { result = getReferentType().getALocation() }
+ override Location getALocation() { result = this.getReferentType().getALocation() }
override string toString() { result = DotNet::PointerType.super.toString() }
@@ -1082,10 +1086,10 @@ class TupleType extends ValueType, @tuple_type {
* Gets the type of the `n`th element of this tuple, indexed from 0.
* For example, the 0th (first) element type of `(int, string)` is `int`.
*/
- Type getElementType(int n) { result = getElement(n).getType() }
+ Type getElementType(int n) { result = this.getElement(n).getType() }
/** Gets an element of this tuple. */
- Field getAnElement() { result = getElement(_) }
+ Field getAnElement() { result = this.getElement(_) }
override Location getALocation() { type_location(this, result) }
@@ -1093,23 +1097,27 @@ class TupleType extends ValueType, @tuple_type {
* Gets the arity of this tuple. For example, the arity of
* `(int, int, double)` is 3.
*/
- int getArity() { result = count(getAnElement()) }
+ int getArity() { result = count(this.getAnElement()) }
language[monotonicAggregates]
override string toStringWithTypes() {
result =
"(" +
- concat(Type t, int i | t = getElement(i).getType() | t.toStringWithTypes(), ", " order by i)
- + ")"
+ concat(Type t, int i |
+ t = this.getElement(i).getType()
+ |
+ t.toStringWithTypes(), ", " order by i
+ ) + ")"
}
language[monotonicAggregates]
override string getName() {
result =
- "(" + concat(Type t, int i | t = getElement(i).getType() | t.getName(), "," order by i) + ")"
+ "(" + concat(Type t, int i | t = this.getElement(i).getType() | t.getName(), "," order by i) +
+ ")"
}
- override string getLabel() { result = getUnderlyingType().getLabel() }
+ override string getLabel() { result = this.getUnderlyingType().getLabel() }
override Type getChild(int i) { result = this.getUnderlyingType().getChild(i) }
diff --git a/csharp/ql/lib/semmle/code/csharp/Unification.qll b/csharp/ql/lib/semmle/code/csharp/Unification.qll
index 173feedb695..d9f39cec603 100644
--- a/csharp/ql/lib/semmle/code/csharp/Unification.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Unification.qll
@@ -277,6 +277,18 @@ module Gvn {
)
}
+ pragma[noinline]
+ private predicate toStringPart(int i, int j) {
+ exists(int offset |
+ exists(GenericType t, int children |
+ t = this.getConstructedGenericDeclaringTypeAt(i) and
+ children = t.getNumberOfArgumentsSelf() and
+ (if this.isDeclaringTypeAt(i) then offset = 1 else offset = 0) and
+ if children = 0 then j in [0 .. offset] else j in [0 .. 2 * children + offset]
+ )
+ )
+ }
+
language[monotonicAggregates]
string toString() {
this.isFullyConstructed() and
@@ -284,13 +296,8 @@ module Gvn {
result = k.toStringBuiltin(this.getArg(0).toString())
or
result =
- strictconcat(int i, int j, int offset |
- exists(GenericType t, int children |
- t = this.getConstructedGenericDeclaringTypeAt(i) and
- children = t.getNumberOfArgumentsSelf() and
- (if this.isDeclaringTypeAt(i) then offset = 1 else offset = 0) and
- if children = 0 then j in [0 .. offset] else j in [0 .. 2 * children + offset]
- )
+ strictconcat(int i, int j |
+ this.toStringPart(i, j)
|
this.toStringConstructedPart(i, j) order by i desc, j
)
diff --git a/csharp/ql/lib/semmle/code/csharp/Variable.qll b/csharp/ql/lib/semmle/code/csharp/Variable.qll
index a13175dfeb0..6592320fdd7 100644
--- a/csharp/ql/lib/semmle/code/csharp/Variable.qll
+++ b/csharp/ql/lib/semmle/code/csharp/Variable.qll
@@ -149,7 +149,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
predicate isIn() { params(this, _, _, _, 5, _, _) }
/** Holds if this parameter is an output or reference parameter. */
- predicate isOutOrRef() { isOut() or isRef() }
+ predicate isOutOrRef() { this.isOut() or this.isRef() }
/**
* Holds if this parameter is a parameter array. For example, `args`
@@ -210,7 +210,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
Expr getDefaultValue() { result = this.getUnboundDeclaration().getChildExpr(0) }
/** Holds if this parameter has a default value. */
- predicate hasDefaultValue() { exists(getDefaultValue()) }
+ predicate hasDefaultValue() { exists(this.getDefaultValue()) }
/** Gets the callable to which this parameter belongs, if any. */
override Callable getCallable() { result = this.getDeclaringElement() }
@@ -238,7 +238,9 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top
* `y` is `5`, and the assigned arguments to `z` are `3` and `6`, respectively.
*/
pragma[nomagic]
- Expr getAnAssignedArgument() { result = getCallable().getACall().getArgumentForParameter(this) }
+ Expr getAnAssignedArgument() {
+ result = this.getCallable().getACall().getArgumentForParameter(this)
+ }
/** Holds if this parameter is potentially overwritten in the body of its callable. */
predicate isOverwritten() {
@@ -323,7 +325,7 @@ class LocalVariable extends LocalScopeVariable, @local_variable {
/** Gets the enclosing callable of this local variable. */
Callable getEnclosingCallable() { result = this.getVariableDeclExpr().getEnclosingCallable() }
- override Callable getCallable() { result = getEnclosingCallable() }
+ override Callable getCallable() { result = this.getEnclosingCallable() }
override predicate isRef() { localvars(this, 3, _, _, _, _) }
diff --git a/csharp/ql/lib/semmle/code/csharp/XML.qll b/csharp/ql/lib/semmle/code/csharp/XML.qll
index 5871fed0ddd..76f3b3cb022 100755
--- a/csharp/ql/lib/semmle/code/csharp/XML.qll
+++ b/csharp/ql/lib/semmle/code/csharp/XML.qll
@@ -24,7 +24,7 @@ class XMLLocatable extends @xmllocatable, TXMLLocatable {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -108,7 +108,7 @@ class XMLParent extends @xmlparent {
}
/** Gets the text value contained in this XML parent. */
- string getTextValue() { result = allCharactersString() }
+ string getTextValue() { result = this.allCharactersString() }
/** Gets a printable representation of this XML parent. */
string toString() { result = this.getName() }
@@ -119,7 +119,7 @@ class XMLFile extends XMLParent, File {
XMLFile() { xmlEncoding(this, _) }
/** Gets a printable representation of this XML file. */
- override string toString() { result = getName() }
+ override string toString() { result = this.getName() }
/** Gets the name of this XML file. */
override string getName() { result = File.super.getAbsolutePath() }
@@ -129,14 +129,14 @@ class XMLFile extends XMLParent, File {
*
* Gets the path of this XML file.
*/
- deprecated string getPath() { result = getAbsolutePath() }
+ deprecated string getPath() { result = this.getAbsolutePath() }
/**
* DEPRECATED: Use `getParentContainer().getAbsolutePath()` instead.
*
* Gets the path of the folder that contains this XML file.
*/
- deprecated string getFolder() { result = getParentContainer().getAbsolutePath() }
+ deprecated string getFolder() { result = this.getParentContainer().getAbsolutePath() }
/** Gets the encoding of this XML file. */
string getEncoding() { xmlEncoding(this, result) }
@@ -200,7 +200,7 @@ class XMLDTD extends XMLLocatable, @xmldtd {
*/
class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
/** Holds if this XML element has the given `name`. */
- predicate hasName(string name) { name = getName() }
+ predicate hasName(string name) { name = this.getName() }
/** Gets the name of this XML element. */
override string getName() { xmlElements(this, result, _, _, _) }
@@ -239,7 +239,7 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
/** Gets a printable representation of this XML element. */
- override string toString() { result = getName() }
+ override string toString() { result = this.getName() }
}
/**
diff --git a/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll b/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll
index d425ec118ed..4f364147395 100644
--- a/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll
+++ b/csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll
@@ -42,7 +42,7 @@ abstract class AssertMethod extends Method {
*
* Gets the index of a parameter being asserted.
*/
- deprecated final int getAssertionIndex() { result = getAnAssertionIndex() }
+ deprecated final int getAssertionIndex() { result = this.getAnAssertionIndex() }
/** Gets the parameter at position `i` being asserted. */
final Parameter getAssertedParameter(int i) {
@@ -55,7 +55,7 @@ abstract class AssertMethod extends Method {
*
* Gets a parameter being asserted.
*/
- deprecated final Parameter getAssertedParameter() { result = getAssertedParameter(_) }
+ deprecated final Parameter getAssertedParameter() { result = this.getAssertedParameter(_) }
/** Gets the failure type if the assertion fails for argument `i`, if any. */
abstract AssertionFailure getAssertionFailure(int i);
diff --git a/csharp/ql/lib/semmle/code/csharp/commons/Collections.qll b/csharp/ql/lib/semmle/code/csharp/commons/Collections.qll
index cee7b647fe7..0121ef13f8c 100644
--- a/csharp/ql/lib/semmle/code/csharp/commons/Collections.qll
+++ b/csharp/ql/lib/semmle/code/csharp/commons/Collections.qll
@@ -3,23 +3,12 @@
import csharp
private string modifyMethodName() {
- result = "Add" or
- result = "AddFirst" or
- result = "AddLast" or
- result = "Clear" or
- result = "Enqueue" or
- result = "ExceptWith" or
- result = "Insert" or
- result = "IntersectWith" or
- result = "Push" or
- result = "Remove" or
- result = "RemoveAt" or
- result = "RemoveFirst" or
- result = "RemoveLast" or
- result = "Set" or
- result = "SetAll" or
- result = "SymmetricExceptWith" or
- result = "UnionWith"
+ result =
+ [
+ "Add", "AddFirst", "AddLast", "Clear", "Enqueue", "ExceptWith", "Insert", "IntersectWith",
+ "Push", "Remove", "RemoveAt", "RemoveFirst", "RemoveLast", "Set", "SetAll",
+ "SymmetricExceptWith", "UnionWith"
+ ]
}
/** A method call that modifies a collection. */
@@ -39,45 +28,27 @@ class CollectionModificationAccess extends Access {
}
private string collectionTypeName() {
- result = "ArrayList" or
- result = "BitArray" or
- result = "Hashtable" or
- result = "ICollection" or
- result = "IDictionary" or
- result = "IList" or
- result = "Queue" or
- result = "ReadOnlyCollectionBase" or
- result = "SortedList" or
- result = "Stack"
+ result =
+ [
+ "ArrayList", "BitArray", "Hashtable", "ICollection", "IDictionary", "IList", "Queue",
+ "ReadOnlyCollectionBase", "SortedList", "Stack"
+ ]
}
-private string collectionNamespaceName() {
- result = "Mono.Collections" or
- result = "System.Collections"
-}
+private string collectionNamespaceName() { result = ["Mono.Collections", "System.Collections"] }
private string genericCollectionNamespaceName() {
- result = "Mono.Collections.Generic" or
- result = "System.Collections.Generic"
+ result = ["Mono.Collections.Generic", "System.Collections.Generic"]
}
private string genericCollectionTypeName() {
- result = "Dictionary<,>" or
- result = "HashSet<>" or
- result = "ICollection<>" or
- result = "IDictionary<,>" or
- result = "IList<>" or
- result = "ISet<>" or
- result = "LinkedList<>" or
- result = "List<>" or
- result = "Queue<>" or
- result = "SortedDictionary<,>" or
- result = "SortedList<,>" or
- result = "SortedSet<>" or
- result = "Stack<>" or
- result = "SynchronizedCollection<>" or
- result = "SynchronizedKeyedCollection<>" or
- result = "SynchronizedReadOnlyCollection<>"
+ result =
+ [
+ "Dictionary<,>", "HashSet<>", "ICollection<>", "IDictionary<,>", "IList<>", "ISet<>",
+ "LinkedList<>", "List<>", "Queue<>", "SortedDictionary<,>", "SortedList<,>", "SortedSet<>",
+ "Stack<>", "SynchronizedCollection<>", "SynchronizedKeyedCollection<>",
+ "SynchronizedReadOnlyCollection<>"
+ ]
}
/** A collection type. */
@@ -105,36 +76,18 @@ class EmptyCollectionCreation extends ObjectCreation {
}
private string readonlyMethodName() {
- result = "BinarySearch" or
- result = "Clone" or
- result = "Contains" or
- result = "ContainsKey" or
- result = "ContainsValue" or
- result = "CopyTo" or
- result = "Equals" or
- result = "FixedArray" or
- result = "FixedSize" or
- result = "Get" or
- result = "GetEnumerator" or
- result = "GetHashCode" or
- result = "GetRange" or
- result = "IndexOf" or
- result = "IsProperSubsetOf" or
- result = "IsProperSupersetOf" or
- result = "IsSubsetOf" or
- result = "IsSupersetOf" or
- result = "LastIndexOf" or
- result = "MemberwiseClone" or
- result = "Peek" or
- result = "ToArray" or
- result = "ToString" or
- result = "TryGetValue"
+ result =
+ [
+ "BinarySearch", "Clone", "Contains", "ContainsKey", "ContainsValue", "CopyTo", "Equals",
+ "FixedArray", "FixedSize", "Get", "GetEnumerator", "GetHashCode", "GetRange", "IndexOf",
+ "IsProperSubsetOf", "IsProperSupersetOf", "IsSubsetOf", "IsSupersetOf", "LastIndexOf",
+ "MemberwiseClone", "Peek", "ToArray", "ToString", "TryGetValue"
+ ]
}
private string noAddMethodName() {
result = readonlyMethodName() or
- result = "Dequeue" or
- result = "Pop"
+ result = ["Dequeue", "Pop"]
}
/** Holds if `a` is an access that does not modify a collection. */
diff --git a/csharp/ql/lib/semmle/code/csharp/commons/GeneratedCode.qll b/csharp/ql/lib/semmle/code/csharp/commons/GeneratedCode.qll
index 42e04ddcbb9..38d559d8ffd 100644
--- a/csharp/ql/lib/semmle/code/csharp/commons/GeneratedCode.qll
+++ b/csharp/ql/lib/semmle/code/csharp/commons/GeneratedCode.qll
@@ -57,7 +57,7 @@ abstract class GeneratedCodeComment extends CommentLine { }
*/
class GenericGeneratedCodeComment extends GeneratedCodeComment {
GenericGeneratedCodeComment() {
- exists(string line, string entity, string was, string automatically | line = getText() |
+ exists(string line, string entity, string was, string automatically | line = this.getText() |
entity = "file|class|interface|art[ei]fact|module|script" and
was = "was|is|has been" and
automatically = "automatically |mechanically |auto[- ]?" and
@@ -70,7 +70,7 @@ class GenericGeneratedCodeComment extends GeneratedCodeComment {
/** A comment warning against modifications. */
class DontModifyMarkerComment extends GeneratedCodeComment {
DontModifyMarkerComment() {
- exists(string line | line = getText() |
+ exists(string line | line = this.getText() |
line.regexpMatch("(?i).*\\bGenerated by\\b.*\\bDo not edit\\b.*") or
line.regexpMatch("(?i).*\\bAny modifications to this file will be lost\\b.*")
)
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/BasicBlocks.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/BasicBlocks.qll
index b4448a71380..08e5925ad50 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/BasicBlocks.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/BasicBlocks.qll
@@ -11,7 +11,7 @@ private import ControlFlow::SuccessorTypes
*/
class BasicBlock extends TBasicBlockStart {
/** Gets an immediate successor of this basic block, if any. */
- BasicBlock getASuccessor() { result.getFirstNode() = getLastNode().getASuccessor() }
+ BasicBlock getASuccessor() { result.getFirstNode() = this.getLastNode().getASuccessor() }
/** Gets an immediate successor of this basic block of a given type, if any. */
BasicBlock getASuccessorByType(ControlFlow::SuccessorType t) {
@@ -42,7 +42,7 @@ class BasicBlock extends TBasicBlockStart {
* The basic block on line 2 is an immediate `true` successor of the
* basic block on line 1.
*/
- BasicBlock getATrueSuccessor() { result.getFirstNode() = getLastNode().getATrueSuccessor() }
+ BasicBlock getATrueSuccessor() { result.getFirstNode() = this.getLastNode().getATrueSuccessor() }
/**
* Gets an immediate `false` successor, if any.
@@ -60,25 +60,27 @@ class BasicBlock extends TBasicBlockStart {
* The basic block on line 2 is an immediate `false` successor of the
* basic block on line 1.
*/
- BasicBlock getAFalseSuccessor() { result.getFirstNode() = getLastNode().getAFalseSuccessor() }
+ BasicBlock getAFalseSuccessor() {
+ result.getFirstNode() = this.getLastNode().getAFalseSuccessor()
+ }
/** Gets the control flow node at a specific (zero-indexed) position in this basic block. */
- ControlFlow::Node getNode(int pos) { bbIndex(getFirstNode(), result, pos) }
+ ControlFlow::Node getNode(int pos) { bbIndex(this.getFirstNode(), result, pos) }
/** Gets a control flow node in this basic block. */
- ControlFlow::Node getANode() { result = getNode(_) }
+ ControlFlow::Node getANode() { result = this.getNode(_) }
/** Gets the first control flow node in this basic block. */
ControlFlow::Node getFirstNode() { this = TBasicBlockStart(result) }
/** Gets the last control flow node in this basic block. */
- ControlFlow::Node getLastNode() { result = getNode(length() - 1) }
+ ControlFlow::Node getLastNode() { result = this.getNode(this.length() - 1) }
/** Gets the callable that this basic block belongs to. */
final Callable getCallable() { result = this.getFirstNode().getEnclosingCallable() }
/** Gets the length of this basic block. */
- int length() { result = strictcount(getANode()) }
+ int length() { result = strictcount(this.getANode()) }
/**
* Holds if this basic block immediately dominates basic block `bb`.
@@ -151,7 +153,7 @@ class BasicBlock extends TBasicBlockStart {
*/
predicate dominates(BasicBlock bb) {
bb = this or
- strictlyDominates(bb)
+ this.strictlyDominates(bb)
}
/**
@@ -177,14 +179,14 @@ class BasicBlock extends TBasicBlockStart {
* does not dominate the basic block on line 6.
*/
predicate inDominanceFrontier(BasicBlock df) {
- dominatesPredecessor(df) and
- not strictlyDominates(df)
+ this.dominatesPredecessor(df) and
+ not this.strictlyDominates(df)
}
/**
* Holds if this basic block dominates a predecessor of `df`.
*/
- private predicate dominatesPredecessor(BasicBlock df) { dominates(df.getAPredecessor()) }
+ private predicate dominatesPredecessor(BasicBlock df) { this.dominates(df.getAPredecessor()) }
/**
* Gets the basic block that immediately dominates this basic block, if any.
@@ -263,7 +265,7 @@ class BasicBlock extends TBasicBlockStart {
* post-dominates itself.
*/
predicate postDominates(BasicBlock bb) {
- strictlyPostDominates(bb) or
+ this.strictlyPostDominates(bb) or
this = bb
}
@@ -276,10 +278,10 @@ class BasicBlock extends TBasicBlockStart {
predicate inLoop() { this.getASuccessor+() = this }
/** Gets a textual representation of this basic block. */
- string toString() { result = getFirstNode().toString() }
+ string toString() { result = this.getFirstNode().toString() }
/** Gets the location of this basic block. */
- Location getLocation() { result = getFirstNode().getLocation() }
+ Location getLocation() { result = this.getFirstNode().getLocation() }
}
/**
@@ -420,7 +422,7 @@ private module JoinBlockPredecessors {
/** A basic block with more than one predecessor. */
class JoinBlock extends BasicBlock {
- JoinBlock() { getFirstNode().isJoin() }
+ JoinBlock() { this.getFirstNode().isJoin() }
/**
* Gets the `i`th predecessor of this join block, with respect to some
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowElement.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowElement.qll
index 7601b83f6b8..9e7fd92d2a4 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowElement.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowElement.qll
@@ -72,13 +72,14 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
ControlFlowElement getAReachableElement() {
// Reachable in same basic block
exists(BasicBlock bb, int i, int j |
- bb.getNode(i) = getAControlFlowNode() and
+ bb.getNode(i) = this.getAControlFlowNode() and
bb.getNode(j) = result.getAControlFlowNode() and
i < j
)
or
// Reachable in different basic blocks
- getAControlFlowNode().getBasicBlock().getASuccessor+().getANode() = result.getAControlFlowNode()
+ this.getAControlFlowNode().getBasicBlock().getASuccessor+().getANode() =
+ result.getAControlFlowNode()
}
pragma[noinline]
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowGraph.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowGraph.qll
index 96b73d8978d..c94184b4f66 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowGraph.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowGraph.qll
@@ -33,10 +33,10 @@ module ControlFlow {
ControlFlowElement getElement() { none() }
/** Gets the location of this control flow node. */
- Location getLocation() { result = getElement().getLocation() }
+ Location getLocation() { result = this.getElement().getLocation() }
/** Holds if this control flow node has conditional successors. */
- predicate isCondition() { exists(getASuccessorByType(any(ConditionalSuccessor e))) }
+ predicate isCondition() { exists(this.getASuccessorByType(any(ConditionalSuccessor e))) }
/** Gets the basic block that this control flow node belongs to. */
BasicBlock getBasicBlock() { result.getANode() = this }
@@ -67,7 +67,7 @@ module ControlFlow {
// potentially very large predicate, so must be inlined
pragma[inline]
predicate dominates(Node that) {
- strictlyDominates(that)
+ this.strictlyDominates(that)
or
this = that
}
@@ -138,7 +138,7 @@ module ControlFlow {
// potentially very large predicate, so must be inlined
pragma[inline]
predicate postDominates(Node that) {
- strictlyPostDominates(that)
+ this.strictlyPostDominates(that)
or
this = that
}
@@ -186,13 +186,13 @@ module ControlFlow {
Node getASuccessorByType(SuccessorType t) { result = getASuccessor(this, t) }
/** Gets an immediate successor, if any. */
- Node getASuccessor() { result = getASuccessorByType(_) }
+ Node getASuccessor() { result = this.getASuccessorByType(_) }
/** Gets an immediate predecessor node of a given flow type, if any. */
Node getAPredecessorByType(SuccessorType t) { result.getASuccessorByType(t) = this }
/** Gets an immediate predecessor, if any. */
- Node getAPredecessor() { result = getAPredecessorByType(_) }
+ Node getAPredecessor() { result = this.getAPredecessorByType(_) }
/**
* Gets an immediate `true` successor, if any.
@@ -211,7 +211,7 @@ module ControlFlow {
* on line 1.
*/
Node getATrueSuccessor() {
- result = getASuccessorByType(any(BooleanSuccessor t | t.getValue() = true))
+ result = this.getASuccessorByType(any(BooleanSuccessor t | t.getValue() = true))
}
/**
@@ -231,7 +231,7 @@ module ControlFlow {
* on line 1.
*/
Node getAFalseSuccessor() {
- result = getASuccessorByType(any(BooleanSuccessor t | t.getValue() = false))
+ result = this.getASuccessorByType(any(BooleanSuccessor t | t.getValue() = false))
}
/** Holds if this node has more than one predecessor. */
@@ -285,7 +285,7 @@ module ControlFlow {
override Callable getEnclosingCallable() { result = this.getCallable() }
- override Location getLocation() { result = getCallable().getLocation() }
+ override Location getLocation() { result = this.getCallable().getLocation() }
override string toString() {
exists(string s |
@@ -293,7 +293,7 @@ module ControlFlow {
or
normal = false and s = "abnormal"
|
- result = "exit " + getCallable() + " (" + s + ")"
+ result = "exit " + this.getCallable() + " (" + s + ")"
)
}
}
@@ -307,9 +307,9 @@ module ControlFlow {
override Callable getEnclosingCallable() { result = this.getCallable() }
- override Location getLocation() { result = getCallable().getLocation() }
+ override Location getLocation() { result = this.getCallable().getLocation() }
- override string toString() { result = "exit " + getCallable().toString() }
+ override string toString() { result = "exit " + this.getCallable().toString() }
}
/**
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll
index 5a402717401..5e3f00c3c5e 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll
@@ -1740,7 +1740,7 @@ module Internal {
e = this.getAChildExpr()
or
exists(Expr mid |
- descendant(mid) and
+ this.descendant(mid) and
not interestingDescendantCandidate(mid) and
e = mid.getAChildExpr()
)
@@ -1748,7 +1748,7 @@ module Internal {
/** Holds if `e` is an interesting descendant of this descendant. */
predicate interestingDescendant(Expr e) {
- descendant(e) and
+ this.descendant(e) and
interestingDescendantCandidate(e)
}
}
@@ -1797,7 +1797,7 @@ module Internal {
override predicate candidate(ControlFlowElement x, ControlFlowElement y) {
exists(BasicBlock bb, Declaration d |
- candidateAux(x, d, bb) and
+ this.candidateAux(x, d, bb) and
y =
any(AccessOrCallExpr e |
e.getAControlFlowNode().getBasicBlock() = bb and
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll
index 8a02fb95dee..82eb5d302ad 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll
@@ -495,7 +495,7 @@ module Expressions {
// Flow from last element of left operand to first element of right operand
last(this.getLeftOperand(), pred, c) and
c.(NullnessCompletion).isNull() and
- first(getRightOperand(), succ)
+ first(this.getRightOperand(), succ)
or
// Post-order: flow from last element of left operand to element itself
last(this.getLeftOperand(), pred, c) and
@@ -504,7 +504,7 @@ module Expressions {
not c.(NullnessCompletion).isNull()
or
// Post-order: flow from last element of right operand to element itself
- last(getRightOperand(), pred, c) and
+ last(this.getRightOperand(), pred, c) and
c instanceof NormalCompletion and
succ = this
}
@@ -575,7 +575,7 @@ module Expressions {
PostOrderTree.super.last(last, c)
or
// Qualifier exits with a `null` completion
- lastQualifier(last, c) and
+ this.lastQualifier(last, c) and
c.(NullnessCompletion).isNull()
}
@@ -1483,7 +1483,7 @@ module Statements {
)
or
// Flow into `finally` block
- pred = getAFinallyPredecessor(c, true) and
+ pred = this.getAFinallyPredecessor(c, true) and
first(this.getFinally(), succ)
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreBasicBlocks.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreBasicBlocks.qll
index 31155dea0ae..de44808b18e 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreBasicBlocks.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreBasicBlocks.qll
@@ -69,9 +69,9 @@ class PreBasicBlock extends ControlFlowElement {
ControlFlowElement getFirstElement() { result = this }
- ControlFlowElement getLastElement() { result = this.getElement(length() - 1) }
+ ControlFlowElement getLastElement() { result = this.getElement(this.length() - 1) }
- int length() { result = strictcount(getAnElement()) }
+ int length() { result = strictcount(this.getAnElement()) }
predicate immediatelyDominates(PreBasicBlock bb) { bbIDominates(this, bb) }
@@ -117,7 +117,7 @@ class ConditionBlock extends PreBasicBlock {
pragma[nomagic]
predicate controls(PreBasicBlock controlled, SuccessorTypes::ConditionalSuccessor s) {
- exists(PreBasicBlock succ, ConditionalCompletion c | immediatelyControls(succ, c) |
+ exists(PreBasicBlock succ, ConditionalCompletion c | this.immediatelyControls(succ, c) |
succ.dominates(controlled) and
s = c.getAMatchingSuccessorType()
)
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll
index 4d1d39de988..83ea302e691 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/Splitting.qll
@@ -628,7 +628,7 @@ module FinallySplitting {
*/
private predicate exit(ControlFlowElement pred, Completion c, boolean inherited) {
exists(TryStmt try, FinallySplitType type |
- exit0(pred, try, this.getNestLevel(), c) and
+ this.exit0(pred, try, this.getNestLevel(), c) and
type = this.getType()
|
if last(try.getFinally(), pred, c)
@@ -690,18 +690,18 @@ module FinallySplitting {
override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
succ(pred, succ, c) and
(
- exit(pred, c, _)
+ this.exit(pred, c, _)
or
- exit(pred, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion(), _)
+ this.exit(pred, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion(), _)
)
}
override predicate hasExitScope(CfgScope scope, ControlFlowElement last, Completion c) {
scopeLast(scope, last, c) and
(
- exit(last, c, _)
+ this.exit(last, c, _)
or
- exit(last, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion(), _)
+ this.exit(last, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion(), _)
)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/SuccessorType.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/SuccessorType.qll
index 648c2cd847c..76da2fb62ef 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/SuccessorType.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/SuccessorType.qll
@@ -77,7 +77,7 @@ module SuccessorTypes {
class BooleanSuccessor extends ConditionalSuccessor, TBooleanSuccessor {
override boolean getValue() { this = TBooleanSuccessor(result) }
- override string toString() { result = getValue().toString() }
+ override string toString() { result = this.getValue().toString() }
}
/**
@@ -310,7 +310,7 @@ module SuccessorTypes {
/** Gets the type of exception. */
ExceptionClass getExceptionClass() { this = TExceptionSuccessor(result) }
- override string toString() { result = "exception(" + getExceptionClass().getName() + ")" }
+ override string toString() { result = "exception(" + this.getExceptionClass().getName() + ")" }
}
/**
diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll
index 884f4406d01..395cb5cb171 100644
--- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll
+++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll
@@ -156,6 +156,7 @@ private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) {
}
/** Holds if `df` is in the dominance frontier of `bb`. */
+pragma[noinline]
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and
not strictlyDominates(bb, df)
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll
index b129203db70..55a8b1f4c3f 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll
@@ -30,7 +30,7 @@ abstract class Bound extends TBound {
* The location spans column `sc` of line `sl` to
* column `ec` of line `el` in file `path`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll
index c7140238213..b689602d7bf 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll
@@ -404,6 +404,7 @@ private string paramsString(InterpretedCallable c) {
)
}
+pragma[nomagic]
private Element interpretElement0(
string namespace, string type, boolean subtypes, string name, string signature
) {
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll
index a20c3876050..3e5c8e51ba5 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll
@@ -78,4 +78,21 @@ module SummaryComponentStack {
class SummarizedCallable = Impl::Public::SummarizedCallable;
+private class SummarizedCallableDefaultClearsContent extends Impl::Public::SummarizedCallable {
+ SummarizedCallableDefaultClearsContent() {
+ this instanceof Impl::Public::SummarizedCallable or none()
+ }
+
+ // By default, we assume that all stores into arguments are definite
+ override predicate clearsContent(int i, DataFlow::Content content) {
+ exists(SummaryComponentStack output |
+ this.propagatesFlow(_, output, _) and
+ output.drop(_) =
+ SummaryComponentStack::push(SummaryComponent::content(content),
+ SummaryComponentStack::argument(i)) and
+ not content instanceof DataFlow::ElementContent
+ )
+ }
+}
+
class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack;
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/LibraryTypeDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/LibraryTypeDataFlow.qll
index f36783f56c6..f405484a55d 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/LibraryTypeDataFlow.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/LibraryTypeDataFlow.qll
@@ -505,20 +505,20 @@ class SystemBooleanFlow extends LibraryTypeDataFlow, SystemBooleanStruct {
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
- methodFlow(source, sink, c) and
+ this.methodFlow(source, sink, c) and
preservesValue = false
}
private predicate methodFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationMethod m
) {
- m = getParseMethod() and
+ m = this.getParseMethod() and
(
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
)
or
- m = getTryParseMethod() and
+ m = this.getTryParseMethod() and
(
source = TCallableFlowSourceArg(0) and
(
@@ -537,12 +537,12 @@ class SystemUriFlow extends LibraryTypeDataFlow, SystemUriClass {
boolean preservesValue
) {
(
- constructorFlow(source, sink, c)
+ this.constructorFlow(source, sink, c)
or
- methodFlow(source, sink, c)
+ this.methodFlow(source, sink, c)
or
exists(Property p |
- propertyFlow(p) and
+ this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -552,7 +552,7 @@ class SystemUriFlow extends LibraryTypeDataFlow, SystemUriClass {
}
private predicate constructorFlow(CallableFlowSource source, CallableFlowSink sink, Constructor c) {
- c = getAMember() and
+ c = this.getAMember() and
c.getParameter(0).getType() instanceof StringType and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
@@ -567,11 +567,11 @@ class SystemUriFlow extends LibraryTypeDataFlow, SystemUriClass {
}
private predicate propertyFlow(Property p) {
- p = getPathAndQueryProperty()
+ p = this.getPathAndQueryProperty()
or
- p = getQueryProperty()
+ p = this.getQueryProperty()
or
- p = getOriginalStringProperty()
+ p = this.getOriginalStringProperty()
}
}
@@ -582,15 +582,15 @@ class SystemIOStringReaderFlow extends LibraryTypeDataFlow, SystemIOStringReader
boolean preservesValue
) {
(
- constructorFlow(source, sink, c)
+ this.constructorFlow(source, sink, c)
or
- methodFlow(source, sink, c)
+ this.methodFlow(source, sink, c)
) and
preservesValue = false
}
private predicate constructorFlow(CallableFlowSource source, CallableFlowSink sink, Constructor c) {
- c = getAMember() and
+ c = this.getAMember() and
c.getParameter(0).getType() instanceof StringType and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
@@ -599,7 +599,7 @@ class SystemIOStringReaderFlow extends LibraryTypeDataFlow, SystemIOStringReader
private predicate methodFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationMethod m
) {
- m.getDeclaringType() = getABaseType*() and
+ m.getDeclaringType() = this.getABaseType*() and
m.getName().matches("Read%") and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn()
@@ -612,17 +612,17 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
- constructorFlow(source, sourceAp, sink, sinkAp, c) and
+ this.constructorFlow(source, sourceAp, sink, sinkAp, c) and
preservesValue = false
or
- methodFlow(source, sourceAp, sink, sinkAp, c, preservesValue)
+ this.methodFlow(source, sourceAp, sink, sinkAp, c, preservesValue)
}
private predicate constructorFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
Constructor c
) {
- c = getAMember() and
+ c = this.getAMember() and
c.getParameter(0).getType().(ArrayType).getElementType() instanceof CharType and
source = TCallableFlowSourceArg(0) and
sourceAp = AccessPath::element() and
@@ -641,14 +641,14 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
sinkAp = AccessPath::empty() and
preservesValue = true
or
- m = getSplitMethod() and
+ m = this.getSplitMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::element() and
preservesValue = false
or
- m = getReplaceMethod() and
+ m = this.getReplaceMethod() and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty() and
(
@@ -661,21 +661,21 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
preservesValue = false
)
or
- m = getSubstringMethod() and
+ m = this.getSubstringMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
- m = getCloneMethod() and
+ m = this.getCloneMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = true
or
- m = getInsertMethod() and
+ m = this.getInsertMethod() and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty() and
(
@@ -688,21 +688,21 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
preservesValue = false
)
or
- m = getNormalizeMethod() and
+ m = this.getNormalizeMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
- m = getRemoveMethod() and
+ m = this.getRemoveMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
- m = getAMethod() and
+ m = this.getAMethod() and
m.getName().regexpMatch("((ToLower|ToUpper)(Invariant)?)|(Trim(Start|End)?)|(Pad(Left|Right))") and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
@@ -710,7 +710,7 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
sinkAp = AccessPath::empty() and
preservesValue = false
or
- m = getConcatMethod() and
+ m = this.getConcatMethod() and
exists(int i |
source = getFlowSourceArg(m, i, sourceAp) and
sink = TCallableFlowSinkReturn() and
@@ -718,20 +718,20 @@ class SystemStringFlow extends LibraryTypeDataFlow, SystemStringClass {
preservesValue = false
)
or
- m = getCopyMethod() and
+ m = this.getCopyMethod() and
source = TCallableFlowSourceArg(0) and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = true
or
- m = getJoinMethod() and
+ m = this.getJoinMethod() and
source = getFlowSourceArg(m, [0, 1], sourceAp) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
- m = getFormatMethod() and
+ m = this.getFormatMethod() and
exists(int i |
(m.getParameter(0).getType() instanceof SystemIFormatProviderInterface implies i != 0) and
source = getFlowSourceArg(m, i, sourceAp) and
@@ -749,10 +749,10 @@ class SystemTextStringBuilderFlow extends LibraryTypeDataFlow, SystemTextStringB
SourceDeclarationCallable c, boolean preservesValue
) {
(
- constructorFlow(source, sourceAp, sink, sinkAp, c) and
+ this.constructorFlow(source, sourceAp, sink, sinkAp, c) and
preservesValue = true
or
- methodFlow(source, sourceAp, sink, sinkAp, c, preservesValue)
+ this.methodFlow(source, sourceAp, sink, sinkAp, c, preservesValue)
)
}
@@ -760,7 +760,7 @@ class SystemTextStringBuilderFlow extends LibraryTypeDataFlow, SystemTextStringB
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
Constructor c
) {
- c = getAMember() and
+ c = this.getAMember() and
c.getParameter(0).getType() instanceof StringType and
source = TCallableFlowSourceArg(0) and
sourceAp = AccessPath::empty() and
@@ -894,7 +894,7 @@ class IEnumerableFlow extends LibraryTypeDataFlow, RefType {
) {
preservesValue = true and
(
- methodFlowLINQExtensions(source, sourceAp, sink, sinkAp, c)
+ this.methodFlowLINQExtensions(source, sourceAp, sink, sinkAp, c)
or
c = this.getFind() and
sourceAp = AccessPath::element() and
@@ -1674,14 +1674,14 @@ class SystemConvertFlow extends LibraryTypeDataFlow, SystemConvertClass {
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
- methodFlow(source, sink, c) and
+ this.methodFlow(source, sink, c) and
preservesValue = false
}
private predicate methodFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationMethod m
) {
- m = getAMethod() and
+ m = this.getAMethod() and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
}
@@ -1694,7 +1694,7 @@ class SystemWebHttpCookieFlow extends LibraryTypeDataFlow, SystemWebHttpCookie {
boolean preservesValue
) {
exists(Property p |
- propertyFlow(p) and
+ this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -1703,8 +1703,8 @@ class SystemWebHttpCookieFlow extends LibraryTypeDataFlow, SystemWebHttpCookie {
}
private predicate propertyFlow(Property p) {
- p = getValueProperty() or
- p = getValuesProperty()
+ p = this.getValueProperty() or
+ p = this.getValuesProperty()
}
}
@@ -1715,7 +1715,7 @@ class SystemNetCookieFlow extends LibraryTypeDataFlow, SystemNetCookieClass {
boolean preservesValue
) {
exists(Property p |
- propertyFlow(p) and
+ this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -1733,7 +1733,7 @@ class SystemNetIPHostEntryFlow extends LibraryTypeDataFlow, SystemNetIPHostEntry
boolean preservesValue
) {
exists(Property p |
- propertyFlow(p) and
+ this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -1742,8 +1742,8 @@ class SystemNetIPHostEntryFlow extends LibraryTypeDataFlow, SystemNetIPHostEntry
}
private predicate propertyFlow(Property p) {
- p = getHostNameProperty() or
- p = getAliasesProperty()
+ p = this.getHostNameProperty() or
+ p = this.getAliasesProperty()
}
}
@@ -1755,7 +1755,7 @@ class SystemWebUIWebControlsTextBoxFlow extends LibraryTypeDataFlow,
boolean preservesValue
) {
exists(Property p |
- propertyFlow(p) and
+ this.propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
@@ -1763,7 +1763,7 @@ class SystemWebUIWebControlsTextBoxFlow extends LibraryTypeDataFlow,
preservesValue = false
}
- private predicate propertyFlow(Property p) { p = getTextProperty() }
+ private predicate propertyFlow(Property p) { p = this.getTextProperty() }
}
/** Data flow for `System.Collections.Generic.KeyValuePair`. */
@@ -1864,11 +1864,11 @@ class SystemThreadingTasksTaskFlow extends LibraryTypeDataFlow, SystemThreadingT
SourceDeclarationCallable c, boolean preservesValue
) {
(
- constructorFlow(source, sink, c) and
+ this.constructorFlow(source, sink, c) and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty()
or
- methodFlow(source, sourceAp, sink, sinkAp, c)
+ this.methodFlow(source, sourceAp, sink, sinkAp, c)
) and
preservesValue = true
}
@@ -1954,9 +1954,9 @@ class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow, SystemThreading
SourceDeclarationCallable c, boolean preservesValue
) {
(
- constructorFlow(source, sourceAp, sink, sinkAp, c)
+ this.constructorFlow(source, sourceAp, sink, sinkAp, c)
or
- methodFlow(source, sourceAp, sink, sinkAp, c)
+ this.methodFlow(source, sourceAp, sink, sinkAp, c)
) and
preservesValue = true
or
@@ -2101,14 +2101,14 @@ private class SystemRuntimeCompilerServicesConfiguredTaskAwaitableTFlow extends
class SystemThreadingTasksFactoryFlow extends LibraryTypeDataFlow {
SystemThreadingTasksFactoryFlow() {
this instanceof SystemThreadingTasksClass and
- getName().regexpMatch("TaskFactory(<>)?")
+ this.getName().regexpMatch("TaskFactory(<>)?")
}
override predicate callableFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
- methodFlow(source, sourceAp, sink, sinkAp, c) and
+ this.methodFlow(source, sourceAp, sink, sinkAp, c) and
preservesValue = true
}
@@ -2236,12 +2236,12 @@ library class SystemTextEncodingFlow extends LibraryTypeDataFlow, SystemTextEnco
preservesValue = false and
c = this.getAMethod() and
exists(Method m | m.getAnOverrider*().getUnboundDeclaration() = c |
- m = getGetBytesMethod() and
+ m = this.getGetBytesMethod() and
source = getFlowSourceArg(m, 0, sourceAp) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
or
- m = [getGetStringMethod(), getGetCharsMethod()] and
+ m = [this.getGetStringMethod(), this.getGetCharsMethod()] and
source = TCallableFlowSourceArg(0) and
sourceAp = AccessPath::element() and
sink = TCallableFlowSinkReturn() and
@@ -2257,9 +2257,9 @@ library class SystemIOMemoryStreamFlow extends LibraryTypeDataFlow, SystemIOMemo
boolean preservesValue
) {
(
- constructorFlow(source, sink, c)
+ this.constructorFlow(source, sink, c)
or
- c = getToArrayMethod().getAnOverrider*() and
+ c = this.getToArrayMethod().getAnOverrider*() and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn()
) and
@@ -2267,7 +2267,7 @@ library class SystemIOMemoryStreamFlow extends LibraryTypeDataFlow, SystemIOMemo
}
private predicate constructorFlow(CallableFlowSource source, CallableFlowSink sink, Constructor c) {
- c = getAMember() and
+ c = this.getAMember() and
c.getParameter(0).getType().(ArrayType).getElementType() instanceof ByteType and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
@@ -2281,17 +2281,17 @@ class SystemIOStreamFlow extends LibraryTypeDataFlow, SystemIOStreamClass {
boolean preservesValue
) {
(
- c = getAReadMethod().getAnOverrider*() and
+ c = this.getAReadMethod().getAnOverrider*() and
c.getParameter(0).getType().(ArrayType).getElementType() instanceof ByteType and
sink = TCallableFlowSinkArg(0) and
source = TCallableFlowSourceQualifier()
or
- c = getAWriteMethod().getAnOverrider*() and
+ c = this.getAWriteMethod().getAnOverrider*() and
c.getParameter(0).getType().(ArrayType).getElementType() instanceof ByteType and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkQualifier()
or
- c = any(Method m | m = getAMethod() and m.getName().matches("CopyTo%")).getAnOverrider*() and
+ c = any(Method m | m = this.getAMethod() and m.getName().matches("CopyTo%")).getAnOverrider*() and
c.getParameter(0).getType() instanceof SystemIOStreamClass and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkArg(0)
@@ -2307,12 +2307,12 @@ class SystemIOCompressionDeflateStreamFlow extends LibraryTypeDataFlow,
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
- constructorFlow(source, sink, c) and
+ this.constructorFlow(source, sink, c) and
preservesValue = false
}
private predicate constructorFlow(CallableFlowSource source, CallableFlowSink sink, Constructor c) {
- c = getAMember() and
+ c = this.getAMember() and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn()
}
@@ -2324,7 +2324,7 @@ class SystemXmlXmlReaderFlow extends LibraryTypeDataFlow, SystemXmlXmlReaderClas
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
- c = getCreateMethod() and
+ c = this.getCreateMethod() and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn() and
preservesValue = false
@@ -2337,7 +2337,7 @@ class SystemXmlXmlDocumentFlow extends LibraryTypeDataFlow, SystemXmlXmlDocument
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
- c = getLoadMethod() and
+ c = this.getLoadMethod() and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkQualifier() and
preservesValue = false
@@ -2352,13 +2352,13 @@ class SystemXmlXmlNodeFlow extends LibraryTypeDataFlow, SystemXmlXmlNodeClass {
) {
(
exists(Property p |
- p = getAProperty() and
+ p = this.getAProperty() and
c = p.getGetter() and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn()
)
or
- c = getASelectNodeMethod() and
+ c = this.getASelectNodeMethod() and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn()
) and
@@ -2372,7 +2372,7 @@ class SystemXmlXmlNamedNodeMapFlow extends LibraryTypeDataFlow, SystemXmlXmlName
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
- c = getGetNamedItemMethod() and
+ c = this.getGetNamedItemMethod() and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
preservesValue = true
@@ -2385,14 +2385,14 @@ class SystemIOPathFlow extends LibraryTypeDataFlow, SystemIOPathClass {
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
- c = getAMethod("Combine") and
+ c = this.getAMethod("Combine") and
source = getFlowSourceArg(c, _, sourceAp) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = false
or
exists(Parameter p |
- c = getAMethod() and
+ c = this.getAMethod() and
c.getName().matches("Get%") and
p = c.getAParameter() and
p.hasName("path") and
@@ -2411,10 +2411,10 @@ class SystemWebHttpUtilityFlow extends LibraryTypeDataFlow, SystemWebHttpUtility
boolean preservesValue
) {
(
- c = getAnHtmlAttributeEncodeMethod() or
- c = getAnHtmlEncodeMethod() or
- c = getAJavaScriptStringEncodeMethod() or
- c = getAnUrlEncodeMethod()
+ c = this.getAnHtmlAttributeEncodeMethod() or
+ c = this.getAnHtmlEncodeMethod() or
+ c = this.getAJavaScriptStringEncodeMethod() or
+ c = this.getAnUrlEncodeMethod()
) and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn() and
@@ -2429,8 +2429,8 @@ class SystemWebHttpServerUtilityFlow extends LibraryTypeDataFlow, SystemWebHttpS
boolean preservesValue
) {
(
- c = getAnHtmlEncodeMethod() or
- c = getAnUrlEncodeMethod()
+ c = this.getAnHtmlEncodeMethod() or
+ c = this.getAnUrlEncodeMethod()
) and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn() and
@@ -2445,8 +2445,8 @@ class SystemNetWebUtilityFlow extends LibraryTypeDataFlow, SystemNetWebUtility {
boolean preservesValue
) {
(
- c = getAnHtmlEncodeMethod() or
- c = getAnUrlEncodeMethod()
+ c = this.getAnHtmlEncodeMethod() or
+ c = this.getAnUrlEncodeMethod()
) and
source = TCallableFlowSourceArg(0) and
sink = TCallableFlowSinkReturn() and
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll
index 44307d68e1f..4f70b53275d 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll
@@ -76,9 +76,9 @@ module Ssa {
override Callable getEnclosingCallable() { this = SsaImpl::TLocalVar(result, _) }
- override string toString() { result = getAssignable().getName() }
+ override string toString() { result = this.getAssignable().getName() }
- override Location getLocation() { result = getAssignable().getLocation() }
+ override Location getLocation() { result = this.getAssignable().getLocation() }
}
/** A fully qualified field or property. */
@@ -105,7 +105,7 @@ module Ssa {
)
}
- override Location getLocation() { result = getFirstAccess().getLocation() }
+ override Location getLocation() { result = this.getFirstAccess().getLocation() }
}
/** A plain field or property. */
@@ -115,8 +115,8 @@ module Ssa {
override string toString() {
exists(Assignable f, string prefix |
- f = getAssignable() and
- result = prefix + "." + getAssignable()
+ f = this.getAssignable() and
+ result = prefix + "." + this.getAssignable()
|
if f.(Modifiable).isStatic()
then prefix = f.getDeclaringType().getQualifiedName()
@@ -134,7 +134,7 @@ module Ssa {
override SourceVariable getQualifier() { this = SsaImpl::TQualifiedFieldOrProp(_, result, _) }
- override string toString() { result = getQualifier() + "." + getAssignable() }
+ override string toString() { result = this.getQualifier() + "." + this.getAssignable() }
}
}
@@ -611,20 +611,20 @@ module Ssa {
* and which targets the same assignable as this SSA definition.
*/
final AssignableDefinition getAPossibleDefinition() {
- exists(Callable setter | SsaImpl::updatesNamedFieldOrProp(_, _, getCall(), _, setter) |
+ exists(Callable setter | SsaImpl::updatesNamedFieldOrProp(_, _, this.getCall(), _, setter) |
result.getEnclosingCallable() = setter and
result.getTarget() = this.getSourceVariable().getAssignable()
)
or
- SsaImpl::updatesCapturedVariable(_, _, getCall(), _, result, _) and
+ SsaImpl::updatesCapturedVariable(_, _, this.getCall(), _, result, _) and
result.getTarget() = this.getSourceVariable().getAssignable()
}
override string toString() {
- result = getToStringPrefix(this) + "SSA call def(" + getSourceVariable() + ")"
+ result = getToStringPrefix(this) + "SSA call def(" + this.getSourceVariable() + ")"
}
- override Location getLocation() { result = getCall().getLocation() }
+ override Location getLocation() { result = this.getCall().getLocation() }
}
/**
@@ -649,10 +649,10 @@ module Ssa {
final Definition getQualifierDefinition() { result = q }
override string toString() {
- result = getToStringPrefix(this) + "SSA qualifier def(" + getSourceVariable() + ")"
+ result = getToStringPrefix(this) + "SSA qualifier def(" + this.getSourceVariable() + ")"
}
- override Location getLocation() { result = getQualifierDefinition().getLocation() }
+ override Location getLocation() { result = this.getQualifierDefinition().getLocation() }
}
/**
@@ -699,7 +699,7 @@ module Ssa {
}
override string toString() {
- result = getToStringPrefix(this) + "SSA phi(" + getSourceVariable() + ")"
+ result = getToStringPrefix(this) + "SSA phi(" + this.getSourceVariable() + ")"
}
/*
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll
index d38975f24bb..0182040fd11 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll
@@ -262,6 +262,19 @@ abstract class DataFlowCall extends TDataFlowCall {
/** Gets the location of this call. */
abstract Location getLocation();
+
+ /**
+ * Holds if this element is at the specified location.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `filepath`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+ final predicate hasLocationInfo(
+ string filepath, int startline, int startcolumn, int endline, int endcolumn
+ ) {
+ this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
+ }
}
/** A non-delegate C# call relevant for data flow. */
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
index 0c99a25ccc4..b3d03ea4e26 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
@@ -110,12 +110,12 @@ abstract class Configuration extends string {
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
+ predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
*/
- predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
+ predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
/**
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
@@ -244,6 +244,8 @@ private class ParamNodeEx extends NodeEx {
}
int getPosition() { this.isParameterOf(_, result) }
+
+ predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
private class RetNodeEx extends NodeEx {
@@ -744,8 +746,12 @@ private module Stage1 {
returnFlowCallableNodeCand(c, kind, config) and
p.getEnclosingCallable() = c and
exists(ap) and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = p.getPosition()
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -1394,8 +1400,12 @@ private module Stage2 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2083,8 +2093,12 @@ private module Stage3 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2139,7 +2153,8 @@ private predicate expensiveLen2unfolding(TypedContent tc, Configuration config)
) and
accessPathApproxCostLimits(apLimit, tupleLimit) and
apLimit < tails and
- tupleLimit < (tails - 1) * nodes
+ tupleLimit < (tails - 1) * nodes and
+ not tc.forceHighPrecision()
)
}
@@ -2842,8 +2857,12 @@ private module Stage4 {
fwdFlow(ret, any(CcCall ccc), apSome(ap), ap0, config) and
kind = ret.getKind() and
p.getPosition() = pos and
- // we don't expect a parameter to return stored in itself
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ p.allowParameterReturnInSelf()
+ )
)
}
@@ -2916,6 +2935,8 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
int getParameterPos() { p.isParameterOf(_, result) }
+ ParamNodeEx getParamNode() { result = p }
+
override string toString() { result = p + ": " + ap }
predicate hasLocationInfo(
@@ -2973,12 +2994,15 @@ private AccessPathApprox getATail(AccessPathApprox apa, Configuration config) {
* expected to be expensive. Holds with `unfold = true` otherwise.
*/
private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration config) {
- exists(int aps, int nodes, int apLimit, int tupleLimit |
- aps = countPotentialAps(apa, config) and
- nodes = countNodesUsingAccessPath(apa, config) and
- accessPathCostLimits(apLimit, tupleLimit) and
- if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
- )
+ if apa.getHead().forceHighPrecision()
+ then unfold = true
+ else
+ exists(int aps, int nodes, int apLimit, int tupleLimit |
+ aps = countPotentialAps(apa, config) and
+ nodes = countNodesUsingAccessPath(apa, config) and
+ accessPathCostLimits(apLimit, tupleLimit) and
+ if apLimit < aps and tupleLimit < (aps - 1) * nodes then unfold = false else unfold = true
+ )
}
/**
@@ -3166,7 +3190,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
}
override string toString() {
- result = "[" + this.toStringImpl(true) + length().toString() + ")]"
+ result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
or
result = "[" + this.toStringImpl(false)
}
@@ -3248,7 +3272,7 @@ class PathNode extends TPathNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3305,9 +3329,11 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
- override string toString() { result = this.getNodeEx().toString() + ppAp() }
+ override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
- override string toStringWithContext() { result = this.getNodeEx().toString() + ppAp() + ppCtx() }
+ override string toStringWithContext() {
+ result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
+ }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -3375,11 +3401,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
override PathNodeImpl getASuccessorImpl() {
// an intermediate step to another intermediate node
- result = getSuccMid()
+ result = this.getSuccMid()
or
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
exists(PathNodeMid mid, PathNodeSink sink |
- mid = getSuccMid() and
+ mid = this.getSuccMid() and
mid.getNodeEx() = sink.getNodeEx() and
mid.getAp() instanceof AccessPathNil and
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
@@ -3456,7 +3482,7 @@ private predicate pathStep(
exists(TypedContent tc | pathReadStep(mid, node, ap.push(tc), tc, cc)) and
sc = mid.getSummaryCtx()
or
- pathIntoCallable(mid, node, _, cc, sc, _) and ap = mid.getAp()
+ pathIntoCallable(mid, node, _, cc, sc, _, _) and ap = mid.getAp()
or
pathOutOfCallable(mid, node, cc) and ap = mid.getAp() and sc instanceof SummaryCtxNone
or
@@ -3533,14 +3559,16 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
- PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa
+ PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
+ Configuration config
) {
exists(ArgNode arg |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
ap = mid.getAp() and
- apa = ap.getApprox()
+ apa = ap.getApprox() and
+ config = mid.getConfiguration()
)
}
@@ -3557,12 +3585,14 @@ private predicate parameterCand(
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
- AccessPath ap
+ AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
- pathIntoArg(mid, i, outercc, call, ap, apa) and
+ pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
+ pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
- parameterCand(callable, any(int j | j <= i and j >= i), apa, mid.getConfiguration())
+ parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
+ pragma[only_bind_into](config))
)
}
@@ -3571,12 +3601,13 @@ private predicate pathIntoCallable0(
* before and after entering the callable are `outercc` and `innercc`,
* respectively.
*/
+pragma[nomagic]
private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
- DataFlowCall call
+ DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
- pathIntoCallable0(mid, callable, i, outercc, call, ap) and
+ pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
(
sc = TSummaryCtxSome(p, ap)
@@ -3606,18 +3637,23 @@ private predicate paramFlowsThrough(
ap = mid.getAp() and
apa = ap.getApprox() and
pos = sc.getParameterPos() and
- not kind.(ParamUpdateReturnKind).getPosition() = pos
+ // we don't expect a parameter to return stored in itself, unless explicitly allowed
+ (
+ not kind.(ParamUpdateReturnKind).getPosition() = pos
+ or
+ sc.getParamNode().allowParameterReturnInSelf()
+ )
)
}
pragma[nomagic]
private predicate pathThroughCallable0(
DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, CallContext cc, AccessPath ap,
- AccessPathApprox apa
+ AccessPathApprox apa, Configuration config
) {
exists(CallContext innercc, SummaryCtx sc |
- pathIntoCallable(mid, _, cc, innercc, sc, call) and
- paramFlowsThrough(kind, innercc, sc, ap, apa, unbindConf(mid.getConfiguration()))
+ pathIntoCallable(mid, _, cc, innercc, sc, call, config) and
+ paramFlowsThrough(kind, innercc, sc, ap, apa, config)
)
}
@@ -3627,9 +3663,9 @@ private predicate pathThroughCallable0(
*/
pragma[noinline]
private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext cc, AccessPath ap) {
- exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa |
- pathThroughCallable0(call, mid, kind, cc, ap, apa) and
- out = getAnOutNodeFlow(kind, call, apa, unbindConf(mid.getConfiguration()))
+ exists(DataFlowCall call, ReturnKindExt kind, AccessPathApprox apa, Configuration config |
+ pathThroughCallable0(call, mid, kind, cc, ap, apa, config) and
+ out = getAnOutNodeFlow(kind, call, apa, config)
)
}
@@ -3643,10 +3679,11 @@ private module Subpaths {
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
- pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
- pathIntoCallable(arg, par, _, innercc, sc, _) and
- paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
- unbindConf(arg.getConfiguration()))
+ exists(Configuration config |
+ pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
+ pathIntoCallable(arg, par, _, innercc, sc, _, config) and
+ paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
+ )
}
/**
@@ -4033,7 +4070,7 @@ private module FlowExploration {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll
index f588a25a176..e11244c42b0 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll
@@ -801,6 +801,9 @@ private module Cached {
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call))
}
+ cached
+ predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
+
cached
newtype TCallContext =
TAnyCallContext() or
@@ -937,7 +940,7 @@ class CallContextSpecificCall extends CallContextCall, TSpecificCall {
}
override predicate relevantFor(DataFlowCallable callable) {
- recordDataFlowCallSite(getCall(), callable)
+ recordDataFlowCallSite(this.getCall(), callable)
}
override predicate matchesCall(DataFlowCall call) { call = this.getCall() }
@@ -1236,6 +1239,13 @@ class TypedContent extends MkTypedContent {
/** Gets a textual representation of this content. */
string toString() { result = c.toString() }
+
+ /**
+ * Holds if access paths with this `TypedContent` at their head always should
+ * be tracked at high precision. This disables adaptive access path precision
+ * for such access paths.
+ */
+ predicate forceHighPrecision() { forceHighPrecision(c) }
}
/**
@@ -1250,7 +1260,7 @@ abstract class AccessPathFront extends TAccessPathFront {
TypedContent getHead() { this = TFrontHead(result) }
- predicate isClearedAt(Node n) { clearsContentCached(n, getHead().getContent()) }
+ predicate isClearedAt(Node n) { clearsContentCached(n, this.getHead().getContent()) }
}
class AccessPathFrontNil extends AccessPathFront, TFrontNil {
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll
index a55e65a81f6..dd64fc70039 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll
@@ -175,6 +175,7 @@ module Consistency {
query predicate postWithInFlow(Node n, string msg) {
isPostUpdateNode(n) and
+ not clearsContent(n, _) and
simpleLocalFlowStep(_, n) and
msg = "PostUpdateNode should not be the target of local flow."
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
index ca4d0fa98e7..d47cfd95d8f 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll
@@ -310,6 +310,18 @@ module LocalFlow {
result = n.(ExplicitParameterNode).getSsaDefinition()
}
+ /**
+ * Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo`
+ * involving SSA definition `def`.
+ */
+ predicate localSsaFlowStepUseUse(Ssa::Definition def, Node nodeFrom, Node nodeTo) {
+ exists(ControlFlow::Node cfnFrom, ControlFlow::Node cfnTo |
+ SsaImpl::adjacentReadPairSameVar(def, cfnFrom, cfnTo) and
+ nodeTo = TExprNode(cfnTo) and
+ nodeFrom = TExprNode(cfnFrom)
+ )
+ }
+
/**
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
* SSA definition `def.
@@ -322,14 +334,7 @@ module LocalFlow {
)
or
// Flow from read to next read
- exists(ControlFlow::Node cfnFrom, ControlFlow::Node cfnTo |
- SsaImpl::adjacentReadPairSameVar(def, cfnFrom, cfnTo) and
- nodeTo = TExprNode(cfnTo)
- |
- nodeFrom = TExprNode(cfnFrom)
- or
- cfnFrom = nodeFrom.(PostUpdateNode).getPreUpdateNode().getControlFlowNode()
- )
+ localSsaFlowStepUseUse(def, nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
or
// Flow into phi node
exists(Ssa::PhiNode phi |
@@ -399,6 +404,12 @@ module LocalFlow {
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
+ exists(Ssa::Definition def |
+ LocalFlow::localSsaFlowStepUseUse(def, nodeFrom, nodeTo) and
+ not FlowSummaryImpl::Private::Steps::summaryClearsContentArg(nodeFrom, _) and
+ not LocalFlow::usesInstanceField(def)
+ )
+ or
LocalFlow::localFlowCapturedVarStep(nodeFrom, nodeTo)
or
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
@@ -716,6 +727,8 @@ private module Cached {
predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) {
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
+ LocalFlow::localSsaFlowStepUseUse(_, nodeFrom, nodeTo)
+ or
exists(Ssa::Definition def |
LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo) and
LocalFlow::usesInstanceField(def)
@@ -940,13 +953,9 @@ private module ParameterNodes {
import ParameterNodes
/** A data-flow node that represents a call argument. */
-class ArgumentNode extends Node {
- ArgumentNode() { this instanceof ArgumentNodeImpl }
-
+class ArgumentNode extends Node instanceof ArgumentNodeImpl {
/** Holds if this argument occurs at the given position in the given call. */
- final predicate argumentOf(DataFlowCall call, int pos) {
- this.(ArgumentNodeImpl).argumentOf(call, pos)
- }
+ final predicate argumentOf(DataFlowCall call, int pos) { super.argumentOf(call, pos) }
}
abstract private class ArgumentNodeImpl extends Node {
@@ -1695,9 +1704,6 @@ predicate clearsContent(Node n, Content c) {
or
fieldOrPropertyStore(_, c, _, n.(ObjectInitializerNode).getInitializer(), false)
or
- FlowSummaryImpl::Private::Steps::summaryStoresIntoArg(c, n) and
- not c instanceof ElementContent
- or
FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c)
or
exists(WithExpr we, ObjectInitializer oi, FieldOrProperty f |
@@ -1918,6 +1924,12 @@ private predicate viableConstantBooleanParamArg(
int accessPathLimit() { result = 5 }
+/**
+ * Holds if access paths with `c` at their head always should be tracked at high
+ * precision. This disables adaptive access path precision for such access paths.
+ */
+predicate forceHighPrecision(Content c) { c instanceof ElementContent }
+
/** The unit type. */
private newtype TUnit = TMkUnit()
@@ -2001,3 +2013,14 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
preservesValue = false
)
}
+
+/**
+ * Holds if flow is allowed to pass from parameter `p` and back to itself as a
+ * side-effect, resulting in a summary from `p` to itself.
+ *
+ * One example would be to allow flow like `p.foo = p.bar;`, which is disallowed
+ * by default as a heuristic.
+ */
+predicate allowParameterReturnInSelf(ParameterNode p) {
+ FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p)
+}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll
index bfc2f5469d0..fa99d518bbd 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll
@@ -58,7 +58,7 @@ class Node extends TNode {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
@@ -98,9 +98,7 @@ class ExprNode extends Node, TExprNode_ {
* The value of a parameter at function entry, viewed as a node in a data
* flow graph.
*/
-class ParameterNode extends Node {
- ParameterNode() { this instanceof ParameterNodeImpl }
-
+class ParameterNode extends Node instanceof ParameterNodeImpl {
/** Gets the parameter corresponding to this node, if any. */
DotNet::Parameter getParameter() {
exists(DataFlowCallable c, int i | this.isParameterOf(c, i) and result = c.getParameter(i))
@@ -110,9 +108,7 @@ class ParameterNode extends Node {
* Holds if this node is the parameter of callable `c` at the specified
* (zero-based) position.
*/
- predicate isParameterOf(DataFlowCallable c, int i) {
- this.(ParameterNodeImpl).isParameterOf(c, i)
- }
+ predicate isParameterOf(DataFlowCallable c, int i) { super.isParameterOf(c, i) }
}
/** A definition, viewed as a node in a data flow graph. */
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll
index 523516e60f8..5955285bd6f 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll
@@ -186,10 +186,17 @@ module Private {
TArgumentSummaryComponent(int i) { parameterPosition(i) } or
TReturnSummaryComponent(ReturnKind rk)
+ private TSummaryComponent thisParam() {
+ result = TParameterSummaryComponent(instanceParameterPosition())
+ }
+
newtype TSummaryComponentStack =
TSingletonSummaryComponentStack(SummaryComponent c) or
TConsSummaryComponentStack(SummaryComponent head, SummaryComponentStack tail) {
tail.(RequiredSummaryComponentStack).required(head)
+ or
+ tail.(RequiredSummaryComponentStack).required(TParameterSummaryComponent(_)) and
+ head = thisParam()
}
pragma[nomagic]
@@ -198,20 +205,65 @@ module Private {
boolean preservesValue
) {
c.propagatesFlow(input, output, preservesValue)
+ or
+ // observe side effects of callbacks on input arguments
+ c.propagatesFlow(output, input, preservesValue) and
+ preservesValue = true and
+ isCallbackParameter(input) and
+ isContentOfArgument(output)
+ or
+ // flow from the receiver of a callback into the instance-parameter
+ exists(SummaryComponentStack s, SummaryComponentStack callbackRef |
+ c.propagatesFlow(s, _, _) or c.propagatesFlow(_, s, _)
+ |
+ callbackRef = s.drop(_) and
+ (isCallbackParameter(callbackRef) or callbackRef.head() = TReturnSummaryComponent(_)) and
+ input = callbackRef.tail() and
+ output = TConsSummaryComponentStack(thisParam(), input) and
+ preservesValue = true
+ )
+ }
+
+ private predicate isCallbackParameter(SummaryComponentStack s) {
+ s.head() = TParameterSummaryComponent(_) and exists(s.tail())
+ }
+
+ private predicate isContentOfArgument(SummaryComponentStack s) {
+ s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail())
+ or
+ s = TSingletonSummaryComponentStack(TArgumentSummaryComponent(_))
+ }
+
+ private predicate outputState(SummarizedCallable c, SummaryComponentStack s) {
+ summary(c, _, s, _)
+ or
+ exists(SummaryComponentStack out |
+ outputState(c, out) and
+ out.head() = TContentSummaryComponent(_) and
+ s = out.tail()
+ )
+ or
+ // Add the argument node corresponding to the requested post-update node
+ inputState(c, s) and isCallbackParameter(s)
+ }
+
+ private predicate inputState(SummarizedCallable c, SummaryComponentStack s) {
+ summary(c, s, _, _)
+ or
+ exists(SummaryComponentStack inp | inputState(c, inp) and s = inp.tail())
+ or
+ exists(SummaryComponentStack out |
+ outputState(c, out) and
+ out.head() = TParameterSummaryComponent(_) and
+ s = out.tail()
+ )
}
private newtype TSummaryNodeState =
- TSummaryNodeInputState(SummaryComponentStack s) {
- exists(SummaryComponentStack input |
- summary(_, input, _, _) and
- s = input.drop(_)
- )
- } or
- TSummaryNodeOutputState(SummaryComponentStack s) {
- exists(SummaryComponentStack output |
- summary(_, _, output, _) and
- s = output.drop(_)
- )
+ TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or
+ TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } or
+ TSummaryNodeClearsContentState(int i, boolean post) {
+ any(SummarizedCallable sc).clearsContent(i, _) and post in [false, true]
}
/**
@@ -238,20 +290,14 @@ module Private {
pragma[nomagic]
predicate isInputState(SummarizedCallable c, SummaryComponentStack s) {
this = TSummaryNodeInputState(s) and
- exists(SummaryComponentStack input |
- summary(c, input, _, _) and
- s = input.drop(_)
- )
+ inputState(c, s)
}
/** Holds if this state is a valid output state for `c`. */
pragma[nomagic]
predicate isOutputState(SummarizedCallable c, SummaryComponentStack s) {
this = TSummaryNodeOutputState(s) and
- exists(SummaryComponentStack output |
- summary(c, _, output, _) and
- s = output.drop(_)
- )
+ outputState(c, s)
}
/** Gets a textual representation of this state. */
@@ -265,6 +311,12 @@ module Private {
this = TSummaryNodeOutputState(s) and
result = "to write: " + s
)
+ or
+ exists(int i, boolean post, string postStr |
+ this = TSummaryNodeClearsContentState(i, post) and
+ (if post = true then postStr = " (post)" else postStr = "") and
+ result = "clear: " + i + postStr
+ )
}
}
@@ -286,6 +338,11 @@ module Private {
not parameterReadState(c, state, _)
or
state.isOutputState(c, _)
+ or
+ exists(int i |
+ c.clearsContent(i, _) and
+ state = TSummaryNodeClearsContentState(i, _)
+ )
}
pragma[noinline]
@@ -321,6 +378,8 @@ module Private {
parameterReadState(c, _, i)
or
isParameterPostUpdate(_, c, i)
+ or
+ c.clearsContent(i, _)
}
private predicate callbackOutput(
@@ -331,19 +390,12 @@ module Private {
receiver = summaryNodeInputState(c, s.drop(1))
}
- private Node pre(Node post) {
- summaryPostUpdateNode(post, result)
- or
- not summaryPostUpdateNode(post, _) and
- result = post
- }
-
private predicate callbackInput(
SummarizedCallable c, SummaryComponentStack s, Node receiver, int i
) {
any(SummaryNodeState state).isOutputState(c, s) and
s.head() = TParameterSummaryComponent(i) and
- receiver = pre(summaryNodeOutputState(c, s.drop(1)))
+ receiver = summaryNodeInputState(c, s.drop(1))
}
/** Holds if a call targeting `receiver` should be synthesized inside `c`. */
@@ -395,11 +447,17 @@ module Private {
or
exists(int i | head = TParameterSummaryComponent(i) |
result =
- getCallbackParameterType(getNodeType(summaryNodeOutputState(pragma[only_bind_out](c),
+ getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.drop(1))), i)
)
)
)
+ or
+ exists(SummarizedCallable c, int i, ParamNode p |
+ n = summaryNode(c, TSummaryNodeClearsContentState(i, false)) and
+ p.isParameterOf(c, i) and
+ result = getNodeType(p)
+ )
}
/** Holds if summary node `out` contains output of kind `rk` from call `c`. */
@@ -421,10 +479,19 @@ module Private {
}
/** Holds if summary node `post` is a post-update node with pre-update node `pre`. */
- predicate summaryPostUpdateNode(Node post, ParamNode pre) {
+ predicate summaryPostUpdateNode(Node post, Node pre) {
exists(SummarizedCallable c, int i |
isParameterPostUpdate(post, c, i) and
- pre.isParameterOf(c, i)
+ pre.(ParamNode).isParameterOf(c, i)
+ or
+ pre = summaryNode(c, TSummaryNodeClearsContentState(i, false)) and
+ post = summaryNode(c, TSummaryNodeClearsContentState(i, true))
+ )
+ or
+ exists(SummarizedCallable callable, SummaryComponentStack s |
+ callbackInput(callable, s, _, _) and
+ pre = summaryNodeOutputState(callable, s) and
+ post = summaryNodeInputState(callable, s)
)
}
@@ -436,6 +503,17 @@ module Private {
)
}
+ /**
+ * Holds if flow is allowed to pass from parameter `p`, to a return
+ * node, and back out to `p`.
+ */
+ predicate summaryAllowParameterReturnInSelf(ParamNode p) {
+ exists(SummarizedCallable c, int i |
+ c.clearsContent(i, _) and
+ p.isParameterOf(c, i)
+ )
+ }
+
/** Provides a compilation of flow summaries to atomic data-flow steps. */
module Steps {
/**
@@ -462,7 +540,21 @@ module Private {
// for `StringBuilder.append(x)` with a specified value flow from qualifier to
// return value and taint flow from argument 0 to the qualifier, then this
// allows us to infer taint flow from argument 0 to the return value.
- summaryPostUpdateNode(pred, succ) and preservesValue = true
+ succ instanceof ParamNode and
+ summaryPostUpdateNode(pred, succ) and
+ preservesValue = true
+ or
+ // Similarly we would like to chain together summaries where values get passed
+ // into callbacks along the way.
+ pred instanceof ArgNode and
+ summaryPostUpdateNode(succ, pred) and
+ preservesValue = true
+ or
+ exists(SummarizedCallable c, int i |
+ pred.(ParamNode).isParameterOf(c, i) and
+ succ = summaryNode(c, TSummaryNodeClearsContentState(i, _)) and
+ preservesValue = true
+ )
}
/**
@@ -490,10 +582,39 @@ module Private {
}
/**
- * Holds if values stored inside content `c` are cleared when passed as
- * input of type `input` in `call`.
+ * Holds if values stored inside content `c` are cleared at `n`. `n` is a
+ * synthesized summary node, so in order for values to be cleared at calls
+ * to the relevant method, it is important that flow does not pass over
+ * the argument, either via use-use flow or def-use flow.
+ *
+ * Example:
+ *
+ * ```
+ * a.b = taint;
+ * a.clearB(); // assume we have a flow summary for `clearB` that clears `b` on the qualifier
+ * sink(a.b);
+ * ```
+ *
+ * In the above, flow should not pass from `a` on the first line (or the second
+ * line) to `a` on the third line. Instead, there will be synthesized flow from
+ * `a` on line 2 to the post-update node for `a` on that line (via an intermediate
+ * node where field `b` is cleared).
*/
- predicate summaryClearsContent(ArgNode arg, Content c) {
+ predicate summaryClearsContent(Node n, Content c) {
+ exists(SummarizedCallable sc, int i |
+ n = summaryNode(sc, TSummaryNodeClearsContentState(i, true)) and
+ sc.clearsContent(i, c)
+ )
+ }
+
+ /**
+ * Holds if values stored inside content `c` are cleared inside a
+ * callable to which `arg` is an argument.
+ *
+ * In such cases, it is important to prevent use-use flow out of
+ * `arg` (see comment for `summaryClearsContent`).
+ */
+ predicate summaryClearsContentArg(ArgNode arg, Content c) {
exists(DataFlowCall call, int i |
viableCallable(call).(SummarizedCallable).clearsContent(i, c) and
arg.argumentOf(call, i)
@@ -553,25 +674,6 @@ module Private {
ret.getKind() = rk
)
}
-
- /**
- * Holds if data is written into content `c` of argument `arg` using a flow summary.
- *
- * Depending on the type of `c`, this predicate may be relevant to include in the
- * definition of `clearsContent()`.
- */
- predicate summaryStoresIntoArg(Content c, Node arg) {
- exists(ParamUpdateReturnKind rk, ReturnNodeExt ret, PostUpdateNode out |
- exists(DataFlowCall call, SummarizedCallable callable |
- getNodeEnclosingCallable(ret) = callable and
- viableCallable(call) = callable and
- summaryStoreStep(_, c, ret) and
- ret.getKind() = pragma[only_bind_into](rk) and
- out = rk.getAnOutNode(call) and
- arg = out.getPreUpdateNode()
- )
- )
- }
}
/**
@@ -824,4 +926,95 @@ module Private {
)
}
}
+
+ /**
+ * Provides query predicates for rendering the generated data flow graph for
+ * a summarized callable.
+ *
+ * Import this module into a `.ql` file of `@kind graph` to render the graph.
+ * The graph is restricted to callables from `RelevantSummarizedCallable`.
+ */
+ module RenderSummarizedCallable {
+ /** A summarized callable to include in the graph. */
+ abstract class RelevantSummarizedCallable extends SummarizedCallable { }
+
+ private newtype TNodeOrCall =
+ MkNode(Node n) {
+ exists(RelevantSummarizedCallable c |
+ n = summaryNode(c, _)
+ or
+ n.(ParamNode).isParameterOf(c, _)
+ )
+ } or
+ MkCall(DataFlowCall call) {
+ call = summaryDataFlowCall(_) and
+ call.getEnclosingCallable() instanceof RelevantSummarizedCallable
+ }
+
+ private class NodeOrCall extends TNodeOrCall {
+ Node asNode() { this = MkNode(result) }
+
+ DataFlowCall asCall() { this = MkCall(result) }
+
+ string toString() {
+ result = this.asNode().toString()
+ or
+ result = this.asCall().toString()
+ }
+
+ /**
+ * Holds if this element is at the specified location.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `filepath`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+ predicate hasLocationInfo(
+ string filepath, int startline, int startcolumn, int endline, int endcolumn
+ ) {
+ this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
+ or
+ this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
+ }
+ }
+
+ query predicate nodes(NodeOrCall n, string key, string val) {
+ key = "semmle.label" and val = n.toString()
+ }
+
+ private predicate edgesComponent(NodeOrCall a, NodeOrCall b, string value) {
+ exists(boolean preservesValue |
+ Private::Steps::summaryLocalStep(a.asNode(), b.asNode(), preservesValue) and
+ if preservesValue = true then value = "value" else value = "taint"
+ )
+ or
+ exists(Content c |
+ Private::Steps::summaryReadStep(a.asNode(), c, b.asNode()) and
+ value = "read (" + c + ")"
+ or
+ Private::Steps::summaryStoreStep(a.asNode(), c, b.asNode()) and
+ value = "store (" + c + ")"
+ or
+ Private::Steps::summaryClearsContent(a.asNode(), c) and
+ b = a and
+ value = "clear (" + c + ")"
+ )
+ or
+ summaryPostUpdateNode(b.asNode(), a.asNode()) and
+ value = "post-update"
+ or
+ b.asCall() = summaryDataFlowCall(a.asNode()) and
+ value = "receiver"
+ or
+ exists(int i |
+ summaryArgumentNode(b.asCall(), a.asNode(), i) and
+ value = "argument (" + i + ")"
+ )
+ }
+
+ query predicate edges(NodeOrCall a, NodeOrCall b, string key, string value) {
+ key = "semmle.label" and
+ value = strictconcat(string s | edgesComponent(a, b, s) | s, " / ")
+ }
+ }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll
index b0f67e8692f..822822a24c6 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll
@@ -16,6 +16,9 @@ private import semmle.code.csharp.dataflow.ExternalFlow
/** Holds is `i` is a valid parameter position. */
predicate parameterPosition(int i) { i in [-1 .. any(Parameter p).getPosition()] }
+/** Gets the parameter position of the instance parameter. */
+int instanceParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks
+
/** Gets the synthesized summary data-flow node for the given values. */
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) }
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll
index 884f4406d01..395cb5cb171 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll
@@ -156,6 +156,7 @@ private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) {
}
/** Holds if `df` is in the dominance frontier of `bb`. */
+pragma[noinline]
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and
not strictlyDominates(bb, df)
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll
index 884f4406d01..395cb5cb171 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll
@@ -156,6 +156,7 @@ private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) {
}
/** Holds if `df` is in the dominance frontier of `bb`. */
+pragma[noinline]
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and
not strictlyDominates(bb, df)
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll
index 2f8e93a4b75..067a9b94f45 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll
@@ -89,14 +89,12 @@ private module Impl {
}
/** An expression whose value may control the execution of another element. */
- class Guard extends Expr {
- Guard() { this instanceof G::Guard }
-
+ class Guard extends Expr instanceof G::Guard {
/**
* Holds if basic block `bb` is guarded by this guard having value `v`.
*/
predicate controlsBasicBlock(ControlFlow::BasicBlock bb, G::AbstractValue v) {
- this.(G::Guard).controlsBasicBlock(bb, v)
+ super.controlsBasicBlock(bb, v)
}
/**
@@ -108,7 +106,7 @@ private module Impl {
exists(Expr e1_, Expr e2_ |
e1 = unique(ExprNode cfn | hasChild(this, e1_, _, cfn) | cfn) and
e2 = unique(ExprNode cfn | hasChild(this, e2_, _, cfn) | cfn) and
- this.(G::Guard).isEquality(e1_, e2_, polarity)
+ super.isEquality(e1_, e2_, polarity)
)
}
}
@@ -421,9 +419,9 @@ module ExprNode {
* "else" expression of this conditional expression.
*/
ExprNode getBranchExpr(boolean branch) {
- branch = true and result = getTrueExpr()
+ branch = true and result = this.getTrueExpr()
or
- branch = false and result = getFalseExpr()
+ branch = false and result = this.getFalseExpr()
}
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll
index 558ecd1b88b..e450c11b5ab 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll
@@ -28,7 +28,7 @@ class SsaReadPositionBlock extends SsaReadPosition, TSsaReadPositionBlock {
/** Gets the basic block corresponding to this position. */
BasicBlock getBlock() { this = TSsaReadPositionBlock(result) }
- override predicate hasReadOfVar(SsaVariable v) { getBlock() = getAReadBasicBlock(v) }
+ override predicate hasReadOfVar(SsaVariable v) { this.getBlock() = getAReadBasicBlock(v) }
override string toString() { result = "block" }
}
@@ -49,8 +49,8 @@ class SsaReadPositionPhiInputEdge extends SsaReadPosition, TSsaReadPositionPhiIn
/** Holds if `inp` is an input to `phi` along this edge. */
predicate phiInput(SsaPhiNode phi, SsaVariable inp) {
- phi.hasInputFromBlock(inp, getOrigBlock()) and
- getPhiBlock() = phi.getBasicBlock()
+ phi.hasInputFromBlock(inp, this.getOrigBlock()) and
+ this.getPhiBlock() = phi.getBasicBlock()
}
override string toString() { result = "edge" }
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll
index f4f73b8247c..acb029c23d9 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll
@@ -75,24 +75,26 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isSanitizer(DataFlow::Node node) { none() }
final override predicate isBarrier(DataFlow::Node node) {
- isSanitizer(node) or
+ this.isSanitizer(node) or
defaultTaintSanitizer(node)
}
/** Holds if taint propagation into `node` is prohibited. */
predicate isSanitizerIn(DataFlow::Node node) { none() }
- final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
+ final override predicate isBarrierIn(DataFlow::Node node) { this.isSanitizerIn(node) }
/** Holds if taint propagation out of `node` is prohibited. */
predicate isSanitizerOut(DataFlow::Node node) { none() }
- final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
+ final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
- final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }
+ final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
+ this.isSanitizerGuard(guard)
+ }
/**
* Holds if the additional taint propagation step from `node1` to `node2`
@@ -101,7 +103,7 @@ abstract class Configuration extends DataFlow::Configuration {
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
- isAdditionalTaintStep(node1, node2) or
+ this.isAdditionalTaintStep(node1, node2) or
defaultAdditionalTaintStep(node1, node2)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll
index d0b4ef45ce8..509bdfb5e04 100644
--- a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll
@@ -11,10 +11,10 @@ private import RuntimeCallable
/** A call. */
class DispatchCall extends Internal::TDispatchCall {
/** Gets a textual representation of this call. */
- string toString() { result = getCall().toString() }
+ string toString() { result = this.getCall().toString() }
/** Gets the location of this call. */
- Location getLocation() { result = getCall().getLocation() }
+ Location getLocation() { result = this.getCall().getLocation() }
/** Gets the underlying expression of this call. */
Expr getCall() { result = Internal::getCall(this) }
@@ -209,7 +209,7 @@ private module Internal {
abstract Expr getArgument(int i);
/** Gets the number of arguments of this call. */
- int getNumberOfArguments() { result = count(int i | exists(getArgument(i))) }
+ int getNumberOfArguments() { result = count(int i | exists(this.getArgument(i))) }
/** Gets the qualifier of this call, if any. */
abstract Expr getQualifier();
@@ -506,12 +506,12 @@ private module Internal {
}
override RuntimeCallable getADynamicTarget() {
- result = getAViableInherited()
+ result = this.getAViableInherited()
or
- result = getAViableOverrider()
+ result = this.getAViableOverrider()
or
// Simple case: target method cannot be overridden
- result = getAStaticTarget() and
+ result = this.getAStaticTarget() and
not result instanceof OverridableCallable
}
@@ -779,9 +779,9 @@ private module Internal {
)
}
- override Expr getQualifier() { result = getCall().getQualifier() }
+ override Expr getQualifier() { result = this.getCall().getQualifier() }
- override Method getAStaticTarget() { result = getCall().getTarget() }
+ override Method getAStaticTarget() { result = this.getCall().getTarget() }
}
/**
@@ -793,24 +793,24 @@ private module Internal {
private class DispatchAccessorCall extends DispatchMethodOrAccessorCall, TDispatchAccessorCall {
override AccessorCall getCall() { this = TDispatchAccessorCall(result) }
- override Expr getArgument(int i) { result = getCall().getArgument(i) }
+ override Expr getArgument(int i) { result = this.getCall().getArgument(i) }
- override Expr getQualifier() { result = getCall().(MemberAccess).getQualifier() }
+ override Expr getQualifier() { result = this.getCall().(MemberAccess).getQualifier() }
- override Accessor getAStaticTarget() { result = getCall().getTarget() }
+ override Accessor getAStaticTarget() { result = this.getCall().getTarget() }
override RuntimeAccessor getADynamicTarget() {
result = DispatchMethodOrAccessorCall.super.getADynamicTarget() and
// Calls to accessors may have `dynamic` expression arguments,
// so we need to check that the types match
- forall(Type argumentType, int i | hasDynamicArg(i, argumentType) |
+ forall(Type argumentType, int i | this.hasDynamicArg(i, argumentType) |
argumentType.isImplicitlyConvertibleTo(result.getParameter(i).getType())
)
}
private predicate hasDynamicArg(int i, Type argumentType) {
exists(Expr argument |
- argument = getArgument(i) and
+ argument = this.getArgument(i) and
argument.stripImplicitCasts().getType() instanceof DynamicType and
argumentType = getAPossibleType(argument, _)
)
@@ -896,7 +896,7 @@ private module Internal {
// names and number of parameters. This set is further reduced in
// `getADynamicTarget()` by taking type information into account.
override Callable getAStaticTarget() {
- result = getACallableWithMatchingName() and
+ result = this.getACallableWithMatchingName() and
exists(int minArgs |
minArgs =
count(Parameter p |
@@ -904,16 +904,19 @@ private module Internal {
not p.hasDefaultValue() and
not p.isParams()
) and
- getNumberOfArguments() >= minArgs and
- (result.(Method).hasParams() or getNumberOfArguments() <= result.getNumberOfParameters())
+ this.getNumberOfArguments() >= minArgs and
+ (
+ result.(Method).hasParams() or
+ this.getNumberOfArguments() <= result.getNumberOfParameters()
+ )
)
}
private RuntimeCallable getACallableWithMatchingName() {
- result.(Operator).getFunctionName() = getName()
+ result.(Operator).getFunctionName() = this.getName()
or
not result instanceof Operator and
- result.getUndecoratedName() = getName()
+ result.getUndecoratedName() = this.getName()
}
// A callable is viable if the following conditions are all satisfied:
@@ -987,7 +990,7 @@ private module Internal {
* type of one of the arguments.
*/
RuntimeCallable getADynamicTargetCandidate() {
- result = getAStaticTarget() and
+ result = this.getAStaticTarget() and
(
result = getADynamicTargetCandidateInstanceMethod(this.getAQualifierType())
or
@@ -999,13 +1002,13 @@ private module Internal {
result instanceof RuntimeInstanceAccessor and
this.hasUnknownQualifierType()
or
- result = getADynamicTargetCandidateOperator()
+ result = this.getADynamicTargetCandidateOperator()
)
}
pragma[noinline]
private RuntimeOperator getADynamicTargetCandidateOperator() {
- result = getAStaticTarget() and
+ result = this.getAStaticTarget() and
result.getDeclaringType() = result.getAParameter().getType()
}
}
@@ -1138,8 +1141,8 @@ private module Internal {
result = DispatchReflectionOrDynamicCall.super.getADynamicTargetCandidate()
or
// Static callables can be called using reflection as well
- result = getAStaticTarget() and
- result.getDeclaringType() = getStaticType() and
+ result = this.getAStaticTarget() and
+ result.getDeclaringType() = this.getStaticType() and
result.(Modifiable).isStatic()
}
@@ -1147,7 +1150,7 @@ private module Internal {
override Expr getArgument(int i) {
exists(int args, ArrayCreation ac |
this = TDispatchReflectionCall(_, _, _, _, args) and
- ac = getAMethodCallArgSource(getCall().getArgument(args)) and
+ ac = getAMethodCallArgSource(this.getCall().getArgument(args)) and
result = ac.getInitializer().getElement(i)
)
}
@@ -1158,20 +1161,20 @@ private module Internal {
TDispatchDynamicMethodCall {
override DynamicMethodCall getCall() { this = TDispatchDynamicMethodCall(result) }
- override string getName() { result = getCall().getLateBoundTargetName() }
+ override string getName() { result = this.getCall().getLateBoundTargetName() }
- override Expr getQualifier() { result = getCall().getQualifier() }
+ override Expr getQualifier() { result = this.getCall().getQualifier() }
override RuntimeMethod getADynamicTargetCandidate() {
- if exists(getCall().getTarget())
+ if exists(this.getCall().getTarget())
then
// static method call
- result = getCall().getTarget()
+ result = this.getCall().getTarget()
else result = DispatchReflectionOrDynamicCall.super.getADynamicTargetCandidate()
}
// Does not take named arguments into account
- override Expr getArgument(int i) { result = getCall().getArgument(i) }
+ override Expr getArgument(int i) { result = this.getCall().getArgument(i) }
}
/** An operator call using dynamic types. */
@@ -1181,14 +1184,14 @@ private module Internal {
override string getName() {
exists(Operator o |
- o.getName() = getCall().getLateBoundTargetName() and
+ o.getName() = this.getCall().getLateBoundTargetName() and
result = o.getFunctionName()
)
}
override Expr getQualifier() { none() }
- override Expr getArgument(int i) { result = getCall().getArgument(i) }
+ override Expr getArgument(int i) { result = this.getCall().getArgument(i) }
}
/** A (potential) call to a property accessor using dynamic types. */
@@ -1255,7 +1258,7 @@ private module Internal {
any(DynamicMemberAccess dma | this = TDispatchDynamicEventAccess(_, dma, _)).getQualifier()
}
- override Expr getArgument(int i) { i = 0 and result = getCall().getRValue() }
+ override Expr getArgument(int i) { i = 0 and result = this.getCall().getRValue() }
}
/** A call to a constructor using dynamic types. */
@@ -1267,9 +1270,9 @@ private module Internal {
override Expr getQualifier() { none() }
- override Expr getArgument(int i) { result = getCall().getArgument(i) }
+ override Expr getArgument(int i) { result = this.getCall().getArgument(i) }
- override RuntimeCallable getADynamicTargetCandidate() { result = getCall().getTarget() }
+ override RuntimeCallable getADynamicTargetCandidate() { result = this.getCall().getTarget() }
}
/** A call where the target can be resolved statically. */
@@ -1285,8 +1288,8 @@ private module Internal {
)
}
- override Callable getAStaticTarget() { result = getCall().getTarget() }
+ override Callable getAStaticTarget() { result = this.getCall().getTarget() }
- override RuntimeCallable getADynamicTarget() { result = getCall().getTarget() }
+ override RuntimeCallable getADynamicTarget() { result = this.getCall().getTarget() }
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dispatch/OverridableCallable.qll b/csharp/ql/lib/semmle/code/csharp/dispatch/OverridableCallable.qll
index 4913ea2bc3c..dc963881cbf 100644
--- a/csharp/ql/lib/semmle/code/csharp/dispatch/OverridableCallable.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dispatch/OverridableCallable.qll
@@ -58,13 +58,13 @@ class OverridableCallable extends Callable {
* `I.M.getAnImplementorSubType(D) = C.M`.
*/
private Callable getAnImplementorSubType(ValueOrRefType t) {
- result = getAnImplementor(t)
+ result = this.getAnImplementor(t)
or
exists(ValueOrRefType mid |
- result = getAnImplementorSubType(mid) and
+ result = this.getAnImplementorSubType(mid) and
t.getBaseClass() = mid and
// There must be no other implementation of this callable in `t`
- forall(Callable other | other = getAnImplementor(t) | other = result)
+ forall(Callable other | other = this.getAnImplementor(t) | other = result)
)
}
@@ -107,8 +107,8 @@ class OverridableCallable extends Callable {
* implements this interface callable, if any.
*/
private Callable getAnOverridingImplementor() {
- result = getAnUltimateImplementor() and
- not result = getAnImplementor(_)
+ result = this.getAnUltimateImplementor() and
+ not result = this.getAnImplementor(_)
}
/**
@@ -150,10 +150,10 @@ class OverridableCallable extends Callable {
}
private Callable getInherited1(ValueOrRefType t) {
- result = getInherited0(t)
+ result = this.getInherited0(t)
or
// An interface implementation
- result = getAnImplementorSubType(t)
+ result = this.getAnImplementorSubType(t)
}
pragma[noinline]
@@ -171,7 +171,7 @@ class OverridableCallable extends Callable {
private predicate isDeclaringSubType(ValueOrRefType t) {
t = this.getDeclaringType()
or
- exists(ValueOrRefType mid | isDeclaringSubType(mid) | t = mid.getASubType())
+ exists(ValueOrRefType mid | this.isDeclaringSubType(mid) | t = mid.getASubType())
}
pragma[noinline]
@@ -232,7 +232,7 @@ class OverridableAccessor extends Accessor, OverridableCallable {
override Accessor getAnImplementor(ValueOrRefType t) {
exists(Virtualizable implementor, int kind |
- getAnImplementorAux(t, implementor, kind) and
+ this.getAnImplementorAux(t, implementor, kind) and
result.getDeclaration() = implementor and
getAccessorKind(result) = kind
)
@@ -241,7 +241,7 @@ class OverridableAccessor extends Accessor, OverridableCallable {
// predicate folding to get proper join order
private predicate getAnImplementorAux(ValueOrRefType t, Virtualizable implementor, int kind) {
exists(Virtualizable implementee |
- implementee = getDeclaration() and
+ implementee = this.getDeclaration() and
kind = getAccessorKind(this) and
implementor = implementee.getAnImplementor(t)
)
@@ -249,7 +249,7 @@ class OverridableAccessor extends Accessor, OverridableCallable {
override Accessor getAnUltimateImplementor() {
exists(Virtualizable implementor, int kind |
- getAnUltimateImplementorAux(implementor, kind) and
+ this.getAnUltimateImplementorAux(implementor, kind) and
result.getDeclaration() = implementor and
getAccessorKind(result) = kind
)
@@ -258,7 +258,7 @@ class OverridableAccessor extends Accessor, OverridableCallable {
// predicate folding to get proper join order
private predicate getAnUltimateImplementorAux(Virtualizable implementor, int kind) {
exists(Virtualizable implementee |
- implementee = getDeclaration() and
+ implementee = this.getDeclaration() and
kind = getAccessorKind(this) and
implementor = implementee.getAnUltimateImplementor()
)
diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Access.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Access.qll
index ab3ea182056..9d7cf3a5867 100644
--- a/csharp/ql/lib/semmle/code/csharp/exprs/Access.qll
+++ b/csharp/ql/lib/semmle/code/csharp/exprs/Access.qll
@@ -115,7 +115,7 @@ class MemberAccess extends Access, QualifiableExpr, @member_access_expr {
not exists(MemberInitializer mi | mi.getLValue() = this)
}
- override Member getQualifiedDeclaration() { result = getTarget() }
+ override Member getQualifiedDeclaration() { result = this.getTarget() }
override Member getTarget() { none() }
}
@@ -147,8 +147,8 @@ class AssignableAccess extends Access, @assignable_access_expr {
* or a `ref` argument in a method call.
*/
predicate isOutOrRefArgument() {
- isOutArgument() or
- isRefArgument()
+ this.isOutArgument() or
+ this.isRefArgument()
}
/**
@@ -507,7 +507,7 @@ class ElementAccess extends AssignableAccess, QualifiableExpr, @element_access_e
* Gets an index expression of this element access, for example
* `1` in `x[0, 1]`.
*/
- Expr getAnIndex() { result = getIndex(_) }
+ Expr getAnIndex() { result = this.getIndex(_) }
/**
* Gets the `i`th index expression of this element access, for example the
@@ -515,7 +515,7 @@ class ElementAccess extends AssignableAccess, QualifiableExpr, @element_access_e
*/
Expr getIndex(int i) { result = this.getChild(i) and i >= 0 }
- override Assignable getQualifiedDeclaration() { result = getTarget() }
+ override Assignable getQualifiedDeclaration() { result = this.getTarget() }
}
/**
@@ -615,7 +615,7 @@ class IndexerWrite extends IndexerAccess, ElementWrite { }
* ```
*/
class VirtualIndexerAccess extends IndexerAccess {
- VirtualIndexerAccess() { targetIsOverridableOrImplementable() }
+ VirtualIndexerAccess() { this.targetIsOverridableOrImplementable() }
}
/**
@@ -647,7 +647,7 @@ library class EventAccessExpr extends Expr, @event_access_expr {
* ```
*/
class EventAccess extends AssignableMemberAccess, EventAccessExpr {
- override Event getTarget() { result = getEvent() }
+ override Event getTarget() { result = this.getEvent() }
override string getAPrimaryQlClass() { result = "EventAccess" }
}
@@ -707,7 +707,7 @@ class EventWrite extends EventAccess, AssignableWrite { }
* ```
*/
class VirtualEventAccess extends EventAccess {
- VirtualEventAccess() { targetIsOverridableOrImplementable() }
+ VirtualEventAccess() { this.targetIsOverridableOrImplementable() }
}
/**
@@ -787,7 +787,7 @@ class LocalFunctionAccess extends CallableAccess {
* ```
*/
class VirtualMethodAccess extends MethodAccess {
- VirtualMethodAccess() { targetIsOverridableOrImplementable() }
+ VirtualMethodAccess() { this.targetIsOverridableOrImplementable() }
}
/**
diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll
index ac98c0eafcf..f20bfba1589 100644
--- a/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll
+++ b/csharp/ql/lib/semmle/code/csharp/exprs/ArithmeticOperation.qll
@@ -138,10 +138,10 @@ class DivExpr extends BinaryArithmeticOperation, @div_expr {
override string getOperator() { result = "/" }
/** Gets the numerator of this division operation. */
- Expr getNumerator() { result = getLeftOperand() }
+ Expr getNumerator() { result = this.getLeftOperand() }
/** Gets the denominator of this division operation. */
- Expr getDenominator() { result = getRightOperand() }
+ Expr getDenominator() { result = this.getRightOperand() }
override string getAPrimaryQlClass() { result = "DivExpr" }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll
index 88ef770160a..562a4dd9cd5 100644
--- a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll
+++ b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll
@@ -27,7 +27,7 @@ class Assignment extends Operation, @assign_expr {
Expr getRValue() { result = this.getChild(0) }
/** Gets the variable being assigned to, if any. */
- Variable getTargetVariable() { result.getAnAccess() = getLValue() }
+ Variable getTargetVariable() { result.getAnAccess() = this.getLValue() }
override string getOperator() { none() }
}
@@ -38,7 +38,7 @@ class Assignment extends Operation, @assign_expr {
class LocalVariableDeclAndInitExpr extends LocalVariableDeclExpr, Assignment {
override string getOperator() { result = "=" }
- override LocalVariable getTargetVariable() { result = getVariable() }
+ override LocalVariable getTargetVariable() { result = this.getVariable() }
override LocalVariableAccess getLValue() { result = Assignment.super.getLValue() }
@@ -86,7 +86,7 @@ class AssignOperation extends Assignment, @assign_op_expr {
* If an expanded version exists, then it is used in the control
* flow graph.
*/
- predicate hasExpandedAssignment() { exists(getExpandedAssignment()) }
+ predicate hasExpandedAssignment() { exists(this.getExpandedAssignment()) }
override string toString() { result = "... " + this.getOperator() + " ..." }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll
index 6dc88e941ef..a4c4ab1b670 100644
--- a/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll
+++ b/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll
@@ -47,7 +47,7 @@ class Call extends DotNet::Call, Expr, @call {
override Expr getRawArgument(int i) { result = this.getArgument(i) }
- override Expr getAnArgument() { result = getArgument(_) }
+ override Expr getAnArgument() { result = this.getArgument(_) }
/** Gets the number of arguments of this call. */
int getNumberOfArguments() { result = count(this.getAnArgument()) }
@@ -80,7 +80,7 @@ class Call extends DotNet::Call, Expr, @call {
*/
cached
override Expr getArgumentForParameter(DotNet::Parameter p) {
- getTarget().getAParameter() = p and
+ this.getTarget().getAParameter() = p and
(
// Appears in the positional part of the call
result = this.getImplicitArgument(p.getPosition()) and
@@ -94,7 +94,7 @@ class Call extends DotNet::Call, Expr, @call {
)
or
// Appears in the named part of the call
- result = getExplicitArgument(p.getName()) and
+ result = this.getExplicitArgument(p.getName()) and
(p.(Parameter).isParams() implies isValidExplicitParamsType(p, result.getType()))
)
}
@@ -112,13 +112,13 @@ class Call extends DotNet::Call, Expr, @call {
pragma[noinline]
private Expr getImplicitArgument(int pos) {
- result = getArgument(pos) and
+ result = this.getArgument(pos) and
not exists(result.getExplicitArgumentName())
}
pragma[nomagic]
private Expr getExplicitArgument(string name) {
- result = getAnArgument() and
+ result = this.getAnArgument() and
result.getExplicitArgumentName() = name
}
@@ -131,7 +131,7 @@ class Call extends DotNet::Call, Expr, @call {
*/
Expr getArgumentForName(string name) {
exists(Parameter p |
- result = getArgumentForParameter(p) and
+ result = this.getArgumentForParameter(p) and
p.hasName(name)
)
}
@@ -219,7 +219,7 @@ class Call extends DotNet::Call, Expr, @call {
*/
Expr getRuntimeArgumentForParameter(Parameter p) {
exists(Callable c |
- c = getARuntimeTarget() and
+ c = this.getARuntimeTarget() and
p = c.getAParameter() and
result = this.getRuntimeArgument(p.getPosition())
)
@@ -231,7 +231,7 @@ class Call extends DotNet::Call, Expr, @call {
*/
Expr getRuntimeArgumentForName(string name) {
exists(Parameter p |
- result = getRuntimeArgumentForParameter(p) and
+ result = this.getRuntimeArgumentForParameter(p) and
p.hasName(name)
)
}
@@ -240,19 +240,19 @@ class Call extends DotNet::Call, Expr, @call {
* Gets an argument that corresponds to a parameter of a potential
* run-time target of this call.
*/
- Expr getARuntimeArgument() { result = getRuntimeArgument(_) }
+ Expr getARuntimeArgument() { result = this.getRuntimeArgument(_) }
/**
* Gets the number of arguments that correspond to a parameter of a potential
* run-time target of this call.
*/
- int getNumberOfRuntimeArguments() { result = count(getARuntimeArgument()) }
+ int getNumberOfRuntimeArguments() { result = count(this.getARuntimeArgument()) }
/**
* Holds if this call has no arguments that correspond to a parameter of a
* potential (run-time) target of this call.
*/
- predicate hasNoRuntimeArguments() { not exists(getARuntimeArgument()) }
+ predicate hasNoRuntimeArguments() { not exists(this.getARuntimeArgument()) }
override string toString() { result = "call" }
}
@@ -295,19 +295,19 @@ private predicate isValidExplicitParamsType(Parameter p, Type t) {
class MethodCall extends Call, QualifiableExpr, LateBindableExpr, @method_invocation_expr {
override Method getTarget() { expr_call(this, result) }
- override Method getQualifiedDeclaration() { result = getTarget() }
+ override Method getQualifiedDeclaration() { result = this.getTarget() }
override string toString() { result = "call to method " + concat(this.getTarget().getName()) }
override string getAPrimaryQlClass() { result = "MethodCall" }
override Expr getRawArgument(int i) {
- if exists(getQualifier())
+ if exists(this.getQualifier())
then
- i = 0 and result = getQualifier()
+ i = 0 and result = this.getQualifier()
or
- result = getArgument(i - 1)
- else result = getArgument(i)
+ result = this.getArgument(i - 1)
+ else result = this.getArgument(i)
}
}
@@ -336,7 +336,7 @@ class ExtensionMethodCall extends MethodCall {
override Expr getArgument(int i) {
exists(int j | result = this.getChildExpr(j) |
- if isOrdinaryStaticCall() then (j = i and j >= 0) else (j = i - 1 and j >= -1)
+ if this.isOrdinaryStaticCall() then (j = i and j >= 0) else (j = i - 1 and j >= -1)
)
}
@@ -379,8 +379,8 @@ class ExtensionMethodCall extends MethodCall {
*/
class VirtualMethodCall extends MethodCall {
VirtualMethodCall() {
- not getQualifier() instanceof BaseAccess and
- getTarget().isOverridableOrImplementable()
+ not this.getQualifier() instanceof BaseAccess and
+ this.getTarget().isOverridableOrImplementable()
}
}
@@ -573,7 +573,7 @@ class DelegateLikeCall extends Call, DelegateLikeCall_ {
)
}
- override Expr getRuntimeArgument(int i) { result = getArgument(i) }
+ override Expr getRuntimeArgument(int i) { result = this.getArgument(i) }
}
/**
@@ -618,11 +618,11 @@ class DelegateCall extends DelegateLikeCall, @delegate_invocation_expr {
}
deprecated private AddEventSource getAnAddEventSourceSameEnclosingCallable() {
- result = getAnAddEventSource(this.getEnclosingCallable())
+ result = this.getAnAddEventSource(this.getEnclosingCallable())
}
deprecated private AddEventSource getAnAddEventSourceDifferentEnclosingCallable() {
- exists(Callable c | result = getAnAddEventSource(c) | c != this.getEnclosingCallable())
+ exists(Callable c | result = this.getAnAddEventSource(c) | c != this.getEnclosingCallable())
}
/**
@@ -683,7 +683,7 @@ class AccessorCall extends Call, QualifiableExpr, @call_access_expr {
*/
class PropertyCall extends AccessorCall, PropertyAccessExpr {
override Accessor getTarget() {
- exists(PropertyAccess pa, Property p | pa = this and p = getProperty() |
+ exists(PropertyAccess pa, Property p | pa = this and p = this.getProperty() |
pa instanceof AssignableRead and result = p.getGetter()
or
pa instanceof AssignableWrite and result = p.getSetter()
@@ -718,7 +718,7 @@ class PropertyCall extends AccessorCall, PropertyAccessExpr {
*/
class IndexerCall extends AccessorCall, IndexerAccessExpr {
override Accessor getTarget() {
- exists(IndexerAccess ia, Indexer i | ia = this and i = getIndexer() |
+ exists(IndexerAccess ia, Indexer i | ia = this and i = this.getIndexer() |
ia instanceof AssignableRead and result = i.getGetter()
or
ia instanceof AssignableWrite and result = i.getSetter()
@@ -761,7 +761,7 @@ class IndexerCall extends AccessorCall, IndexerAccessExpr {
class EventCall extends AccessorCall, EventAccessExpr {
override EventAccessor getTarget() {
exists(Event e, AddOrRemoveEventExpr aoree |
- e = getEvent() and
+ e = this.getEvent() and
aoree.getLValue() = this
|
aoree instanceof AddEventExpr and result = e.getAddEventAccessor()
@@ -799,7 +799,7 @@ class EventCall extends AccessorCall, EventAccessExpr {
class LocalFunctionCall extends Call, @local_function_invocation_expr {
override LocalFunction getTarget() { expr_call(this, result) }
- override string toString() { result = "call to local function " + getTarget().getName() }
+ override string toString() { result = "call to local function " + this.getTarget().getName() }
override string getAPrimaryQlClass() { result = "LocalFunctionCall" }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Creation.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Creation.qll
index c9ae3919004..84bcf7b87bc 100644
--- a/csharp/ql/lib/semmle/code/csharp/exprs/Creation.qll
+++ b/csharp/ql/lib/semmle/code/csharp/exprs/Creation.qll
@@ -45,7 +45,7 @@ class ObjectInitializer extends ObjectOrCollectionInitializer, @object_init_expr
* }
* ```
*/
- MemberInitializer getAMemberInitializer() { result = getMemberInitializer(_) }
+ MemberInitializer getAMemberInitializer() { result = this.getMemberInitializer(_) }
/**
* Gets the `i`th member initializer of this object initializer. For example,
@@ -122,7 +122,7 @@ class CollectionInitializer extends ObjectOrCollectionInitializer, @collection_i
* };
* ```
*/
- ElementInitializer getAnElementInitializer() { result = getElementInitializer(_) }
+ ElementInitializer getAnElementInitializer() { result = this.getElementInitializer(_) }
/**
* Gets the `i`th element initializer of this collection initializer, for
@@ -180,7 +180,7 @@ class ElementInitializer extends MethodCall {
*/
class ObjectCreation extends Call, LateBindableExpr, @object_creation_expr {
/** Gets the type of the newly created object. */
- ValueOrRefType getObjectType() { result = getType() }
+ ValueOrRefType getObjectType() { result = this.getType() }
override Constructor getTarget() { expr_call(this, result) }
@@ -320,7 +320,7 @@ class ArrayInitializer extends Expr, @array_init_expr {
* };
* ```
*/
- Expr getAnElement() { result = getElement(_) }
+ Expr getAnElement() { result = this.getElement(_) }
/**
* Gets the `i`th element of this array initializer, for example the second
@@ -365,7 +365,7 @@ class ArrayCreation extends Expr, @array_creation_expr {
* new int[5, 10]
* ```
*/
- Expr getALengthArgument() { result = getLengthArgument(_) }
+ Expr getALengthArgument() { result = this.getLengthArgument(_) }
/**
* Gets the `i`th dimension's length argument of this array creation, for
@@ -427,7 +427,7 @@ class AnonymousFunctionExpr extends Expr, Callable, Modifiable, @anonymous_funct
override string toString() { result = Expr.super.toString() }
- override string toStringWithTypes() { result = toString() }
+ override string toStringWithTypes() { result = this.toString() }
}
/**
diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Dynamic.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Dynamic.qll
index ea6012ca3e1..eda31432f38 100644
--- a/csharp/ql/lib/semmle/code/csharp/exprs/Dynamic.qll
+++ b/csharp/ql/lib/semmle/code/csharp/exprs/Dynamic.qll
@@ -15,7 +15,7 @@ private import semmle.code.csharp.dispatch.Dispatch
* (`DynamicAccessorCall`), or a dynamic element access (`DynamicElementAccess`).
*/
class DynamicExpr extends LateBindableExpr {
- DynamicExpr() { isLateBound() }
+ DynamicExpr() { this.isLateBound() }
}
/**
@@ -67,7 +67,7 @@ class DynamicObjectCreation extends DynamicExpr, ObjectCreation {
* may not be known at compile-time (as in the example above).
*/
class DynamicMethodCall extends DynamicExpr, MethodCall {
- override string toString() { result = "dynamic call to method " + getLateBoundTargetName() }
+ override string toString() { result = "dynamic call to method " + this.getLateBoundTargetName() }
override string getAPrimaryQlClass() { result = "DynamicMethodCall" }
}
@@ -97,7 +97,9 @@ class DynamicMethodCall extends DynamicExpr, MethodCall {
* target operator may not be known at compile-time (as in the example above).
*/
class DynamicOperatorCall extends DynamicExpr, OperatorCall {
- override string toString() { result = "dynamic call to operator " + getLateBoundTargetName() }
+ override string toString() {
+ result = "dynamic call to operator " + this.getLateBoundTargetName()
+ }
override string getAPrimaryQlClass() { result = "DynamicOperatorCall" }
}
@@ -189,7 +191,9 @@ class DynamicAccess extends DynamicExpr {
*/
class DynamicMemberAccess extends DynamicAccess, MemberAccess, AssignableAccess,
@dynamic_member_access_expr {
- override string toString() { result = "dynamic access to member " + getLateBoundTargetName() }
+ override string toString() {
+ result = "dynamic access to member " + this.getLateBoundTargetName()
+ }
override string getAPrimaryQlClass() { result = "DynamicMemberAccess" }
diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll
index 0988bb84340..47477afe2b9 100644
--- a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll
+++ b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll
@@ -103,7 +103,7 @@ class Expr extends DotNet::Expr, ControlFlowElement, @expr {
class LateBindableExpr extends Expr, @late_bindable_expr {
/** Holds if this expression is late bound. */
predicate isLateBound() {
- exists(getLateBoundTargetName()) or
+ exists(this.getLateBoundTargetName()) or
isDynamicMemberAccess(this) or
isDynamicElementAccess(this)
}
@@ -221,9 +221,9 @@ class BinaryOperation extends Operation, @bin_op {
/** Gets the other operand of this binary operation, given operand `o`. */
Expr getOtherOperand(Expr o) {
- o = getLeftOperand() and result = getRightOperand()
+ o = this.getLeftOperand() and result = this.getRightOperand()
or
- o = getRightOperand() and result = getLeftOperand()
+ o = this.getRightOperand() and result = this.getLeftOperand()
}
override string getOperator() { none() }
@@ -368,7 +368,7 @@ class RelationalPatternExpr extends PatternExpr, @relational_pattern_expr {
/** Gets the expression of this relational pattern. */
Expr getExpr() { result = this.getChild(0) }
- override string toString() { result = getOperator() + " ..." }
+ override string toString() { result = this.getOperator() + " ..." }
}
/** A less-than pattern, for example `< 10` in `x is < 10`. */
@@ -520,7 +520,7 @@ class NotPatternExpr extends UnaryPatternExpr, @not_pattern_expr {
/** A binary pattern. For example, `1 or 2`. */
class BinaryPatternExpr extends PatternExpr, @binary_pattern_expr {
/** Gets a pattern. */
- PatternExpr getAnOperand() { result = getLeftOperand() or result = getRightOperand() }
+ PatternExpr getAnOperand() { result = this.getLeftOperand() or result = this.getRightOperand() }
/** Gets the left pattern. */
PatternExpr getLeftOperand() { result = this.getChild(0) }
@@ -743,7 +743,7 @@ class DefaultValueExpr extends Expr, @default_expr {
TypeAccess getTypeAccess() { result = this.getChild(0) }
override string toString() {
- if exists(getTypeAccess()) then result = "default(...)" else result = "default"
+ if exists(this.getTypeAccess()) then result = "default(...)" else result = "default"
}
override string getAPrimaryQlClass() { result = "DefaultValueExpr" }
@@ -757,7 +757,7 @@ class SizeofExpr extends UnaryOperation, @sizeof_expr {
* Gets the type access in this `sizeof` expression, for example `int` in
* `sizeof(int)`.
*/
- TypeAccess getTypeAccess() { result = getOperand() }
+ TypeAccess getTypeAccess() { result = this.getOperand() }
override string getOperator() { result = "sizeof(..)" }
@@ -830,7 +830,7 @@ class AddressOfExpr extends UnaryOperation, @address_of_expr {
*/
class AwaitExpr extends Expr, @await_expr {
/** Gets the expression being awaited. */
- Expr getExpr() { result = getChild(0) }
+ Expr getExpr() { result = this.getChild(0) }
override string toString() { result = "await ..." }
@@ -881,7 +881,7 @@ class InterpolatedStringExpr extends Expr, @interpolated_string_expr {
* element (`getText(0)` gets the text).
*/
Expr getInsert(int i) {
- result = getChild(i) and
+ result = this.getChild(i) and
not result instanceof StringLiteral
}
@@ -891,13 +891,13 @@ class InterpolatedStringExpr extends Expr, @interpolated_string_expr {
* `$"Hello, {name}!"`. Note that there is no text element at index `i = 1`,
* but instead an insert (`getInsert(1)` gets the insert).
*/
- StringLiteral getText(int i) { result = getChild(i) }
+ StringLiteral getText(int i) { result = this.getChild(i) }
/** Gets an insert in this interpolated string. */
- Expr getAnInsert() { result = getInsert(_) }
+ Expr getAnInsert() { result = this.getInsert(_) }
/** Gets a text element in this interpolated string. */
- StringLiteral getAText() { result = getText(_) }
+ StringLiteral getAText() { result = this.getText(_) }
}
/**
@@ -914,7 +914,7 @@ class ThrowElement extends ControlFlowElement, DotNet::Throw, @throw_element {
/** Gets the type of exception being thrown. */
Class getThrownExceptionType() {
- result = getExpr().getType()
+ result = this.getExpr().getType()
or
// Corner case: `throw null`
this.getExpr().getType() instanceof NullType and
@@ -958,7 +958,7 @@ class QualifiableExpr extends Expr, @qualifiable_expr {
Expr getQualifier() { result = this.getChildExpr(-1) }
/** Holds if this expression is qualified. */
- final predicate hasQualifier() { exists(getQualifier()) }
+ final predicate hasQualifier() { exists(this.getQualifier()) }
/** Holds if this expression has an implicit `this` qualifier. */
predicate hasImplicitThisQualifier() { this.getQualifier().(ThisAccess).isImplicit() }
@@ -1029,10 +1029,10 @@ class TupleExpr extends Expr, @tuple_expr {
override string toString() { result = "(..., ...)" }
/** Gets the `i`th argument of this tuple. */
- Expr getArgument(int i) { result = getChild(i) }
+ Expr getArgument(int i) { result = this.getChild(i) }
/** Gets an argument of this tuple. */
- Expr getAnArgument() { result = getArgument(_) }
+ Expr getAnArgument() { result = this.getArgument(_) }
/** Holds if this tuple is a read access. */
deprecated predicate isReadAccess() { not this = getAnAssignOrForeachChild() }
@@ -1057,11 +1057,11 @@ class TupleExpr extends Expr, @tuple_expr {
*/
class RefExpr extends Expr, @ref_expr {
/** Gets the expression being referenced. */
- Expr getExpr() { result = getChild(0) }
+ Expr getExpr() { result = this.getChild(0) }
override string toString() { result = "ref ..." }
- override Type getType() { result = getExpr().getType() }
+ override Type getType() { result = this.getExpr().getType() }
override string getAPrimaryQlClass() { result = "RefExpr" }
}
@@ -1154,7 +1154,7 @@ class DefineSymbolExpr extends Expr, @define_symbol_expr {
/** Gets the name of the symbol. */
string getName() { directive_define_symbols(this, result) }
- override string toString() { result = getName() }
+ override string toString() { result = this.getName() }
override string getAPrimaryQlClass() { result = "DefineSymbolExpr" }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Literal.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Literal.qll
index 0ca9f6d0db0..842e27fb96b 100644
--- a/csharp/ql/lib/semmle/code/csharp/exprs/Literal.qll
+++ b/csharp/ql/lib/semmle/code/csharp/exprs/Literal.qll
@@ -23,9 +23,9 @@ class Literal extends DotNet::Literal, Expr, @literal_expr {
class BoolLiteral extends Literal, @bool_literal_expr {
/** Gets the value of this Boolean literal. */
boolean getBoolValue() {
- getValue() = "true" and result = true
+ this.getValue() = "true" and result = true
or
- getValue() = "false" and result = false
+ this.getValue() = "false" and result = false
}
override string getAPrimaryQlClass() { result = "BoolLiteral" }
@@ -105,7 +105,7 @@ class DecimalLiteral extends RealLiteral, @decimal_literal_expr {
* A `string` literal, for example `"Hello, World!"`.
*/
class StringLiteral extends DotNet::StringLiteral, Literal, @string_literal_expr {
- override string toString() { result = "\"" + getValue().replaceAll("\"", "\\\"") + "\"" }
+ override string toString() { result = "\"" + this.getValue().replaceAll("\"", "\\\"") + "\"" }
override string getAPrimaryQlClass() { result = "StringLiteral" }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll
index 36882d3b12e..723832906c6 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/EntityFramework.qll
@@ -239,7 +239,7 @@ module EntityFramework {
private class SystemDataEntityDbSetSqlQuerySinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
row =
- ["System.Data.Entity;DbSet;false;SqlQuery;(System.String,System.Object[]);;Argument[0];sql"]
+ "System.Data.Entity;DbSet;false;SqlQuery;(System.String,System.Object[]);;Argument[0];sql"
}
}
@@ -317,7 +317,7 @@ module EntityFramework {
dist = 0
)
or
- step(_, _, c1, t1, dist - 1) and
+ this.step(_, _, c1, t1, dist - 1) and
dist < DataFlowPrivate::accessPathLimit() - 1 and
not isNotMapped(t2) and
(
@@ -374,11 +374,11 @@ module EntityFramework {
}
private predicate stepRev(Content c1, Type t1, Content c2, Type t2, int dist) {
- step(c1, t1, c2, t2, dist) and
- c2.(PropertyContent).getProperty() = getAColumnProperty(dist)
+ this.step(c1, t1, c2, t2, dist) and
+ c2.(PropertyContent).getProperty() = this.getAColumnProperty(dist)
or
- stepRev(c2, t2, _, _, dist + 1) and
- step(c1, t1, c2, t2, dist)
+ this.stepRev(c2, t2, _, _, dist + 1) and
+ this.step(c1, t1, c2, t2, dist)
}
/** Gets a `SaveChanges[Async]` method. */
@@ -453,8 +453,8 @@ module EntityFramework {
) {
exists(Property mapped |
preservesValue = true and
- input(input, mapped) and
- output(output, mapped)
+ this.input(input, mapped) and
+ this.output(output, mapped)
)
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll
index 3c659d86d46..2ffbfe6e7e1 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Format.qll
@@ -155,13 +155,13 @@ class InvalidFormatString extends StringLiteral {
int oldstartcolumn, int padding
|
this.getLocation().hasLocationInfo(filepath, startline, oldstartcolumn, endline, endcolumn) and
- startcolumn = padding + oldstartcolumn + getInvalidOffset() and
+ startcolumn = padding + oldstartcolumn + this.getInvalidOffset() and
toUrl(filepath, startline, startcolumn, endline, endcolumn, result)
|
// Single-line string literal beginning " or @"
// Figure out the correct indent.
startline = endline and
- padding = endcolumn - oldstartcolumn - getValue().length()
+ padding = endcolumn - oldstartcolumn - this.getValue().length()
or
// Multi-line literal beginning @"
startline != endline and
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll
index abd820bdfe4..c0c1a765469 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/JsonNET.qll
@@ -62,25 +62,25 @@ module JsonNET {
boolean preservesValue
) {
// ToString methods
- c = getAToStringMethod() and
+ c = this.getAToStringMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
or
// Deserialize methods
- c = getADeserializeMethod() and
+ c = this.getADeserializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
or
// Serialize methods
- c = getASerializeMethod() and
+ c = this.getASerializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
or
// Populate methods
- c = getAPopulateMethod() and
+ c = this.getAPopulateMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink = any(CallableFlowSinkArg arg | arg.getArgumentIndex() = 1)
@@ -120,21 +120,13 @@ module JsonNET {
SerializedMember() {
// This member has a Json attribute
exists(Class attribute | attribute = this.getAnAttribute().getType() |
- attribute.hasName("JsonPropertyAttribute")
- or
- attribute.hasName("JsonDictionaryAttribute")
- or
- attribute.hasName("JsonRequiredAttribute")
- or
- attribute.hasName("JsonArrayAttribute")
- or
- attribute.hasName("JsonConverterAttribute")
- or
- attribute.hasName("JsonExtensionDataAttribute")
- or
- attribute.hasName("SerializableAttribute") // System.SerializableAttribute
- or
- attribute.hasName("DataMemberAttribute") // System.DataMemberAttribute
+ attribute
+ .hasName([
+ "JsonPropertyAttribute", "JsonDictionaryAttribute", "JsonRequiredAttribute",
+ "JsonArrayAttribute", "JsonConverterAttribute", "JsonExtensionDataAttribute",
+ "SerializableAttribute", // System.SerializableAttribute
+ "DataMemberAttribute" // System.DataMemberAttribute
+ ])
)
or
// This field is a member of an explicitly serialized type
@@ -175,7 +167,7 @@ module JsonNET {
/** Any attribute class that marks a member to not be serialized. */
private class NotSerializedAttributeClass extends JsonClass {
NotSerializedAttributeClass() {
- this.hasName("JsonIgnoreAttribute") or this.hasName("NonSerializedAttribute")
+ this.hasName(["JsonIgnoreAttribute", "NonSerializedAttribute"])
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Moq.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Moq.qll
index 92811122696..e0705ac7d98 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/Moq.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Moq.qll
@@ -21,7 +21,7 @@ class ReturnsMethod extends Method {
*/
Expr getAReturnedExpr() {
exists(MethodCall mc, Expr arg |
- mc = getACall() and
+ mc = this.getACall() and
arg = mc.getArgument(0)
|
if arg instanceof LambdaExpr then arg.(LambdaExpr).canReturn(result) else result = arg
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/NHibernate.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/NHibernate.qll
index ddf7fd410bf..6ce6efb815f 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/NHibernate.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/NHibernate.qll
@@ -28,15 +28,7 @@ module NHibernate {
/** Gets a type parameter that specifies a mapped class. */
TypeParameter getAMappedObjectTp() {
- exists(string methodName |
- methodName = "Load<>"
- or
- methodName = "Merge<>"
- or
- methodName = "Get<>"
- or
- methodName = "Query<>"
- |
+ exists(string methodName | methodName = ["Load<>", "Merge<>", "Get<>", "Query<>"] |
result = this.getAMethod(methodName).(UnboundGenericMethod).getTypeParameter(0)
)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll
index 20ab350ffd4..e33004f109d 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/System.qll
@@ -157,7 +157,7 @@ class SystemIComparableTInterface extends SystemUnboundGenericInterface {
result.getDeclaringType() = this and
result.hasName("CompareTo") and
result.getNumberOfParameters() = 1 and
- result.getParameter(0).getType() = getTypeParameter(0) and
+ result.getParameter(0).getType() = this.getTypeParameter(0) and
result.getReturnType() instanceof IntType
}
}
@@ -171,7 +171,7 @@ class SystemIEquatableTInterface extends SystemUnboundGenericInterface {
result.getDeclaringType() = this and
result.hasName("Equals") and
result.getNumberOfParameters() = 1 and
- result.getParameter(0).getType() = getTypeParameter(0) and
+ result.getParameter(0).getType() = this.getTypeParameter(0) and
result.getReturnType() instanceof BoolType
}
}
@@ -239,7 +239,7 @@ class SystemLazyClass extends SystemUnboundGenericClass {
Property getValueProperty() {
result.getDeclaringType() = this and
result.hasName("Value") and
- result.getType() = getTypeParameter(0)
+ result.getType() = this.getTypeParameter(0)
}
}
@@ -254,7 +254,7 @@ class SystemNullableStruct extends SystemUnboundGenericStruct {
Property getValueProperty() {
result.getDeclaringType() = this and
result.hasName("Value") and
- result.getType() = getTypeParameter(0)
+ result.getType() = this.getTypeParameter(0)
}
/** Gets the `HasValue` property. */
@@ -268,7 +268,7 @@ class SystemNullableStruct extends SystemUnboundGenericStruct {
Method getAGetValueOrDefaultMethod() {
result.getDeclaringType() = this and
result.hasName("GetValueOrDefault") and
- result.getReturnType() = getTypeParameter(0)
+ result.getReturnType() = this.getTypeParameter(0)
}
}
@@ -588,7 +588,7 @@ class IEquatableEqualsMethod extends Method {
m = any(SystemIEquatableTInterface i).getAConstructedGeneric().getAMethod() and
m.getUnboundDeclaration() = any(SystemIEquatableTInterface i).getEqualsMethod()
|
- this = m or getAnUltimateImplementee() = m
+ this = m or this.getAnUltimateImplementee() = m
)
}
}
@@ -677,7 +677,7 @@ class DisposeMethod extends Method {
/** A method with the signature `void Dispose(bool)`. */
library class DisposeBoolMethod extends Method {
DisposeBoolMethod() {
- hasName("Dispose") and
+ this.hasName("Dispose") and
this.getReturnType() instanceof VoidType and
this.getNumberOfParameters() = 1 and
this.getParameter(0).getType() instanceof BoolType
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/WCF.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/WCF.qll
index 655648d88c9..befb5f3ae1f 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/WCF.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/WCF.qll
@@ -49,7 +49,7 @@ class OperationMethod extends Method {
i.getAnAttribute() instanceof ServiceContractAttribute and
m.getDeclaringType() = i and
m.getAnAttribute() instanceof OperationContractAttribute and
- getImplementee() = m
+ this.getImplementee() = m
)
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll
index 5fe6665bd47..a918b603818 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll
@@ -6,129 +6,133 @@ import semmle.code.csharp.frameworks.Microsoft
/** The `Microsoft.AspNetCore` namespace. */
class MicrosoftAspNetCoreNamespace extends Namespace {
MicrosoftAspNetCoreNamespace() {
- getParentNamespace() instanceof MicrosoftNamespace and
- hasName("AspNetCore")
+ this.getParentNamespace() instanceof MicrosoftNamespace and
+ this.hasName("AspNetCore")
}
}
/** The `Microsoft.AspNetCore.Mvc` namespace. */
class MicrosoftAspNetCoreMvcNamespace extends Namespace {
MicrosoftAspNetCoreMvcNamespace() {
- getParentNamespace() instanceof MicrosoftAspNetCoreNamespace and
- hasName("Mvc")
+ this.getParentNamespace() instanceof MicrosoftAspNetCoreNamespace and
+ this.hasName("Mvc")
}
}
/** The 'Microsoft.AspNetCore.Mvc.ViewFeatures' namespace. */
class MicrosoftAspNetCoreMvcViewFeatures extends Namespace {
MicrosoftAspNetCoreMvcViewFeatures() {
- getParentNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
- hasName("ViewFeatures")
+ this.getParentNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
+ this.hasName("ViewFeatures")
}
}
/** The 'Microsoft.AspNetCore.Mvc.Rendering' namespace. */
class MicrosoftAspNetCoreMvcRendering extends Namespace {
MicrosoftAspNetCoreMvcRendering() {
- getParentNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
- hasName("Rendering")
+ this.getParentNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
+ this.hasName("Rendering")
}
}
/** An attribute whose type is in the `Microsoft.AspNetCore.Mvc` namespace. */
class MicrosoftAspNetCoreMvcAttribute extends Attribute {
MicrosoftAspNetCoreMvcAttribute() {
- getType().getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace
+ this.getType().getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace
}
}
/** A `Microsoft.AspNetCore.Mvc.HttpPost` attribute. */
class MicrosoftAspNetCoreMvcHttpPostAttribute extends MicrosoftAspNetCoreMvcAttribute {
- MicrosoftAspNetCoreMvcHttpPostAttribute() { getType().hasName("HttpPostAttribute") }
+ MicrosoftAspNetCoreMvcHttpPostAttribute() { this.getType().hasName("HttpPostAttribute") }
}
/** A `Microsoft.AspNetCore.Mvc.HttpPut` attribute. */
class MicrosoftAspNetCoreMvcHttpPutAttribute extends MicrosoftAspNetCoreMvcAttribute {
- MicrosoftAspNetCoreMvcHttpPutAttribute() { getType().hasName("HttpPutAttribute") }
+ MicrosoftAspNetCoreMvcHttpPutAttribute() { this.getType().hasName("HttpPutAttribute") }
}
/** A `Microsoft.AspNetCore.Mvc.HttpDelete` attribute. */
class MicrosoftAspNetCoreMvcHttpDeleteAttribute extends MicrosoftAspNetCoreMvcAttribute {
- MicrosoftAspNetCoreMvcHttpDeleteAttribute() { getType().hasName("HttpDeleteAttribute") }
+ MicrosoftAspNetCoreMvcHttpDeleteAttribute() { this.getType().hasName("HttpDeleteAttribute") }
}
/** A `Microsoft.AspNetCore.Mvc.NonAction` attribute. */
class MicrosoftAspNetCoreMvcNonActionAttribute extends MicrosoftAspNetCoreMvcAttribute {
- MicrosoftAspNetCoreMvcNonActionAttribute() { getType().hasName("NonActionAttribute") }
+ MicrosoftAspNetCoreMvcNonActionAttribute() { this.getType().hasName("NonActionAttribute") }
}
/** The `Microsoft.AspNetCore.Antiforgery` namespace. */
class MicrosoftAspNetCoreAntiforgeryNamespace extends Namespace {
MicrosoftAspNetCoreAntiforgeryNamespace() {
- getParentNamespace() instanceof MicrosoftAspNetCoreNamespace and
- hasName("Antiforgery")
+ this.getParentNamespace() instanceof MicrosoftAspNetCoreNamespace and
+ this.hasName("Antiforgery")
}
}
/** The `Microsoft.AspNetCore.Mvc.Filters` namespace. */
class MicrosoftAspNetCoreMvcFilters extends Namespace {
MicrosoftAspNetCoreMvcFilters() {
- getParentNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
- hasName("Filters")
+ this.getParentNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
+ this.hasName("Filters")
}
}
/** The `Microsoft.AspNetCore.Mvc.Filters.IFilterMetadataInterface` interface. */
class MicrosoftAspNetCoreMvcIFilterMetadataInterface extends Interface {
MicrosoftAspNetCoreMvcIFilterMetadataInterface() {
- getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
- hasName("IFilterMetadata")
+ this.getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
+ this.hasName("IFilterMetadata")
}
}
/** The `Microsoft.AspNetCore.IAuthorizationFilter` interface. */
class MicrosoftAspNetCoreIAuthorizationFilterInterface extends Interface {
MicrosoftAspNetCoreIAuthorizationFilterInterface() {
- getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
- hasName("IAsyncAuthorizationFilter")
+ this.getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
+ this.hasName("IAsyncAuthorizationFilter")
}
/** Gets the `OnAuthorizationAsync` method. */
- Method getOnAuthorizationMethod() { result = getAMethod("OnAuthorizationAsync") }
+ Method getOnAuthorizationMethod() { result = this.getAMethod("OnAuthorizationAsync") }
}
/** The `Microsoft.AspNetCore.IAntiforgery` interface. */
class MicrosoftAspNetCoreIAntiForgeryInterface extends Interface {
MicrosoftAspNetCoreIAntiForgeryInterface() {
- getNamespace() instanceof MicrosoftAspNetCoreAntiforgeryNamespace and
- hasName("IAntiforgery")
+ this.getNamespace() instanceof MicrosoftAspNetCoreAntiforgeryNamespace and
+ this.hasName("IAntiforgery")
}
/** Gets the `ValidateRequestAsync` method. */
- Method getValidateMethod() { result = getAMethod("ValidateRequestAsync") }
+ Method getValidateMethod() { result = this.getAMethod("ValidateRequestAsync") }
}
/** The `Microsoft.AspNetCore.DefaultAntiForgery` class, or another user-supplied class that implements `IAntiForgery`. */
class AntiForgeryClass extends Class {
- AntiForgeryClass() { getABaseInterface*() instanceof MicrosoftAspNetCoreIAntiForgeryInterface }
+ AntiForgeryClass() {
+ this.getABaseInterface*() instanceof MicrosoftAspNetCoreIAntiForgeryInterface
+ }
/** Gets the `ValidateRequestAsync` method. */
- Method getValidateMethod() { result = getAMethod("ValidateRequestAsync") }
+ Method getValidateMethod() { result = this.getAMethod("ValidateRequestAsync") }
}
/** An authorization filter class defined by AspNetCore or the user. */
class AuthorizationFilterClass extends Class {
AuthorizationFilterClass() {
- getABaseInterface*() instanceof MicrosoftAspNetCoreIAuthorizationFilterInterface
+ this.getABaseInterface*() instanceof MicrosoftAspNetCoreIAuthorizationFilterInterface
}
/** Gets the `OnAuthorization` method provided by this filter. */
- Method getOnAuthorizationMethod() { result = getAMethod("OnAuthorizationAsync") }
+ Method getOnAuthorizationMethod() { result = this.getAMethod("OnAuthorizationAsync") }
}
/** An attribute whose type has a name like `[Auto...]Validate[...]Anti[Ff]orgery[...Token]Attribute`. */
class ValidateAntiForgeryAttribute extends Attribute {
- ValidateAntiForgeryAttribute() { getType().getName().matches("%Validate%Anti_orgery%Attribute") }
+ ValidateAntiForgeryAttribute() {
+ this.getType().getName().matches("%Validate%Anti_orgery%Attribute")
+ }
}
/**
@@ -137,43 +141,43 @@ class ValidateAntiForgeryAttribute extends Attribute {
*/
class ValidateAntiforgeryTokenAuthorizationFilter extends Class {
ValidateAntiforgeryTokenAuthorizationFilter() {
- getABaseInterface*() instanceof MicrosoftAspNetCoreMvcIFilterMetadataInterface and
- getName().matches("%Validate%Anti_orgery%")
+ this.getABaseInterface*() instanceof MicrosoftAspNetCoreMvcIFilterMetadataInterface and
+ this.getName().matches("%Validate%Anti_orgery%")
}
}
/** The `Microsoft.AspNetCore.Mvc.Filters.FilterCollection` class. */
class MicrosoftAspNetCoreMvcFilterCollection extends Class {
MicrosoftAspNetCoreMvcFilterCollection() {
- getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
- hasName("FilterCollection")
+ this.getNamespace() instanceof MicrosoftAspNetCoreMvcFilters and
+ this.hasName("FilterCollection")
}
/** Gets an `Add` method. */
Method getAddMethod() {
- result = getAMethod("Add") or
- result = getABaseType().getAMethod("Add")
+ result = this.getAMethod("Add") or
+ result = this.getABaseType().getAMethod("Add")
}
}
/** The `Microsoft.AspNetCore.Mvc.MvcOptions` class. */
class MicrosoftAspNetCoreMvcOptions extends Class {
MicrosoftAspNetCoreMvcOptions() {
- getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
- hasName("MvcOptions")
+ this.getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
+ this.hasName("MvcOptions")
}
/** Gets the `Filters` property. */
- Property getFilterCollectionProperty() { result = getProperty("Filters") }
+ Property getFilterCollectionProperty() { result = this.getProperty("Filters") }
}
/** The base class for controllers in MVC, i.e. `Microsoft.AspNetCore.Mvc.Controller` or `Microsoft.AspNetCore.Mvc.ControllerBase` class. */
class MicrosoftAspNetCoreMvcControllerBaseClass extends Class {
MicrosoftAspNetCoreMvcControllerBaseClass() {
- getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
+ this.getNamespace() instanceof MicrosoftAspNetCoreMvcNamespace and
(
- hasName("Controller") or
- hasName("ControllerBase")
+ this.hasName("Controller") or
+ this.hasName("ControllerBase")
)
}
}
@@ -181,12 +185,12 @@ class MicrosoftAspNetCoreMvcControllerBaseClass extends Class {
/** A subtype of `Microsoft.AspNetCore.Mvc.Controller` or `Microsoft.AspNetCore.Mvc.ControllerBase`. */
class MicrosoftAspNetCoreMvcController extends Class {
MicrosoftAspNetCoreMvcController() {
- getABaseType*() instanceof MicrosoftAspNetCoreMvcControllerBaseClass
+ this.getABaseType*() instanceof MicrosoftAspNetCoreMvcControllerBaseClass
}
/** Gets an action method for this controller. */
Method getAnActionMethod() {
- result = getAMethod() and
+ result = this.getAMethod() and
result.isPublic() and
not result.isStatic() and
not result.getAnAttribute() instanceof MicrosoftAspNetCoreMvcNonActionAttribute
@@ -208,12 +212,12 @@ class MicrosoftAspNetCoreMvcController extends Class {
/** The `Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper` interface. */
class MicrosoftAspNetCoreMvcRenderingIHtmlHelperInterface extends Interface {
MicrosoftAspNetCoreMvcRenderingIHtmlHelperInterface() {
- getNamespace() instanceof MicrosoftAspNetCoreMvcRendering and
- hasName("IHtmlHelper")
+ this.getNamespace() instanceof MicrosoftAspNetCoreMvcRendering and
+ this.hasName("IHtmlHelper")
}
/** Gets the `Raw` method. */
- Method getRawMethod() { result = getAMethod("Raw") }
+ Method getRawMethod() { result = this.getAMethod("Raw") }
}
/** A class deriving from `Microsoft.AspNetCore.Mvc.Razor.RazorPageBase`, implements Razor page in ASPNET Core. */
@@ -223,7 +227,7 @@ class MicrosoftAspNetCoreMvcRazorPageBase extends Class {
}
/** Gets the `WriteLiteral` method. */
- Method getWriteLiteralMethod() { result = getAMethod("WriteLiteral") }
+ Method getWriteLiteralMethod() { result = this.getAMethod("WriteLiteral") }
}
/** A class deriving from `Microsoft.AspNetCore.Http.HttpRequest`, implements `HttpRequest` in ASP.NET Core. */
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll
index a3616e57522..2b632d2b07c 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/collections/Generic.qll
@@ -41,8 +41,8 @@ class SystemCollectionsGenericIComparerTInterface extends SystemCollectionsGener
result.getDeclaringType() = this and
result.hasName("Compare") and
result.getNumberOfParameters() = 2 and
- result.getParameter(0).getType() = getTypeParameter(0) and
- result.getParameter(1).getType() = getTypeParameter(0) and
+ result.getParameter(0).getType() = this.getTypeParameter(0) and
+ result.getParameter(1).getType() = this.getTypeParameter(0) and
result.getReturnType() instanceof IntType
}
}
@@ -56,8 +56,8 @@ class SystemCollectionsGenericIEqualityComparerTInterface extends SystemCollecti
result.getDeclaringType() = this and
result.hasName("Equals") and
result.getNumberOfParameters() = 2 and
- result.getParameter(0).getType() = getTypeParameter(0) and
- result.getParameter(1).getType() = getTypeParameter(0) and
+ result.getParameter(0).getType() = this.getTypeParameter(0) and
+ result.getParameter(1).getType() = this.getTypeParameter(0) and
result.getReturnType() instanceof BoolType
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/SqlClient.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/SqlClient.qll
index 858100fe7f7..c3b6f1fdd6d 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/SqlClient.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/data/SqlClient.qll
@@ -13,7 +13,7 @@ class SystemDataSqlClientNamespace extends Namespace {
/** A class in the `System.Data.SqlClient` namespace. */
class SystemDataSqlClientClass extends Class {
- SystemDataSqlClientClass() { getNamespace() instanceof SystemDataSqlClientNamespace }
+ SystemDataSqlClientClass() { this.getNamespace() instanceof SystemDataSqlClientNamespace }
}
/** The `System.Data.SqlClient.SqlDataAdapter` class. */
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll
index 1820192da11..531fa6ef721 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/text/RegularExpressions.qll
@@ -67,7 +67,7 @@ class RegexOperation extends Call {
*/
Expr getInput() {
if this instanceof MethodCall
- then result = getArgumentForName("input")
+ then result = this.getArgumentForName("input")
else
exists(MethodCall call |
call.getTarget() = any(SystemTextRegularExpressionsRegexClass rs).getAMethod() and
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/Mvc.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/Mvc.qll
index 78aaa6dc065..b2051a8464f 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/Mvc.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/Mvc.qll
@@ -6,8 +6,8 @@ private import semmle.code.csharp.frameworks.system.Web
/** The `System.Web.Mvc` namespace. */
class SystemWebMvcNamespace extends Namespace {
SystemWebMvcNamespace() {
- getParentNamespace() instanceof SystemWebNamespace and
- hasName("Mvc")
+ this.getParentNamespace() instanceof SystemWebNamespace and
+ this.hasName("Mvc")
}
}
@@ -31,7 +31,7 @@ class SystemWebMvcHtmlHelperClass extends SystemWebMvcClass {
/** An attribute whose type is in the `System.Web.Mvc` namespace. */
class SystemWebMvcAttribute extends Attribute {
- SystemWebMvcAttribute() { getType().getNamespace() instanceof SystemWebMvcNamespace }
+ SystemWebMvcAttribute() { this.getType().getNamespace() instanceof SystemWebMvcNamespace }
}
/** An attribute whose type is `System.Web.Mvc.HttpPost`. */
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/WebPages.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/WebPages.qll
index 0d43f76719b..915acbfe41f 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/WebPages.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/web/WebPages.qll
@@ -6,16 +6,16 @@ private import semmle.code.csharp.frameworks.system.Web
/** The `System.Web.WebPages` namespace. */
class SystemWebWebPagesNamespace extends Namespace {
SystemWebWebPagesNamespace() {
- getParentNamespace() instanceof SystemWebNamespace and
- hasName("WebPages")
+ this.getParentNamespace() instanceof SystemWebNamespace and
+ this.hasName("WebPages")
}
}
/** The `System.Web.WebPages.WebPageExecutingBase` class. */
class SystemWebWebPagesWebPageExecutingBaseClass extends Class {
SystemWebWebPagesWebPageExecutingBaseClass() {
- getNamespace() instanceof SystemWebWebPagesNamespace and
- hasName("WebPageExecutingBase")
+ this.getNamespace() instanceof SystemWebWebPagesNamespace and
+ this.hasName("WebPageExecutingBase")
}
}
@@ -24,8 +24,8 @@ class WebPageClass extends Class {
WebPageClass() { this.getBaseClass*() instanceof SystemWebWebPagesWebPageExecutingBaseClass }
/** Gets the `WriteLiteral` method. */
- Method getWriteLiteralMethod() { result = getAMethod("WriteLiteral") }
+ Method getWriteLiteralMethod() { result = this.getAMethod("WriteLiteral") }
/** Gets the `WriteLiteralTo` method. */
- Method getWriteLiteralToMethod() { result = getAMethod("WriteLiteralTo") }
+ Method getWriteLiteralToMethod() { result = this.getAMethod("WriteLiteralTo") }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/security/PrivateData.qll b/csharp/ql/lib/semmle/code/csharp/security/PrivateData.qll
index 10bb06679b7..3ca81e614ad 100644
--- a/csharp/ql/lib/semmle/code/csharp/security/PrivateData.qll
+++ b/csharp/ql/lib/semmle/code/csharp/security/PrivateData.qll
@@ -14,26 +14,22 @@ import semmle.code.csharp.frameworks.system.windows.Forms
/** A string for `match` that identifies strings that look like they represent private data. */
private string privateNames() {
- // Inspired by the list on https://cwe.mitre.org/data/definitions/359.html
- // Government identifiers, such as Social Security Numbers
- result = "%social%security%number%" or
- // Contact information, such as home addresses and telephone numbers
- result = "%postcode%" or
- result = "%zipcode%" or
- result = "%telephone%" or
- // Geographic location - where the user is (or was)
- result = "%latitude%" or
- result = "%longitude%" or
- // Financial data - such as credit card numbers, salary, bank accounts, and debts
- result = "%creditcard%" or
- result = "%salary%" or
- result = "%bankaccount%" or
- // Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc.
- result = "%email%" or
- result = "%mobile%" or
- result = "%employer%" or
- // Health - medical conditions, insurance status, prescription records
- result = "%medical%"
+ result =
+ [
+ // Inspired by the list on https://cwe.mitre.org/data/definitions/359.html
+ // Government identifiers, such as Social Security Numbers
+ "%social%security%number%",
+ // Contact information, such as home addresses and telephone numbers
+ "%postcode%", "%zipcode%", "%telephone%",
+ // Geographic location - where the user is (or was)
+ "%latitude%", "%longitude%",
+ // Financial data - such as credit card numbers, salary, bank accounts, and debts
+ "%creditcard%", "%salary%", "%bankaccount%",
+ // Communications - e-mail addresses, private e-mail messages, SMS text messages, chat logs, etc.
+ "%email%", "%mobile%", "%employer%",
+ // Health - medical conditions, insurance status, prescription records
+ "%medical%"
+ ]
}
/** An expression that might contain private data. */
diff --git a/csharp/ql/lib/semmle/code/csharp/security/SensitiveActions.qll b/csharp/ql/lib/semmle/code/csharp/security/SensitiveActions.qll
index cc7701ad318..483000895aa 100644
--- a/csharp/ql/lib/semmle/code/csharp/security/SensitiveActions.qll
+++ b/csharp/ql/lib/semmle/code/csharp/security/SensitiveActions.qll
@@ -72,7 +72,7 @@ class SensitiveProperty extends Property {
/** A parameter to a library method that may hold a sensitive value. */
class SensitiveLibraryParameter extends Parameter {
SensitiveLibraryParameter() {
- fromLibrary() and
+ this.fromLibrary() and
exists(string s | this.getName().toLowerCase() = s | s.matches(suspicious()))
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll b/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll
index 915dae12a9f..3cf3fa107bf 100644
--- a/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll
+++ b/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll
@@ -21,7 +21,7 @@ module HardcodedSymmetricEncryptionKey {
abstract class Sanitizer extends DataFlow::ExprNode { }
private class ByteArrayType extends ArrayType {
- ByteArrayType() { getElementType() instanceof ByteType }
+ ByteArrayType() { this.getElementType() instanceof ByteType }
}
private class ByteArrayLiteralSource extends Source {
@@ -49,7 +49,7 @@ module HardcodedSymmetricEncryptionKey {
private class SymmetricEncryptionCreateEncryptorSink extends Sink {
SymmetricEncryptionCreateEncryptorSink() {
exists(SymmetricAlgorithm ag, MethodCall mc | mc = ag.getASymmetricEncryptor() |
- asExpr() = mc.getArgumentForName("rgbKey")
+ this.asExpr() = mc.getArgumentForName("rgbKey")
)
}
@@ -59,7 +59,7 @@ module HardcodedSymmetricEncryptionKey {
private class SymmetricEncryptionCreateDecryptorSink extends Sink {
SymmetricEncryptionCreateDecryptorSink() {
exists(SymmetricAlgorithm ag, MethodCall mc | mc = ag.getASymmetricDecryptor() |
- asExpr() = mc.getArgumentForName("rgbKey")
+ this.asExpr() = mc.getArgumentForName("rgbKey")
)
}
diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll
index bccd71d7096..fd643b5b7f0 100644
--- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll
+++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll
@@ -69,7 +69,7 @@ class ExternalAPIDataNode extends DataFlow::Node {
int getIndex() { result = i }
/** Gets the description of the callable being called. */
- string getCallableDescription() { result = getCallable().getQualifiedName() }
+ string getCallableDescription() { result = this.getCallable().getQualifiedName() }
}
/** A configuration for tracking flow from `RemoteFlowSource`s to `ExternalAPIDataNode`s. */
@@ -108,7 +108,7 @@ class ExternalAPIUsedWithUntrustedData extends TExternalAPI {
/** Gets the number of untrusted sources used with this external API. */
int getNumberOfUntrustedSources() {
- result = count(getUntrustedDataNode().getAnUntrustedSource())
+ result = count(this.getUntrustedDataNode().getAnUntrustedSource())
}
/** Gets a textual representation of this element. */
diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll
index 4be005be4de..d0999605b61 100644
--- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll
+++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/XSSSinks.qll
@@ -166,7 +166,7 @@ class AspInlineMember extends AspInlineCode {
Member getMember() { result = member }
/** Gets the type of this member. */
- Type getType() { result = getMemberType(getMember()) }
+ Type getType() { result = getMemberType(this.getMember()) }
}
/** Gets a value that is written to the member accessed by the given `AspInlineMember`. */
@@ -251,7 +251,7 @@ private class HttpResponseBaseSink extends Sink {
*/
private class StringContentSinkModelCsv extends SinkModelCsv {
override predicate row(string row) {
- row = ["System.Net.Http;StringContent;false;StringContent;;;Argument[0];xss"]
+ row = "System.Net.Http;StringContent;false;StringContent;;;Argument[0];xss"
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll
index 673473eb49b..30736bdabf6 100644
--- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll
+++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsinks/ExternalLocationSink.qll
@@ -38,12 +38,7 @@ class TraceMessageSink extends ExternalLocationSink {
trace.hasQualifiedName("System.Diagnostics", "TraceSource")
|
this.getExpr() = trace.getAMethod().getACall().getArgumentForName(parameterName) and
- (
- parameterName = "format" or
- parameterName = "args" or
- parameterName = "message" or
- parameterName = "category"
- )
+ parameterName = ["format", "args", "message", "category"]
)
}
}
diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll
index 25647e50f2e..2448f80e8ba 100644
--- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll
+++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/flowsources/Remote.qll
@@ -43,15 +43,8 @@ class AspNetQueryStringMember extends Member {
* request.
*/
private string getHttpRequestFlowPropertyNames() {
- result = "QueryString" or
- result = "Headers" or
- result = "RawUrl" or
- result = "Url" or
- result = "Cookies" or
- result = "Form" or
- result = "Params" or
- result = "Path" or
- result = "PathInfo"
+ result =
+ ["QueryString", "Headers", "RawUrl", "Url", "Cookies", "Form", "Params", "Path", "PathInfo"]
}
/** A data flow source of remote user input (ASP.NET query string). */
@@ -86,7 +79,7 @@ class AspNetUnvalidatedQueryStringRemoteFlowSource extends AspNetRemoteFlowSourc
/** A data flow source of remote user input (ASP.NET user input). */
class AspNetUserInputRemoteFlowSource extends AspNetRemoteFlowSource, DataFlow::ExprNode {
- AspNetUserInputRemoteFlowSource() { getType() instanceof SystemWebUIWebControlsTextBoxClass }
+ AspNetUserInputRemoteFlowSource() { this.getType() instanceof SystemWebUIWebControlsTextBoxClass }
override string getSourceType() { result = "ASP.NET user input" }
}
@@ -113,7 +106,7 @@ class AspNetServiceRemoteFlowSource extends RemoteFlowSource, DataFlow::Paramete
/** A data flow source of remote user input (ASP.NET request message). */
class SystemNetHttpRequestMessageRemoteFlowSource extends RemoteFlowSource, DataFlow::ExprNode {
SystemNetHttpRequestMessageRemoteFlowSource() {
- getType() instanceof SystemWebHttpRequestMessageClass
+ this.getType() instanceof SystemWebHttpRequestMessageClass
}
override string getSourceType() { result = "ASP.NET request message" }
diff --git a/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll
index 2483452113a..17856d3e7e8 100644
--- a/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll
+++ b/csharp/ql/lib/semmle/code/csharp/security/xml/InsecureXMLQuery.qll
@@ -157,8 +157,8 @@ module XmlReader {
override predicate isUnsafe(string reason) {
exists(string dtdReason, string resolverReason |
- dtdEnabled(dtdReason, _) and
- insecureResolver(resolverReason, _) and
+ this.dtdEnabled(dtdReason, _) and
+ this.insecureResolver(resolverReason, _) and
reason = dtdReason + ", " + resolverReason
)
}
diff --git a/csharp/ql/lib/semmle/code/dotnet/Callable.qll b/csharp/ql/lib/semmle/code/dotnet/Callable.qll
index 2beccfe422c..0a63e5c95cd 100644
--- a/csharp/ql/lib/semmle/code/dotnet/Callable.qll
+++ b/csharp/ql/lib/semmle/code/dotnet/Callable.qll
@@ -75,7 +75,7 @@ class Callable extends Parameterizable, @dotnet_callable {
}
private string getReturnTypeLabel() {
- result = getReturnType().getLabel()
+ result = this.getReturnType().getLabel()
or
not exists(this.getReturnType()) and result = "System.Void"
}
diff --git a/csharp/ql/lib/semmle/code/dotnet/Declaration.qll b/csharp/ql/lib/semmle/code/dotnet/Declaration.qll
index 7f78077d766..60e434f9ae6 100644
--- a/csharp/ql/lib/semmle/code/dotnet/Declaration.qll
+++ b/csharp/ql/lib/semmle/code/dotnet/Declaration.qll
@@ -16,7 +16,7 @@ class Declaration extends NamedElement, @dotnet_declaration {
string getUndecoratedName() { none() }
/** Holds if this element has undecorated name 'name'. */
- final predicate hasUndecoratedName(string name) { name = getUndecoratedName() }
+ final predicate hasUndecoratedName(string name) { name = this.getUndecoratedName() }
/** Gets the type containing this declaration, if any. */
Type getDeclaringType() { none() }
diff --git a/csharp/ql/lib/semmle/code/dotnet/Element.qll b/csharp/ql/lib/semmle/code/dotnet/Element.qll
index 3b1955887f9..d8c27f88e10 100644
--- a/csharp/ql/lib/semmle/code/dotnet/Element.qll
+++ b/csharp/ql/lib/semmle/code/dotnet/Element.qll
@@ -35,7 +35,7 @@ class Element extends @dotnet_element {
* Gets the "language" of this program element, as defined by the extension of the filename.
* For example, C# has language "cs", and Visual Basic has language "vb".
*/
- final string getLanguage() { result = getLocation().getFile().getExtension() }
+ final string getLanguage() { result = this.getLocation().getFile().getExtension() }
/** Gets the full textual representation of this element, including type information. */
string toStringWithTypes() { result = this.toString() }
@@ -43,7 +43,7 @@ class Element extends @dotnet_element {
/**
* Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
*/
- final string getPrimaryQlClasses() { result = concat(getAPrimaryQlClass(), ",") }
+ final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") }
/**
* Gets the name of a primary CodeQL class to which this element belongs.
@@ -66,7 +66,7 @@ class NamedElement extends Element, @dotnet_named_element {
string getName() { none() }
/** Holds if this element has name 'name'. */
- final predicate hasName(string name) { name = getName() }
+ final predicate hasName(string name) { name = this.getName() }
/**
* Gets the fully qualified name of this element, for example the
diff --git a/csharp/ql/lib/semmle/code/dotnet/Expr.qll b/csharp/ql/lib/semmle/code/dotnet/Expr.qll
index e5bea3a52d7..15d658f54c2 100644
--- a/csharp/ql/lib/semmle/code/dotnet/Expr.qll
+++ b/csharp/ql/lib/semmle/code/dotnet/Expr.qll
@@ -45,7 +45,7 @@ class Call extends Expr, @dotnet_call {
Expr getArgument(int i) { none() }
/** Gets an argument to this call. */
- Expr getAnArgument() { result = getArgument(_) }
+ Expr getAnArgument() { result = this.getArgument(_) }
/** Gets the expression that is supplied for parameter `p`. */
Expr getArgumentForParameter(Parameter p) { none() }
diff --git a/csharp/ql/lib/semmle/code/dotnet/Generics.qll b/csharp/ql/lib/semmle/code/dotnet/Generics.qll
index 9b236cdbfb9..f84718d4b82 100644
--- a/csharp/ql/lib/semmle/code/dotnet/Generics.qll
+++ b/csharp/ql/lib/semmle/code/dotnet/Generics.qll
@@ -14,7 +14,7 @@ abstract class UnboundGeneric extends Generic {
abstract TypeParameter getTypeParameter(int i);
/** Gets a type parameter. */
- TypeParameter getATypeParameter() { result = getTypeParameter(_) }
+ TypeParameter getATypeParameter() { result = this.getTypeParameter(_) }
/**
* Gets one of the constructed versions of this declaration,
@@ -32,7 +32,7 @@ abstract class ConstructedGeneric extends Generic {
abstract Type getTypeArgument(int i);
/** Gets a type argument. */
- Type getATypeArgument() { result = getTypeArgument(_) }
+ Type getATypeArgument() { result = this.getTypeArgument(_) }
/**
* Gets the unbound generic declaration from which this declaration was
diff --git a/csharp/ql/lib/semmle/code/dotnet/Namespace.qll b/csharp/ql/lib/semmle/code/dotnet/Namespace.qll
index 55b42e737db..324448728de 100644
--- a/csharp/ql/lib/semmle/code/dotnet/Namespace.qll
+++ b/csharp/ql/lib/semmle/code/dotnet/Namespace.qll
@@ -33,7 +33,7 @@ class Namespace extends Declaration, @namespace {
override string toString() { result = this.getQualifiedName() }
/** Holds if this is the global namespace. */
- final predicate isGlobalNamespace() { getName() = "" }
+ final predicate isGlobalNamespace() { this.getName() = "" }
/** Gets the simple name of this namespace, for example `IO` in `System.IO`. */
final override string getName() { namespaces(this, result) }
diff --git a/csharp/ql/lib/semmle/code/dotnet/Type.qll b/csharp/ql/lib/semmle/code/dotnet/Type.qll
index 5dc9c409c18..81fefa96550 100644
--- a/csharp/ql/lib/semmle/code/dotnet/Type.qll
+++ b/csharp/ql/lib/semmle/code/dotnet/Type.qll
@@ -24,11 +24,11 @@ class ValueOrRefType extends Type, @dotnet_valueorreftype {
Namespace getDeclaringNamespace() { none() }
private string getPrefixWithTypes() {
- result = getDeclaringType().getLabel() + "."
+ result = this.getDeclaringType().getLabel() + "."
or
- if getDeclaringNamespace().isGlobalNamespace()
+ if this.getDeclaringNamespace().isGlobalNamespace()
then result = ""
- else result = getDeclaringNamespace().getQualifiedName() + "."
+ else result = this.getDeclaringNamespace().getQualifiedName() + "."
}
pragma[noinline]
@@ -64,9 +64,9 @@ class TypeParameter extends Type, @dotnet_type_parameter {
/** Gets the index of this type parameter. For example the index of `U` in `Func` is 1. */
int getIndex() { none() }
- final override string getLabel() { result = "!" + getIndex() }
+ final override string getLabel() { result = "!" + this.getIndex() }
- override string getUndecoratedName() { result = "!" + getIndex() }
+ override string getUndecoratedName() { result = "!" + this.getIndex() }
}
/** A pointer type. */
@@ -76,9 +76,9 @@ class PointerType extends Type, @dotnet_pointer_type {
override string getName() { result = this.getReferentType().getName() + "*" }
- final override string getLabel() { result = getReferentType().getLabel() + "*" }
+ final override string getLabel() { result = this.getReferentType().getLabel() + "*" }
- override string toStringWithTypes() { result = getReferentType().toStringWithTypes() + "*" }
+ override string toStringWithTypes() { result = this.getReferentType().toStringWithTypes() + "*" }
}
/** An array type. */
@@ -86,7 +86,7 @@ class ArrayType extends ValueOrRefType, @dotnet_array_type {
/** Gets the type of the array element. */
Type getElementType() { none() }
- final override string getLabel() { result = getElementType().getLabel() + "[]" }
+ final override string getLabel() { result = this.getElementType().getLabel() + "[]" }
- override string toStringWithTypes() { result = getElementType().toStringWithTypes() + "[]" }
+ override string toStringWithTypes() { result = this.getElementType().toStringWithTypes() + "[]" }
}
diff --git a/csharp/ql/lib/semmle/code/dotnet/Variable.qll b/csharp/ql/lib/semmle/code/dotnet/Variable.qll
index 9f9a12e7d98..ee9ccebbbe6 100644
--- a/csharp/ql/lib/semmle/code/dotnet/Variable.qll
+++ b/csharp/ql/lib/semmle/code/dotnet/Variable.qll
@@ -15,10 +15,10 @@ class Field extends Variable, Member, @dotnet_field { }
/** A parameter to a .Net callable, property or function pointer type. */
class Parameter extends Variable, @dotnet_parameter {
/** Gets the raw position of this parameter, including the `this` parameter at index 0. */
- final int getRawPosition() { this = getDeclaringElement().getRawParameter(result) }
+ final int getRawPosition() { this = this.getDeclaringElement().getRawParameter(result) }
/** Gets the position of this parameter, excluding the `this` parameter. */
- int getPosition() { this = getDeclaringElement().getParameter(result) }
+ int getPosition() { this = this.getDeclaringElement().getParameter(result) }
/** Gets the callable defining this parameter. */
Callable getCallable() { result = this.getDeclaringElement() }
diff --git a/csharp/ql/lib/tutorial.qll b/csharp/ql/lib/tutorial.qll
new file mode 100644
index 00000000000..8cb1797a532
--- /dev/null
+++ b/csharp/ql/lib/tutorial.qll
@@ -0,0 +1,1207 @@
+/**
+ * This library is used in the QL detective tutorials.
+ *
+ * Note: Data is usually stored in a separate database and the QL libraries only contain predicates,
+ * but for this tutorial both the data and the predicates are stored in the library.
+ */
+class Person extends string {
+ Person() {
+ this = "Ronil" or
+ this = "Dina" or
+ this = "Ravi" or
+ this = "Bruce" or
+ this = "Jo" or
+ this = "Aida" or
+ this = "Esme" or
+ this = "Charlie" or
+ this = "Fred" or
+ this = "Meera" or
+ this = "Maya" or
+ this = "Chad" or
+ this = "Tiana" or
+ this = "Laura" or
+ this = "George" or
+ this = "Will" or
+ this = "Mary" or
+ this = "Almira" or
+ this = "Susannah" or
+ this = "Rhoda" or
+ this = "Cynthia" or
+ this = "Eunice" or
+ this = "Olive" or
+ this = "Virginia" or
+ this = "Angeline" or
+ this = "Helen" or
+ this = "Cornelia" or
+ this = "Harriet" or
+ this = "Mahala" or
+ this = "Abby" or
+ this = "Margaret" or
+ this = "Deb" or
+ this = "Minerva" or
+ this = "Severus" or
+ this = "Lavina" or
+ this = "Adeline" or
+ this = "Cath" or
+ this = "Elisa" or
+ this = "Lucretia" or
+ this = "Anne" or
+ this = "Eleanor" or
+ this = "Joanna" or
+ this = "Adam" or
+ this = "Agnes" or
+ this = "Rosanna" or
+ this = "Clara" or
+ this = "Melissa" or
+ this = "Amy" or
+ this = "Isabel" or
+ this = "Jemima" or
+ this = "Cordelia" or
+ this = "Melinda" or
+ this = "Delila" or
+ this = "Jeremiah" or
+ this = "Elijah" or
+ this = "Hester" or
+ this = "Walter" or
+ this = "Oliver" or
+ this = "Hugh" or
+ this = "Aaron" or
+ this = "Reuben" or
+ this = "Eli" or
+ this = "Amos" or
+ this = "Augustus" or
+ this = "Theodore" or
+ this = "Ira" or
+ this = "Timothy" or
+ this = "Cyrus" or
+ this = "Horace" or
+ this = "Simon" or
+ this = "Asa" or
+ this = "Frank" or
+ this = "Nelson" or
+ this = "Leonard" or
+ this = "Harrison" or
+ this = "Anthony" or
+ this = "Louis" or
+ this = "Milton" or
+ this = "Noah" or
+ this = "Cornelius" or
+ this = "Abdul" or
+ this = "Warren" or
+ this = "Harvey" or
+ this = "Dennis" or
+ this = "Wesley" or
+ this = "Sylvester" or
+ this = "Gilbert" or
+ this = "Sullivan" or
+ this = "Edmund" or
+ this = "Wilson" or
+ this = "Perry" or
+ this = "Matthew" or
+ this = "Simba" or
+ this = "Nala" or
+ this = "Rafiki" or
+ this = "Shenzi" or
+ this = "Ernest" or
+ this = "Gertrude" or
+ this = "Oscar" or
+ this = "Lilian" or
+ this = "Raymond" or
+ this = "Elgar" or
+ this = "Elmer" or
+ this = "Herbert" or
+ this = "Maude" or
+ this = "Mae" or
+ this = "Otto" or
+ this = "Edwin" or
+ this = "Ophelia" or
+ this = "Parsley" or
+ this = "Sage" or
+ this = "Rosemary" or
+ this = "Thyme" or
+ this = "Garfunkel" or
+ this = "King Basil" or
+ this = "Stephen"
+ }
+
+ /** Gets the hair color of the person. If the person is bald, there is no result. */
+ string getHairColor() {
+ this = "Ronil" and result = "black"
+ or
+ this = "Dina" and result = "black"
+ or
+ this = "Ravi" and result = "black"
+ or
+ this = "Bruce" and result = "brown"
+ or
+ this = "Jo" and result = "red"
+ or
+ this = "Aida" and result = "blond"
+ or
+ this = "Esme" and result = "blond"
+ or
+ this = "Fred" and result = "gray"
+ or
+ this = "Meera" and result = "brown"
+ or
+ this = "Maya" and result = "brown"
+ or
+ this = "Chad" and result = "brown"
+ or
+ this = "Tiana" and result = "black"
+ or
+ this = "Laura" and result = "blond"
+ or
+ this = "George" and result = "blond"
+ or
+ this = "Will" and result = "blond"
+ or
+ this = "Mary" and result = "blond"
+ or
+ this = "Almira" and result = "black"
+ or
+ this = "Susannah" and result = "blond"
+ or
+ this = "Rhoda" and result = "blond"
+ or
+ this = "Cynthia" and result = "gray"
+ or
+ this = "Eunice" and result = "white"
+ or
+ this = "Olive" and result = "brown"
+ or
+ this = "Virginia" and result = "brown"
+ or
+ this = "Angeline" and result = "red"
+ or
+ this = "Helen" and result = "white"
+ or
+ this = "Cornelia" and result = "gray"
+ or
+ this = "Harriet" and result = "white"
+ or
+ this = "Mahala" and result = "black"
+ or
+ this = "Abby" and result = "red"
+ or
+ this = "Margaret" and result = "brown"
+ or
+ this = "Deb" and result = "brown"
+ or
+ this = "Minerva" and result = "brown"
+ or
+ this = "Severus" and result = "black"
+ or
+ this = "Lavina" and result = "brown"
+ or
+ this = "Adeline" and result = "brown"
+ or
+ this = "Cath" and result = "brown"
+ or
+ this = "Elisa" and result = "brown"
+ or
+ this = "Lucretia" and result = "gray"
+ or
+ this = "Anne" and result = "black"
+ or
+ this = "Eleanor" and result = "brown"
+ or
+ this = "Joanna" and result = "brown"
+ or
+ this = "Adam" and result = "black"
+ or
+ this = "Agnes" and result = "black"
+ or
+ this = "Rosanna" and result = "gray"
+ or
+ this = "Clara" and result = "blond"
+ or
+ this = "Melissa" and result = "brown"
+ or
+ this = "Amy" and result = "brown"
+ or
+ this = "Isabel" and result = "black"
+ or
+ this = "Jemima" and result = "red"
+ or
+ this = "Cordelia" and result = "red"
+ or
+ this = "Melinda" and result = "gray"
+ or
+ this = "Delila" and result = "white"
+ or
+ this = "Jeremiah" and result = "gray"
+ or
+ this = "Hester" and result = "black"
+ or
+ this = "Walter" and result = "black"
+ or
+ this = "Aaron" and result = "gray"
+ or
+ this = "Reuben" and result = "gray"
+ or
+ this = "Eli" and result = "gray"
+ or
+ this = "Amos" and result = "white"
+ or
+ this = "Augustus" and result = "white"
+ or
+ this = "Theodore" and result = "white"
+ or
+ this = "Timothy" and result = "brown"
+ or
+ this = "Cyrus" and result = "brown"
+ or
+ this = "Horace" and result = "brown"
+ or
+ this = "Simon" and result = "brown"
+ or
+ this = "Asa" and result = "brown"
+ or
+ this = "Frank" and result = "brown"
+ or
+ this = "Nelson" and result = "black"
+ or
+ this = "Leonard" and result = "black"
+ or
+ this = "Harrison" and result = "black"
+ or
+ this = "Anthony" and result = "black"
+ or
+ this = "Louis" and result = "black"
+ or
+ this = "Milton" and result = "blond"
+ or
+ this = "Noah" and result = "blond"
+ or
+ this = "Cornelius" and result = "red"
+ or
+ this = "Abdul" and result = "brown"
+ or
+ this = "Warren" and result = "red"
+ or
+ this = "Harvey" and result = "blond"
+ or
+ this = "Dennis" and result = "blond"
+ or
+ this = "Wesley" and result = "brown"
+ or
+ this = "Sylvester" and result = "brown"
+ or
+ this = "Gilbert" and result = "brown"
+ or
+ this = "Sullivan" and result = "brown"
+ or
+ this = "Edmund" and result = "brown"
+ or
+ this = "Wilson" and result = "blond"
+ or
+ this = "Perry" and result = "black"
+ or
+ this = "Simba" and result = "brown"
+ or
+ this = "Nala" and result = "brown"
+ or
+ this = "Rafiki" and result = "red"
+ or
+ this = "Shenzi" and result = "gray"
+ or
+ this = "Ernest" and result = "blond"
+ or
+ this = "Gertrude" and result = "brown"
+ or
+ this = "Oscar" and result = "blond"
+ or
+ this = "Lilian" and result = "brown"
+ or
+ this = "Raymond" and result = "brown"
+ or
+ this = "Elgar" and result = "brown"
+ or
+ this = "Elmer" and result = "brown"
+ or
+ this = "Herbert" and result = "brown"
+ or
+ this = "Maude" and result = "brown"
+ or
+ this = "Mae" and result = "brown"
+ or
+ this = "Otto" and result = "black"
+ or
+ this = "Edwin" and result = "black"
+ or
+ this = "Ophelia" and result = "brown"
+ or
+ this = "Parsley" and result = "brown"
+ or
+ this = "Sage" and result = "brown"
+ or
+ this = "Rosemary" and result = "brown"
+ or
+ this = "Thyme" and result = "brown"
+ or
+ this = "Garfunkel" and result = "brown"
+ or
+ this = "King Basil" and result = "brown"
+ or
+ this = "Stephen" and result = "black"
+ or
+ this = "Stephen" and result = "gray"
+ }
+
+ /** Gets the age of the person (in years). If the person is deceased, there is no result. */
+ int getAge() {
+ this = "Ronil" and result = 21
+ or
+ this = "Dina" and result = 53
+ or
+ this = "Ravi" and result = 16
+ or
+ this = "Bruce" and result = 35
+ or
+ this = "Jo" and result = 47
+ or
+ this = "Aida" and result = 26
+ or
+ this = "Esme" and result = 25
+ or
+ this = "Charlie" and result = 31
+ or
+ this = "Fred" and result = 68
+ or
+ this = "Meera" and result = 62
+ or
+ this = "Maya" and result = 29
+ or
+ this = "Chad" and result = 49
+ or
+ this = "Tiana" and result = 18
+ or
+ this = "Laura" and result = 2
+ or
+ this = "George" and result = 3
+ or
+ this = "Will" and result = 41
+ or
+ this = "Mary" and result = 51
+ or
+ this = "Almira" and result = 1
+ or
+ this = "Susannah" and result = 97
+ or
+ this = "Rhoda" and result = 39
+ or
+ this = "Cynthia" and result = 89
+ or
+ this = "Eunice" and result = 83
+ or
+ this = "Olive" and result = 25
+ or
+ this = "Virginia" and result = 52
+ or
+ this = "Angeline" and result = 22
+ or
+ this = "Helen" and result = 79
+ or
+ this = "Cornelia" and result = 59
+ or
+ this = "Harriet" and result = 57
+ or
+ this = "Mahala" and result = 61
+ or
+ this = "Abby" and result = 24
+ or
+ this = "Margaret" and result = 59
+ or
+ this = "Deb" and result = 31
+ or
+ this = "Minerva" and result = 72
+ or
+ this = "Severus" and result = 61
+ or
+ this = "Lavina" and result = 33
+ or
+ this = "Adeline" and result = 17
+ or
+ this = "Cath" and result = 22
+ or
+ this = "Elisa" and result = 9
+ or
+ this = "Lucretia" and result = 56
+ or
+ this = "Anne" and result = 11
+ or
+ this = "Eleanor" and result = 80
+ or
+ this = "Joanna" and result = 43
+ or
+ this = "Adam" and result = 37
+ or
+ this = "Agnes" and result = 47
+ or
+ this = "Rosanna" and result = 61
+ or
+ this = "Clara" and result = 31
+ or
+ this = "Melissa" and result = 37
+ or
+ this = "Amy" and result = 12
+ or
+ this = "Isabel" and result = 6
+ or
+ this = "Jemima" and result = 16
+ or
+ this = "Cordelia" and result = 21
+ or
+ this = "Melinda" and result = 55
+ or
+ this = "Delila" and result = 66
+ or
+ this = "Jeremiah" and result = 54
+ or
+ this = "Elijah" and result = 42
+ or
+ this = "Hester" and result = 68
+ or
+ this = "Walter" and result = 66
+ or
+ this = "Oliver" and result = 33
+ or
+ this = "Hugh" and result = 51
+ or
+ this = "Aaron" and result = 49
+ or
+ this = "Reuben" and result = 58
+ or
+ this = "Eli" and result = 70
+ or
+ this = "Amos" and result = 65
+ or
+ this = "Augustus" and result = 56
+ or
+ this = "Theodore" and result = 69
+ or
+ this = "Ira" and result = 1
+ or
+ this = "Timothy" and result = 54
+ or
+ this = "Cyrus" and result = 78
+ or
+ this = "Horace" and result = 34
+ or
+ this = "Simon" and result = 23
+ or
+ this = "Asa" and result = 28
+ or
+ this = "Frank" and result = 59
+ or
+ this = "Nelson" and result = 38
+ or
+ this = "Leonard" and result = 58
+ or
+ this = "Harrison" and result = 7
+ or
+ this = "Anthony" and result = 2
+ or
+ this = "Louis" and result = 34
+ or
+ this = "Milton" and result = 36
+ or
+ this = "Noah" and result = 48
+ or
+ this = "Cornelius" and result = 41
+ or
+ this = "Abdul" and result = 67
+ or
+ this = "Warren" and result = 47
+ or
+ this = "Harvey" and result = 31
+ or
+ this = "Dennis" and result = 39
+ or
+ this = "Wesley" and result = 13
+ or
+ this = "Sylvester" and result = 19
+ or
+ this = "Gilbert" and result = 16
+ or
+ this = "Sullivan" and result = 17
+ or
+ this = "Edmund" and result = 29
+ or
+ this = "Wilson" and result = 27
+ or
+ this = "Perry" and result = 31
+ or
+ this = "Matthew" and result = 55
+ or
+ this = "Simba" and result = 8
+ or
+ this = "Nala" and result = 7
+ or
+ this = "Rafiki" and result = 76
+ or
+ this = "Shenzi" and result = 67
+ }
+
+ /** Gets the height of the person (in cm). If the person is deceased, there is no result. */
+ float getHeight() {
+ this = "Ronil" and result = 183.0
+ or
+ this = "Dina" and result = 155.1
+ or
+ this = "Ravi" and result = 175.2
+ or
+ this = "Bruce" and result = 191.3
+ or
+ this = "Jo" and result = 163.4
+ or
+ this = "Aida" and result = 182.6
+ or
+ this = "Esme" and result = 176.9
+ or
+ this = "Charlie" and result = 189.7
+ or
+ this = "Fred" and result = 179.4
+ or
+ this = "Meera" and result = 160.1
+ or
+ this = "Maya" and result = 153.0
+ or
+ this = "Chad" and result = 168.5
+ or
+ this = "Tiana" and result = 149.7
+ or
+ this = "Laura" and result = 87.5
+ or
+ this = "George" and result = 96.4
+ or
+ this = "Will" and result = 167.1
+ or
+ this = "Mary" and result = 159.8
+ or
+ this = "Almira" and result = 62.1
+ or
+ this = "Susannah" and result = 145.8
+ or
+ this = "Rhoda" and result = 180.1
+ or
+ this = "Cynthia" and result = 161.8
+ or
+ this = "Eunice" and result = 153.2
+ or
+ this = "Olive" and result = 179.9
+ or
+ this = "Virginia" and result = 165.1
+ or
+ this = "Angeline" and result = 172.3
+ or
+ this = "Helen" and result = 163.1
+ or
+ this = "Cornelia" and result = 160.8
+ or
+ this = "Harriet" and result = 163.2
+ or
+ this = "Mahala" and result = 157.7
+ or
+ this = "Abby" and result = 174.5
+ or
+ this = "Margaret" and result = 165.6
+ or
+ this = "Deb" and result = 171.6
+ or
+ this = "Minerva" and result = 168.7
+ or
+ this = "Severus" and result = 188.8
+ or
+ this = "Lavina" and result = 155.1
+ or
+ this = "Adeline" and result = 165.5
+ or
+ this = "Cath" and result = 147.8
+ or
+ this = "Elisa" and result = 129.4
+ or
+ this = "Lucretia" and result = 153.6
+ or
+ this = "Anne" and result = 140.4
+ or
+ this = "Eleanor" and result = 151.1
+ or
+ this = "Joanna" and result = 167.2
+ or
+ this = "Adam" and result = 155.5
+ or
+ this = "Agnes" and result = 156.8
+ or
+ this = "Rosanna" and result = 162.4
+ or
+ this = "Clara" and result = 158.6
+ or
+ this = "Melissa" and result = 182.3
+ or
+ this = "Amy" and result = 147.1
+ or
+ this = "Isabel" and result = 121.4
+ or
+ this = "Jemima" and result = 149.8
+ or
+ this = "Cordelia" and result = 151.7
+ or
+ this = "Melinda" and result = 154.4
+ or
+ this = "Delila" and result = 163.4
+ or
+ this = "Jeremiah" and result = 167.5
+ or
+ this = "Elijah" and result = 184.5
+ or
+ this = "Hester" and result = 152.7
+ or
+ this = "Walter" and result = 159.6
+ or
+ this = "Oliver" and result = 192.4
+ or
+ this = "Hugh" and result = 173.1
+ or
+ this = "Aaron" and result = 176.6
+ or
+ this = "Reuben" and result = 169.9
+ or
+ this = "Eli" and result = 180.4
+ or
+ this = "Amos" and result = 167.4
+ or
+ this = "Augustus" and result = 156.5
+ or
+ this = "Theodore" and result = 176.6
+ or
+ this = "Ira" and result = 54.1
+ or
+ this = "Timothy" and result = 172.2
+ or
+ this = "Cyrus" and result = 157.9
+ or
+ this = "Horace" and result = 169.3
+ or
+ this = "Simon" and result = 157.1
+ or
+ this = "Asa" and result = 149.4
+ or
+ this = "Frank" and result = 167.2
+ or
+ this = "Nelson" and result = 173.0
+ or
+ this = "Leonard" and result = 172.0
+ or
+ this = "Harrison" and result = 126.0
+ or
+ this = "Anthony" and result = 98.4
+ or
+ this = "Louis" and result = 186.8
+ or
+ this = "Milton" and result = 157.8
+ or
+ this = "Noah" and result = 190.5
+ or
+ this = "Cornelius" and result = 183.1
+ or
+ this = "Abdul" and result = 182.0
+ or
+ this = "Warren" and result = 175.0
+ or
+ this = "Harvey" and result = 169.3
+ or
+ this = "Dennis" and result = 160.4
+ or
+ this = "Wesley" and result = 139.8
+ or
+ this = "Sylvester" and result = 188.2
+ or
+ this = "Gilbert" and result = 177.6
+ or
+ this = "Sullivan" and result = 168.3
+ or
+ this = "Edmund" and result = 159.2
+ or
+ this = "Wilson" and result = 167.6
+ or
+ this = "Perry" and result = 189.1
+ or
+ this = "Matthew" and result = 167.2
+ or
+ this = "Simba" and result = 140.1
+ or
+ this = "Nala" and result = 138.0
+ or
+ this = "Rafiki" and result = 139.3
+ or
+ this = "Shenzi" and result = 171.1
+ }
+
+ /** Gets the location of the person's home ("north", "south", "east", or "west"). If the person is deceased, there is no result. */
+ string getLocation() {
+ this = "Ronil" and result = "north"
+ or
+ this = "Dina" and result = "north"
+ or
+ this = "Ravi" and result = "north"
+ or
+ this = "Bruce" and result = "south"
+ or
+ this = "Jo" and result = "west"
+ or
+ this = "Aida" and result = "east"
+ or
+ this = "Esme" and result = "east"
+ or
+ this = "Charlie" and result = "south"
+ or
+ this = "Fred" and result = "west"
+ or
+ this = "Meera" and result = "south"
+ or
+ this = "Maya" and result = "south"
+ or
+ this = "Chad" and result = "south"
+ or
+ this = "Tiana" and result = "west"
+ or
+ this = "Laura" and result = "south"
+ or
+ this = "George" and result = "south"
+ or
+ this = "Will" and result = "south"
+ or
+ this = "Mary" and result = "south"
+ or
+ this = "Almira" and result = "south"
+ or
+ this = "Susannah" and result = "north"
+ or
+ this = "Rhoda" and result = "north"
+ or
+ this = "Cynthia" and result = "north"
+ or
+ this = "Eunice" and result = "north"
+ or
+ this = "Olive" and result = "west"
+ or
+ this = "Virginia" and result = "west"
+ or
+ this = "Angeline" and result = "west"
+ or
+ this = "Helen" and result = "west"
+ or
+ this = "Cornelia" and result = "east"
+ or
+ this = "Harriet" and result = "east"
+ or
+ this = "Mahala" and result = "east"
+ or
+ this = "Abby" and result = "east"
+ or
+ this = "Margaret" and result = "east"
+ or
+ this = "Deb" and result = "east"
+ or
+ this = "Minerva" and result = "south"
+ or
+ this = "Severus" and result = "north"
+ or
+ this = "Lavina" and result = "east"
+ or
+ this = "Adeline" and result = "west"
+ or
+ this = "Cath" and result = "east"
+ or
+ this = "Elisa" and result = "east"
+ or
+ this = "Lucretia" and result = "north"
+ or
+ this = "Anne" and result = "north"
+ or
+ this = "Eleanor" and result = "south"
+ or
+ this = "Joanna" and result = "south"
+ or
+ this = "Adam" and result = "east"
+ or
+ this = "Agnes" and result = "east"
+ or
+ this = "Rosanna" and result = "east"
+ or
+ this = "Clara" and result = "east"
+ or
+ this = "Melissa" and result = "west"
+ or
+ this = "Amy" and result = "west"
+ or
+ this = "Isabel" and result = "west"
+ or
+ this = "Jemima" and result = "west"
+ or
+ this = "Cordelia" and result = "west"
+ or
+ this = "Melinda" and result = "west"
+ or
+ this = "Delila" and result = "south"
+ or
+ this = "Jeremiah" and result = "north"
+ or
+ this = "Elijah" and result = "north"
+ or
+ this = "Hester" and result = "east"
+ or
+ this = "Walter" and result = "east"
+ or
+ this = "Oliver" and result = "east"
+ or
+ this = "Hugh" and result = "south"
+ or
+ this = "Aaron" and result = "south"
+ or
+ this = "Reuben" and result = "west"
+ or
+ this = "Eli" and result = "west"
+ or
+ this = "Amos" and result = "east"
+ or
+ this = "Augustus" and result = "south"
+ or
+ this = "Theodore" and result = "west"
+ or
+ this = "Ira" and result = "south"
+ or
+ this = "Timothy" and result = "north"
+ or
+ this = "Cyrus" and result = "north"
+ or
+ this = "Horace" and result = "east"
+ or
+ this = "Simon" and result = "east"
+ or
+ this = "Asa" and result = "east"
+ or
+ this = "Frank" and result = "west"
+ or
+ this = "Nelson" and result = "west"
+ or
+ this = "Leonard" and result = "west"
+ or
+ this = "Harrison" and result = "north"
+ or
+ this = "Anthony" and result = "north"
+ or
+ this = "Louis" and result = "north"
+ or
+ this = "Milton" and result = "south"
+ or
+ this = "Noah" and result = "south"
+ or
+ this = "Cornelius" and result = "east"
+ or
+ this = "Abdul" and result = "east"
+ or
+ this = "Warren" and result = "west"
+ or
+ this = "Harvey" and result = "west"
+ or
+ this = "Dennis" and result = "west"
+ or
+ this = "Wesley" and result = "west"
+ or
+ this = "Sylvester" and result = "south"
+ or
+ this = "Gilbert" and result = "east"
+ or
+ this = "Sullivan" and result = "east"
+ or
+ this = "Edmund" and result = "north"
+ or
+ this = "Wilson" and result = "north"
+ or
+ this = "Perry" and result = "west"
+ or
+ this = "Matthew" and result = "east"
+ or
+ this = "Simba" and result = "south"
+ or
+ this = "Nala" and result = "south"
+ or
+ this = "Rafiki" and result = "north"
+ or
+ this = "Shenzi" and result = "west"
+ }
+
+ /** Holds if the person is deceased. */
+ predicate isDeceased() {
+ this = "Ernest" or
+ this = "Gertrude" or
+ this = "Oscar" or
+ this = "Lilian" or
+ this = "Edwin" or
+ this = "Raymond" or
+ this = "Elgar" or
+ this = "Elmer" or
+ this = "Herbert" or
+ this = "Maude" or
+ this = "Mae" or
+ this = "Otto" or
+ this = "Ophelia" or
+ this = "Parsley" or
+ this = "Sage" or
+ this = "Rosemary" or
+ this = "Thyme" or
+ this = "Garfunkel" or
+ this = "King Basil"
+ }
+
+ /** Gets a parent of the person (alive or deceased). */
+ Person getAParent() {
+ this = "Stephen" and result = "Edmund"
+ or
+ this = "Edmund" and result = "Augustus"
+ or
+ this = "Augustus" and result = "Stephen"
+ or
+ this = "Abby" and result = "Cornelia"
+ or
+ this = "Abby" and result = "Amos"
+ or
+ this = "Abdul" and result = "Susannah"
+ or
+ this = "Adam" and result = "Amos"
+ or
+ this = "Adeline" and result = "Melinda"
+ or
+ this = "Adeline" and result = "Frank"
+ or
+ this = "Agnes" and result = "Abdul"
+ or
+ this = "Aida" and result = "Agnes"
+ or
+ this = "Almira" and result = "Sylvester"
+ or
+ this = "Amos" and result = "Eunice"
+ or
+ this = "Amy" and result = "Noah"
+ or
+ this = "Amy" and result = "Chad"
+ or
+ this = "Angeline" and result = "Reuben"
+ or
+ this = "Angeline" and result = "Lucretia"
+ or
+ this = "Anne" and result = "Rhoda"
+ or
+ this = "Anne" and result = "Louis"
+ or
+ this = "Anthony" and result = "Lavina"
+ or
+ this = "Anthony" and result = "Asa"
+ or
+ this = "Asa" and result = "Cornelia"
+ or
+ this = "Cath" and result = "Harriet"
+ or
+ this = "Charlie" and result = "Matthew"
+ or
+ this = "Clara" and result = "Ernest"
+ or
+ this = "Cornelia" and result = "Cynthia"
+ or
+ this = "Cornelius" and result = "Eli"
+ or
+ this = "Deb" and result = "Margaret"
+ or
+ this = "Dennis" and result = "Fred"
+ or
+ this = "Eli" and result = "Susannah"
+ or
+ this = "Elijah" and result = "Delila"
+ or
+ this = "Elisa" and result = "Deb"
+ or
+ this = "Elisa" and result = "Horace"
+ or
+ this = "Esme" and result = "Margaret"
+ or
+ this = "Frank" and result = "Eleanor"
+ or
+ this = "Frank" and result = "Cyrus"
+ or
+ this = "George" and result = "Maya"
+ or
+ this = "George" and result = "Wilson"
+ or
+ this = "Gilbert" and result = "Cornelius"
+ or
+ this = "Harriet" and result = "Cynthia"
+ or
+ this = "Harrison" and result = "Louis"
+ or
+ this = "Harvey" and result = "Fred"
+ or
+ this = "Helen" and result = "Susannah"
+ or
+ this = "Hester" and result = "Edwin"
+ or
+ this = "Hugh" and result = "Cyrus"
+ or
+ this = "Hugh" and result = "Helen"
+ or
+ this = "Ira" and result = "Maya"
+ or
+ this = "Ira" and result = "Wilson"
+ or
+ this = "Isabel" and result = "Perry"
+ or
+ this = "Isabel" and result = "Harvey"
+ or
+ this = "Jemima" and result = "Melinda"
+ or
+ this = "Jemima" and result = "Frank"
+ or
+ this = "Ernest" and result = "Lilian"
+ or
+ this = "Ernest" and result = "Oscar"
+ or
+ this = "Gertrude" and result = "Ophelia"
+ or
+ this = "Gertrude" and result = "Raymond"
+ or
+ this = "Lilian" and result = "Elgar"
+ or
+ this = "Lilian" and result = "Mae"
+ or
+ this = "Raymond" and result = "Elgar"
+ or
+ this = "Raymond" and result = "Mae"
+ or
+ this = "Elmer" and result = "Ophelia"
+ or
+ this = "Elmer" and result = "Raymond"
+ or
+ this = "Herbert" and result = "Ophelia"
+ or
+ this = "Herbert" and result = "Raymond"
+ or
+ this = "Maude" and result = "Ophelia"
+ or
+ this = "Maude" and result = "Raymond"
+ or
+ this = "Otto" and result = "Elgar"
+ or
+ this = "Otto" and result = "Mae"
+ or
+ this = "Edwin" and result = "Otto"
+ or
+ this = "Parsley" and result = "Simon"
+ or
+ this = "Parsley" and result = "Garfunkel"
+ or
+ this = "Sage" and result = "Simon"
+ or
+ this = "Sage" and result = "Garfunkel"
+ or
+ this = "Rosemary" and result = "Simon"
+ or
+ this = "Rosemary" and result = "Garfunkel"
+ or
+ this = "Thyme" and result = "Simon"
+ or
+ this = "Thyme" and result = "Garfunkel"
+ or
+ this = "King Basil" and result = "Ophelia"
+ or
+ this = "King Basil" and result = "Raymond"
+ or
+ this = "Jo" and result = "Theodore"
+ or
+ this = "Joanna" and result = "Shenzi"
+ or
+ this = "Laura" and result = "Maya"
+ or
+ this = "Laura" and result = "Wilson"
+ or
+ this = "Lavina" and result = "Mahala"
+ or
+ this = "Lavina" and result = "Walter"
+ or
+ this = "Leonard" and result = "Cyrus"
+ or
+ this = "Leonard" and result = "Helen"
+ or
+ this = "Lucretia" and result = "Eleanor"
+ or
+ this = "Lucretia" and result = "Cyrus"
+ or
+ this = "Mahala" and result = "Eunice"
+ or
+ this = "Margaret" and result = "Cynthia"
+ or
+ this = "Matthew" and result = "Cyrus"
+ or
+ this = "Matthew" and result = "Helen"
+ or
+ this = "Maya" and result = "Meera"
+ or
+ this = "Melinda" and result = "Rafiki"
+ or
+ this = "Melissa" and result = "Mahala"
+ or
+ this = "Melissa" and result = "Walter"
+ or
+ this = "Nala" and result = "Bruce"
+ or
+ this = "Nelson" and result = "Mahala"
+ or
+ this = "Nelson" and result = "Walter"
+ or
+ this = "Noah" and result = "Eli"
+ or
+ this = "Olive" and result = "Reuben"
+ or
+ this = "Olive" and result = "Lucretia"
+ or
+ this = "Oliver" and result = "Matthew"
+ or
+ this = "Perry" and result = "Leonard"
+ or
+ this = "Ravi" and result = "Dina"
+ or
+ this = "Simba" and result = "Will"
+ or
+ this = "Simon" and result = "Margaret"
+ or
+ this = "Sullivan" and result = "Cornelius"
+ or
+ this = "Sylvester" and result = "Timothy"
+ or
+ this = "Theodore" and result = "Susannah"
+ or
+ this = "Tiana" and result = "Jo"
+ or
+ this = "Virginia" and result = "Helen"
+ or
+ this = "Warren" and result = "Shenzi"
+ or
+ this = "Wesley" and result = "Warren"
+ or
+ this = "Wesley" and result = "Jo"
+ or
+ this = "Will" and result = "Eli"
+ }
+
+ /** Holds if the person is allowed in the region. Initially, all villagers are allowed in every region. */
+ predicate isAllowedIn(string region) {
+ region = "north" or
+ region = "south" or
+ region = "east" or
+ region = "west"
+ }
+}
+
+/** Returns a parent of the person. */
+Person parentOf(Person p) { result = p.getAParent() }
diff --git a/csharp/ql/src/AlertSuppression.ql b/csharp/ql/src/AlertSuppression.ql
index 1467731809b..3cb6d759b6e 100644
--- a/csharp/ql/src/AlertSuppression.ql
+++ b/csharp/ql/src/AlertSuppression.ql
@@ -55,7 +55,7 @@ class SuppressionScope extends @commentline {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql
index 0b4f4fd99b8..a0542a94735 100644
--- a/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql
+++ b/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql
@@ -123,6 +123,8 @@ class ConstantMatchingCondition extends ConstantCondition {
se.getCase(i).getPattern() = this.(DiscardExpr) and
i > 0
)
+ or
+ this = any(PositionalPatternExpr ppe).getPattern(_)
}
override string getMessage() {
diff --git a/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll b/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll
index d604dfaeefe..b65cdcd1961 100644
--- a/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll
+++ b/csharp/ql/src/Bad Practices/Magic Constants/MagicConstants.qll
@@ -7,179 +7,30 @@ import semmle.code.csharp.frameworks.System
*/
private predicate trivialPositiveIntValue(string s) {
- s = "0" or
- s = "1" or
- s = "2" or
- s = "3" or
- s = "4" or
- s = "5" or
- s = "6" or
- s = "7" or
- s = "8" or
- s = "9" or
- s = "10" or
- s = "11" or
- s = "12" or
- s = "13" or
- s = "14" or
- s = "15" or
- s = "16" or
- s = "17" or
- s = "18" or
- s = "19" or
- s = "20" or
- s = "16" or
- s = "32" or
- s = "64" or
- s = "128" or
- s = "256" or
- s = "512" or
- s = "1024" or
- s = "2048" or
- s = "4096" or
- s = "16384" or
- s = "32768" or
- s = "65536" or
- s = "1048576" or
- s = "2147483648" or
- s = "4294967296" or
- s = "15" or
- s = "31" or
- s = "63" or
- s = "127" or
- s = "255" or
- s = "511" or
- s = "1023" or
- s = "2047" or
- s = "4095" or
- s = "16383" or
- s = "32767" or
- s = "65535" or
- s = "1048577" or
- s = "2147483647" or
- s = "4294967295" or
- s = "0x00000001" or
- s = "0x00000002" or
- s = "0x00000004" or
- s = "0x00000008" or
- s = "0x00000010" or
- s = "0x00000020" or
- s = "0x00000040" or
- s = "0x00000080" or
- s = "0x00000100" or
- s = "0x00000200" or
- s = "0x00000400" or
- s = "0x00000800" or
- s = "0x00001000" or
- s = "0x00002000" or
- s = "0x00004000" or
- s = "0x00008000" or
- s = "0x00010000" or
- s = "0x00020000" or
- s = "0x00040000" or
- s = "0x00080000" or
- s = "0x00100000" or
- s = "0x00200000" or
- s = "0x00400000" or
- s = "0x00800000" or
- s = "0x01000000" or
- s = "0x02000000" or
- s = "0x04000000" or
- s = "0x08000000" or
- s = "0x10000000" or
- s = "0x20000000" or
- s = "0x40000000" or
- s = "0x80000000" or
- s = "0x00000001" or
- s = "0x00000003" or
- s = "0x00000007" or
- s = "0x0000000f" or
- s = "0x0000001f" or
- s = "0x0000003f" or
- s = "0x0000007f" or
- s = "0x000000ff" or
- s = "0x000001ff" or
- s = "0x000003ff" or
- s = "0x000007ff" or
- s = "0x00000fff" or
- s = "0x00001fff" or
- s = "0x00003fff" or
- s = "0x00007fff" or
- s = "0x0000ffff" or
- s = "0x0001ffff" or
- s = "0x0003ffff" or
- s = "0x0007ffff" or
- s = "0x000fffff" or
- s = "0x001fffff" or
- s = "0x003fffff" or
- s = "0x007fffff" or
- s = "0x00ffffff" or
- s = "0x01ffffff" or
- s = "0x03ffffff" or
- s = "0x07ffffff" or
- s = "0x0fffffff" or
- s = "0x1fffffff" or
- s = "0x3fffffff" or
- s = "0x7fffffff" or
- s = "0xffffffff" or
- s = "0x0001" or
- s = "0x0002" or
- s = "0x0004" or
- s = "0x0008" or
- s = "0x0010" or
- s = "0x0020" or
- s = "0x0040" or
- s = "0x0080" or
- s = "0x0100" or
- s = "0x0200" or
- s = "0x0400" or
- s = "0x0800" or
- s = "0x1000" or
- s = "0x2000" or
- s = "0x4000" or
- s = "0x8000" or
- s = "0x0001" or
- s = "0x0003" or
- s = "0x0007" or
- s = "0x000f" or
- s = "0x001f" or
- s = "0x003f" or
- s = "0x007f" or
- s = "0x00ff" or
- s = "0x01ff" or
- s = "0x03ff" or
- s = "0x07ff" or
- s = "0x0fff" or
- s = "0x1fff" or
- s = "0x3fff" or
- s = "0x7fff" or
- s = "0xffff" or
- s = "0x01" or
- s = "0x02" or
- s = "0x04" or
- s = "0x08" or
- s = "0x10" or
- s = "0x20" or
- s = "0x40" or
- s = "0x80" or
- s = "0x01" or
- s = "0x03" or
- s = "0x07" or
- s = "0x0f" or
- s = "0x1f" or
- s = "0x3f" or
- s = "0x7f" or
- s = "0xff" or
- s = "0x00" or
- s = "10" or
- s = "100" or
- s = "1000" or
- s = "10000" or
- s = "100000" or
- s = "1000000" or
- s = "10000000" or
- s = "100000000" or
- s = "1000000000"
+ s =
+ [
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16",
+ "17", "18", "19", "20", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096",
+ "16384", "32768", "65536", "1048576", "2147483648", "4294967296", "15", "31", "63", "127",
+ "255", "511", "1023", "2047", "4095", "16383", "32767", "65535", "1048577", "2147483647",
+ "4294967295", "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010",
+ "0x00000020", "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400",
+ "0x00000800", "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000",
+ "0x00020000", "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000",
+ "0x00800000", "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000",
+ "0x20000000", "0x40000000", "0x80000000", "0x00000001", "0x00000003", "0x00000007",
+ "0x0000000f", "0x0000001f", "0x0000003f", "0x0000007f", "0x000000ff", "0x000001ff",
+ "0x000003ff", "0x000007ff", "0x00000fff", "0x00001fff", "0x00003fff", "0x00007fff",
+ "0x0000ffff", "0x0001ffff", "0x0003ffff", "0x0007ffff", "0x000fffff", "0x001fffff",
+ "0x003fffff", "0x007fffff", "0x00ffffff", "0x01ffffff", "0x03ffffff", "0x07ffffff",
+ "0x0fffffff", "0x1fffffff", "0x3fffffff", "0x7fffffff", "0xffffffff", "0x0001", "0x0002",
+ "0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100", "0x0200", "0x0400",
+ "0x0800", "0x1000", "0x2000", "0x4000", "0x8000", "0x0001", "0x0003", "0x0007", "0x000f",
+ "0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff", "0x03ff", "0x07ff", "0x0fff", "0x1fff",
+ "0x3fff", "0x7fff", "0xffff", "0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80",
+ "0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00", "10", "100", "1000",
+ "10000", "100000", "1000000", "10000000", "100000000", "1000000000"
+ ]
}
private predicate trivialIntValue(string s) {
@@ -193,15 +44,7 @@ private predicate intTrivial(Literal lit) {
}
private predicate powerOfTen(float f) {
- f = 10 or
- f = 100 or
- f = 1000 or
- f = 10000 or
- f = 100000 or
- f = 1000000 or
- f = 10000000 or
- f = 100000000 or
- f = 1000000000
+ f = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]
}
private predicate floatTrivial(Literal lit) {
diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql
index be381328582..2bf51653d99 100644
--- a/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql
+++ b/csharp/ql/src/Bad Practices/Naming Conventions/DefaultControlNames.ql
@@ -13,16 +13,11 @@
import csharp
predicate controlName(string prefix) {
- prefix = "[Ll]abel" or
- prefix = "[Bb]utton" or
- prefix = "[Pp]anel" or
- prefix = "[Rr]adio[Bb]utton" or
- prefix = "[Pp]rop" or
- prefix = "[Ss]atus[Ss]trip" or
- prefix = "[Tt]able[Ll]ayout[Dd]esigner" or
- prefix = "[Tt]ext[Bb]ox" or
- prefix = "[Tt]ool[Ss]trip" or
- prefix = "[Pp]icture[Bb]ox"
+ prefix =
+ [
+ "[Ll]abel", "[Bb]utton", "[Pp]anel", "[Rr]adio[Bb]utton", "[Pp]rop", "[Ss]atus[Ss]trip",
+ "[Tt]able[Ll]ayout[Dd]esigner", "[Tt]ext[Bb]ox", "[Tt]ool[Ss]trip", "[Pp]icture[Bb]ox"
+ ]
}
predicate usedInHumanWrittenCode(Field f) {
diff --git a/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.ql b/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.ql
index f161edda6c4..cb778465df8 100644
--- a/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.ql
+++ b/csharp/ql/src/Bad Practices/Naming Conventions/VariableNameTooShort.ql
@@ -34,16 +34,7 @@ select variable, "Variable name '" + name + "' is too short."
// Adjustable: acceptable short names
//
predicate allowedName(string name) {
- name = "url" or
- name = "cmd" or
- name = "UK" or
- name = "uri" or
- name = "top" or
- name = "row" or
- name = "pin" or
- name = "log" or
- name = "key" or
- name = "_"
+ name = ["url", "cmd", "UK", "uri", "top", "row", "pin", "log", "key", "_"]
}
//
diff --git a/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql b/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql
index 1064a76c2e0..4612091743f 100644
--- a/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql
+++ b/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql
@@ -37,21 +37,11 @@ Expr getADelegateExpr(Callable c) {
*/
predicate nonEscapingCall(Call c) {
exists(string name | c.getTarget().hasName(name) |
- name = "ForEach" or
- name = "Count" or
- name = "Any" or
- name = "All" or
- name = "Average" or
- name = "Aggregate" or
- name = "First" or
- name = "Last" or
- name = "FirstOrDefault" or
- name = "LastOrDefault" or
- name = "LongCount" or
- name = "Max" or
- name = "Single" or
- name = "SingleOrDefault" or
- name = "Sum"
+ name =
+ [
+ "ForEach", "Count", "Any", "All", "Average", "Aggregate", "First", "Last", "FirstOrDefault",
+ "LastOrDefault", "LongCount", "Max", "Single", "SingleOrDefault", "Sum"
+ ]
)
}
@@ -72,7 +62,8 @@ predicate mayEscape(LocalVariable v) {
class RelevantDefinition extends AssignableDefinition {
RelevantDefinition() {
- this instanceof AssignableDefinitions::AssignmentDefinition
+ this.(AssignableDefinitions::AssignmentDefinition).getAssignment() =
+ any(Assignment a | not a = any(UsingDeclStmt uds).getAVariableDeclExpr())
or
this instanceof AssignableDefinitions::MutationDefinition
or
@@ -115,12 +106,7 @@ class RelevantDefinition extends AssignableDefinition {
private predicate isDefaultLikeInitializer() {
this.isInitializer() and
exists(Expr e | e = this.getSource().stripCasts() |
- exists(string val | val = e.getValue() |
- val = "0" or
- val = "-1" or
- val = "" or
- val = "false"
- )
+ e.getValue() = ["0", "-1", "", "false"]
or
e instanceof NullLiteral
or
diff --git a/csharp/ql/src/Diagnostics/DiagnosticExtractionErrors.ql b/csharp/ql/src/Diagnostics/DiagnosticExtractionErrors.ql
index 23943d8491f..e9e2a42bfa8 100644
--- a/csharp/ql/src/Diagnostics/DiagnosticExtractionErrors.ql
+++ b/csharp/ql/src/Diagnostics/DiagnosticExtractionErrors.ql
@@ -21,8 +21,8 @@ abstract private class DiagnosticError extends TDiagnosticError {
abstract Location getLocation();
string getLocationMessage() {
- if getLocation().getFile().fromSource()
- then result = " in " + getLocation().getFile()
+ if this.getLocation().getFile().fromSource()
+ then result = " in " + this.getLocation().getFile()
else result = ""
}
}
diff --git a/csharp/ql/src/Stubs/Stubs.qll b/csharp/ql/src/Stubs/Stubs.qll
index 6f92fb12f55..e0c009b8783 100644
--- a/csharp/ql/src/Stubs/Stubs.qll
+++ b/csharp/ql/src/Stubs/Stubs.qll
@@ -128,6 +128,7 @@ abstract private class GeneratedType extends Type, GeneratedElement {
/** Gets the entire C# stub code for this type. */
pragma[nomagic]
final string getStub(Assembly assembly) {
+ this.isInAssembly(assembly) and
if this.isDuplicate(assembly)
then
result =
@@ -161,7 +162,7 @@ abstract private class GeneratedType extends Type, GeneratedElement {
if this instanceof Enum
then result = ""
else
- if exists(getAnInterestingBaseType())
+ if exists(this.getAnInterestingBaseType())
then
result =
" : " +
@@ -220,15 +221,15 @@ abstract private class GeneratedType extends Type, GeneratedElement {
}
final Type getAGeneratedType() {
- result = getAnInterestingBaseType()
+ result = this.getAnInterestingBaseType()
or
- result = getAGeneratedMember().(Callable).getReturnType()
+ result = this.getAGeneratedMember().(Callable).getReturnType()
or
- result = getAGeneratedMember().(Callable).getAParameter().getType()
+ result = this.getAGeneratedMember().(Callable).getAParameter().getType()
or
- result = getAGeneratedMember().(Property).getType()
+ result = this.getAGeneratedMember().(Property).getType()
or
- result = getAGeneratedMember().(Field).getType()
+ result = this.getAGeneratedMember().(Field).getType()
}
}
@@ -331,7 +332,8 @@ private class GeneratedNamespace extends Namespace, GeneratedElement {
final string getStubs(Assembly assembly) {
result =
- getPreamble() + getTypeStubs(assembly) + getSubNamespaceStubs(assembly) + getPostAmble()
+ this.getPreamble() + this.getTypeStubs(assembly) + this.getSubNamespaceStubs(assembly) +
+ this.getPostAmble()
}
/** Gets the `n`th generated child namespace, indexed from 0. */
@@ -358,7 +360,7 @@ private class GeneratedNamespace extends Namespace, GeneratedElement {
this.isInAssembly(assembly) and
result =
concat(GeneratedNamespace child, int i |
- child = getChildNamespace(i) and child.isInAssembly(assembly)
+ child = this.getChildNamespace(i) and child.isInAssembly(assembly)
|
child.getStubs(assembly) order by i
)
@@ -612,83 +614,18 @@ private string stubImplementation(Virtualizable c) {
}
private predicate isKeyword(string s) {
- s = "abstract" or
- s = "as" or
- s = "base" or
- s = "bool" or
- s = "break" or
- s = "byte" or
- s = "case" or
- s = "catch" or
- s = "char" or
- s = "checked" or
- s = "class" or
- s = "const" or
- s = "continue" or
- s = "decimal" or
- s = "default" or
- s = "delegate" or
- s = "do" or
- s = "double" or
- s = "else" or
- s = "enum" or
- s = "event" or
- s = "explicit" or
- s = "extern" or
- s = "false" or
- s = "finally" or
- s = "fixed" or
- s = "float" or
- s = "for" or
- s = "foreach" or
- s = "goto" or
- s = "if" or
- s = "implicit" or
- s = "in" or
- s = "int" or
- s = "interface" or
- s = "internal" or
- s = "is" or
- s = "lock" or
- s = "long" or
- s = "namespace" or
- s = "new" or
- s = "null" or
- s = "object" or
- s = "operator" or
- s = "out" or
- s = "override" or
- s = "params" or
- s = "private" or
- s = "protected" or
- s = "public" or
- s = "readonly" or
- s = "ref" or
- s = "return" or
- s = "sbyte" or
- s = "sealed" or
- s = "short" or
- s = "sizeof" or
- s = "stackalloc" or
- s = "static" or
- s = "string" or
- s = "struct" or
- s = "switch" or
- s = "this" or
- s = "throw" or
- s = "true" or
- s = "try" or
- s = "typeof" or
- s = "uint" or
- s = "ulong" or
- s = "unchecked" or
- s = "unsafe" or
- s = "ushort" or
- s = "using" or
- s = "virtual" or
- s = "void" or
- s = "volatile" or
- s = "while"
+ s =
+ [
+ "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked",
+ "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else",
+ "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach",
+ "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long",
+ "namespace", "new", "null", "object", "operator", "out", "override", "params", "private",
+ "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof",
+ "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try",
+ "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void",
+ "volatile", "while"
+ ]
}
bindingset[s]
diff --git a/csharp/ql/src/definitions.qll b/csharp/ql/src/definitions.qll
index ade40435e18..559bc0d3908 100644
--- a/csharp/ql/src/definitions.qll
+++ b/csharp/ql/src/definitions.qll
@@ -13,7 +13,7 @@ abstract class Use extends @type_mention_parent {
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
- * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll
index 4b86f9a7cec..bb8630a5e0c 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/IRBlock.qll
@@ -24,7 +24,7 @@ class IRBlockBase extends TIRBlock {
final string toString() { result = getFirstInstruction(this).toString() }
/** Gets the source location of the first non-`Phi` instruction in this block. */
- final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
+ final Language::Location getLocation() { result = this.getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
@@ -39,7 +39,7 @@ class IRBlockBase extends TIRBlock {
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
- funcBlock.getEnclosingFunction() = getEnclosingFunction() and
+ funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
@@ -59,15 +59,15 @@ class IRBlockBase extends TIRBlock {
* Get the `Phi` instructions that appear at the start of this block.
*/
final PhiInstruction getAPhiInstruction() {
- Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
+ Construction::getPhiInstructionBlockStart(result) = this.getFirstInstruction()
}
/**
* Gets an instruction in this block. This includes `Phi` instructions.
*/
final Instruction getAnInstruction() {
- result = getInstruction(_) or
- result = getAPhiInstruction()
+ result = this.getInstruction(_) or
+ result = this.getAPhiInstruction()
}
/**
@@ -78,7 +78,9 @@ class IRBlockBase extends TIRBlock {
/**
* Gets the last instruction in this block.
*/
- final Instruction getLastInstruction() { result = getInstruction(getInstructionCount() - 1) }
+ final Instruction getLastInstruction() {
+ result = this.getInstruction(this.getInstructionCount() - 1)
+ }
/**
* Gets the number of non-`Phi` instructions in this block.
@@ -149,7 +151,7 @@ class IRBlock extends IRBlockBase {
* Block `A` dominates block `B` if any control flow path from the entry block of the function to
* block `B` must pass through block `A`. A block always dominates itself.
*/
- final predicate dominates(IRBlock block) { strictlyDominates(block) or this = block }
+ final predicate dominates(IRBlock block) { this.strictlyDominates(block) or this = block }
/**
* Gets a block on the dominance frontier of this block.
@@ -159,8 +161,8 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock dominanceFrontier() {
- dominates(result.getAPredecessor()) and
- not strictlyDominates(result)
+ this.dominates(result.getAPredecessor()) and
+ not this.strictlyDominates(result)
}
/**
@@ -189,7 +191,7 @@ class IRBlock extends IRBlockBase {
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
- final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
+ final predicate postDominates(IRBlock block) { this.strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
@@ -199,16 +201,16 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
- postDominates(result.getASuccessor()) and
- not strictlyPostDominates(result)
+ this.postDominates(result.getASuccessor()) and
+ not this.strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
final predicate isReachableFromFunctionEntry() {
- this = getEnclosingIRFunction().getEntryBlock() or
- getAPredecessor().isReachableFromFunctionEntry()
+ this = this.getEnclosingIRFunction().getEntryBlock() or
+ this.getAPredecessor().isReachableFromFunctionEntry()
}
}
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll
index 2fb3edad602..88a973fc5a8 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll
@@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction {
}
/** Gets a textual representation of this element. */
- final string toString() { result = getOpcode().toString() + ": " + getAST().toString() }
+ final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() }
/**
* Gets a string showing the result, opcode, and operands of the instruction, equivalent to what
@@ -50,7 +50,8 @@ class Instruction extends Construction::TStageInstruction {
* `mu0_28(int) = Store r0_26, r0_27`
*/
final string getDumpString() {
- result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
+ result =
+ this.getResultString() + " = " + this.getOperationString() + " " + this.getOperandsString()
}
private predicate shouldGenerateDumpStrings() {
@@ -66,10 +67,13 @@ class Instruction extends Construction::TStageInstruction {
* VariableAddress[x]
*/
final string getOperationString() {
- shouldGenerateDumpStrings() and
- if exists(getImmediateString())
- then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
- else result = getOperationPrefix() + getOpcode().toString()
+ this.shouldGenerateDumpStrings() and
+ if exists(this.getImmediateString())
+ then
+ result =
+ this.getOperationPrefix() + this.getOpcode().toString() + "[" + this.getImmediateString() +
+ "]"
+ else result = this.getOperationPrefix() + this.getOpcode().toString()
}
/**
@@ -78,17 +82,17 @@ class Instruction extends Construction::TStageInstruction {
string getImmediateString() { none() }
private string getOperationPrefix() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = ""
}
private string getResultPrefix() {
- shouldGenerateDumpStrings() and
- if getResultIRType() instanceof IRVoidType
+ this.shouldGenerateDumpStrings() and
+ if this.getResultIRType() instanceof IRVoidType
then result = "v"
else
- if hasMemoryResult()
- then if isResultModeled() then result = "m" else result = "mu"
+ if this.hasMemoryResult()
+ then if this.isResultModeled() then result = "m" else result = "mu"
else result = "r"
}
@@ -97,7 +101,7 @@ class Instruction extends Construction::TStageInstruction {
* used by debugging and printing code only.
*/
int getDisplayIndexInBlock() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
exists(IRBlock block |
this = block.getInstruction(result)
or
@@ -111,12 +115,12 @@ class Instruction extends Construction::TStageInstruction {
}
private int getLineRank() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
this =
rank[result](Instruction instr |
instr =
- getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
- getLocation().getStartLine())
+ getAnInstructionAtLine(this.getEnclosingIRFunction(), this.getLocation().getFile(),
+ this.getLocation().getStartLine())
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
@@ -130,8 +134,9 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1`
*/
string getResultId() {
- shouldGenerateDumpStrings() and
- result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
+ this.shouldGenerateDumpStrings() and
+ result =
+ this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank()
}
/**
@@ -142,8 +147,8 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1(int*)`
*/
final string getResultString() {
- shouldGenerateDumpStrings() and
- result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
+ this.shouldGenerateDumpStrings() and
+ result = this.getResultId() + "(" + this.getResultLanguageType().getDumpString() + ")"
}
/**
@@ -153,10 +158,10 @@ class Instruction extends Construction::TStageInstruction {
* Example: `func:r3_4, this:r3_5`
*/
string getOperandsString() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
result =
concat(Operand operand |
- operand = getAnOperand()
+ operand = this.getAnOperand()
|
operand.getDumpString(), ", " order by operand.getDumpSortOrder()
)
@@ -190,7 +195,7 @@ class Instruction extends Construction::TStageInstruction {
* Gets the function that contains this instruction.
*/
final Language::Function getEnclosingFunction() {
- result = getEnclosingIRFunction().getFunction()
+ result = this.getEnclosingIRFunction().getFunction()
}
/**
@@ -208,7 +213,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the location of the source code for this instruction.
*/
- final Language::Location getLocation() { result = getAST().getLocation() }
+ final Language::Location getLocation() { result = this.getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
@@ -243,7 +248,7 @@ class Instruction extends Construction::TStageInstruction {
* a result, its result type will be `IRVoidType`.
*/
cached
- final IRType getResultIRType() { result = getResultLanguageType().getIRType() }
+ final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() }
/**
* Gets the type of the result produced by this instruction. If the
@@ -254,7 +259,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final Language::Type getResultType() {
exists(Language::LanguageType resultType |
- resultType = getResultLanguageType() and
+ resultType = this.getResultLanguageType() and
(
resultType.hasUnspecifiedType(result, _)
or
@@ -283,7 +288,7 @@ class Instruction extends Construction::TStageInstruction {
* result of the `Load` instruction is a prvalue of type `int`, representing
* the integer value loaded from variable `x`.
*/
- final predicate isGLValue() { getResultLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getResultLanguageType().hasType(_, true) }
/**
* Gets the size of the result produced by this instruction, in bytes. If the
@@ -292,7 +297,7 @@ class Instruction extends Construction::TStageInstruction {
* If `this.isGLValue()` holds for this instruction, the value of
* `getResultSize()` will always be the size of a pointer.
*/
- final int getResultSize() { result = getResultLanguageType().getByteSize() }
+ final int getResultSize() { result = this.getResultLanguageType().getByteSize() }
/**
* Gets the opcode that specifies the operation performed by this instruction.
@@ -314,14 +319,16 @@ class Instruction extends Construction::TStageInstruction {
/**
* Holds if this instruction produces a memory result.
*/
- final predicate hasMemoryResult() { exists(getResultMemoryAccess()) }
+ final predicate hasMemoryResult() { exists(this.getResultMemoryAccess()) }
/**
* Gets the kind of memory access performed by this instruction's result.
* Holds only for instructions with a memory result.
*/
pragma[inline]
- final MemoryAccessKind getResultMemoryAccess() { result = getOpcode().getWriteMemoryAccess() }
+ final MemoryAccessKind getResultMemoryAccess() {
+ result = this.getOpcode().getWriteMemoryAccess()
+ }
/**
* Holds if the memory access performed by this instruction's result will not always write to
@@ -332,7 +339,7 @@ class Instruction extends Construction::TStageInstruction {
* (for example, the global side effects of a function call).
*/
pragma[inline]
- final predicate hasResultMayMemoryAccess() { getOpcode().hasMayWriteMemoryAccess() }
+ final predicate hasResultMayMemoryAccess() { this.getOpcode().hasMayWriteMemoryAccess() }
/**
* Gets the operand that holds the memory address to which this instruction stores its
@@ -340,7 +347,7 @@ class Instruction extends Construction::TStageInstruction {
* is `r1`.
*/
final AddressOperand getResultAddressOperand() {
- getResultMemoryAccess().usesAddressOperand() and
+ this.getResultMemoryAccess().usesAddressOperand() and
result.getUse() = this
}
@@ -349,7 +356,7 @@ class Instruction extends Construction::TStageInstruction {
* result, if any. For example, in `m3 = Store r1, r2`, the result of `getResultAddressOperand()`
* is the instruction that defines `r1`.
*/
- final Instruction getResultAddress() { result = getResultAddressOperand().getDef() }
+ final Instruction getResultAddress() { result = this.getResultAddressOperand().getDef() }
/**
* Holds if the result of this instruction is precisely modeled in SSA. Always
@@ -368,7 +375,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final predicate isResultModeled() {
// Register results are always in SSA form.
- not hasMemoryResult() or
+ not this.hasMemoryResult() or
Construction::hasModeledMemoryResult(this)
}
@@ -412,7 +419,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct successors of this instruction.
*/
- final Instruction getASuccessor() { result = getSuccessor(_) }
+ final Instruction getASuccessor() { result = this.getSuccessor(_) }
/**
* Gets a predecessor of this instruction such that the predecessor reaches
@@ -423,7 +430,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct predecessors of this instruction.
*/
- final Instruction getAPredecessor() { result = getPredecessor(_) }
+ final Instruction getAPredecessor() { result = this.getPredecessor(_) }
}
/**
@@ -543,7 +550,7 @@ class IndexedInstruction extends Instruction {
* at this instruction. This instruction has no predecessors.
*/
class EnterFunctionInstruction extends Instruction {
- EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
+ EnterFunctionInstruction() { this.getOpcode() instanceof Opcode::EnterFunction }
}
/**
@@ -554,7 +561,7 @@ class EnterFunctionInstruction extends Instruction {
* struct, or union, see `FieldAddressInstruction`.
*/
class VariableAddressInstruction extends VariableInstruction {
- VariableAddressInstruction() { getOpcode() instanceof Opcode::VariableAddress }
+ VariableAddressInstruction() { this.getOpcode() instanceof Opcode::VariableAddress }
}
/**
@@ -566,7 +573,7 @@ class VariableAddressInstruction extends VariableInstruction {
* The result has an `IRFunctionAddress` type.
*/
class FunctionAddressInstruction extends FunctionInstruction {
- FunctionAddressInstruction() { getOpcode() instanceof Opcode::FunctionAddress }
+ FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
/**
@@ -577,7 +584,7 @@ class FunctionAddressInstruction extends FunctionInstruction {
* initializes that parameter.
*/
class InitializeParameterInstruction extends VariableInstruction {
- InitializeParameterInstruction() { getOpcode() instanceof Opcode::InitializeParameter }
+ InitializeParameterInstruction() { this.getOpcode() instanceof Opcode::InitializeParameter }
/**
* Gets the parameter initialized by this instruction.
@@ -603,7 +610,7 @@ class InitializeParameterInstruction extends VariableInstruction {
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
- InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
+ InitializeNonLocalInstruction() { this.getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
@@ -611,7 +618,7 @@ class InitializeNonLocalInstruction extends Instruction {
* with the value of that memory on entry to the function.
*/
class InitializeIndirectionInstruction extends VariableInstruction {
- InitializeIndirectionInstruction() { getOpcode() instanceof Opcode::InitializeIndirection }
+ InitializeIndirectionInstruction() { this.getOpcode() instanceof Opcode::InitializeIndirection }
/**
* Gets the parameter initialized by this instruction.
@@ -635,24 +642,24 @@ class InitializeIndirectionInstruction extends VariableInstruction {
* An instruction that initializes the `this` pointer parameter of the enclosing function.
*/
class InitializeThisInstruction extends Instruction {
- InitializeThisInstruction() { getOpcode() instanceof Opcode::InitializeThis }
+ InitializeThisInstruction() { this.getOpcode() instanceof Opcode::InitializeThis }
}
/**
* An instruction that computes the address of a non-static field of an object.
*/
class FieldAddressInstruction extends FieldInstruction {
- FieldAddressInstruction() { getOpcode() instanceof Opcode::FieldAddress }
+ FieldAddressInstruction() { this.getOpcode() instanceof Opcode::FieldAddress }
/**
* Gets the operand that provides the address of the object containing the field.
*/
- final UnaryOperand getObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the object containing the field.
*/
- final Instruction getObjectAddress() { result = getObjectAddressOperand().getDef() }
+ final Instruction getObjectAddress() { result = this.getObjectAddressOperand().getDef() }
}
/**
@@ -661,17 +668,19 @@ class FieldAddressInstruction extends FieldInstruction {
* This instruction is used for element access to C# arrays.
*/
class ElementsAddressInstruction extends UnaryInstruction {
- ElementsAddressInstruction() { getOpcode() instanceof Opcode::ElementsAddress }
+ ElementsAddressInstruction() { this.getOpcode() instanceof Opcode::ElementsAddress }
/**
* Gets the operand that provides the address of the array object.
*/
- final UnaryOperand getArrayObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getArrayObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the array object.
*/
- final Instruction getArrayObjectAddress() { result = getArrayObjectAddressOperand().getDef() }
+ final Instruction getArrayObjectAddress() {
+ result = this.getArrayObjectAddressOperand().getDef()
+ }
}
/**
@@ -685,7 +694,7 @@ class ElementsAddressInstruction extends UnaryInstruction {
* taken may want to ignore any function that contains an `ErrorInstruction`.
*/
class ErrorInstruction extends Instruction {
- ErrorInstruction() { getOpcode() instanceof Opcode::Error }
+ ErrorInstruction() { this.getOpcode() instanceof Opcode::Error }
}
/**
@@ -695,7 +704,7 @@ class ErrorInstruction extends Instruction {
* an initializer, or whose initializer only partially initializes the variable.
*/
class UninitializedInstruction extends VariableInstruction {
- UninitializedInstruction() { getOpcode() instanceof Opcode::Uninitialized }
+ UninitializedInstruction() { this.getOpcode() instanceof Opcode::Uninitialized }
/**
* Gets the variable that is uninitialized.
@@ -710,7 +719,7 @@ class UninitializedInstruction extends VariableInstruction {
* least one instruction, even when the AST has no semantic effect.
*/
class NoOpInstruction extends Instruction {
- NoOpInstruction() { getOpcode() instanceof Opcode::NoOp }
+ NoOpInstruction() { this.getOpcode() instanceof Opcode::NoOp }
}
/**
@@ -732,32 +741,32 @@ class NoOpInstruction extends Instruction {
* `void`-returning function.
*/
class ReturnInstruction extends Instruction {
- ReturnInstruction() { getOpcode() instanceof ReturnOpcode }
+ ReturnInstruction() { this.getOpcode() instanceof ReturnOpcode }
}
/**
* An instruction that returns control to the caller of the function, without returning a value.
*/
class ReturnVoidInstruction extends ReturnInstruction {
- ReturnVoidInstruction() { getOpcode() instanceof Opcode::ReturnVoid }
+ ReturnVoidInstruction() { this.getOpcode() instanceof Opcode::ReturnVoid }
}
/**
* An instruction that returns control to the caller of the function, including a return value.
*/
class ReturnValueInstruction extends ReturnInstruction {
- ReturnValueInstruction() { getOpcode() instanceof Opcode::ReturnValue }
+ ReturnValueInstruction() { this.getOpcode() instanceof Opcode::ReturnValue }
/**
* Gets the operand that provides the value being returned by the function.
*/
- final LoadOperand getReturnValueOperand() { result = getAnOperand() }
+ final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available.
*/
- final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
+ final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
}
/**
@@ -770,28 +779,28 @@ class ReturnValueInstruction extends ReturnInstruction {
* that the caller initialized the memory pointed to by the parameter before the call.
*/
class ReturnIndirectionInstruction extends VariableInstruction {
- ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
+ ReturnIndirectionInstruction() { this.getOpcode() instanceof Opcode::ReturnIndirection }
/**
* Gets the operand that provides the value of the pointed-to memory.
*/
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the pointed-to memory, if an exact
* definition is available.
*/
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/**
* Gets the operand that provides the address of the pointed-to memory.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the pointed-to memory.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
/**
* Gets the parameter for which this instruction reads the final pointed-to value within the
@@ -821,12 +830,12 @@ class ReturnIndirectionInstruction extends VariableInstruction {
*
* There are several different copy instructions, depending on the source and destination of the
* copy operation:
- * - `CopyInstruction` - Copies a register operand to a register result.
+ * - `CopyValueInstruction` - Copies a register operand to a register result.
* - `LoadInstruction` - Copies a memory operand to a register result.
* - `StoreInstruction` - Copies a register operand to a memory result.
*/
class CopyInstruction extends Instruction {
- CopyInstruction() { getOpcode() instanceof CopyOpcode }
+ CopyInstruction() { this.getOpcode() instanceof CopyOpcode }
/**
* Gets the operand that provides the input value of the copy.
@@ -837,16 +846,16 @@ class CopyInstruction extends Instruction {
* Gets the instruction whose result provides the input value of the copy, if an exact definition
* is available.
*/
- final Instruction getSourceValue() { result = getSourceValueOperand().getDef() }
+ final Instruction getSourceValue() { result = this.getSourceValueOperand().getDef() }
}
/**
* An instruction that returns a register result containing a copy of its register operand.
*/
class CopyValueInstruction extends CopyInstruction, UnaryInstruction {
- CopyValueInstruction() { getOpcode() instanceof Opcode::CopyValue }
+ CopyValueInstruction() { this.getOpcode() instanceof Opcode::CopyValue }
- final override UnaryOperand getSourceValueOperand() { result = getAnOperand() }
+ final override UnaryOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -863,47 +872,49 @@ private string getAddressOperandDescription(AddressOperand operand) {
* An instruction that returns a register result containing a copy of its memory operand.
*/
class LoadInstruction extends CopyInstruction {
- LoadInstruction() { getOpcode() instanceof Opcode::Load }
+ LoadInstruction() { this.getOpcode() instanceof Opcode::Load }
final override string getImmediateString() {
- result = getAddressOperandDescription(getSourceAddressOperand())
+ result = getAddressOperandDescription(this.getSourceAddressOperand())
}
/**
* Gets the operand that provides the address of the value being loaded.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the value being loaded.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
- final override LoadOperand getSourceValueOperand() { result = getAnOperand() }
+ final override LoadOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
* An instruction that returns a memory result containing a copy of its register operand.
*/
class StoreInstruction extends CopyInstruction {
- StoreInstruction() { getOpcode() instanceof Opcode::Store }
+ StoreInstruction() { this.getOpcode() instanceof Opcode::Store }
final override string getImmediateString() {
- result = getAddressOperandDescription(getDestinationAddressOperand())
+ result = getAddressOperandDescription(this.getDestinationAddressOperand())
}
/**
* Gets the operand that provides the address of the location to which the value will be stored.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the location to which the value will
* be stored, if an exact definition is available.
*/
- final Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ final Instruction getDestinationAddress() {
+ result = this.getDestinationAddressOperand().getDef()
+ }
- final override StoreValueOperand getSourceValueOperand() { result = getAnOperand() }
+ final override StoreValueOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -911,27 +922,27 @@ class StoreInstruction extends CopyInstruction {
* operand.
*/
class ConditionalBranchInstruction extends Instruction {
- ConditionalBranchInstruction() { getOpcode() instanceof Opcode::ConditionalBranch }
+ ConditionalBranchInstruction() { this.getOpcode() instanceof Opcode::ConditionalBranch }
/**
* Gets the operand that provides the Boolean condition controlling the branch.
*/
- final ConditionOperand getConditionOperand() { result = getAnOperand() }
+ final ConditionOperand getConditionOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the Boolean condition controlling the branch.
*/
- final Instruction getCondition() { result = getConditionOperand().getDef() }
+ final Instruction getCondition() { result = this.getConditionOperand().getDef() }
/**
* Gets the instruction to which control will flow if the condition is true.
*/
- final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }
+ final Instruction getTrueSuccessor() { result = this.getSuccessor(EdgeKind::trueEdge()) }
/**
* Gets the instruction to which control will flow if the condition is false.
*/
- final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
+ final Instruction getFalseSuccessor() { result = this.getSuccessor(EdgeKind::falseEdge()) }
}
/**
@@ -943,14 +954,14 @@ class ConditionalBranchInstruction extends Instruction {
* successors.
*/
class ExitFunctionInstruction extends Instruction {
- ExitFunctionInstruction() { getOpcode() instanceof Opcode::ExitFunction }
+ ExitFunctionInstruction() { this.getOpcode() instanceof Opcode::ExitFunction }
}
/**
* An instruction whose result is a constant value.
*/
class ConstantInstruction extends ConstantValueInstruction {
- ConstantInstruction() { getOpcode() instanceof Opcode::Constant }
+ ConstantInstruction() { this.getOpcode() instanceof Opcode::Constant }
}
/**
@@ -959,7 +970,7 @@ class ConstantInstruction extends ConstantValueInstruction {
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
exists(IRType resultType |
- resultType = getResultIRType() and
+ resultType = this.getResultIRType() and
(resultType instanceof IRIntegerType or resultType instanceof IRBooleanType)
)
}
@@ -969,7 +980,7 @@ class IntegerConstantInstruction extends ConstantInstruction {
* An instruction whose result is a constant value of floating-point type.
*/
class FloatConstantInstruction extends ConstantInstruction {
- FloatConstantInstruction() { getResultIRType() instanceof IRFloatingPointType }
+ FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType }
}
/**
@@ -978,7 +989,9 @@ class FloatConstantInstruction extends ConstantInstruction {
class StringConstantInstruction extends VariableInstruction {
override IRStringLiteral var;
- final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) }
+ final override string getImmediateString() {
+ result = Language::getStringLiteralText(this.getValue())
+ }
/**
* Gets the string literal whose address is returned by this instruction.
@@ -990,37 +1003,37 @@ class StringConstantInstruction extends VariableInstruction {
* An instruction whose result is computed from two operands.
*/
class BinaryInstruction extends Instruction {
- BinaryInstruction() { getOpcode() instanceof BinaryOpcode }
+ BinaryInstruction() { this.getOpcode() instanceof BinaryOpcode }
/**
* Gets the left operand of this binary instruction.
*/
- final LeftOperand getLeftOperand() { result = getAnOperand() }
+ final LeftOperand getLeftOperand() { result = this.getAnOperand() }
/**
* Gets the right operand of this binary instruction.
*/
- final RightOperand getRightOperand() { result = getAnOperand() }
+ final RightOperand getRightOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the left operand of this binary
* instruction.
*/
- final Instruction getLeft() { result = getLeftOperand().getDef() }
+ final Instruction getLeft() { result = this.getLeftOperand().getDef() }
/**
* Gets the instruction whose result provides the value of the right operand of this binary
* instruction.
*/
- final Instruction getRight() { result = getRightOperand().getDef() }
+ final Instruction getRight() { result = this.getRightOperand().getDef() }
/**
* Holds if this instruction's operands are `op1` and `op2`, in either order.
*/
final predicate hasOperands(Operand op1, Operand op2) {
- op1 = getLeftOperand() and op2 = getRightOperand()
+ op1 = this.getLeftOperand() and op2 = this.getRightOperand()
or
- op1 = getRightOperand() and op2 = getLeftOperand()
+ op1 = this.getRightOperand() and op2 = this.getLeftOperand()
}
}
@@ -1028,7 +1041,7 @@ class BinaryInstruction extends Instruction {
* An instruction that computes the result of an arithmetic operation.
*/
class ArithmeticInstruction extends Instruction {
- ArithmeticInstruction() { getOpcode() instanceof ArithmeticOpcode }
+ ArithmeticInstruction() { this.getOpcode() instanceof ArithmeticOpcode }
}
/**
@@ -1050,7 +1063,7 @@ class UnaryArithmeticInstruction extends ArithmeticInstruction, UnaryInstruction
* performed according to IEEE-754.
*/
class AddInstruction extends BinaryArithmeticInstruction {
- AddInstruction() { getOpcode() instanceof Opcode::Add }
+ AddInstruction() { this.getOpcode() instanceof Opcode::Add }
}
/**
@@ -1061,7 +1074,7 @@ class AddInstruction extends BinaryArithmeticInstruction {
* according to IEEE-754.
*/
class SubInstruction extends BinaryArithmeticInstruction {
- SubInstruction() { getOpcode() instanceof Opcode::Sub }
+ SubInstruction() { this.getOpcode() instanceof Opcode::Sub }
}
/**
@@ -1072,7 +1085,7 @@ class SubInstruction extends BinaryArithmeticInstruction {
* performed according to IEEE-754.
*/
class MulInstruction extends BinaryArithmeticInstruction {
- MulInstruction() { getOpcode() instanceof Opcode::Mul }
+ MulInstruction() { this.getOpcode() instanceof Opcode::Mul }
}
/**
@@ -1083,7 +1096,7 @@ class MulInstruction extends BinaryArithmeticInstruction {
* to IEEE-754.
*/
class DivInstruction extends BinaryArithmeticInstruction {
- DivInstruction() { getOpcode() instanceof Opcode::Div }
+ DivInstruction() { this.getOpcode() instanceof Opcode::Div }
}
/**
@@ -1093,7 +1106,7 @@ class DivInstruction extends BinaryArithmeticInstruction {
* division by zero or integer overflow is undefined.
*/
class RemInstruction extends BinaryArithmeticInstruction {
- RemInstruction() { getOpcode() instanceof Opcode::Rem }
+ RemInstruction() { this.getOpcode() instanceof Opcode::Rem }
}
/**
@@ -1104,14 +1117,14 @@ class RemInstruction extends BinaryArithmeticInstruction {
* is performed according to IEEE-754.
*/
class NegateInstruction extends UnaryArithmeticInstruction {
- NegateInstruction() { getOpcode() instanceof Opcode::Negate }
+ NegateInstruction() { this.getOpcode() instanceof Opcode::Negate }
}
/**
* An instruction that computes the result of a bitwise operation.
*/
class BitwiseInstruction extends Instruction {
- BitwiseInstruction() { getOpcode() instanceof BitwiseOpcode }
+ BitwiseInstruction() { this.getOpcode() instanceof BitwiseOpcode }
}
/**
@@ -1130,7 +1143,7 @@ class UnaryBitwiseInstruction extends BitwiseInstruction, UnaryInstruction { }
* Both operands must have the same integer type, which will also be the result type.
*/
class BitAndInstruction extends BinaryBitwiseInstruction {
- BitAndInstruction() { getOpcode() instanceof Opcode::BitAnd }
+ BitAndInstruction() { this.getOpcode() instanceof Opcode::BitAnd }
}
/**
@@ -1139,7 +1152,7 @@ class BitAndInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitOrInstruction extends BinaryBitwiseInstruction {
- BitOrInstruction() { getOpcode() instanceof Opcode::BitOr }
+ BitOrInstruction() { this.getOpcode() instanceof Opcode::BitOr }
}
/**
@@ -1148,7 +1161,7 @@ class BitOrInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitXorInstruction extends BinaryBitwiseInstruction {
- BitXorInstruction() { getOpcode() instanceof Opcode::BitXor }
+ BitXorInstruction() { this.getOpcode() instanceof Opcode::BitXor }
}
/**
@@ -1159,7 +1172,7 @@ class BitXorInstruction extends BinaryBitwiseInstruction {
* rightmost bits are zero-filled.
*/
class ShiftLeftInstruction extends BinaryBitwiseInstruction {
- ShiftLeftInstruction() { getOpcode() instanceof Opcode::ShiftLeft }
+ ShiftLeftInstruction() { this.getOpcode() instanceof Opcode::ShiftLeft }
}
/**
@@ -1172,7 +1185,7 @@ class ShiftLeftInstruction extends BinaryBitwiseInstruction {
* of the left operand.
*/
class ShiftRightInstruction extends BinaryBitwiseInstruction {
- ShiftRightInstruction() { getOpcode() instanceof Opcode::ShiftRight }
+ ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
@@ -1183,7 +1196,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
int elementSize;
PointerArithmeticInstruction() {
- getOpcode() instanceof PointerArithmeticOpcode and
+ this.getOpcode() instanceof PointerArithmeticOpcode and
elementSize = Raw::getInstructionElementSize(this)
}
@@ -1206,7 +1219,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
* An instruction that adds or subtracts an integer offset from a pointer.
*/
class PointerOffsetInstruction extends PointerArithmeticInstruction {
- PointerOffsetInstruction() { getOpcode() instanceof PointerOffsetOpcode }
+ PointerOffsetInstruction() { this.getOpcode() instanceof PointerOffsetOpcode }
}
/**
@@ -1217,7 +1230,7 @@ class PointerOffsetInstruction extends PointerArithmeticInstruction {
* overflow is undefined.
*/
class PointerAddInstruction extends PointerOffsetInstruction {
- PointerAddInstruction() { getOpcode() instanceof Opcode::PointerAdd }
+ PointerAddInstruction() { this.getOpcode() instanceof Opcode::PointerAdd }
}
/**
@@ -1228,7 +1241,7 @@ class PointerAddInstruction extends PointerOffsetInstruction {
* pointer underflow is undefined.
*/
class PointerSubInstruction extends PointerOffsetInstruction {
- PointerSubInstruction() { getOpcode() instanceof Opcode::PointerSub }
+ PointerSubInstruction() { this.getOpcode() instanceof Opcode::PointerSub }
}
/**
@@ -1241,31 +1254,31 @@ class PointerSubInstruction extends PointerOffsetInstruction {
* undefined.
*/
class PointerDiffInstruction extends PointerArithmeticInstruction {
- PointerDiffInstruction() { getOpcode() instanceof Opcode::PointerDiff }
+ PointerDiffInstruction() { this.getOpcode() instanceof Opcode::PointerDiff }
}
/**
* An instruction whose result is computed from a single operand.
*/
class UnaryInstruction extends Instruction {
- UnaryInstruction() { getOpcode() instanceof UnaryOpcode }
+ UnaryInstruction() { this.getOpcode() instanceof UnaryOpcode }
/**
* Gets the sole operand of this instruction.
*/
- final UnaryOperand getUnaryOperand() { result = getAnOperand() }
+ final UnaryOperand getUnaryOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the sole operand of this instruction.
*/
- final Instruction getUnary() { result = getUnaryOperand().getDef() }
+ final Instruction getUnary() { result = this.getUnaryOperand().getDef() }
}
/**
* An instruction that converts the value of its operand to a value of a different type.
*/
class ConvertInstruction extends UnaryInstruction {
- ConvertInstruction() { getOpcode() instanceof Opcode::Convert }
+ ConvertInstruction() { this.getOpcode() instanceof Opcode::Convert }
}
/**
@@ -1279,7 +1292,7 @@ class ConvertInstruction extends UnaryInstruction {
* `as` expression.
*/
class CheckedConvertOrNullInstruction extends UnaryInstruction {
- CheckedConvertOrNullInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrNull }
+ CheckedConvertOrNullInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrNull }
}
/**
@@ -1293,7 +1306,7 @@ class CheckedConvertOrNullInstruction extends UnaryInstruction {
* expression.
*/
class CheckedConvertOrThrowInstruction extends UnaryInstruction {
- CheckedConvertOrThrowInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrThrow }
+ CheckedConvertOrThrowInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrThrow }
}
/**
@@ -1306,7 +1319,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {
- CompleteObjectAddressInstruction() { getOpcode() instanceof Opcode::CompleteObjectAddress }
+ CompleteObjectAddressInstruction() { this.getOpcode() instanceof Opcode::CompleteObjectAddress }
}
/**
@@ -1351,7 +1364,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* An instruction that converts from the address of a derived class to the address of a base class.
*/
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
- ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode }
+ ConvertToBaseInstruction() { this.getOpcode() instanceof ConvertToBaseOpcode }
}
/**
@@ -1361,7 +1374,9 @@ class ConvertToBaseInstruction extends InheritanceConversionInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase }
+ ConvertToNonVirtualBaseInstruction() {
+ this.getOpcode() instanceof Opcode::ConvertToNonVirtualBase
+ }
}
/**
@@ -1371,7 +1386,7 @@ class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase }
+ ConvertToVirtualBaseInstruction() { this.getOpcode() instanceof Opcode::ConvertToVirtualBase }
}
/**
@@ -1381,7 +1396,7 @@ class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
- ConvertToDerivedInstruction() { getOpcode() instanceof Opcode::ConvertToDerived }
+ ConvertToDerivedInstruction() { this.getOpcode() instanceof Opcode::ConvertToDerived }
}
/**
@@ -1390,7 +1405,7 @@ class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
* The operand must have an integer type, which will also be the result type.
*/
class BitComplementInstruction extends UnaryBitwiseInstruction {
- BitComplementInstruction() { getOpcode() instanceof Opcode::BitComplement }
+ BitComplementInstruction() { this.getOpcode() instanceof Opcode::BitComplement }
}
/**
@@ -1399,14 +1414,14 @@ class BitComplementInstruction extends UnaryBitwiseInstruction {
* The operand must have a Boolean type, which will also be the result type.
*/
class LogicalNotInstruction extends UnaryInstruction {
- LogicalNotInstruction() { getOpcode() instanceof Opcode::LogicalNot }
+ LogicalNotInstruction() { this.getOpcode() instanceof Opcode::LogicalNot }
}
/**
* An instruction that compares two numeric operands.
*/
class CompareInstruction extends BinaryInstruction {
- CompareInstruction() { getOpcode() instanceof CompareOpcode }
+ CompareInstruction() { this.getOpcode() instanceof CompareOpcode }
}
/**
@@ -1417,7 +1432,7 @@ class CompareInstruction extends BinaryInstruction {
* unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareEQInstruction extends CompareInstruction {
- CompareEQInstruction() { getOpcode() instanceof Opcode::CompareEQ }
+ CompareEQInstruction() { this.getOpcode() instanceof Opcode::CompareEQ }
}
/**
@@ -1428,14 +1443,14 @@ class CompareEQInstruction extends CompareInstruction {
* `left == right`. Floating-point comparison is performed according to IEEE-754.
*/
class CompareNEInstruction extends CompareInstruction {
- CompareNEInstruction() { getOpcode() instanceof Opcode::CompareNE }
+ CompareNEInstruction() { this.getOpcode() instanceof Opcode::CompareNE }
}
/**
* An instruction that does a relative comparison of two values, such as `<` or `>=`.
*/
class RelationalInstruction extends CompareInstruction {
- RelationalInstruction() { getOpcode() instanceof RelationalOpcode }
+ RelationalInstruction() { this.getOpcode() instanceof RelationalOpcode }
/**
* Gets the operand on the "greater" (or "greater-or-equal") side
@@ -1467,11 +1482,11 @@ class RelationalInstruction extends CompareInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLTInstruction extends RelationalInstruction {
- CompareLTInstruction() { getOpcode() instanceof Opcode::CompareLT }
+ CompareLTInstruction() { this.getOpcode() instanceof Opcode::CompareLT }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { any() }
}
@@ -1484,11 +1499,11 @@ class CompareLTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGTInstruction extends RelationalInstruction {
- CompareGTInstruction() { getOpcode() instanceof Opcode::CompareGT }
+ CompareGTInstruction() { this.getOpcode() instanceof Opcode::CompareGT }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { any() }
}
@@ -1502,11 +1517,11 @@ class CompareGTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLEInstruction extends RelationalInstruction {
- CompareLEInstruction() { getOpcode() instanceof Opcode::CompareLE }
+ CompareLEInstruction() { this.getOpcode() instanceof Opcode::CompareLE }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { none() }
}
@@ -1520,11 +1535,11 @@ class CompareLEInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGEInstruction extends RelationalInstruction {
- CompareGEInstruction() { getOpcode() instanceof Opcode::CompareGE }
+ CompareGEInstruction() { this.getOpcode() instanceof Opcode::CompareGE }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { none() }
}
@@ -1543,78 +1558,78 @@ class CompareGEInstruction extends RelationalInstruction {
* of any case edge.
*/
class SwitchInstruction extends Instruction {
- SwitchInstruction() { getOpcode() instanceof Opcode::Switch }
+ SwitchInstruction() { this.getOpcode() instanceof Opcode::Switch }
/** Gets the operand that provides the integer value controlling the switch. */
- final ConditionOperand getExpressionOperand() { result = getAnOperand() }
+ final ConditionOperand getExpressionOperand() { result = this.getAnOperand() }
/** Gets the instruction whose result provides the integer value controlling the switch. */
- final Instruction getExpression() { result = getExpressionOperand().getDef() }
+ final Instruction getExpression() { result = this.getExpressionOperand().getDef() }
/** Gets the successor instructions along the case edges of the switch. */
- final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }
+ final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = this.getSuccessor(edge)) }
/** Gets the successor instruction along the default edge of the switch, if any. */
- final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
+ final Instruction getDefaultSuccessor() { result = this.getSuccessor(EdgeKind::defaultEdge()) }
}
/**
* An instruction that calls a function.
*/
class CallInstruction extends Instruction {
- CallInstruction() { getOpcode() instanceof Opcode::Call }
+ CallInstruction() { this.getOpcode() instanceof Opcode::Call }
final override string getImmediateString() {
- result = getStaticCallTarget().toString()
+ result = this.getStaticCallTarget().toString()
or
- not exists(getStaticCallTarget()) and result = "?"
+ not exists(this.getStaticCallTarget()) and result = "?"
}
/**
* Gets the operand the specifies the target function of the call.
*/
- final CallTargetOperand getCallTargetOperand() { result = getAnOperand() }
+ final CallTargetOperand getCallTargetOperand() { result = this.getAnOperand() }
/**
* Gets the `Instruction` that computes the target function of the call. This is usually a
* `FunctionAddress` instruction, but can also be an arbitrary instruction that produces a
* function pointer.
*/
- final Instruction getCallTarget() { result = getCallTargetOperand().getDef() }
+ final Instruction getCallTarget() { result = this.getCallTargetOperand().getDef() }
/**
* Gets all of the argument operands of the call, including the `this` pointer, if any.
*/
- final ArgumentOperand getAnArgumentOperand() { result = getAnOperand() }
+ final ArgumentOperand getAnArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
final Language::Function getStaticCallTarget() {
- result = getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
+ result = this.getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
}
/**
* Gets all of the arguments of the call, including the `this` pointer, if any.
*/
- final Instruction getAnArgument() { result = getAnArgumentOperand().getDef() }
+ final Instruction getAnArgument() { result = this.getAnArgumentOperand().getDef() }
/**
* Gets the `this` pointer argument operand of the call, if any.
*/
- final ThisArgumentOperand getThisArgumentOperand() { result = getAnOperand() }
+ final ThisArgumentOperand getThisArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `this` pointer argument of the call, if any.
*/
- final Instruction getThisArgument() { result = getThisArgumentOperand().getDef() }
+ final Instruction getThisArgument() { result = this.getThisArgumentOperand().getDef() }
/**
* Gets the argument operand at the specified index.
*/
pragma[noinline]
final PositionalArgumentOperand getPositionalArgumentOperand(int index) {
- result = getAnOperand() and
+ result = this.getAnOperand() and
result.getIndex() = index
}
@@ -1623,7 +1638,7 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final Instruction getPositionalArgument(int index) {
- result = getPositionalArgumentOperand(index).getDef()
+ result = this.getPositionalArgumentOperand(index).getDef()
}
/**
@@ -1631,16 +1646,16 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final ArgumentOperand getArgumentOperand(int index) {
- index >= 0 and result = getPositionalArgumentOperand(index)
+ index >= 0 and result = this.getPositionalArgumentOperand(index)
or
- index = -1 and result = getThisArgumentOperand()
+ index = -1 and result = this.getThisArgumentOperand()
}
/**
* Gets the argument at the specified index, or `this` if `index` is `-1`.
*/
pragma[noinline]
- final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() }
+ final Instruction getArgument(int index) { result = this.getArgumentOperand(index).getDef() }
/**
* Gets the number of arguments of the call, including the `this` pointer, if any.
@@ -1665,7 +1680,7 @@ class CallInstruction extends Instruction {
* An instruction representing a side effect of a function call.
*/
class SideEffectInstruction extends Instruction {
- SideEffectInstruction() { getOpcode() instanceof SideEffectOpcode }
+ SideEffectInstruction() { this.getOpcode() instanceof SideEffectOpcode }
/**
* Gets the instruction whose execution causes this side effect.
@@ -1680,7 +1695,7 @@ class SideEffectInstruction extends Instruction {
* accessed by that call.
*/
class CallSideEffectInstruction extends SideEffectInstruction {
- CallSideEffectInstruction() { getOpcode() instanceof Opcode::CallSideEffect }
+ CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
}
/**
@@ -1691,7 +1706,7 @@ class CallSideEffectInstruction extends SideEffectInstruction {
* call target cannot write to escaped memory.
*/
class CallReadSideEffectInstruction extends SideEffectInstruction {
- CallReadSideEffectInstruction() { getOpcode() instanceof Opcode::CallReadSideEffect }
+ CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
}
/**
@@ -1699,33 +1714,33 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
* specific parameter.
*/
class ReadSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- ReadSideEffectInstruction() { getOpcode() instanceof ReadSideEffectOpcode }
+ ReadSideEffectInstruction() { this.getOpcode() instanceof ReadSideEffectOpcode }
/** Gets the operand for the value that will be read from this instruction, if known. */
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/** Gets the value that will be read from this instruction, if known. */
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/** Gets the operand for the address from which this instruction may read. */
- final AddressOperand getArgumentOperand() { result = getAnOperand() }
+ final AddressOperand getArgumentOperand() { result = this.getAnOperand() }
/** Gets the address from which this instruction may read. */
- final Instruction getArgumentDef() { result = getArgumentOperand().getDef() }
+ final Instruction getArgumentDef() { result = this.getArgumentOperand().getDef() }
}
/**
* An instruction representing the read of an indirect parameter within a function call.
*/
class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
- IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
+ IndirectReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::IndirectReadSideEffect }
}
/**
* An instruction representing the read of an indirect buffer parameter within a function call.
*/
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
- BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
+ BufferReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::BufferReadSideEffect }
}
/**
@@ -1733,18 +1748,18 @@ class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
*/
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
SizedBufferReadSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferReadSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferReadSideEffect
}
/**
* Gets the operand that holds the number of bytes read from the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes read from the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1752,17 +1767,17 @@ class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
* specific parameter.
*/
class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
+ WriteSideEffectInstruction() { this.getOpcode() instanceof WriteSideEffectOpcode }
/**
* Get the operand that holds the address of the memory to be written.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the memory to be written.
*/
- Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ Instruction getDestinationAddress() { result = this.getDestinationAddressOperand().getDef() }
}
/**
@@ -1770,7 +1785,7 @@ class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstructi
*/
class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
}
}
@@ -1780,7 +1795,7 @@ class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction
*/
class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
BufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::BufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::BufferMustWriteSideEffect
}
}
@@ -1790,18 +1805,18 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1812,7 +1827,7 @@ class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstructi
*/
class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
}
}
@@ -1822,7 +1837,9 @@ class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
* Unlike `BufferWriteSideEffectInstruction`, the buffer might not be completely overwritten.
*/
class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
- BufferMayWriteSideEffectInstruction() { getOpcode() instanceof Opcode::BufferMayWriteSideEffect }
+ BufferMayWriteSideEffectInstruction() {
+ this.getOpcode() instanceof Opcode::BufferMayWriteSideEffect
+ }
}
/**
@@ -1832,18 +1849,18 @@ class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1852,80 +1869,80 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio
*/
class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
InitializeDynamicAllocationInstruction() {
- getOpcode() instanceof Opcode::InitializeDynamicAllocation
+ this.getOpcode() instanceof Opcode::InitializeDynamicAllocation
}
/**
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
- final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getAllocationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address for the allocation this instruction is initializing.
*/
- final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
+ final Instruction getAllocationAddress() { result = this.getAllocationAddressOperand().getDef() }
}
/**
* An instruction representing a GNU or MSVC inline assembly statement.
*/
class InlineAsmInstruction extends Instruction {
- InlineAsmInstruction() { getOpcode() instanceof Opcode::InlineAsm }
+ InlineAsmInstruction() { this.getOpcode() instanceof Opcode::InlineAsm }
}
/**
* An instruction that throws an exception.
*/
class ThrowInstruction extends Instruction {
- ThrowInstruction() { getOpcode() instanceof ThrowOpcode }
+ ThrowInstruction() { this.getOpcode() instanceof ThrowOpcode }
}
/**
* An instruction that throws a new exception.
*/
class ThrowValueInstruction extends ThrowInstruction {
- ThrowValueInstruction() { getOpcode() instanceof Opcode::ThrowValue }
+ ThrowValueInstruction() { this.getOpcode() instanceof Opcode::ThrowValue }
/**
* Gets the address operand of the exception thrown by this instruction.
*/
- final AddressOperand getExceptionAddressOperand() { result = getAnOperand() }
+ final AddressOperand getExceptionAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address of the exception thrown by this instruction.
*/
- final Instruction getExceptionAddress() { result = getExceptionAddressOperand().getDef() }
+ final Instruction getExceptionAddress() { result = this.getExceptionAddressOperand().getDef() }
/**
* Gets the operand for the exception thrown by this instruction.
*/
- final LoadOperand getExceptionOperand() { result = getAnOperand() }
+ final LoadOperand getExceptionOperand() { result = this.getAnOperand() }
/**
* Gets the exception thrown by this instruction.
*/
- final Instruction getException() { result = getExceptionOperand().getDef() }
+ final Instruction getException() { result = this.getExceptionOperand().getDef() }
}
/**
* An instruction that re-throws the current exception.
*/
class ReThrowInstruction extends ThrowInstruction {
- ReThrowInstruction() { getOpcode() instanceof Opcode::ReThrow }
+ ReThrowInstruction() { this.getOpcode() instanceof Opcode::ReThrow }
}
/**
* An instruction that exits the current function by propagating an exception.
*/
class UnwindInstruction extends Instruction {
- UnwindInstruction() { getOpcode() instanceof Opcode::Unwind }
+ UnwindInstruction() { this.getOpcode() instanceof Opcode::Unwind }
}
/**
* An instruction that starts a `catch` handler.
*/
class CatchInstruction extends Instruction {
- CatchInstruction() { getOpcode() instanceof CatchOpcode }
+ CatchInstruction() { this.getOpcode() instanceof CatchOpcode }
}
/**
@@ -1935,7 +1952,7 @@ class CatchByTypeInstruction extends CatchInstruction {
Language::LanguageType exceptionType;
CatchByTypeInstruction() {
- getOpcode() instanceof Opcode::CatchByType and
+ this.getOpcode() instanceof Opcode::CatchByType and
exceptionType = Raw::getInstructionExceptionType(this)
}
@@ -1951,21 +1968,21 @@ class CatchByTypeInstruction extends CatchInstruction {
* An instruction that catches any exception.
*/
class CatchAnyInstruction extends CatchInstruction {
- CatchAnyInstruction() { getOpcode() instanceof Opcode::CatchAny }
+ CatchAnyInstruction() { this.getOpcode() instanceof Opcode::CatchAny }
}
/**
* An instruction that initializes all escaped memory.
*/
class AliasedDefinitionInstruction extends Instruction {
- AliasedDefinitionInstruction() { getOpcode() instanceof Opcode::AliasedDefinition }
+ AliasedDefinitionInstruction() { this.getOpcode() instanceof Opcode::AliasedDefinition }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
- AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
+ AliasedUseInstruction() { this.getOpcode() instanceof Opcode::AliasedUse }
}
/**
@@ -1979,7 +1996,7 @@ class AliasedUseInstruction extends Instruction {
* runtime.
*/
class PhiInstruction extends Instruction {
- PhiInstruction() { getOpcode() instanceof Opcode::Phi }
+ PhiInstruction() { this.getOpcode() instanceof Opcode::Phi }
/**
* Gets all of the instruction's `PhiInputOperand`s, representing the values that flow from each predecessor block.
@@ -2047,29 +2064,29 @@ class PhiInstruction extends Instruction {
* https://link.springer.com/content/pdf/10.1007%2F3-540-61053-7_66.pdf.
*/
class ChiInstruction extends Instruction {
- ChiInstruction() { getOpcode() instanceof Opcode::Chi }
+ ChiInstruction() { this.getOpcode() instanceof Opcode::Chi }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final ChiTotalOperand getTotalOperand() { result = getAnOperand() }
+ final ChiTotalOperand getTotalOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final Instruction getTotal() { result = getTotalOperand().getDef() }
+ final Instruction getTotal() { result = this.getTotalOperand().getDef() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final ChiPartialOperand getPartialOperand() { result = getAnOperand() }
+ final ChiPartialOperand getPartialOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final Instruction getPartial() { result = getPartialOperand().getDef() }
+ final Instruction getPartial() { result = this.getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
@@ -2093,7 +2110,7 @@ class ChiInstruction extends Instruction {
* or `Switch` instruction where that particular edge is infeasible.
*/
class UnreachedInstruction extends Instruction {
- UnreachedInstruction() { getOpcode() instanceof Opcode::Unreached }
+ UnreachedInstruction() { this.getOpcode() instanceof Opcode::Unreached }
}
/**
@@ -2106,7 +2123,7 @@ class BuiltInOperationInstruction extends Instruction {
Language::BuiltInOperation operation;
BuiltInOperationInstruction() {
- getOpcode() instanceof BuiltInOperationOpcode and
+ this.getOpcode() instanceof BuiltInOperationOpcode and
operation = Raw::getInstructionBuiltInOperation(this)
}
@@ -2122,9 +2139,9 @@ class BuiltInOperationInstruction extends Instruction {
* actual operation is specified by the `getBuiltInOperation()` predicate.
*/
class BuiltInInstruction extends BuiltInOperationInstruction {
- BuiltInInstruction() { getOpcode() instanceof Opcode::BuiltIn }
+ BuiltInInstruction() { this.getOpcode() instanceof Opcode::BuiltIn }
- final override string getImmediateString() { result = getBuiltInOperation().toString() }
+ final override string getImmediateString() { result = this.getBuiltInOperation().toString() }
}
/**
@@ -2135,7 +2152,7 @@ class BuiltInInstruction extends BuiltInOperationInstruction {
* to the `...` parameter.
*/
class VarArgsStartInstruction extends UnaryInstruction {
- VarArgsStartInstruction() { getOpcode() instanceof Opcode::VarArgsStart }
+ VarArgsStartInstruction() { this.getOpcode() instanceof Opcode::VarArgsStart }
}
/**
@@ -2145,7 +2162,7 @@ class VarArgsStartInstruction extends UnaryInstruction {
* a result.
*/
class VarArgsEndInstruction extends UnaryInstruction {
- VarArgsEndInstruction() { getOpcode() instanceof Opcode::VarArgsEnd }
+ VarArgsEndInstruction() { this.getOpcode() instanceof Opcode::VarArgsEnd }
}
/**
@@ -2155,7 +2172,7 @@ class VarArgsEndInstruction extends UnaryInstruction {
* argument.
*/
class VarArgInstruction extends UnaryInstruction {
- VarArgInstruction() { getOpcode() instanceof Opcode::VarArg }
+ VarArgInstruction() { this.getOpcode() instanceof Opcode::VarArg }
}
/**
@@ -2166,7 +2183,7 @@ class VarArgInstruction extends UnaryInstruction {
* argument of the `...` parameter.
*/
class NextVarArgInstruction extends UnaryInstruction {
- NextVarArgInstruction() { getOpcode() instanceof Opcode::NextVarArg }
+ NextVarArgInstruction() { this.getOpcode() instanceof Opcode::NextVarArg }
}
/**
@@ -2180,5 +2197,5 @@ class NextVarArgInstruction extends UnaryInstruction {
* The result is the address of the newly allocated object.
*/
class NewObjInstruction extends Instruction {
- NewObjInstruction() { getOpcode() instanceof Opcode::NewObj }
+ NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
}
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Operand.qll b/csharp/ql/src/experimental/ir/implementation/raw/Operand.qll
index d7cf89ca9aa..85d217bd361 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/Operand.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/Operand.qll
@@ -46,12 +46,12 @@ class Operand extends TStageOperand {
/**
* Gets the location of the source code for this operand.
*/
- final Language::Location getLocation() { result = getUse().getLocation() }
+ final Language::Location getLocation() { result = this.getUse().getLocation() }
/**
* Gets the function that contains this operand.
*/
- final IRFunction getEnclosingIRFunction() { result = getUse().getEnclosingIRFunction() }
+ final IRFunction getEnclosingIRFunction() { result = this.getUse().getEnclosingIRFunction() }
/**
* Gets the `Instruction` that consumes this operand.
@@ -74,7 +74,7 @@ class Operand extends TStageOperand {
*/
final Instruction getDef() {
result = this.getAnyDef() and
- getDefinitionOverlap() instanceof MustExactlyOverlap
+ this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
@@ -82,7 +82,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` that consumes this operand.
*/
- deprecated final Instruction getUseInstruction() { result = getUse() }
+ deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
@@ -91,7 +91,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` whose result is the value of the operand.
*/
- deprecated final Instruction getDefinitionInstruction() { result = getAnyDef() }
+ deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
@@ -101,7 +101,9 @@ class Operand extends TStageOperand {
/**
* Holds if the result of the definition instruction does not exactly overlap this use.
*/
- final predicate isDefinitionInexact() { not getDefinitionOverlap() instanceof MustExactlyOverlap }
+ final predicate isDefinitionInexact() {
+ not this.getDefinitionOverlap() instanceof MustExactlyOverlap
+ }
/**
* Gets a prefix to use when dumping the operand in an operand list.
@@ -121,7 +123,7 @@ class Operand extends TStageOperand {
* For example: `this:r3_5`
*/
final string getDumpString() {
- result = getDumpLabel() + getInexactSpecifier() + getDefinitionId()
+ result = this.getDumpLabel() + this.getInexactSpecifier() + this.getDefinitionId()
}
/**
@@ -129,9 +131,9 @@ class Operand extends TStageOperand {
* definition is not modeled in SSA.
*/
private string getDefinitionId() {
- result = getAnyDef().getResultId()
+ result = this.getAnyDef().getResultId()
or
- not exists(getAnyDef()) and result = "m?"
+ not exists(this.getAnyDef()) and result = "m?"
}
/**
@@ -140,7 +142,7 @@ class Operand extends TStageOperand {
* the empty string.
*/
private string getInexactSpecifier() {
- if isDefinitionInexact() then result = "~" else result = ""
+ if this.isDefinitionInexact() then result = "~" else result = ""
}
/**
@@ -155,7 +157,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- Language::LanguageType getLanguageType() { result = getAnyDef().getResultLanguageType() }
+ Language::LanguageType getLanguageType() { result = this.getAnyDef().getResultLanguageType() }
/**
* Gets the language-neutral type of the value consumed by this operand. This is usually the same
@@ -164,7 +166,7 @@ class Operand extends TStageOperand {
* from the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final IRType getIRType() { result = getLanguageType().getIRType() }
+ final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the value consumed by this operand. This is usually the same as the
@@ -173,7 +175,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final Language::Type getType() { getLanguageType().hasType(result, _) }
+ final Language::Type getType() { this.getLanguageType().hasType(result, _) }
/**
* Holds if the value consumed by this operand is a glvalue. If this
@@ -182,13 +184,13 @@ class Operand extends TStageOperand {
* not hold, the value of the operand represents a value whose type is
* given by `getType()`.
*/
- final predicate isGLValue() { getLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getLanguageType().hasType(_, true) }
/**
* Gets the size of the value consumed by this operand, in bytes. If the operand does not have
* a known constant size, this predicate does not hold.
*/
- final int getSize() { result = getLanguageType().getByteSize() }
+ final int getSize() { result = this.getLanguageType().getByteSize() }
}
/**
@@ -205,7 +207,7 @@ class MemoryOperand extends Operand {
/**
* Gets the kind of memory access performed by the operand.
*/
- MemoryAccessKind getMemoryAccess() { result = getUse().getOpcode().getReadMemoryAccess() }
+ MemoryAccessKind getMemoryAccess() { result = this.getUse().getOpcode().getReadMemoryAccess() }
/**
* Holds if the memory access performed by this operand will not always read from every bit in the
@@ -215,7 +217,7 @@ class MemoryOperand extends Operand {
* conservative estimate of the memory that might actually be accessed at runtime (for example,
* the global side effects of a function call).
*/
- predicate hasMayReadMemoryAccess() { getUse().getOpcode().hasMayReadMemoryAccess() }
+ predicate hasMayReadMemoryAccess() { this.getUse().getOpcode().hasMayReadMemoryAccess() }
/**
* Returns the operand that holds the memory address from which the current operand loads its
@@ -223,8 +225,8 @@ class MemoryOperand extends Operand {
* is `r1`.
*/
final AddressOperand getAddressOperand() {
- getMemoryAccess().usesAddressOperand() and
- result.getUse() = getUse()
+ this.getMemoryAccess().usesAddressOperand() and
+ result.getUse() = this.getUse()
}
}
@@ -294,7 +296,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
- final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
+ final override Overlap getDefinitionOverlap() { this.hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
@@ -449,13 +451,17 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
final override Overlap getDefinitionOverlap() { result = overlap }
- final override int getDumpSortOrder() { result = 11 + getPredecessorBlock().getDisplayIndex() }
-
- final override string getDumpLabel() {
- result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
+ final override int getDumpSortOrder() {
+ result = 11 + this.getPredecessorBlock().getDisplayIndex()
}
- final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
+ final override string getDumpLabel() {
+ result = "from " + this.getPredecessorBlock().getDisplayIndex().toString() + ":"
+ }
+
+ final override string getDumpId() {
+ result = this.getPredecessorBlock().getDisplayIndex().toString()
+ }
/**
* Gets the predecessor block from which this value comes.
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll
index a172800b377..99833c70d0b 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedCondition.qll
@@ -139,13 +139,13 @@ class TranslatedLogicalOrExpr extends TranslatedBinaryLogicalOperation {
override LogicalOrExpr expr;
override Instruction getChildTrueSuccessor(ConditionBase child) {
- child = getAnOperand() and
+ child = this.getAnOperand() and
result = this.getConditionContext().getChildTrueSuccessor(this)
}
override Instruction getChildFalseSuccessor(ConditionBase child) {
child = this.getLeftOperand() and
- result = getRightOperand().getFirstInstruction()
+ result = this.getRightOperand().getFirstInstruction()
or
child = this.getRightOperand() and
result = this.getConditionContext().getChildFalseSuccessor(this)
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll
index 86cbdbb4360..9b4fbbba723 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedDeclaration.qll
@@ -48,7 +48,7 @@ class TranslatedLocalVariableDeclaration extends TranslatedLocalDeclaration,
override LocalVariable getDeclVar() { result = var }
- override Type getVarType() { result = getVariableType(getDeclVar()) }
+ override Type getVarType() { result = getVariableType(this.getDeclVar()) }
override Type getTargetType() { result = getVariableType(var) }
@@ -58,7 +58,7 @@ class TranslatedLocalVariableDeclaration extends TranslatedLocalDeclaration,
or
this.hasUninitializedInstruction() and tag = InitializerStoreTag()
) and
- result = getIRUserVariable(getFunction(), getDeclVar())
+ result = getIRUserVariable(this.getFunction(), this.getDeclVar())
}
override TranslatedInitialization getInitialization() {
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll
index 04e05dc9814..ea1ad7931cb 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedElement.qll
@@ -456,7 +456,7 @@ abstract class TranslatedElement extends TTranslatedElement {
* there is no enclosing `try`.
*/
Instruction getExceptionSuccessorInstruction() {
- result = getParent().getExceptionSuccessorInstruction()
+ result = this.getParent().getExceptionSuccessorInstruction()
}
/**
@@ -558,7 +558,7 @@ abstract class TranslatedElement extends TTranslatedElement {
* Gets the temporary variable generated by this element with tag `tag`.
*/
final IRTempVariable getTempVariable(TempVariableTag tag) {
- result.getAST() = getAST() and
+ result.getAST() = this.getAST() and
result.getTag() = tag and
this.hasTempVariable(tag, _)
}
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll
index 72c408a3f2a..362ed3e0d2b 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedExpr.qll
@@ -98,7 +98,7 @@ abstract class TranslatedCoreExpr extends TranslatedExpr {
}
final CSharpType getResultCSharpType() {
- if isResultLValue() = true
+ if this.isResultLValue() = true
then result = getTypeForGLValue(expr.getType())
else result = getTypeForPRValue(expr.getType())
}
@@ -138,18 +138,18 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext,
tag = ConditionValueFalseConstantTag()
) and
opcode instanceof Opcode::Constant and
- resultType = getResultCSharpType()
+ resultType = this.getResultCSharpType()
or
(
tag = ConditionValueTrueStoreTag() or
tag = ConditionValueFalseStoreTag()
) and
opcode instanceof Opcode::Store and
- resultType = getResultCSharpType()
+ resultType = this.getResultCSharpType()
or
tag = ConditionValueResultLoadTag() and
opcode instanceof Opcode::Load and
- resultType = getResultCSharpType()
+ resultType = this.getResultCSharpType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -258,7 +258,7 @@ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad {
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {
tag = LoadTag() and
opcode instanceof Opcode::Load and
- if producesExprResult()
+ if this.producesExprResult()
then resultType = getTypeForPRValue(expr.getType())
else resultType = getTypeForGLValue(expr.getType())
}
@@ -542,7 +542,7 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
}
final override TranslatedElement getChild(int id) {
- id = -1 and result = getBaseOperand()
+ id = -1 and result = this.getBaseOperand()
or
result = this.getOffsetOperand(id)
}
@@ -559,7 +559,7 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
or
// The successor of the last `PointerAdd` instruction is
// the successor of the `TranslatedArrayAccess`.
- tag = PointerAddTag(getRank() - 1) and
+ tag = PointerAddTag(this.getRank() - 1) and
result = this.getParent().getChildSuccessor(this)
or
// The successor of an `ElementsAddress` instruction is
@@ -582,27 +582,29 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
result = this.getInstruction(PointerAddTag(child.getAST().getIndex()))
}
- override Instruction getResult() { result = this.getInstruction(PointerAddTag(getRank() - 1)) }
+ override Instruction getResult() {
+ result = this.getInstruction(PointerAddTag(this.getRank() - 1))
+ }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {
exists(int index |
- inBounds(index) and
+ this.inBounds(index) and
tag = PointerAddTag(index) and
opcode instanceof Opcode::PointerAdd and
- resultType = getTypeForPRValue(getArrayOfDim(getRank() - index, expr.getType()))
+ resultType = getTypeForPRValue(getArrayOfDim(this.getRank() - index, expr.getType()))
)
or
exists(int index |
- inBounds(index) and
+ this.inBounds(index) and
tag = ElementsAddressTag(index) and
opcode instanceof Opcode::ElementsAddress and
- resultType = getTypeForPRValue(getArrayOfDim(getRank() - index, expr.getType()))
+ resultType = getTypeForPRValue(getArrayOfDim(this.getRank() - index, expr.getType()))
)
}
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
exists(int index |
- inBounds(index) and
+ this.inBounds(index) and
tag = PointerAddTag(index) and
(
operandTag instanceof LeftOperandTag and
@@ -632,7 +634,7 @@ class TranslatedArrayAccess extends TranslatedNonConstantExpr {
override int getInstructionElementSize(InstructionTag tag) {
exists(int index |
- inBounds(index) and
+ this.inBounds(index) and
tag = PointerAddTag(index) and
result = Language::getTypeSize(expr.getQualifier().getType().(ArrayType).getElementType())
)
@@ -989,9 +991,9 @@ abstract class TranslatedSingleInstructionExpr extends TranslatedNonConstantExpr
abstract Opcode getOpcode();
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {
- opcode = getOpcode() and
+ opcode = this.getOpcode() and
tag = OnlyInstructionTag() and
- resultType = getResultCSharpType()
+ resultType = this.getResultCSharpType()
}
final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
@@ -1189,7 +1191,7 @@ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr {
override int getInstructionElementSize(InstructionTag tag) {
tag = OnlyInstructionTag() and
exists(Opcode opcode |
- opcode = getOpcode() and
+ opcode = this.getOpcode() and
(
opcode instanceof Opcode::PointerAdd or
opcode instanceof Opcode::PointerSub or
@@ -1200,7 +1202,9 @@ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr {
}
private TranslatedExpr getPointerOperand() {
- if swapOperandsOnOp() then result = this.getRightOperand() else result = this.getLeftOperand()
+ if this.swapOperandsOnOp()
+ then result = this.getRightOperand()
+ else result = this.getLeftOperand()
}
private predicate swapOperandsOnOp() {
@@ -1425,7 +1429,7 @@ class TranslatedAssignOperation extends TranslatedAssignment {
resultType = getTypeForPRValue(this.getLeftOperand().getResultType())
or
tag = AssignOperationOpTag() and
- opcode = getOpcode() and
+ opcode = this.getOpcode() and
resultType = getTypeForPRValue(this.getConvertedLeftOperandType())
or
tag = AssignmentStoreTag() and
@@ -1452,7 +1456,7 @@ class TranslatedAssignOperation extends TranslatedAssignment {
opcode instanceof Opcode::PointerSub
)
) and
- result = Language::getTypeSize(getResultType().(PointerType).getReferentType())
+ result = Language::getTypeSize(this.getResultType().(PointerType).getReferentType())
}
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
@@ -1799,7 +1803,7 @@ class TranslatedIsExpr extends TranslatedNonConstantExpr {
result = this.getInstruction(GeneratedConstantTag())
)
or
- hasVar() and
+ this.hasVar() and
tag = GeneratedBranchTag() and
operandTag instanceof ConditionOperandTag and
result = this.getInstruction(GeneratedNEQTag())
@@ -1848,7 +1852,7 @@ class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationCont
}
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getInitialization() and
+ child = this.getInitialization() and
result = this.getInstruction(LoadTag())
}
@@ -1922,7 +1926,7 @@ class TranslatedDelegateCall extends TranslatedNonConstantExpr {
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInvokeCall() and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {
@@ -1973,7 +1977,7 @@ abstract class TranslatedCreation extends TranslatedCoreExpr, TTranslatedCreatio
else result = this.getInstruction(NewObjTag())
}
- override Instruction getReceiver() { result = getInstruction(NewObjTag()) }
+ override Instruction getReceiver() { result = this.getInstruction(NewObjTag()) }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
@@ -1998,11 +2002,11 @@ abstract class TranslatedCreation extends TranslatedCoreExpr, TTranslatedCreatio
child = this.getConstructorCall() and
if exists(this.getInitializerExpr())
then result = this.getInitializerExpr().getFirstInstruction()
- else result = getLoadOrChildSuccessor()
+ else result = this.getLoadOrChildSuccessor()
)
or
child = this.getInitializerExpr() and
- result = getLoadOrChildSuccessor()
+ result = this.getLoadOrChildSuccessor()
}
private Instruction getLoadOrChildSuccessor() {
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll
index 65488a1b95d..94b48b0985d 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedFunction.qll
@@ -68,20 +68,20 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
or
(
tag = AliasedDefinitionTag() and
- if exists(getThisType())
+ if exists(this.getThisType())
then result = this.getInstruction(InitializeThisTag())
else
- if exists(getParameter(0))
+ if exists(this.getParameter(0))
then result = this.getParameter(0).getFirstInstruction()
else result = this.getBodyOrReturn()
)
or
(
tag = InitializeThisTag() and
- if exists(getParameter(0))
+ if exists(this.getParameter(0))
then result = this.getParameter(0).getFirstInstruction()
else
- if exists(getConstructorInitializer())
+ if exists(this.getConstructorInitializer())
then result = this.getConstructorInitializer().getFirstInstruction()
else result = this.getBodyOrReturn()
)
@@ -106,7 +106,7 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
if exists(callable.getParameter(paramIndex + 1))
then result = this.getParameter(paramIndex + 1).getFirstInstruction()
else
- if exists(getConstructorInitializer())
+ if exists(this.getConstructorInitializer())
then result = this.getConstructorInitializer().getFirstInstruction()
else result = this.getBodyOrReturn()
)
@@ -136,12 +136,12 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
or
tag = InitializeThisTag() and
opcode instanceof Opcode::InitializeThis and
- resultType = getTypeForGLValue(getThisType())
+ resultType = getTypeForGLValue(this.getThisType())
or
tag = ReturnValueAddressTag() and
opcode instanceof Opcode::VariableAddress and
- not getReturnType() instanceof VoidType and
- resultType = getTypeForGLValue(getReturnType())
+ not this.getReturnType() instanceof VoidType and
+ resultType = getTypeForGLValue(this.getReturnType())
or
(
tag = ReturnTag() and
@@ -201,7 +201,7 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
final override predicate hasTempVariable(TempVariableTag tag, CSharpType type) {
tag = ReturnValueTempVar() and
type = getTypeForPRValue(this.getReturnType()) and
- not getReturnType() instanceof VoidType
+ not this.getReturnType() instanceof VoidType
}
/**
@@ -320,7 +320,7 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
tag = InitializerStoreTag() or
tag = InitializerVariableAddressTag()
) and
- result = getIRUserVariable(getFunction(), param)
+ result = getIRUserVariable(this.getFunction(), param)
}
final override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll
index cbe0e7c1d2a..77e41c15e72 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedInitialization.qll
@@ -139,7 +139,7 @@ class TranslatedDirectInitialization extends TranslatedInitialization {
opcode instanceof Opcode::Store and
resultType = getTypeForPRValue(this.getContext().getTargetType())
or
- needsConversion() and
+ this.needsConversion() and
tag = AssignmentConvertRightTag() and
// For now only use `Opcode::Convert` to
// crudely represent conversions. Could
@@ -153,9 +153,9 @@ class TranslatedDirectInitialization extends TranslatedInitialization {
result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
or
- needsConversion() and
+ this.needsConversion() and
tag = AssignmentConvertRightTag() and
- result = getInstruction(InitializerStoreTag()) and
+ result = this.getInstruction(InitializerStoreTag()) and
kind instanceof GotoEdge
}
@@ -203,7 +203,7 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
ArrayInitializer initList;
final override string toString() {
- result = initList.toString() + "[" + getElementIndex().toString() + "]"
+ result = initList.toString() + "[" + this.getElementIndex().toString() + "]"
}
final override Language::AST getAST() { result = initList }
@@ -211,54 +211,54 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
final override Callable getFunction() { result = initList.getEnclosingCallable() }
final override Instruction getFirstInstruction() {
- result = this.getInstruction(getElementIndexTag())
+ result = this.getInstruction(this.getElementIndexTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {
- tag = getElementIndexTag() and
+ tag = this.getElementIndexTag() and
opcode instanceof Opcode::Constant and
resultType = getIntType()
or
- tag = getElementAddressTag() and
+ tag = this.getElementAddressTag() and
opcode instanceof Opcode::PointerAdd and
- resultType = getTypeForGLValue(getElementType())
+ resultType = getTypeForGLValue(this.getElementType())
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
- tag = getElementIndexTag() and
- result = this.getInstruction(getElementAddressTag()) and
+ tag = this.getElementIndexTag() and
+ result = this.getInstruction(this.getElementAddressTag()) and
kind instanceof GotoEdge
}
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
- tag = getElementAddressTag() and
+ tag = this.getElementAddressTag() and
(
operandTag instanceof LeftOperandTag and
result = this.getParent().(InitializationContext).getTargetAddress()
or
operandTag instanceof RightOperandTag and
- result = this.getInstruction(getElementIndexTag())
+ result = this.getInstruction(this.getElementIndexTag())
)
}
override int getInstructionElementSize(InstructionTag tag) {
- tag = getElementAddressTag() and
- result = Language::getTypeSize(getElementType())
+ tag = this.getElementAddressTag() and
+ result = Language::getTypeSize(this.getElementType())
}
override string getInstructionConstantValue(InstructionTag tag) {
- tag = getElementIndexTag() and
- result = getElementIndex().toString()
+ tag = this.getElementIndexTag() and
+ result = this.getElementIndex().toString()
}
abstract int getElementIndex();
final InstructionTag getElementAddressTag() {
- result = InitializerElementAddressTag(getElementIndex())
+ result = InitializerElementAddressTag(this.getElementIndex())
}
final InstructionTag getElementIndexTag() {
- result = InitializerElementIndexTag(getElementIndex())
+ result = InitializerElementIndexTag(this.getElementIndex())
}
final ArrayInitializer getInitList() { result = initList }
@@ -278,14 +278,16 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
this = TTranslatedExplicitElementInitialization(initList, elementIndex)
}
- override Instruction getTargetAddress() { result = this.getInstruction(getElementAddressTag()) }
+ override Instruction getTargetAddress() {
+ result = this.getInstruction(this.getElementAddressTag())
+ }
- override Type getTargetType() { result = getElementType() }
+ override Type getTargetType() { result = this.getElementType() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind)
or
- tag = getElementAddressTag() and
+ tag = this.getElementAddressTag() and
result = this.getInitialization().getFirstInstruction() and
kind instanceof GotoEdge
}
@@ -340,7 +342,7 @@ class TranslatedConstructorInitializer extends TranslatedConstructorCallFromCons
override string toString() { result = "constructor init: " + call.toString() }
override Instruction getFirstInstruction() {
- if needsConversion()
+ if this.needsConversion()
then result = this.getInstruction(OnlyInstructionTag())
else result = this.getConstructorCall().getFirstInstruction()
}
@@ -361,13 +363,13 @@ class TranslatedConstructorInitializer extends TranslatedConstructorCallFromCons
override Instruction getReceiver() {
if this.needsConversion()
then result = this.getInstruction(OnlyInstructionTag())
- else result = getTranslatedFunction(getFunction()).getInitializeThisInstruction()
+ else result = getTranslatedFunction(this.getFunction()).getInitializeThisInstruction()
}
override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
- result = getTranslatedFunction(getFunction()).getInitializeThisInstruction()
+ result = getTranslatedFunction(this.getFunction()).getInitializeThisInstruction()
}
predicate needsConversion() {
diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll
index 81de9a6b7c9..2f91484094a 100644
--- a/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll
+++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/TranslatedStmt.qll
@@ -79,7 +79,7 @@ class TranslatedDeclStmt extends TranslatedStmt {
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = this.getLocalDeclaration(index) and
- if index = (getChildCount() - 1)
+ if index = (this.getChildCount() - 1)
then result = this.getParent().getChildSuccessor(this)
else result = this.getLocalDeclaration(index + 1).getFirstInstruction()
)
@@ -276,14 +276,14 @@ class TranslatedBlock extends TranslatedStmt {
override TranslatedElement getChild(int id) { result = this.getStmt(id) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {
- isEmpty() and
+ this.isEmpty() and
opcode instanceof Opcode::NoOp and
tag = OnlyInstructionTag() and
resultType = getVoidType()
}
override Instruction getFirstInstruction() {
- if isEmpty()
+ if this.isEmpty()
then result = this.getInstruction(OnlyInstructionTag())
else result = this.getStmt(0).getFirstInstruction()
}
@@ -303,7 +303,7 @@ class TranslatedBlock extends TranslatedStmt {
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = this.getStmt(index) and
- if index = (getStmtCount() - 1)
+ if index = (this.getStmtCount() - 1)
then result = this.getParent().getChildSuccessor(this)
else result = this.getStmt(index + 1).getFirstInstruction()
)
@@ -347,7 +347,7 @@ class TranslatedCatchByTypeClause extends TranslatedClause {
}
override TranslatedElement getChild(int id) {
- id = 0 and result = getParameter()
+ id = 0 and result = this.getParameter()
or
result = super.getChild(id)
}
@@ -355,14 +355,14 @@ class TranslatedCatchByTypeClause extends TranslatedClause {
override Instruction getChildSuccessor(TranslatedElement child) {
result = super.getChildSuccessor(child)
or
- child = getParameter() and result = this.getBlock().getFirstInstruction()
+ child = this.getParameter() and result = this.getBlock().getFirstInstruction()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = CatchTag() and
(
kind instanceof GotoEdge and
- result = getParameter().getFirstInstruction()
+ result = this.getParameter().getFirstInstruction()
or
kind instanceof ExceptionEdge and
result = this.getParent().(TranslatedTryStmt).getNextHandler(this)
@@ -559,8 +559,8 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
final TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getBody()) }
final Instruction getFirstConditionInstruction() {
- if hasCondition()
- then result = getCondition().getFirstInstruction()
+ if this.hasCondition()
+ then result = this.getCondition().getFirstInstruction()
else result = this.getBody().getFirstInstruction()
}
@@ -611,13 +611,13 @@ class TranslatedForStmt extends TranslatedLoop {
override ForStmt stmt;
override TranslatedElement getChild(int id) {
- initializerIndex(id) and result = this.getDeclAndInit(id)
+ this.initializerIndex(id) and result = this.getDeclAndInit(id)
or
- result = this.getUpdate(updateIndex(id))
+ result = this.getUpdate(this.updateIndex(id))
or
- id = initializersNo() + updatesNo() and result = this.getCondition()
+ id = this.initializersNo() + this.updatesNo() and result = this.getCondition()
or
- id = initializersNo() + updatesNo() + 1 and result = this.getBody()
+ id = this.initializersNo() + this.updatesNo() + 1 and result = this.getBody()
}
private TranslatedElement getDeclAndInit(int index) {
@@ -636,11 +636,11 @@ class TranslatedForStmt extends TranslatedLoop {
private int updatesNo() { result = count(stmt.getAnUpdate()) }
- private predicate initializerIndex(int index) { index in [0 .. initializersNo() - 1] }
+ private predicate initializerIndex(int index) { index in [0 .. this.initializersNo() - 1] }
private int updateIndex(int index) {
- result in [0 .. updatesNo() - 1] and
- index = initializersNo() + result
+ result in [0 .. this.updatesNo() - 1] and
+ index = this.initializersNo() + result
}
override Instruction getFirstInstruction() {
@@ -652,11 +652,11 @@ class TranslatedForStmt extends TranslatedLoop {
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = this.getDeclAndInit(index) and
- index < initializersNo() - 1 and
+ index < this.initializersNo() - 1 and
result = this.getDeclAndInit(index + 1).getFirstInstruction()
)
or
- child = this.getDeclAndInit(initializersNo() - 1) and
+ child = this.getDeclAndInit(this.initializersNo() - 1) and
result = this.getFirstConditionInstruction()
or
(
@@ -671,7 +671,7 @@ class TranslatedForStmt extends TranslatedLoop {
result = this.getUpdate(index + 1).getFirstInstruction()
)
or
- child = this.getUpdate(updatesNo() - 1) and
+ child = this.getUpdate(this.updatesNo() - 1) and
result = this.getFirstConditionInstruction()
}
}
@@ -693,7 +693,7 @@ abstract class TranslatedSpecificJump extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind instanceof GotoEdge and
- result = getTargetInstruction()
+ result = this.getTargetInstruction()
}
override Instruction getChildSuccessor(TranslatedElement child) { none() }
@@ -832,7 +832,7 @@ class TranslatedSwitchStmt extends TranslatedStmt {
not exists(stmt.getDefaultCase()) and
tag = SwitchBranchTag() and
kind instanceof DefaultEdge and
- result = getParent().getChildSuccessor(this)
+ result = this.getParent().getChildSuccessor(this)
}
private EdgeKind getCaseEdge(CaseStmt caseStmt) {
@@ -862,19 +862,21 @@ class TranslatedEnumeratorForeach extends TranslatedLoop {
override ForeachStmt stmt;
override TranslatedElement getChild(int id) {
- id = 0 and result = getTempEnumDecl()
+ id = 0 and result = this.getTempEnumDecl()
or
- id = 1 and result = getTry()
+ id = 1 and result = this.getTry()
}
- override Instruction getFirstInstruction() { result = getTempEnumDecl().getFirstInstruction() }
+ override Instruction getFirstInstruction() {
+ result = this.getTempEnumDecl().getFirstInstruction()
+ }
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getTempEnumDecl() and
- result = getTry().getFirstInstruction()
+ child = this.getTempEnumDecl() and
+ result = this.getTry().getFirstInstruction()
or
- child = getTry() and
- result = getParent().getChildSuccessor(this)
+ child = this.getTry() and
+ result = this.getParent().getChildSuccessor(this)
}
private TranslatedElement getTry() { result = ForeachElements::getTry(stmt) }
@@ -909,9 +911,9 @@ class TranslatedFixedStmt extends TranslatedStmt {
override FixedStmt stmt;
override TranslatedElement getChild(int id) {
- result = getDecl(id)
+ result = this.getDecl(id)
or
- id = noDecls() and result = this.getBody()
+ id = this.noDecls() and result = this.getBody()
}
override Instruction getFirstInstruction() { result = this.getDecl(0).getFirstInstruction() }
@@ -947,24 +949,26 @@ class TranslatedLockStmt extends TranslatedStmt {
override LockStmt stmt;
override TranslatedElement getChild(int id) {
- id = 0 and result = getLockedVarDecl()
+ id = 0 and result = this.getLockedVarDecl()
or
- id = 1 and result = getLockWasTakenDecl()
+ id = 1 and result = this.getLockWasTakenDecl()
or
- id = 2 and result = getTry()
+ id = 2 and result = this.getTry()
}
- override Instruction getFirstInstruction() { result = getLockedVarDecl().getFirstInstruction() }
+ override Instruction getFirstInstruction() {
+ result = this.getLockedVarDecl().getFirstInstruction()
+ }
override Instruction getChildSuccessor(TranslatedElement child) {
- child = getLockedVarDecl() and
- result = getLockWasTakenDecl().getFirstInstruction()
+ child = this.getLockedVarDecl() and
+ result = this.getLockWasTakenDecl().getFirstInstruction()
or
- child = getLockWasTakenDecl() and
- result = getTry().getFirstInstruction()
+ child = this.getLockWasTakenDecl() and
+ result = this.getTry().getFirstInstruction()
or
- child = getTry() and
- result = getParent().getChildSuccessor(this)
+ child = this.getTry() and
+ result = this.getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {
@@ -1017,13 +1021,13 @@ class TranslatedUsingBlockStmt extends TranslatedStmt {
override UsingBlockStmt stmt;
override TranslatedElement getChild(int id) {
- result = getDecl(id)
+ result = this.getDecl(id)
or
- id = getNumberOfDecls() and result = this.getBody()
+ id = this.getNumberOfDecls() and result = this.getBody()
}
override Instruction getFirstInstruction() {
- if getNumberOfDecls() > 0
+ if this.getNumberOfDecls() > 0
then result = this.getDecl(0).getFirstInstruction()
else result = this.getBody().getFirstInstruction()
}
@@ -1060,7 +1064,7 @@ class TranslatedUsingBlockStmt extends TranslatedStmt {
class TranslatedUsingDeclStmt extends TranslatedStmt {
override UsingDeclStmt stmt;
- override TranslatedElement getChild(int id) { result = getDecl(id) }
+ override TranslatedElement getChild(int id) { result = this.getDecl(id) }
override Instruction getFirstInstruction() { result = this.getDecl(0).getFirstInstruction() }
diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll
index 4b86f9a7cec..bb8630a5e0c 100644
--- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll
+++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/IRBlock.qll
@@ -24,7 +24,7 @@ class IRBlockBase extends TIRBlock {
final string toString() { result = getFirstInstruction(this).toString() }
/** Gets the source location of the first non-`Phi` instruction in this block. */
- final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
+ final Language::Location getLocation() { result = this.getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
@@ -39,7 +39,7 @@ class IRBlockBase extends TIRBlock {
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
- funcBlock.getEnclosingFunction() = getEnclosingFunction() and
+ funcBlock.getEnclosingFunction() = this.getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
@@ -59,15 +59,15 @@ class IRBlockBase extends TIRBlock {
* Get the `Phi` instructions that appear at the start of this block.
*/
final PhiInstruction getAPhiInstruction() {
- Construction::getPhiInstructionBlockStart(result) = getFirstInstruction()
+ Construction::getPhiInstructionBlockStart(result) = this.getFirstInstruction()
}
/**
* Gets an instruction in this block. This includes `Phi` instructions.
*/
final Instruction getAnInstruction() {
- result = getInstruction(_) or
- result = getAPhiInstruction()
+ result = this.getInstruction(_) or
+ result = this.getAPhiInstruction()
}
/**
@@ -78,7 +78,9 @@ class IRBlockBase extends TIRBlock {
/**
* Gets the last instruction in this block.
*/
- final Instruction getLastInstruction() { result = getInstruction(getInstructionCount() - 1) }
+ final Instruction getLastInstruction() {
+ result = this.getInstruction(this.getInstructionCount() - 1)
+ }
/**
* Gets the number of non-`Phi` instructions in this block.
@@ -149,7 +151,7 @@ class IRBlock extends IRBlockBase {
* Block `A` dominates block `B` if any control flow path from the entry block of the function to
* block `B` must pass through block `A`. A block always dominates itself.
*/
- final predicate dominates(IRBlock block) { strictlyDominates(block) or this = block }
+ final predicate dominates(IRBlock block) { this.strictlyDominates(block) or this = block }
/**
* Gets a block on the dominance frontier of this block.
@@ -159,8 +161,8 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock dominanceFrontier() {
- dominates(result.getAPredecessor()) and
- not strictlyDominates(result)
+ this.dominates(result.getAPredecessor()) and
+ not this.strictlyDominates(result)
}
/**
@@ -189,7 +191,7 @@ class IRBlock extends IRBlockBase {
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
* function must pass through block `A`. A block always post-dominates itself.
*/
- final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
+ final predicate postDominates(IRBlock block) { this.strictlyPostDominates(block) or this = block }
/**
* Gets a block on the post-dominance frontier of this block.
@@ -199,16 +201,16 @@ class IRBlock extends IRBlockBase {
*/
pragma[noinline]
final IRBlock postPominanceFrontier() {
- postDominates(result.getASuccessor()) and
- not strictlyPostDominates(result)
+ this.postDominates(result.getASuccessor()) and
+ not this.strictlyPostDominates(result)
}
/**
* Holds if this block is reachable from the entry block of its function.
*/
final predicate isReachableFromFunctionEntry() {
- this = getEnclosingIRFunction().getEntryBlock() or
- getAPredecessor().isReachableFromFunctionEntry()
+ this = this.getEnclosingIRFunction().getEntryBlock() or
+ this.getAPredecessor().isReachableFromFunctionEntry()
}
}
diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll
index 2fb3edad602..88a973fc5a8 100644
--- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll
+++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll
@@ -41,7 +41,7 @@ class Instruction extends Construction::TStageInstruction {
}
/** Gets a textual representation of this element. */
- final string toString() { result = getOpcode().toString() + ": " + getAST().toString() }
+ final string toString() { result = this.getOpcode().toString() + ": " + this.getAST().toString() }
/**
* Gets a string showing the result, opcode, and operands of the instruction, equivalent to what
@@ -50,7 +50,8 @@ class Instruction extends Construction::TStageInstruction {
* `mu0_28(int) = Store r0_26, r0_27`
*/
final string getDumpString() {
- result = getResultString() + " = " + getOperationString() + " " + getOperandsString()
+ result =
+ this.getResultString() + " = " + this.getOperationString() + " " + this.getOperandsString()
}
private predicate shouldGenerateDumpStrings() {
@@ -66,10 +67,13 @@ class Instruction extends Construction::TStageInstruction {
* VariableAddress[x]
*/
final string getOperationString() {
- shouldGenerateDumpStrings() and
- if exists(getImmediateString())
- then result = getOperationPrefix() + getOpcode().toString() + "[" + getImmediateString() + "]"
- else result = getOperationPrefix() + getOpcode().toString()
+ this.shouldGenerateDumpStrings() and
+ if exists(this.getImmediateString())
+ then
+ result =
+ this.getOperationPrefix() + this.getOpcode().toString() + "[" + this.getImmediateString() +
+ "]"
+ else result = this.getOperationPrefix() + this.getOpcode().toString()
}
/**
@@ -78,17 +82,17 @@ class Instruction extends Construction::TStageInstruction {
string getImmediateString() { none() }
private string getOperationPrefix() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
if this instanceof SideEffectInstruction then result = "^" else result = ""
}
private string getResultPrefix() {
- shouldGenerateDumpStrings() and
- if getResultIRType() instanceof IRVoidType
+ this.shouldGenerateDumpStrings() and
+ if this.getResultIRType() instanceof IRVoidType
then result = "v"
else
- if hasMemoryResult()
- then if isResultModeled() then result = "m" else result = "mu"
+ if this.hasMemoryResult()
+ then if this.isResultModeled() then result = "m" else result = "mu"
else result = "r"
}
@@ -97,7 +101,7 @@ class Instruction extends Construction::TStageInstruction {
* used by debugging and printing code only.
*/
int getDisplayIndexInBlock() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
exists(IRBlock block |
this = block.getInstruction(result)
or
@@ -111,12 +115,12 @@ class Instruction extends Construction::TStageInstruction {
}
private int getLineRank() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
this =
rank[result](Instruction instr |
instr =
- getAnInstructionAtLine(getEnclosingIRFunction(), getLocation().getFile(),
- getLocation().getStartLine())
+ getAnInstructionAtLine(this.getEnclosingIRFunction(), this.getLocation().getFile(),
+ this.getLocation().getStartLine())
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)
@@ -130,8 +134,9 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1`
*/
string getResultId() {
- shouldGenerateDumpStrings() and
- result = getResultPrefix() + getAST().getLocation().getStartLine() + "_" + getLineRank()
+ this.shouldGenerateDumpStrings() and
+ result =
+ this.getResultPrefix() + this.getAST().getLocation().getStartLine() + "_" + this.getLineRank()
}
/**
@@ -142,8 +147,8 @@ class Instruction extends Construction::TStageInstruction {
* Example: `r1_1(int*)`
*/
final string getResultString() {
- shouldGenerateDumpStrings() and
- result = getResultId() + "(" + getResultLanguageType().getDumpString() + ")"
+ this.shouldGenerateDumpStrings() and
+ result = this.getResultId() + "(" + this.getResultLanguageType().getDumpString() + ")"
}
/**
@@ -153,10 +158,10 @@ class Instruction extends Construction::TStageInstruction {
* Example: `func:r3_4, this:r3_5`
*/
string getOperandsString() {
- shouldGenerateDumpStrings() and
+ this.shouldGenerateDumpStrings() and
result =
concat(Operand operand |
- operand = getAnOperand()
+ operand = this.getAnOperand()
|
operand.getDumpString(), ", " order by operand.getDumpSortOrder()
)
@@ -190,7 +195,7 @@ class Instruction extends Construction::TStageInstruction {
* Gets the function that contains this instruction.
*/
final Language::Function getEnclosingFunction() {
- result = getEnclosingIRFunction().getFunction()
+ result = this.getEnclosingIRFunction().getFunction()
}
/**
@@ -208,7 +213,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets the location of the source code for this instruction.
*/
- final Language::Location getLocation() { result = getAST().getLocation() }
+ final Language::Location getLocation() { result = this.getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
@@ -243,7 +248,7 @@ class Instruction extends Construction::TStageInstruction {
* a result, its result type will be `IRVoidType`.
*/
cached
- final IRType getResultIRType() { result = getResultLanguageType().getIRType() }
+ final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() }
/**
* Gets the type of the result produced by this instruction. If the
@@ -254,7 +259,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final Language::Type getResultType() {
exists(Language::LanguageType resultType |
- resultType = getResultLanguageType() and
+ resultType = this.getResultLanguageType() and
(
resultType.hasUnspecifiedType(result, _)
or
@@ -283,7 +288,7 @@ class Instruction extends Construction::TStageInstruction {
* result of the `Load` instruction is a prvalue of type `int`, representing
* the integer value loaded from variable `x`.
*/
- final predicate isGLValue() { getResultLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getResultLanguageType().hasType(_, true) }
/**
* Gets the size of the result produced by this instruction, in bytes. If the
@@ -292,7 +297,7 @@ class Instruction extends Construction::TStageInstruction {
* If `this.isGLValue()` holds for this instruction, the value of
* `getResultSize()` will always be the size of a pointer.
*/
- final int getResultSize() { result = getResultLanguageType().getByteSize() }
+ final int getResultSize() { result = this.getResultLanguageType().getByteSize() }
/**
* Gets the opcode that specifies the operation performed by this instruction.
@@ -314,14 +319,16 @@ class Instruction extends Construction::TStageInstruction {
/**
* Holds if this instruction produces a memory result.
*/
- final predicate hasMemoryResult() { exists(getResultMemoryAccess()) }
+ final predicate hasMemoryResult() { exists(this.getResultMemoryAccess()) }
/**
* Gets the kind of memory access performed by this instruction's result.
* Holds only for instructions with a memory result.
*/
pragma[inline]
- final MemoryAccessKind getResultMemoryAccess() { result = getOpcode().getWriteMemoryAccess() }
+ final MemoryAccessKind getResultMemoryAccess() {
+ result = this.getOpcode().getWriteMemoryAccess()
+ }
/**
* Holds if the memory access performed by this instruction's result will not always write to
@@ -332,7 +339,7 @@ class Instruction extends Construction::TStageInstruction {
* (for example, the global side effects of a function call).
*/
pragma[inline]
- final predicate hasResultMayMemoryAccess() { getOpcode().hasMayWriteMemoryAccess() }
+ final predicate hasResultMayMemoryAccess() { this.getOpcode().hasMayWriteMemoryAccess() }
/**
* Gets the operand that holds the memory address to which this instruction stores its
@@ -340,7 +347,7 @@ class Instruction extends Construction::TStageInstruction {
* is `r1`.
*/
final AddressOperand getResultAddressOperand() {
- getResultMemoryAccess().usesAddressOperand() and
+ this.getResultMemoryAccess().usesAddressOperand() and
result.getUse() = this
}
@@ -349,7 +356,7 @@ class Instruction extends Construction::TStageInstruction {
* result, if any. For example, in `m3 = Store r1, r2`, the result of `getResultAddressOperand()`
* is the instruction that defines `r1`.
*/
- final Instruction getResultAddress() { result = getResultAddressOperand().getDef() }
+ final Instruction getResultAddress() { result = this.getResultAddressOperand().getDef() }
/**
* Holds if the result of this instruction is precisely modeled in SSA. Always
@@ -368,7 +375,7 @@ class Instruction extends Construction::TStageInstruction {
*/
final predicate isResultModeled() {
// Register results are always in SSA form.
- not hasMemoryResult() or
+ not this.hasMemoryResult() or
Construction::hasModeledMemoryResult(this)
}
@@ -412,7 +419,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct successors of this instruction.
*/
- final Instruction getASuccessor() { result = getSuccessor(_) }
+ final Instruction getASuccessor() { result = this.getSuccessor(_) }
/**
* Gets a predecessor of this instruction such that the predecessor reaches
@@ -423,7 +430,7 @@ class Instruction extends Construction::TStageInstruction {
/**
* Gets all direct predecessors of this instruction.
*/
- final Instruction getAPredecessor() { result = getPredecessor(_) }
+ final Instruction getAPredecessor() { result = this.getPredecessor(_) }
}
/**
@@ -543,7 +550,7 @@ class IndexedInstruction extends Instruction {
* at this instruction. This instruction has no predecessors.
*/
class EnterFunctionInstruction extends Instruction {
- EnterFunctionInstruction() { getOpcode() instanceof Opcode::EnterFunction }
+ EnterFunctionInstruction() { this.getOpcode() instanceof Opcode::EnterFunction }
}
/**
@@ -554,7 +561,7 @@ class EnterFunctionInstruction extends Instruction {
* struct, or union, see `FieldAddressInstruction`.
*/
class VariableAddressInstruction extends VariableInstruction {
- VariableAddressInstruction() { getOpcode() instanceof Opcode::VariableAddress }
+ VariableAddressInstruction() { this.getOpcode() instanceof Opcode::VariableAddress }
}
/**
@@ -566,7 +573,7 @@ class VariableAddressInstruction extends VariableInstruction {
* The result has an `IRFunctionAddress` type.
*/
class FunctionAddressInstruction extends FunctionInstruction {
- FunctionAddressInstruction() { getOpcode() instanceof Opcode::FunctionAddress }
+ FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress }
}
/**
@@ -577,7 +584,7 @@ class FunctionAddressInstruction extends FunctionInstruction {
* initializes that parameter.
*/
class InitializeParameterInstruction extends VariableInstruction {
- InitializeParameterInstruction() { getOpcode() instanceof Opcode::InitializeParameter }
+ InitializeParameterInstruction() { this.getOpcode() instanceof Opcode::InitializeParameter }
/**
* Gets the parameter initialized by this instruction.
@@ -603,7 +610,7 @@ class InitializeParameterInstruction extends VariableInstruction {
* initialized elsewhere, would not otherwise have a definition in this function.
*/
class InitializeNonLocalInstruction extends Instruction {
- InitializeNonLocalInstruction() { getOpcode() instanceof Opcode::InitializeNonLocal }
+ InitializeNonLocalInstruction() { this.getOpcode() instanceof Opcode::InitializeNonLocal }
}
/**
@@ -611,7 +618,7 @@ class InitializeNonLocalInstruction extends Instruction {
* with the value of that memory on entry to the function.
*/
class InitializeIndirectionInstruction extends VariableInstruction {
- InitializeIndirectionInstruction() { getOpcode() instanceof Opcode::InitializeIndirection }
+ InitializeIndirectionInstruction() { this.getOpcode() instanceof Opcode::InitializeIndirection }
/**
* Gets the parameter initialized by this instruction.
@@ -635,24 +642,24 @@ class InitializeIndirectionInstruction extends VariableInstruction {
* An instruction that initializes the `this` pointer parameter of the enclosing function.
*/
class InitializeThisInstruction extends Instruction {
- InitializeThisInstruction() { getOpcode() instanceof Opcode::InitializeThis }
+ InitializeThisInstruction() { this.getOpcode() instanceof Opcode::InitializeThis }
}
/**
* An instruction that computes the address of a non-static field of an object.
*/
class FieldAddressInstruction extends FieldInstruction {
- FieldAddressInstruction() { getOpcode() instanceof Opcode::FieldAddress }
+ FieldAddressInstruction() { this.getOpcode() instanceof Opcode::FieldAddress }
/**
* Gets the operand that provides the address of the object containing the field.
*/
- final UnaryOperand getObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the object containing the field.
*/
- final Instruction getObjectAddress() { result = getObjectAddressOperand().getDef() }
+ final Instruction getObjectAddress() { result = this.getObjectAddressOperand().getDef() }
}
/**
@@ -661,17 +668,19 @@ class FieldAddressInstruction extends FieldInstruction {
* This instruction is used for element access to C# arrays.
*/
class ElementsAddressInstruction extends UnaryInstruction {
- ElementsAddressInstruction() { getOpcode() instanceof Opcode::ElementsAddress }
+ ElementsAddressInstruction() { this.getOpcode() instanceof Opcode::ElementsAddress }
/**
* Gets the operand that provides the address of the array object.
*/
- final UnaryOperand getArrayObjectAddressOperand() { result = getAnOperand() }
+ final UnaryOperand getArrayObjectAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the array object.
*/
- final Instruction getArrayObjectAddress() { result = getArrayObjectAddressOperand().getDef() }
+ final Instruction getArrayObjectAddress() {
+ result = this.getArrayObjectAddressOperand().getDef()
+ }
}
/**
@@ -685,7 +694,7 @@ class ElementsAddressInstruction extends UnaryInstruction {
* taken may want to ignore any function that contains an `ErrorInstruction`.
*/
class ErrorInstruction extends Instruction {
- ErrorInstruction() { getOpcode() instanceof Opcode::Error }
+ ErrorInstruction() { this.getOpcode() instanceof Opcode::Error }
}
/**
@@ -695,7 +704,7 @@ class ErrorInstruction extends Instruction {
* an initializer, or whose initializer only partially initializes the variable.
*/
class UninitializedInstruction extends VariableInstruction {
- UninitializedInstruction() { getOpcode() instanceof Opcode::Uninitialized }
+ UninitializedInstruction() { this.getOpcode() instanceof Opcode::Uninitialized }
/**
* Gets the variable that is uninitialized.
@@ -710,7 +719,7 @@ class UninitializedInstruction extends VariableInstruction {
* least one instruction, even when the AST has no semantic effect.
*/
class NoOpInstruction extends Instruction {
- NoOpInstruction() { getOpcode() instanceof Opcode::NoOp }
+ NoOpInstruction() { this.getOpcode() instanceof Opcode::NoOp }
}
/**
@@ -732,32 +741,32 @@ class NoOpInstruction extends Instruction {
* `void`-returning function.
*/
class ReturnInstruction extends Instruction {
- ReturnInstruction() { getOpcode() instanceof ReturnOpcode }
+ ReturnInstruction() { this.getOpcode() instanceof ReturnOpcode }
}
/**
* An instruction that returns control to the caller of the function, without returning a value.
*/
class ReturnVoidInstruction extends ReturnInstruction {
- ReturnVoidInstruction() { getOpcode() instanceof Opcode::ReturnVoid }
+ ReturnVoidInstruction() { this.getOpcode() instanceof Opcode::ReturnVoid }
}
/**
* An instruction that returns control to the caller of the function, including a return value.
*/
class ReturnValueInstruction extends ReturnInstruction {
- ReturnValueInstruction() { getOpcode() instanceof Opcode::ReturnValue }
+ ReturnValueInstruction() { this.getOpcode() instanceof Opcode::ReturnValue }
/**
* Gets the operand that provides the value being returned by the function.
*/
- final LoadOperand getReturnValueOperand() { result = getAnOperand() }
+ final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available.
*/
- final Instruction getReturnValue() { result = getReturnValueOperand().getDef() }
+ final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
}
/**
@@ -770,28 +779,28 @@ class ReturnValueInstruction extends ReturnInstruction {
* that the caller initialized the memory pointed to by the parameter before the call.
*/
class ReturnIndirectionInstruction extends VariableInstruction {
- ReturnIndirectionInstruction() { getOpcode() instanceof Opcode::ReturnIndirection }
+ ReturnIndirectionInstruction() { this.getOpcode() instanceof Opcode::ReturnIndirection }
/**
* Gets the operand that provides the value of the pointed-to memory.
*/
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the pointed-to memory, if an exact
* definition is available.
*/
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/**
* Gets the operand that provides the address of the pointed-to memory.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the pointed-to memory.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
/**
* Gets the parameter for which this instruction reads the final pointed-to value within the
@@ -821,12 +830,12 @@ class ReturnIndirectionInstruction extends VariableInstruction {
*
* There are several different copy instructions, depending on the source and destination of the
* copy operation:
- * - `CopyInstruction` - Copies a register operand to a register result.
+ * - `CopyValueInstruction` - Copies a register operand to a register result.
* - `LoadInstruction` - Copies a memory operand to a register result.
* - `StoreInstruction` - Copies a register operand to a memory result.
*/
class CopyInstruction extends Instruction {
- CopyInstruction() { getOpcode() instanceof CopyOpcode }
+ CopyInstruction() { this.getOpcode() instanceof CopyOpcode }
/**
* Gets the operand that provides the input value of the copy.
@@ -837,16 +846,16 @@ class CopyInstruction extends Instruction {
* Gets the instruction whose result provides the input value of the copy, if an exact definition
* is available.
*/
- final Instruction getSourceValue() { result = getSourceValueOperand().getDef() }
+ final Instruction getSourceValue() { result = this.getSourceValueOperand().getDef() }
}
/**
* An instruction that returns a register result containing a copy of its register operand.
*/
class CopyValueInstruction extends CopyInstruction, UnaryInstruction {
- CopyValueInstruction() { getOpcode() instanceof Opcode::CopyValue }
+ CopyValueInstruction() { this.getOpcode() instanceof Opcode::CopyValue }
- final override UnaryOperand getSourceValueOperand() { result = getAnOperand() }
+ final override UnaryOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -863,47 +872,49 @@ private string getAddressOperandDescription(AddressOperand operand) {
* An instruction that returns a register result containing a copy of its memory operand.
*/
class LoadInstruction extends CopyInstruction {
- LoadInstruction() { getOpcode() instanceof Opcode::Load }
+ LoadInstruction() { this.getOpcode() instanceof Opcode::Load }
final override string getImmediateString() {
- result = getAddressOperandDescription(getSourceAddressOperand())
+ result = getAddressOperandDescription(this.getSourceAddressOperand())
}
/**
* Gets the operand that provides the address of the value being loaded.
*/
- final AddressOperand getSourceAddressOperand() { result = getAnOperand() }
+ final AddressOperand getSourceAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the value being loaded.
*/
- final Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
+ final Instruction getSourceAddress() { result = this.getSourceAddressOperand().getDef() }
- final override LoadOperand getSourceValueOperand() { result = getAnOperand() }
+ final override LoadOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
* An instruction that returns a memory result containing a copy of its register operand.
*/
class StoreInstruction extends CopyInstruction {
- StoreInstruction() { getOpcode() instanceof Opcode::Store }
+ StoreInstruction() { this.getOpcode() instanceof Opcode::Store }
final override string getImmediateString() {
- result = getAddressOperandDescription(getDestinationAddressOperand())
+ result = getAddressOperandDescription(this.getDestinationAddressOperand())
}
/**
* Gets the operand that provides the address of the location to which the value will be stored.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the location to which the value will
* be stored, if an exact definition is available.
*/
- final Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ final Instruction getDestinationAddress() {
+ result = this.getDestinationAddressOperand().getDef()
+ }
- final override StoreValueOperand getSourceValueOperand() { result = getAnOperand() }
+ final override StoreValueOperand getSourceValueOperand() { result = this.getAnOperand() }
}
/**
@@ -911,27 +922,27 @@ class StoreInstruction extends CopyInstruction {
* operand.
*/
class ConditionalBranchInstruction extends Instruction {
- ConditionalBranchInstruction() { getOpcode() instanceof Opcode::ConditionalBranch }
+ ConditionalBranchInstruction() { this.getOpcode() instanceof Opcode::ConditionalBranch }
/**
* Gets the operand that provides the Boolean condition controlling the branch.
*/
- final ConditionOperand getConditionOperand() { result = getAnOperand() }
+ final ConditionOperand getConditionOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the Boolean condition controlling the branch.
*/
- final Instruction getCondition() { result = getConditionOperand().getDef() }
+ final Instruction getCondition() { result = this.getConditionOperand().getDef() }
/**
* Gets the instruction to which control will flow if the condition is true.
*/
- final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }
+ final Instruction getTrueSuccessor() { result = this.getSuccessor(EdgeKind::trueEdge()) }
/**
* Gets the instruction to which control will flow if the condition is false.
*/
- final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
+ final Instruction getFalseSuccessor() { result = this.getSuccessor(EdgeKind::falseEdge()) }
}
/**
@@ -943,14 +954,14 @@ class ConditionalBranchInstruction extends Instruction {
* successors.
*/
class ExitFunctionInstruction extends Instruction {
- ExitFunctionInstruction() { getOpcode() instanceof Opcode::ExitFunction }
+ ExitFunctionInstruction() { this.getOpcode() instanceof Opcode::ExitFunction }
}
/**
* An instruction whose result is a constant value.
*/
class ConstantInstruction extends ConstantValueInstruction {
- ConstantInstruction() { getOpcode() instanceof Opcode::Constant }
+ ConstantInstruction() { this.getOpcode() instanceof Opcode::Constant }
}
/**
@@ -959,7 +970,7 @@ class ConstantInstruction extends ConstantValueInstruction {
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
exists(IRType resultType |
- resultType = getResultIRType() and
+ resultType = this.getResultIRType() and
(resultType instanceof IRIntegerType or resultType instanceof IRBooleanType)
)
}
@@ -969,7 +980,7 @@ class IntegerConstantInstruction extends ConstantInstruction {
* An instruction whose result is a constant value of floating-point type.
*/
class FloatConstantInstruction extends ConstantInstruction {
- FloatConstantInstruction() { getResultIRType() instanceof IRFloatingPointType }
+ FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType }
}
/**
@@ -978,7 +989,9 @@ class FloatConstantInstruction extends ConstantInstruction {
class StringConstantInstruction extends VariableInstruction {
override IRStringLiteral var;
- final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) }
+ final override string getImmediateString() {
+ result = Language::getStringLiteralText(this.getValue())
+ }
/**
* Gets the string literal whose address is returned by this instruction.
@@ -990,37 +1003,37 @@ class StringConstantInstruction extends VariableInstruction {
* An instruction whose result is computed from two operands.
*/
class BinaryInstruction extends Instruction {
- BinaryInstruction() { getOpcode() instanceof BinaryOpcode }
+ BinaryInstruction() { this.getOpcode() instanceof BinaryOpcode }
/**
* Gets the left operand of this binary instruction.
*/
- final LeftOperand getLeftOperand() { result = getAnOperand() }
+ final LeftOperand getLeftOperand() { result = this.getAnOperand() }
/**
* Gets the right operand of this binary instruction.
*/
- final RightOperand getRightOperand() { result = getAnOperand() }
+ final RightOperand getRightOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the value of the left operand of this binary
* instruction.
*/
- final Instruction getLeft() { result = getLeftOperand().getDef() }
+ final Instruction getLeft() { result = this.getLeftOperand().getDef() }
/**
* Gets the instruction whose result provides the value of the right operand of this binary
* instruction.
*/
- final Instruction getRight() { result = getRightOperand().getDef() }
+ final Instruction getRight() { result = this.getRightOperand().getDef() }
/**
* Holds if this instruction's operands are `op1` and `op2`, in either order.
*/
final predicate hasOperands(Operand op1, Operand op2) {
- op1 = getLeftOperand() and op2 = getRightOperand()
+ op1 = this.getLeftOperand() and op2 = this.getRightOperand()
or
- op1 = getRightOperand() and op2 = getLeftOperand()
+ op1 = this.getRightOperand() and op2 = this.getLeftOperand()
}
}
@@ -1028,7 +1041,7 @@ class BinaryInstruction extends Instruction {
* An instruction that computes the result of an arithmetic operation.
*/
class ArithmeticInstruction extends Instruction {
- ArithmeticInstruction() { getOpcode() instanceof ArithmeticOpcode }
+ ArithmeticInstruction() { this.getOpcode() instanceof ArithmeticOpcode }
}
/**
@@ -1050,7 +1063,7 @@ class UnaryArithmeticInstruction extends ArithmeticInstruction, UnaryInstruction
* performed according to IEEE-754.
*/
class AddInstruction extends BinaryArithmeticInstruction {
- AddInstruction() { getOpcode() instanceof Opcode::Add }
+ AddInstruction() { this.getOpcode() instanceof Opcode::Add }
}
/**
@@ -1061,7 +1074,7 @@ class AddInstruction extends BinaryArithmeticInstruction {
* according to IEEE-754.
*/
class SubInstruction extends BinaryArithmeticInstruction {
- SubInstruction() { getOpcode() instanceof Opcode::Sub }
+ SubInstruction() { this.getOpcode() instanceof Opcode::Sub }
}
/**
@@ -1072,7 +1085,7 @@ class SubInstruction extends BinaryArithmeticInstruction {
* performed according to IEEE-754.
*/
class MulInstruction extends BinaryArithmeticInstruction {
- MulInstruction() { getOpcode() instanceof Opcode::Mul }
+ MulInstruction() { this.getOpcode() instanceof Opcode::Mul }
}
/**
@@ -1083,7 +1096,7 @@ class MulInstruction extends BinaryArithmeticInstruction {
* to IEEE-754.
*/
class DivInstruction extends BinaryArithmeticInstruction {
- DivInstruction() { getOpcode() instanceof Opcode::Div }
+ DivInstruction() { this.getOpcode() instanceof Opcode::Div }
}
/**
@@ -1093,7 +1106,7 @@ class DivInstruction extends BinaryArithmeticInstruction {
* division by zero or integer overflow is undefined.
*/
class RemInstruction extends BinaryArithmeticInstruction {
- RemInstruction() { getOpcode() instanceof Opcode::Rem }
+ RemInstruction() { this.getOpcode() instanceof Opcode::Rem }
}
/**
@@ -1104,14 +1117,14 @@ class RemInstruction extends BinaryArithmeticInstruction {
* is performed according to IEEE-754.
*/
class NegateInstruction extends UnaryArithmeticInstruction {
- NegateInstruction() { getOpcode() instanceof Opcode::Negate }
+ NegateInstruction() { this.getOpcode() instanceof Opcode::Negate }
}
/**
* An instruction that computes the result of a bitwise operation.
*/
class BitwiseInstruction extends Instruction {
- BitwiseInstruction() { getOpcode() instanceof BitwiseOpcode }
+ BitwiseInstruction() { this.getOpcode() instanceof BitwiseOpcode }
}
/**
@@ -1130,7 +1143,7 @@ class UnaryBitwiseInstruction extends BitwiseInstruction, UnaryInstruction { }
* Both operands must have the same integer type, which will also be the result type.
*/
class BitAndInstruction extends BinaryBitwiseInstruction {
- BitAndInstruction() { getOpcode() instanceof Opcode::BitAnd }
+ BitAndInstruction() { this.getOpcode() instanceof Opcode::BitAnd }
}
/**
@@ -1139,7 +1152,7 @@ class BitAndInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitOrInstruction extends BinaryBitwiseInstruction {
- BitOrInstruction() { getOpcode() instanceof Opcode::BitOr }
+ BitOrInstruction() { this.getOpcode() instanceof Opcode::BitOr }
}
/**
@@ -1148,7 +1161,7 @@ class BitOrInstruction extends BinaryBitwiseInstruction {
* Both operands must have the same integer type, which will also be the result type.
*/
class BitXorInstruction extends BinaryBitwiseInstruction {
- BitXorInstruction() { getOpcode() instanceof Opcode::BitXor }
+ BitXorInstruction() { this.getOpcode() instanceof Opcode::BitXor }
}
/**
@@ -1159,7 +1172,7 @@ class BitXorInstruction extends BinaryBitwiseInstruction {
* rightmost bits are zero-filled.
*/
class ShiftLeftInstruction extends BinaryBitwiseInstruction {
- ShiftLeftInstruction() { getOpcode() instanceof Opcode::ShiftLeft }
+ ShiftLeftInstruction() { this.getOpcode() instanceof Opcode::ShiftLeft }
}
/**
@@ -1172,7 +1185,7 @@ class ShiftLeftInstruction extends BinaryBitwiseInstruction {
* of the left operand.
*/
class ShiftRightInstruction extends BinaryBitwiseInstruction {
- ShiftRightInstruction() { getOpcode() instanceof Opcode::ShiftRight }
+ ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
@@ -1183,7 +1196,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
int elementSize;
PointerArithmeticInstruction() {
- getOpcode() instanceof PointerArithmeticOpcode and
+ this.getOpcode() instanceof PointerArithmeticOpcode and
elementSize = Raw::getInstructionElementSize(this)
}
@@ -1206,7 +1219,7 @@ class PointerArithmeticInstruction extends BinaryInstruction {
* An instruction that adds or subtracts an integer offset from a pointer.
*/
class PointerOffsetInstruction extends PointerArithmeticInstruction {
- PointerOffsetInstruction() { getOpcode() instanceof PointerOffsetOpcode }
+ PointerOffsetInstruction() { this.getOpcode() instanceof PointerOffsetOpcode }
}
/**
@@ -1217,7 +1230,7 @@ class PointerOffsetInstruction extends PointerArithmeticInstruction {
* overflow is undefined.
*/
class PointerAddInstruction extends PointerOffsetInstruction {
- PointerAddInstruction() { getOpcode() instanceof Opcode::PointerAdd }
+ PointerAddInstruction() { this.getOpcode() instanceof Opcode::PointerAdd }
}
/**
@@ -1228,7 +1241,7 @@ class PointerAddInstruction extends PointerOffsetInstruction {
* pointer underflow is undefined.
*/
class PointerSubInstruction extends PointerOffsetInstruction {
- PointerSubInstruction() { getOpcode() instanceof Opcode::PointerSub }
+ PointerSubInstruction() { this.getOpcode() instanceof Opcode::PointerSub }
}
/**
@@ -1241,31 +1254,31 @@ class PointerSubInstruction extends PointerOffsetInstruction {
* undefined.
*/
class PointerDiffInstruction extends PointerArithmeticInstruction {
- PointerDiffInstruction() { getOpcode() instanceof Opcode::PointerDiff }
+ PointerDiffInstruction() { this.getOpcode() instanceof Opcode::PointerDiff }
}
/**
* An instruction whose result is computed from a single operand.
*/
class UnaryInstruction extends Instruction {
- UnaryInstruction() { getOpcode() instanceof UnaryOpcode }
+ UnaryInstruction() { this.getOpcode() instanceof UnaryOpcode }
/**
* Gets the sole operand of this instruction.
*/
- final UnaryOperand getUnaryOperand() { result = getAnOperand() }
+ final UnaryOperand getUnaryOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the sole operand of this instruction.
*/
- final Instruction getUnary() { result = getUnaryOperand().getDef() }
+ final Instruction getUnary() { result = this.getUnaryOperand().getDef() }
}
/**
* An instruction that converts the value of its operand to a value of a different type.
*/
class ConvertInstruction extends UnaryInstruction {
- ConvertInstruction() { getOpcode() instanceof Opcode::Convert }
+ ConvertInstruction() { this.getOpcode() instanceof Opcode::Convert }
}
/**
@@ -1279,7 +1292,7 @@ class ConvertInstruction extends UnaryInstruction {
* `as` expression.
*/
class CheckedConvertOrNullInstruction extends UnaryInstruction {
- CheckedConvertOrNullInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrNull }
+ CheckedConvertOrNullInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrNull }
}
/**
@@ -1293,7 +1306,7 @@ class CheckedConvertOrNullInstruction extends UnaryInstruction {
* expression.
*/
class CheckedConvertOrThrowInstruction extends UnaryInstruction {
- CheckedConvertOrThrowInstruction() { getOpcode() instanceof Opcode::CheckedConvertOrThrow }
+ CheckedConvertOrThrowInstruction() { this.getOpcode() instanceof Opcode::CheckedConvertOrThrow }
}
/**
@@ -1306,7 +1319,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
* the most-derived object.
*/
class CompleteObjectAddressInstruction extends UnaryInstruction {
- CompleteObjectAddressInstruction() { getOpcode() instanceof Opcode::CompleteObjectAddress }
+ CompleteObjectAddressInstruction() { this.getOpcode() instanceof Opcode::CompleteObjectAddress }
}
/**
@@ -1351,7 +1364,7 @@ class InheritanceConversionInstruction extends UnaryInstruction {
* An instruction that converts from the address of a derived class to the address of a base class.
*/
class ConvertToBaseInstruction extends InheritanceConversionInstruction {
- ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode }
+ ConvertToBaseInstruction() { this.getOpcode() instanceof ConvertToBaseOpcode }
}
/**
@@ -1361,7 +1374,9 @@ class ConvertToBaseInstruction extends InheritanceConversionInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase }
+ ConvertToNonVirtualBaseInstruction() {
+ this.getOpcode() instanceof Opcode::ConvertToNonVirtualBase
+ }
}
/**
@@ -1371,7 +1386,7 @@ class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
- ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase }
+ ConvertToVirtualBaseInstruction() { this.getOpcode() instanceof Opcode::ConvertToVirtualBase }
}
/**
@@ -1381,7 +1396,7 @@ class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction {
* If the operand holds a null address, the result is a null address.
*/
class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
- ConvertToDerivedInstruction() { getOpcode() instanceof Opcode::ConvertToDerived }
+ ConvertToDerivedInstruction() { this.getOpcode() instanceof Opcode::ConvertToDerived }
}
/**
@@ -1390,7 +1405,7 @@ class ConvertToDerivedInstruction extends InheritanceConversionInstruction {
* The operand must have an integer type, which will also be the result type.
*/
class BitComplementInstruction extends UnaryBitwiseInstruction {
- BitComplementInstruction() { getOpcode() instanceof Opcode::BitComplement }
+ BitComplementInstruction() { this.getOpcode() instanceof Opcode::BitComplement }
}
/**
@@ -1399,14 +1414,14 @@ class BitComplementInstruction extends UnaryBitwiseInstruction {
* The operand must have a Boolean type, which will also be the result type.
*/
class LogicalNotInstruction extends UnaryInstruction {
- LogicalNotInstruction() { getOpcode() instanceof Opcode::LogicalNot }
+ LogicalNotInstruction() { this.getOpcode() instanceof Opcode::LogicalNot }
}
/**
* An instruction that compares two numeric operands.
*/
class CompareInstruction extends BinaryInstruction {
- CompareInstruction() { getOpcode() instanceof CompareOpcode }
+ CompareInstruction() { this.getOpcode() instanceof CompareOpcode }
}
/**
@@ -1417,7 +1432,7 @@ class CompareInstruction extends BinaryInstruction {
* unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareEQInstruction extends CompareInstruction {
- CompareEQInstruction() { getOpcode() instanceof Opcode::CompareEQ }
+ CompareEQInstruction() { this.getOpcode() instanceof Opcode::CompareEQ }
}
/**
@@ -1428,14 +1443,14 @@ class CompareEQInstruction extends CompareInstruction {
* `left == right`. Floating-point comparison is performed according to IEEE-754.
*/
class CompareNEInstruction extends CompareInstruction {
- CompareNEInstruction() { getOpcode() instanceof Opcode::CompareNE }
+ CompareNEInstruction() { this.getOpcode() instanceof Opcode::CompareNE }
}
/**
* An instruction that does a relative comparison of two values, such as `<` or `>=`.
*/
class RelationalInstruction extends CompareInstruction {
- RelationalInstruction() { getOpcode() instanceof RelationalOpcode }
+ RelationalInstruction() { this.getOpcode() instanceof RelationalOpcode }
/**
* Gets the operand on the "greater" (or "greater-or-equal") side
@@ -1467,11 +1482,11 @@ class RelationalInstruction extends CompareInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLTInstruction extends RelationalInstruction {
- CompareLTInstruction() { getOpcode() instanceof Opcode::CompareLT }
+ CompareLTInstruction() { this.getOpcode() instanceof Opcode::CompareLT }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { any() }
}
@@ -1484,11 +1499,11 @@ class CompareLTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGTInstruction extends RelationalInstruction {
- CompareGTInstruction() { getOpcode() instanceof Opcode::CompareGT }
+ CompareGTInstruction() { this.getOpcode() instanceof Opcode::CompareGT }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { any() }
}
@@ -1502,11 +1517,11 @@ class CompareGTInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareLEInstruction extends RelationalInstruction {
- CompareLEInstruction() { getOpcode() instanceof Opcode::CompareLE }
+ CompareLEInstruction() { this.getOpcode() instanceof Opcode::CompareLE }
- override Instruction getLesser() { result = getLeft() }
+ override Instruction getLesser() { result = this.getLeft() }
- override Instruction getGreater() { result = getRight() }
+ override Instruction getGreater() { result = this.getRight() }
override predicate isStrict() { none() }
}
@@ -1520,11 +1535,11 @@ class CompareLEInstruction extends RelationalInstruction {
* are unordered. Floating-point comparison is performed according to IEEE-754.
*/
class CompareGEInstruction extends RelationalInstruction {
- CompareGEInstruction() { getOpcode() instanceof Opcode::CompareGE }
+ CompareGEInstruction() { this.getOpcode() instanceof Opcode::CompareGE }
- override Instruction getLesser() { result = getRight() }
+ override Instruction getLesser() { result = this.getRight() }
- override Instruction getGreater() { result = getLeft() }
+ override Instruction getGreater() { result = this.getLeft() }
override predicate isStrict() { none() }
}
@@ -1543,78 +1558,78 @@ class CompareGEInstruction extends RelationalInstruction {
* of any case edge.
*/
class SwitchInstruction extends Instruction {
- SwitchInstruction() { getOpcode() instanceof Opcode::Switch }
+ SwitchInstruction() { this.getOpcode() instanceof Opcode::Switch }
/** Gets the operand that provides the integer value controlling the switch. */
- final ConditionOperand getExpressionOperand() { result = getAnOperand() }
+ final ConditionOperand getExpressionOperand() { result = this.getAnOperand() }
/** Gets the instruction whose result provides the integer value controlling the switch. */
- final Instruction getExpression() { result = getExpressionOperand().getDef() }
+ final Instruction getExpression() { result = this.getExpressionOperand().getDef() }
/** Gets the successor instructions along the case edges of the switch. */
- final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }
+ final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = this.getSuccessor(edge)) }
/** Gets the successor instruction along the default edge of the switch, if any. */
- final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
+ final Instruction getDefaultSuccessor() { result = this.getSuccessor(EdgeKind::defaultEdge()) }
}
/**
* An instruction that calls a function.
*/
class CallInstruction extends Instruction {
- CallInstruction() { getOpcode() instanceof Opcode::Call }
+ CallInstruction() { this.getOpcode() instanceof Opcode::Call }
final override string getImmediateString() {
- result = getStaticCallTarget().toString()
+ result = this.getStaticCallTarget().toString()
or
- not exists(getStaticCallTarget()) and result = "?"
+ not exists(this.getStaticCallTarget()) and result = "?"
}
/**
* Gets the operand the specifies the target function of the call.
*/
- final CallTargetOperand getCallTargetOperand() { result = getAnOperand() }
+ final CallTargetOperand getCallTargetOperand() { result = this.getAnOperand() }
/**
* Gets the `Instruction` that computes the target function of the call. This is usually a
* `FunctionAddress` instruction, but can also be an arbitrary instruction that produces a
* function pointer.
*/
- final Instruction getCallTarget() { result = getCallTargetOperand().getDef() }
+ final Instruction getCallTarget() { result = this.getCallTargetOperand().getDef() }
/**
* Gets all of the argument operands of the call, including the `this` pointer, if any.
*/
- final ArgumentOperand getAnArgumentOperand() { result = getAnOperand() }
+ final ArgumentOperand getAnArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
final Language::Function getStaticCallTarget() {
- result = getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
+ result = this.getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
}
/**
* Gets all of the arguments of the call, including the `this` pointer, if any.
*/
- final Instruction getAnArgument() { result = getAnArgumentOperand().getDef() }
+ final Instruction getAnArgument() { result = this.getAnArgumentOperand().getDef() }
/**
* Gets the `this` pointer argument operand of the call, if any.
*/
- final ThisArgumentOperand getThisArgumentOperand() { result = getAnOperand() }
+ final ThisArgumentOperand getThisArgumentOperand() { result = this.getAnOperand() }
/**
* Gets the `this` pointer argument of the call, if any.
*/
- final Instruction getThisArgument() { result = getThisArgumentOperand().getDef() }
+ final Instruction getThisArgument() { result = this.getThisArgumentOperand().getDef() }
/**
* Gets the argument operand at the specified index.
*/
pragma[noinline]
final PositionalArgumentOperand getPositionalArgumentOperand(int index) {
- result = getAnOperand() and
+ result = this.getAnOperand() and
result.getIndex() = index
}
@@ -1623,7 +1638,7 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final Instruction getPositionalArgument(int index) {
- result = getPositionalArgumentOperand(index).getDef()
+ result = this.getPositionalArgumentOperand(index).getDef()
}
/**
@@ -1631,16 +1646,16 @@ class CallInstruction extends Instruction {
*/
pragma[noinline]
final ArgumentOperand getArgumentOperand(int index) {
- index >= 0 and result = getPositionalArgumentOperand(index)
+ index >= 0 and result = this.getPositionalArgumentOperand(index)
or
- index = -1 and result = getThisArgumentOperand()
+ index = -1 and result = this.getThisArgumentOperand()
}
/**
* Gets the argument at the specified index, or `this` if `index` is `-1`.
*/
pragma[noinline]
- final Instruction getArgument(int index) { result = getArgumentOperand(index).getDef() }
+ final Instruction getArgument(int index) { result = this.getArgumentOperand(index).getDef() }
/**
* Gets the number of arguments of the call, including the `this` pointer, if any.
@@ -1665,7 +1680,7 @@ class CallInstruction extends Instruction {
* An instruction representing a side effect of a function call.
*/
class SideEffectInstruction extends Instruction {
- SideEffectInstruction() { getOpcode() instanceof SideEffectOpcode }
+ SideEffectInstruction() { this.getOpcode() instanceof SideEffectOpcode }
/**
* Gets the instruction whose execution causes this side effect.
@@ -1680,7 +1695,7 @@ class SideEffectInstruction extends Instruction {
* accessed by that call.
*/
class CallSideEffectInstruction extends SideEffectInstruction {
- CallSideEffectInstruction() { getOpcode() instanceof Opcode::CallSideEffect }
+ CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
}
/**
@@ -1691,7 +1706,7 @@ class CallSideEffectInstruction extends SideEffectInstruction {
* call target cannot write to escaped memory.
*/
class CallReadSideEffectInstruction extends SideEffectInstruction {
- CallReadSideEffectInstruction() { getOpcode() instanceof Opcode::CallReadSideEffect }
+ CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
}
/**
@@ -1699,33 +1714,33 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
* specific parameter.
*/
class ReadSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- ReadSideEffectInstruction() { getOpcode() instanceof ReadSideEffectOpcode }
+ ReadSideEffectInstruction() { this.getOpcode() instanceof ReadSideEffectOpcode }
/** Gets the operand for the value that will be read from this instruction, if known. */
- final SideEffectOperand getSideEffectOperand() { result = getAnOperand() }
+ final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
/** Gets the value that will be read from this instruction, if known. */
- final Instruction getSideEffect() { result = getSideEffectOperand().getDef() }
+ final Instruction getSideEffect() { result = this.getSideEffectOperand().getDef() }
/** Gets the operand for the address from which this instruction may read. */
- final AddressOperand getArgumentOperand() { result = getAnOperand() }
+ final AddressOperand getArgumentOperand() { result = this.getAnOperand() }
/** Gets the address from which this instruction may read. */
- final Instruction getArgumentDef() { result = getArgumentOperand().getDef() }
+ final Instruction getArgumentDef() { result = this.getArgumentOperand().getDef() }
}
/**
* An instruction representing the read of an indirect parameter within a function call.
*/
class IndirectReadSideEffectInstruction extends ReadSideEffectInstruction {
- IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
+ IndirectReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::IndirectReadSideEffect }
}
/**
* An instruction representing the read of an indirect buffer parameter within a function call.
*/
class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
- BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
+ BufferReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::BufferReadSideEffect }
}
/**
@@ -1733,18 +1748,18 @@ class BufferReadSideEffectInstruction extends ReadSideEffectInstruction {
*/
class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
SizedBufferReadSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferReadSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferReadSideEffect
}
/**
* Gets the operand that holds the number of bytes read from the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes read from the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1752,17 +1767,17 @@ class SizedBufferReadSideEffectInstruction extends ReadSideEffectInstruction {
* specific parameter.
*/
class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
- WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
+ WriteSideEffectInstruction() { this.getOpcode() instanceof WriteSideEffectOpcode }
/**
* Get the operand that holds the address of the memory to be written.
*/
- final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the address of the memory to be written.
*/
- Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
+ Instruction getDestinationAddress() { result = this.getDestinationAddressOperand().getDef() }
}
/**
@@ -1770,7 +1785,7 @@ class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstructi
*/
class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
}
}
@@ -1780,7 +1795,7 @@ class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction
*/
class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
BufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::BufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::BufferMustWriteSideEffect
}
}
@@ -1790,18 +1805,18 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMustWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1812,7 +1827,7 @@ class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstructi
*/
class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
IndirectMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
}
}
@@ -1822,7 +1837,9 @@ class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
* Unlike `BufferWriteSideEffectInstruction`, the buffer might not be completely overwritten.
*/
class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
- BufferMayWriteSideEffectInstruction() { getOpcode() instanceof Opcode::BufferMayWriteSideEffect }
+ BufferMayWriteSideEffectInstruction() {
+ this.getOpcode() instanceof Opcode::BufferMayWriteSideEffect
+ }
}
/**
@@ -1832,18 +1849,18 @@ class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
*/
class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
SizedBufferMayWriteSideEffectInstruction() {
- getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
+ this.getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
}
/**
* Gets the operand that holds the number of bytes written to the buffer.
*/
- final BufferSizeOperand getBufferSizeOperand() { result = getAnOperand() }
+ final BufferSizeOperand getBufferSizeOperand() { result = this.getAnOperand() }
/**
* Gets the instruction whose result provides the number of bytes written to the buffer.
*/
- final Instruction getBufferSize() { result = getBufferSizeOperand().getDef() }
+ final Instruction getBufferSize() { result = this.getBufferSizeOperand().getDef() }
}
/**
@@ -1852,80 +1869,80 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio
*/
class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
InitializeDynamicAllocationInstruction() {
- getOpcode() instanceof Opcode::InitializeDynamicAllocation
+ this.getOpcode() instanceof Opcode::InitializeDynamicAllocation
}
/**
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
- final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
+ final AddressOperand getAllocationAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address for the allocation this instruction is initializing.
*/
- final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
+ final Instruction getAllocationAddress() { result = this.getAllocationAddressOperand().getDef() }
}
/**
* An instruction representing a GNU or MSVC inline assembly statement.
*/
class InlineAsmInstruction extends Instruction {
- InlineAsmInstruction() { getOpcode() instanceof Opcode::InlineAsm }
+ InlineAsmInstruction() { this.getOpcode() instanceof Opcode::InlineAsm }
}
/**
* An instruction that throws an exception.
*/
class ThrowInstruction extends Instruction {
- ThrowInstruction() { getOpcode() instanceof ThrowOpcode }
+ ThrowInstruction() { this.getOpcode() instanceof ThrowOpcode }
}
/**
* An instruction that throws a new exception.
*/
class ThrowValueInstruction extends ThrowInstruction {
- ThrowValueInstruction() { getOpcode() instanceof Opcode::ThrowValue }
+ ThrowValueInstruction() { this.getOpcode() instanceof Opcode::ThrowValue }
/**
* Gets the address operand of the exception thrown by this instruction.
*/
- final AddressOperand getExceptionAddressOperand() { result = getAnOperand() }
+ final AddressOperand getExceptionAddressOperand() { result = this.getAnOperand() }
/**
* Gets the address of the exception thrown by this instruction.
*/
- final Instruction getExceptionAddress() { result = getExceptionAddressOperand().getDef() }
+ final Instruction getExceptionAddress() { result = this.getExceptionAddressOperand().getDef() }
/**
* Gets the operand for the exception thrown by this instruction.
*/
- final LoadOperand getExceptionOperand() { result = getAnOperand() }
+ final LoadOperand getExceptionOperand() { result = this.getAnOperand() }
/**
* Gets the exception thrown by this instruction.
*/
- final Instruction getException() { result = getExceptionOperand().getDef() }
+ final Instruction getException() { result = this.getExceptionOperand().getDef() }
}
/**
* An instruction that re-throws the current exception.
*/
class ReThrowInstruction extends ThrowInstruction {
- ReThrowInstruction() { getOpcode() instanceof Opcode::ReThrow }
+ ReThrowInstruction() { this.getOpcode() instanceof Opcode::ReThrow }
}
/**
* An instruction that exits the current function by propagating an exception.
*/
class UnwindInstruction extends Instruction {
- UnwindInstruction() { getOpcode() instanceof Opcode::Unwind }
+ UnwindInstruction() { this.getOpcode() instanceof Opcode::Unwind }
}
/**
* An instruction that starts a `catch` handler.
*/
class CatchInstruction extends Instruction {
- CatchInstruction() { getOpcode() instanceof CatchOpcode }
+ CatchInstruction() { this.getOpcode() instanceof CatchOpcode }
}
/**
@@ -1935,7 +1952,7 @@ class CatchByTypeInstruction extends CatchInstruction {
Language::LanguageType exceptionType;
CatchByTypeInstruction() {
- getOpcode() instanceof Opcode::CatchByType and
+ this.getOpcode() instanceof Opcode::CatchByType and
exceptionType = Raw::getInstructionExceptionType(this)
}
@@ -1951,21 +1968,21 @@ class CatchByTypeInstruction extends CatchInstruction {
* An instruction that catches any exception.
*/
class CatchAnyInstruction extends CatchInstruction {
- CatchAnyInstruction() { getOpcode() instanceof Opcode::CatchAny }
+ CatchAnyInstruction() { this.getOpcode() instanceof Opcode::CatchAny }
}
/**
* An instruction that initializes all escaped memory.
*/
class AliasedDefinitionInstruction extends Instruction {
- AliasedDefinitionInstruction() { getOpcode() instanceof Opcode::AliasedDefinition }
+ AliasedDefinitionInstruction() { this.getOpcode() instanceof Opcode::AliasedDefinition }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
- AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
+ AliasedUseInstruction() { this.getOpcode() instanceof Opcode::AliasedUse }
}
/**
@@ -1979,7 +1996,7 @@ class AliasedUseInstruction extends Instruction {
* runtime.
*/
class PhiInstruction extends Instruction {
- PhiInstruction() { getOpcode() instanceof Opcode::Phi }
+ PhiInstruction() { this.getOpcode() instanceof Opcode::Phi }
/**
* Gets all of the instruction's `PhiInputOperand`s, representing the values that flow from each predecessor block.
@@ -2047,29 +2064,29 @@ class PhiInstruction extends Instruction {
* https://link.springer.com/content/pdf/10.1007%2F3-540-61053-7_66.pdf.
*/
class ChiInstruction extends Instruction {
- ChiInstruction() { getOpcode() instanceof Opcode::Chi }
+ ChiInstruction() { this.getOpcode() instanceof Opcode::Chi }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final ChiTotalOperand getTotalOperand() { result = getAnOperand() }
+ final ChiTotalOperand getTotalOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the previous state of all memory that might be aliased by the
* memory write.
*/
- final Instruction getTotal() { result = getTotalOperand().getDef() }
+ final Instruction getTotal() { result = this.getTotalOperand().getDef() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final ChiPartialOperand getPartialOperand() { result = getAnOperand() }
+ final ChiPartialOperand getPartialOperand() { result = this.getAnOperand() }
/**
* Gets the operand that represents the new value written by the memory write.
*/
- final Instruction getPartial() { result = getPartialOperand().getDef() }
+ final Instruction getPartial() { result = this.getPartialOperand().getDef() }
/**
* Gets the bit range `[startBit, endBit)` updated by the partial operand of this `ChiInstruction`, relative to the start address of the total operand.
@@ -2093,7 +2110,7 @@ class ChiInstruction extends Instruction {
* or `Switch` instruction where that particular edge is infeasible.
*/
class UnreachedInstruction extends Instruction {
- UnreachedInstruction() { getOpcode() instanceof Opcode::Unreached }
+ UnreachedInstruction() { this.getOpcode() instanceof Opcode::Unreached }
}
/**
@@ -2106,7 +2123,7 @@ class BuiltInOperationInstruction extends Instruction {
Language::BuiltInOperation operation;
BuiltInOperationInstruction() {
- getOpcode() instanceof BuiltInOperationOpcode and
+ this.getOpcode() instanceof BuiltInOperationOpcode and
operation = Raw::getInstructionBuiltInOperation(this)
}
@@ -2122,9 +2139,9 @@ class BuiltInOperationInstruction extends Instruction {
* actual operation is specified by the `getBuiltInOperation()` predicate.
*/
class BuiltInInstruction extends BuiltInOperationInstruction {
- BuiltInInstruction() { getOpcode() instanceof Opcode::BuiltIn }
+ BuiltInInstruction() { this.getOpcode() instanceof Opcode::BuiltIn }
- final override string getImmediateString() { result = getBuiltInOperation().toString() }
+ final override string getImmediateString() { result = this.getBuiltInOperation().toString() }
}
/**
@@ -2135,7 +2152,7 @@ class BuiltInInstruction extends BuiltInOperationInstruction {
* to the `...` parameter.
*/
class VarArgsStartInstruction extends UnaryInstruction {
- VarArgsStartInstruction() { getOpcode() instanceof Opcode::VarArgsStart }
+ VarArgsStartInstruction() { this.getOpcode() instanceof Opcode::VarArgsStart }
}
/**
@@ -2145,7 +2162,7 @@ class VarArgsStartInstruction extends UnaryInstruction {
* a result.
*/
class VarArgsEndInstruction extends UnaryInstruction {
- VarArgsEndInstruction() { getOpcode() instanceof Opcode::VarArgsEnd }
+ VarArgsEndInstruction() { this.getOpcode() instanceof Opcode::VarArgsEnd }
}
/**
@@ -2155,7 +2172,7 @@ class VarArgsEndInstruction extends UnaryInstruction {
* argument.
*/
class VarArgInstruction extends UnaryInstruction {
- VarArgInstruction() { getOpcode() instanceof Opcode::VarArg }
+ VarArgInstruction() { this.getOpcode() instanceof Opcode::VarArg }
}
/**
@@ -2166,7 +2183,7 @@ class VarArgInstruction extends UnaryInstruction {
* argument of the `...` parameter.
*/
class NextVarArgInstruction extends UnaryInstruction {
- NextVarArgInstruction() { getOpcode() instanceof Opcode::NextVarArg }
+ NextVarArgInstruction() { this.getOpcode() instanceof Opcode::NextVarArg }
}
/**
@@ -2180,5 +2197,5 @@ class NextVarArgInstruction extends UnaryInstruction {
* The result is the address of the newly allocated object.
*/
class NewObjInstruction extends Instruction {
- NewObjInstruction() { getOpcode() instanceof Opcode::NewObj }
+ NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
}
diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll
index d7cf89ca9aa..85d217bd361 100644
--- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll
+++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Operand.qll
@@ -46,12 +46,12 @@ class Operand extends TStageOperand {
/**
* Gets the location of the source code for this operand.
*/
- final Language::Location getLocation() { result = getUse().getLocation() }
+ final Language::Location getLocation() { result = this.getUse().getLocation() }
/**
* Gets the function that contains this operand.
*/
- final IRFunction getEnclosingIRFunction() { result = getUse().getEnclosingIRFunction() }
+ final IRFunction getEnclosingIRFunction() { result = this.getUse().getEnclosingIRFunction() }
/**
* Gets the `Instruction` that consumes this operand.
@@ -74,7 +74,7 @@ class Operand extends TStageOperand {
*/
final Instruction getDef() {
result = this.getAnyDef() and
- getDefinitionOverlap() instanceof MustExactlyOverlap
+ this.getDefinitionOverlap() instanceof MustExactlyOverlap
}
/**
@@ -82,7 +82,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` that consumes this operand.
*/
- deprecated final Instruction getUseInstruction() { result = getUse() }
+ deprecated final Instruction getUseInstruction() { result = this.getUse() }
/**
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
@@ -91,7 +91,7 @@ class Operand extends TStageOperand {
*
* Gets the `Instruction` whose result is the value of the operand.
*/
- deprecated final Instruction getDefinitionInstruction() { result = getAnyDef() }
+ deprecated final Instruction getDefinitionInstruction() { result = this.getAnyDef() }
/**
* Gets the overlap relationship between the operand's definition and its use.
@@ -101,7 +101,9 @@ class Operand extends TStageOperand {
/**
* Holds if the result of the definition instruction does not exactly overlap this use.
*/
- final predicate isDefinitionInexact() { not getDefinitionOverlap() instanceof MustExactlyOverlap }
+ final predicate isDefinitionInexact() {
+ not this.getDefinitionOverlap() instanceof MustExactlyOverlap
+ }
/**
* Gets a prefix to use when dumping the operand in an operand list.
@@ -121,7 +123,7 @@ class Operand extends TStageOperand {
* For example: `this:r3_5`
*/
final string getDumpString() {
- result = getDumpLabel() + getInexactSpecifier() + getDefinitionId()
+ result = this.getDumpLabel() + this.getInexactSpecifier() + this.getDefinitionId()
}
/**
@@ -129,9 +131,9 @@ class Operand extends TStageOperand {
* definition is not modeled in SSA.
*/
private string getDefinitionId() {
- result = getAnyDef().getResultId()
+ result = this.getAnyDef().getResultId()
or
- not exists(getAnyDef()) and result = "m?"
+ not exists(this.getAnyDef()) and result = "m?"
}
/**
@@ -140,7 +142,7 @@ class Operand extends TStageOperand {
* the empty string.
*/
private string getInexactSpecifier() {
- if isDefinitionInexact() then result = "~" else result = ""
+ if this.isDefinitionInexact() then result = "~" else result = ""
}
/**
@@ -155,7 +157,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- Language::LanguageType getLanguageType() { result = getAnyDef().getResultLanguageType() }
+ Language::LanguageType getLanguageType() { result = this.getAnyDef().getResultLanguageType() }
/**
* Gets the language-neutral type of the value consumed by this operand. This is usually the same
@@ -164,7 +166,7 @@ class Operand extends TStageOperand {
* from the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final IRType getIRType() { result = getLanguageType().getIRType() }
+ final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the value consumed by this operand. This is usually the same as the
@@ -173,7 +175,7 @@ class Operand extends TStageOperand {
* the definition type, such as in the case of a partial read or a read from a pointer that
* has been cast to a different type.
*/
- final Language::Type getType() { getLanguageType().hasType(result, _) }
+ final Language::Type getType() { this.getLanguageType().hasType(result, _) }
/**
* Holds if the value consumed by this operand is a glvalue. If this
@@ -182,13 +184,13 @@ class Operand extends TStageOperand {
* not hold, the value of the operand represents a value whose type is
* given by `getType()`.
*/
- final predicate isGLValue() { getLanguageType().hasType(_, true) }
+ final predicate isGLValue() { this.getLanguageType().hasType(_, true) }
/**
* Gets the size of the value consumed by this operand, in bytes. If the operand does not have
* a known constant size, this predicate does not hold.
*/
- final int getSize() { result = getLanguageType().getByteSize() }
+ final int getSize() { result = this.getLanguageType().getByteSize() }
}
/**
@@ -205,7 +207,7 @@ class MemoryOperand extends Operand {
/**
* Gets the kind of memory access performed by the operand.
*/
- MemoryAccessKind getMemoryAccess() { result = getUse().getOpcode().getReadMemoryAccess() }
+ MemoryAccessKind getMemoryAccess() { result = this.getUse().getOpcode().getReadMemoryAccess() }
/**
* Holds if the memory access performed by this operand will not always read from every bit in the
@@ -215,7 +217,7 @@ class MemoryOperand extends Operand {
* conservative estimate of the memory that might actually be accessed at runtime (for example,
* the global side effects of a function call).
*/
- predicate hasMayReadMemoryAccess() { getUse().getOpcode().hasMayReadMemoryAccess() }
+ predicate hasMayReadMemoryAccess() { this.getUse().getOpcode().hasMayReadMemoryAccess() }
/**
* Returns the operand that holds the memory address from which the current operand loads its
@@ -223,8 +225,8 @@ class MemoryOperand extends Operand {
* is `r1`.
*/
final AddressOperand getAddressOperand() {
- getMemoryAccess().usesAddressOperand() and
- result.getUse() = getUse()
+ this.getMemoryAccess().usesAddressOperand() and
+ result.getUse() = this.getUse()
}
}
@@ -294,7 +296,7 @@ class NonPhiMemoryOperand extends NonPhiOperand, MemoryOperand, TNonPhiMemoryOpe
result = unique(Instruction defInstr | hasDefinition(defInstr, _))
}
- final override Overlap getDefinitionOverlap() { hasDefinition(_, result) }
+ final override Overlap getDefinitionOverlap() { this.hasDefinition(_, result) }
pragma[noinline]
private predicate hasDefinition(Instruction defInstr, Overlap overlap) {
@@ -449,13 +451,17 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
final override Overlap getDefinitionOverlap() { result = overlap }
- final override int getDumpSortOrder() { result = 11 + getPredecessorBlock().getDisplayIndex() }
-
- final override string getDumpLabel() {
- result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
+ final override int getDumpSortOrder() {
+ result = 11 + this.getPredecessorBlock().getDisplayIndex()
}
- final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
+ final override string getDumpLabel() {
+ result = "from " + this.getPredecessorBlock().getDisplayIndex().toString() + ":"
+ }
+
+ final override string getDumpId() {
+ result = this.getPredecessorBlock().getDisplayIndex().toString()
+ }
/**
* Gets the predecessor block from which this value comes.
diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasAnalysisImports.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasAnalysisImports.qll
index e0bf271dcc7..b0eb5ec98cb 100644
--- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasAnalysisImports.qll
+++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/internal/AliasAnalysisImports.qll
@@ -36,7 +36,7 @@ module AliasModels {
* Holds if this is the input value of the parameter with index `index`.
* DEPRECATED: Use `isParameter(index)` instead.
*/
- deprecated final predicate isInParameter(ParameterIndex index) { isParameter(index) }
+ deprecated final predicate isInParameter(ParameterIndex index) { this.isParameter(index) }
/**
* Holds if this is the input value pointed to by a pointer parameter to a function, or the input
@@ -63,7 +63,7 @@ module AliasModels {
* DEPRECATED: Use `isParameterDeref(index)` instead.
*/
deprecated final predicate isInParameterPointer(ParameterIndex index) {
- isParameterDeref(index)
+ this.isParameterDeref(index)
}
/**
@@ -86,7 +86,7 @@ module AliasModels {
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
- deprecated final predicate isInQualifier() { isQualifierObject() }
+ deprecated final predicate isInQualifier() { this.isQualifierObject() }
/**
* Holds if this is the input value of the `this` pointer of an instance member function.
@@ -184,7 +184,7 @@ module AliasModels {
* DEPRECATED: Use `isParameterDeref(index)` instead.
*/
deprecated final predicate isOutParameterPointer(ParameterIndex index) {
- isParameterDeref(index)
+ this.isParameterDeref(index)
}
/**
@@ -207,7 +207,7 @@ module AliasModels {
* function.
* DEPRECATED: Use `isQualifierObject()` instead.
*/
- deprecated final predicate isOutQualifier() { isQualifierObject() }
+ deprecated final predicate isOutQualifier() { this.isQualifierObject() }
/**
* Holds if this is the value returned by a function.
@@ -232,7 +232,7 @@ module AliasModels {
* Holds if this is the value returned by a function.
* DEPRECATED: Use `isReturnValue()` instead.
*/
- deprecated final predicate isOutReturnValue() { isReturnValue() }
+ deprecated final predicate isOutReturnValue() { this.isReturnValue() }
/**
* Holds if this is the output value pointed to by the return value of a function, if the function
@@ -260,7 +260,7 @@ module AliasModels {
* function returns a reference.
* DEPRECATED: Use `isReturnValueDeref()` instead.
*/
- deprecated final predicate isOutReturnPointer() { isReturnValueDeref() }
+ deprecated final predicate isOutReturnPointer() { this.isReturnValueDeref() }
/**
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this is the value, or
diff --git a/csharp/ql/src/experimental/ir/internal/IRGuards.qll b/csharp/ql/src/experimental/ir/internal/IRGuards.qll
index d01dcbed1e1..40780a3920e 100644
--- a/csharp/ql/src/experimental/ir/internal/IRGuards.qll
+++ b/csharp/ql/src/experimental/ir/internal/IRGuards.qll
@@ -147,7 +147,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
exists(boolean testIsTrue |
- comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
+ this.comparesLt(left, right, k, isLessThan, testIsTrue) and this.controls(block, testIsTrue)
)
}
@@ -161,7 +161,7 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
exists(boolean testIsTrue |
- comparesEq(left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue)
+ this.comparesEq(left, right, k, areEqual, testIsTrue) and this.controls(block, testIsTrue)
)
}
}
@@ -326,9 +326,9 @@ class IRGuardCondition extends Instruction {
cached
predicate controlsEdge(IRBlock pred, IRBlock succ, boolean testIsTrue) {
pred.getASuccessor() = succ and
- controls(pred, testIsTrue)
+ this.controls(pred, testIsTrue)
or
- hasBranchEdge(succ, testIsTrue) and
+ this.hasBranchEdge(succ, testIsTrue) and
branch.getCondition() = this and
branch.getBlock() = pred
}
diff --git a/csharp/ql/src/experimental/ir/internal/IntegerInterval.qll b/csharp/ql/src/experimental/ir/internal/IntegerInterval.qll
index cd12b9b627a..4f8f4b4e672 100644
--- a/csharp/ql/src/experimental/ir/internal/IntegerInterval.qll
+++ b/csharp/ql/src/experimental/ir/internal/IntegerInterval.qll
@@ -18,10 +18,11 @@ Overlap getOverlap(IntValue defStart, IntValue defEnd, IntValue useStart, IntVal
else
if isLE(defStart, useStart) and isGE(defEnd, useEnd)
then result instanceof MustTotallyOverlap
- else
- if isLE(defEnd, useStart) or isGE(defStart, useEnd)
- then none()
- else result instanceof MayPartiallyOverlap
+ else (
+ not isLE(defEnd, useStart) and
+ not isGE(defStart, useEnd) and
+ result instanceof MayPartiallyOverlap
+ )
}
/**
diff --git a/csharp/ql/src/experimental/ir/rangeanalysis/RangeUtils.qll b/csharp/ql/src/experimental/ir/rangeanalysis/RangeUtils.qll
index 4a7f1d69840..b7fdfc3546f 100644
--- a/csharp/ql/src/experimental/ir/rangeanalysis/RangeUtils.qll
+++ b/csharp/ql/src/experimental/ir/rangeanalysis/RangeUtils.qll
@@ -52,10 +52,7 @@ IntValue getArrayDim(Variable arr) {
arr.getInitializer() = ac and
if exists(ac.getLengthArgument(0))
then result = ac.getLengthArgument(0).getValue().toInt()
- else
- if exists(ac.getInitializer())
- then result = ac.getInitializer().getNumberOfElements()
- else none()
+ else result = ac.getInitializer().getNumberOfElements()
)
}
diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml
index fc9ac2f6895..7c00298a638 100644
--- a/csharp/ql/src/qlpack.yml
+++ b/csharp/ql/src/qlpack.yml
@@ -2,6 +2,7 @@ name: codeql/csharp-queries
version: 0.0.2
suites: codeql-suites
extractor: csharp
+defaultSuiteFile: codeql-suites/csharp-code-scanning.qls
dependencies:
codeql/csharp-all: "*"
codeql/suite-helpers: "*"
diff --git a/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll b/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll
new file mode 100644
index 00000000000..52a790cca28
--- /dev/null
+++ b/csharp/ql/test/TestUtilities/InlineExpectationsTest.qll
@@ -0,0 +1,346 @@
+/**
+ * Provides a library for writing QL tests whose success or failure is based on expected results
+ * embedded in the test source code as comments, rather than the contents of an `.expected` file
+ * (in that the `.expected` file should always be empty).
+ *
+ * To add this framework to a new language:
+ * - Add a file `InlineExpectationsTestPrivate.qll` that defines a `ExpectationComment` class. This class
+ * must support a `getContents` method that returns the contents of the given comment, _excluding_
+ * the comment indicator itself. It should also define `toString` and `getLocation` as usual.
+ *
+ * To create a new inline expectations test:
+ * - Declare a class that extends `InlineExpectationsTest`. In the characteristic predicate of the
+ * new class, bind `this` to a unique string (usually the name of the test).
+ * - Override the `hasActualResult()` predicate to produce the actual results of the query. For each
+ * result, specify a `Location`, a text description of the element for which the result was
+ * reported, a short string to serve as the tag to identify expected results for this test, and the
+ * expected value of the result.
+ * - Override `getARelevantTag()` to return the set of tags that can be produced by
+ * `hasActualResult()`. Often this is just a single tag.
+ *
+ * Example:
+ * ```ql
+ * class ConstantValueTest extends InlineExpectationsTest {
+ * ConstantValueTest() { this = "ConstantValueTest" }
+ *
+ * override string getARelevantTag() {
+ * // We only use one tag for this test.
+ * result = "const"
+ * }
+ *
+ * override predicate hasActualResult(
+ * Location location, string element, string tag, string value
+ * ) {
+ * exists(Expr e |
+ * tag = "const" and // The tag for this test.
+ * value = e.getValue() and // The expected value. Will only hold for constant expressions.
+ * location = e.getLocation() and // The location of the result to be reported.
+ * element = e.toString() // The display text for the result.
+ * )
+ * }
+ * }
+ * ```
+ *
+ * There is no need to write a `select` clause or query predicate. All of the differences between
+ * expected results and actual results will be reported in the `failures()` query predicate.
+ *
+ * To annotate the test source code with an expected result, place a comment starting with a `$` on the
+ * same line as the expected result, with text of the following format as the body of the comment:
+ *
+ * `tag=expected-value`
+ *
+ * Where `tag` is the value of the `tag` parameter from `hasActualResult()`, and `expected-value` is
+ * the value of the `value` parameter from `hasActualResult()`. The `=expected-value` portion may be
+ * omitted, in which case `expected-value` is treated as the empty string. Multiple expectations may
+ * be placed in the same comment. Any actual result that
+ * appears on a line that does not contain a matching expected result comment will be reported with
+ * a message of the form "Unexpected result: tag=value". Any expected result comment for which there
+ * is no matching actual result will be reported with a message of the form
+ * "Missing result: tag=expected-value".
+ *
+ * Example:
+ * ```cpp
+ * int i = x + 5; // $ const=5
+ * int j = y + (7 - 3) // $ const=7 const=3 const=4 // The result of the subtraction is a constant.
+ * ```
+ *
+ * For tests that contain known missing and spurious results, it is possible to further
+ * annotate that a particular expected result is known to be spurious, or that a particular
+ * missing result is known to be missing:
+ *
+ * `$ SPURIOUS: tag=expected-value` // Spurious result
+ * `$ MISSING: tag=expected-value` // Missing result
+ *
+ * A spurious expectation is treated as any other expected result, except that if there is no
+ * matching actual result, the message will be of the form "Fixed spurious result: tag=value". A
+ * missing expectation is treated as if there were no expected result, except that if a
+ * matching expected result is found, the message will be of the form
+ * "Fixed missing result: tag=value".
+ *
+ * A single line can contain all the expected, spurious and missing results of that line. For instance:
+ * `$ tag1=value1 SPURIOUS: tag2=value2 MISSING: tag3=value3`.
+ *
+ * If the same result value is expected for two or more tags on the same line, there is a shorthand
+ * notation available:
+ *
+ * `tag1,tag2=expected-value`
+ *
+ * is equivalent to:
+ *
+ * `tag1=expected-value tag2=expected-value`
+ */
+
+private import InlineExpectationsTestPrivate
+
+/**
+ * Base class for tests with inline expectations. The test extends this class to provide the actual
+ * results of the query, which are then compared with the expected results in comments to produce a
+ * list of failure messages that point out where the actual results differ from the expected
+ * results.
+ */
+abstract class InlineExpectationsTest extends string {
+ bindingset[this]
+ InlineExpectationsTest() { any() }
+
+ /**
+ * Returns all tags that can be generated by this test. Most tests will only ever produce a single
+ * tag. Any expected result comments for a tag that is not returned by the `getARelevantTag()`
+ * predicate for an active test will be ignored. This makes it possible to write multiple tests in
+ * different `.ql` files that all query the same source code.
+ */
+ abstract string getARelevantTag();
+
+ /**
+ * Returns the actual results of the query that is being tested. Each result consist of the
+ * following values:
+ * - `location` - The source code location of the result. Any expected result comment must appear
+ * on the start line of this location.
+ * - `element` - Display text for the element on which the result is reported.
+ * - `tag` - The tag that marks this result as coming from this test. This must be one of the tags
+ * returned by `getARelevantTag()`.
+ * - `value` - The value of the result, which will be matched against the value associated with
+ * `tag` in any expected result comment on that line.
+ */
+ abstract predicate hasActualResult(Location location, string element, string tag, string value);
+
+ final predicate hasFailureMessage(FailureLocatable element, string message) {
+ exists(ActualResult actualResult |
+ actualResult.getTest() = this and
+ element = actualResult and
+ (
+ exists(FalseNegativeExpectation falseNegative |
+ falseNegative.matchesActualResult(actualResult) and
+ message = "Fixed missing result:" + falseNegative.getExpectationText()
+ )
+ or
+ not exists(ValidExpectation expectation | expectation.matchesActualResult(actualResult)) and
+ message = "Unexpected result: " + actualResult.getExpectationText()
+ )
+ )
+ or
+ exists(ValidExpectation expectation |
+ not exists(ActualResult actualResult | expectation.matchesActualResult(actualResult)) and
+ expectation.getTag() = getARelevantTag() and
+ element = expectation and
+ (
+ expectation instanceof GoodExpectation and
+ message = "Missing result:" + expectation.getExpectationText()
+ or
+ expectation instanceof FalsePositiveExpectation and
+ message = "Fixed spurious result:" + expectation.getExpectationText()
+ )
+ )
+ or
+ exists(InvalidExpectation expectation |
+ element = expectation and
+ message = "Invalid expectation syntax: " + expectation.getExpectation()
+ )
+ }
+}
+
+/**
+ * RegEx pattern to match a comment containing one or more expected results. The comment must have
+ * `$` as its first non-whitespace character. Any subsequent character
+ * is treated as part of the expected results, except that the comment may contain a `//` sequence
+ * to treat the remainder of the line as a regular (non-interpreted) comment.
+ */
+private string expectationCommentPattern() { result = "\\s*\\$((?:[^/]|/[^/])*)(?://.*)?" }
+
+/**
+ * The possible columns in an expectation comment. The `TDefaultColumn` branch represents the first
+ * column in a comment. This column is not precedeeded by a name. `TNamedColumn(name)` represents a
+ * column containing expected results preceeded by the string `name:`.
+ */
+private newtype TColumn =
+ TDefaultColumn() or
+ TNamedColumn(string name) { name = ["MISSING", "SPURIOUS"] }
+
+bindingset[start, content]
+private int getEndOfColumnPosition(int start, string content) {
+ result =
+ min(string name, int cand |
+ exists(TNamedColumn(name)) and
+ cand = content.indexOf(name + ":") and
+ cand >= start
+ |
+ cand
+ )
+ or
+ not exists(string name |
+ exists(TNamedColumn(name)) and
+ content.indexOf(name + ":") >= start
+ ) and
+ result = content.length()
+}
+
+private predicate getAnExpectation(
+ ExpectationComment comment, TColumn column, string expectation, string tags, string value
+) {
+ exists(string content |
+ content = comment.getContents().regexpCapture(expectationCommentPattern(), 1) and
+ (
+ column = TDefaultColumn() and
+ exists(int end |
+ end = getEndOfColumnPosition(0, content) and
+ expectation = content.prefix(end).regexpFind(expectationPattern(), _, _).trim()
+ )
+ or
+ exists(string name, int start, int end |
+ column = TNamedColumn(name) and
+ start = content.indexOf(name + ":") + name.length() + 1 and
+ end = getEndOfColumnPosition(start, content) and
+ expectation = content.substring(start, end).regexpFind(expectationPattern(), _, _).trim()
+ )
+ )
+ ) and
+ tags = expectation.regexpCapture(expectationPattern(), 1) and
+ if exists(expectation.regexpCapture(expectationPattern(), 2))
+ then value = expectation.regexpCapture(expectationPattern(), 2)
+ else value = ""
+}
+
+private string getColumnString(TColumn column) {
+ column = TDefaultColumn() and result = ""
+ or
+ column = TNamedColumn(result)
+}
+
+/**
+ * RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or
+ * more comma-separated tags containing only letters, digits, `-` and `_` (note that the first character
+ * must not be a digit), optionally followed by `=` and the expected value.
+ */
+private string expectationPattern() {
+ exists(string tag, string tags, string value |
+ tag = "[A-Za-z-_][A-Za-z-_0-9]*" and
+ tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and
+ // In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`.
+ // For example, `b"foo"`.
+ value = "((?:[bru]*\"[^\"]*\"|[bru]*'[^']*'|\\S+)*)" and
+ result = tags + "(?:=" + value + ")?"
+ )
+}
+
+private newtype TFailureLocatable =
+ TActualResult(
+ InlineExpectationsTest test, Location location, string element, string tag, string value
+ ) {
+ test.hasActualResult(location, element, tag, value)
+ } or
+ TValidExpectation(ExpectationComment comment, string tag, string value, string knownFailure) {
+ exists(TColumn column, string tags |
+ getAnExpectation(comment, column, _, tags, value) and
+ tag = tags.splitAt(",") and
+ knownFailure = getColumnString(column)
+ )
+ } or
+ TInvalidExpectation(ExpectationComment comment, string expectation) {
+ getAnExpectation(comment, _, expectation, _, _) and
+ not expectation.regexpMatch(expectationPattern())
+ }
+
+class FailureLocatable extends TFailureLocatable {
+ string toString() { none() }
+
+ Location getLocation() { none() }
+
+ final string getExpectationText() { result = getTag() + "=" + getValue() }
+
+ string getTag() { none() }
+
+ string getValue() { none() }
+}
+
+class ActualResult extends FailureLocatable, TActualResult {
+ InlineExpectationsTest test;
+ Location location;
+ string element;
+ string tag;
+ string value;
+
+ ActualResult() { this = TActualResult(test, location, element, tag, value) }
+
+ override string toString() { result = element }
+
+ override Location getLocation() { result = location }
+
+ InlineExpectationsTest getTest() { result = test }
+
+ override string getTag() { result = tag }
+
+ override string getValue() { result = value }
+}
+
+abstract private class Expectation extends FailureLocatable {
+ ExpectationComment comment;
+
+ override string toString() { result = comment.toString() }
+
+ override Location getLocation() { result = comment.getLocation() }
+}
+
+private class ValidExpectation extends Expectation, TValidExpectation {
+ string tag;
+ string value;
+ string knownFailure;
+
+ ValidExpectation() { this = TValidExpectation(comment, tag, value, knownFailure) }
+
+ override string getTag() { result = tag }
+
+ override string getValue() { result = value }
+
+ string getKnownFailure() { result = knownFailure }
+
+ predicate matchesActualResult(ActualResult actualResult) {
+ getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
+ getLocation().getFile() = actualResult.getLocation().getFile() and
+ getTag() = actualResult.getTag() and
+ getValue() = actualResult.getValue()
+ }
+}
+
+/* Note: These next three classes correspond to all the possible values of type `TColumn`. */
+class GoodExpectation extends ValidExpectation {
+ GoodExpectation() { getKnownFailure() = "" }
+}
+
+class FalsePositiveExpectation extends ValidExpectation {
+ FalsePositiveExpectation() { getKnownFailure() = "SPURIOUS" }
+}
+
+class FalseNegativeExpectation extends ValidExpectation {
+ FalseNegativeExpectation() { getKnownFailure() = "MISSING" }
+}
+
+class InvalidExpectation extends Expectation, TInvalidExpectation {
+ string expectation;
+
+ InvalidExpectation() { this = TInvalidExpectation(comment, expectation) }
+
+ string getExpectation() { result = expectation }
+}
+
+query predicate failures(FailureLocatable element, string message) {
+ exists(InlineExpectationsTest test | test.hasFailureMessage(element, message))
+}
diff --git a/csharp/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll b/csharp/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll
new file mode 100644
index 00000000000..3df85cc0fd6
--- /dev/null
+++ b/csharp/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll
@@ -0,0 +1,10 @@
+import csharp
+import semmle.code.csharp.Comments
+
+/**
+ * A class representing line comments in C# used by the InlineExpectations core code
+ */
+class ExpectationComment extends SinglelineComment {
+ /** Gets the contents of the given comment, _without_ the preceding comment marker (`//`). */
+ string getContents() { result = this.getText() }
+}
diff --git a/csharp/ql/test/TestUtilities/InlineFlowTest.qll b/csharp/ql/test/TestUtilities/InlineFlowTest.qll
new file mode 100644
index 00000000000..6bd44e81df3
--- /dev/null
+++ b/csharp/ql/test/TestUtilities/InlineFlowTest.qll
@@ -0,0 +1,110 @@
+/**
+ * Provides a simple base test for flow-related tests using inline expectations.
+ *
+ * Example for a test.ql:
+ * ```ql
+ * import csharp
+ * import DataFlow::PathGraph
+ * import TestUtilities.InlineFlowTest
+ *
+ * from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
+ * where conf.hasFlowPath(source, sink)
+ * select sink, source, sink, "$@", source, source.toString()
+ * ```
+ *
+ * To declare expecations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files.
+ * Example of the corresponding test file, e.g. Test.cs
+ * ```csharp
+ * public class Test
+ * {
+ * object Source() { return null; }
+ * string Taint() { return null; }
+ * void Sink(object o) { }
+ *
+ * public void test()
+ * {
+ * var s = Source(1);
+ * Sink(s); // $ hasValueFlow=1
+ * var t = "foo" + Taint(2);
+ * Sink(t); // $ hasTaintFlow=2
+ * }
+ * }
+ * ```
+ *
+ * If you're not interested in a specific flow type, you can disable either value or taint flow expectations as follows:
+ * ```ql
+ * class HasFlowTest extends InlineFlowTest {
+ * override DataFlow::Configuration getTaintFlowConfig() { none() }
+ *
+ * override DataFlow::Configuration getValueFlowConfig() { none() }
+ * }
+ * ```
+ *
+ * If you need more fine-grained tuning, consider implementing a test using `InlineExpectationsTest`.
+ */
+
+import csharp
+import TestUtilities.InlineExpectationsTest
+
+private predicate defaultSource(DataFlow::Node src) {
+ src.asExpr().(MethodCall).getTarget().getUndecoratedName() = ["Source", "Taint"]
+}
+
+private predicate defaultSink(DataFlow::Node sink) {
+ exists(MethodCall mc | mc.getTarget().hasUndecoratedName("Sink") |
+ sink.asExpr() = mc.getAnArgument()
+ )
+}
+
+class DefaultValueFlowConf extends DataFlow::Configuration {
+ DefaultValueFlowConf() { this = "qltest:defaultValueFlowConf" }
+
+ override predicate isSource(DataFlow::Node n) { defaultSource(n) }
+
+ override predicate isSink(DataFlow::Node n) { defaultSink(n) }
+
+ override int fieldFlowBranchLimit() { result = 1000 }
+}
+
+class DefaultTaintFlowConf extends TaintTracking::Configuration {
+ DefaultTaintFlowConf() { this = "qltest:defaultTaintFlowConf" }
+
+ override predicate isSource(DataFlow::Node n) { defaultSource(n) }
+
+ override predicate isSink(DataFlow::Node n) { defaultSink(n) }
+
+ override int fieldFlowBranchLimit() { result = 1000 }
+}
+
+private string getSourceArgString(DataFlow::Node src) {
+ defaultSource(src) and
+ src.asExpr().(MethodCall).getAnArgument().getValue() = result
+}
+
+class InlineFlowTest extends InlineExpectationsTest {
+ InlineFlowTest() { this = "HasFlowTest" }
+
+ override string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
+
+ override predicate hasActualResult(Location location, string element, string tag, string value) {
+ tag = "hasValueFlow" and
+ exists(DataFlow::Node src, DataFlow::Node sink | getValueFlowConfig().hasFlow(src, sink) |
+ sink.getLocation() = location and
+ element = sink.toString() and
+ if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
+ )
+ or
+ tag = "hasTaintFlow" and
+ exists(DataFlow::Node src, DataFlow::Node sink |
+ getTaintFlowConfig().hasFlow(src, sink) and not getValueFlowConfig().hasFlow(src, sink)
+ |
+ sink.getLocation() = location and
+ element = sink.toString() and
+ if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
+ )
+ }
+
+ DataFlow::Configuration getValueFlowConfig() { result = any(DefaultValueFlowConf config) }
+
+ DataFlow::Configuration getTaintFlowConfig() { result = any(DefaultTaintFlowConf config) }
+}
diff --git a/csharp/ql/test/library-tests/assemblies/CompareVersions.ql b/csharp/ql/test/library-tests/assemblies/CompareVersions.ql
index cb4b6745258..ec1b13dcbe6 100644
--- a/csharp/ql/test/library-tests/assemblies/CompareVersions.ql
+++ b/csharp/ql/test/library-tests/assemblies/CompareVersions.ql
@@ -1,16 +1,8 @@
import csharp
Version getAVersion() {
- result = "1.2" or
- result = "1.2.0" or
- result = "1.2.0.0" or
- result = "1.3" or
- result = "1.3.1" or
- result = "1.3.1.2" or
- result = "1.3.1.3" or
- result = "1.3.2" or
- result = "1.4" or
- result = "2.3.1"
+ result =
+ ["1.2", "1.2.0", "1.2.0.0", "1.3", "1.3.1", "1.3.1.2", "1.3.1.3", "1.3.2", "1.4", "2.3.1"]
}
from Version v1, Version v2
diff --git a/csharp/ql/test/library-tests/assemblies/ValidVersions.ql b/csharp/ql/test/library-tests/assemblies/ValidVersions.ql
index da5b749200c..3e66e165461 100644
--- a/csharp/ql/test/library-tests/assemblies/ValidVersions.ql
+++ b/csharp/ql/test/library-tests/assemblies/ValidVersions.ql
@@ -1,14 +1,6 @@
import csharp
from Version version
-where
- version = "1.2.3.4" or
- version = "2.3.24" or
- version = "1.2" or
- version = "xxx" or
- version = "1.x" or
- version = "1" or
- version = "" or
- version = "1234.56"
+where version = ["1.2.3.4", "2.3.24", "1.2", "xxx", "1.x", "1", "", "1234.56"]
select version, version.getMajor(), version.getMajorRevision(), version.getMinor(),
version.getMinorRevision()
diff --git a/csharp/ql/test/library-tests/assignables/AssignableDefinition.ql b/csharp/ql/test/library-tests/assignables/AssignableDefinition.ql
index 6f24ecaa0e9..ad5facdab45 100644
--- a/csharp/ql/test/library-tests/assignables/AssignableDefinition.ql
+++ b/csharp/ql/test/library-tests/assignables/AssignableDefinition.ql
@@ -6,14 +6,14 @@ newtype TTargetAccessOption =
class TargetAccessOption extends TTargetAccessOption {
string toString() {
- result = som().toString()
+ result = this.som().toString()
or
- exists(non()) and result = ""
+ exists(this.non()) and result = ""
}
Location getLocation() {
- result = som().getLocation() or
- result = non().getLocation()
+ result = this.som().getLocation() or
+ result = this.non().getLocation()
}
private AssignableAccess som() { this = TTargetAccessSome(result) }
@@ -31,14 +31,14 @@ newtype TSourceOption =
class SourceOption extends TSourceOption {
string toString() {
- result = som().toString()
+ result = this.som().toString()
or
- exists(non()) and result = ""
+ exists(this.non()) and result = ""
}
Location getLocation() {
- result = som().getLocation() or
- result = non().getLocation()
+ result = this.som().getLocation() or
+ result = this.non().getLocation()
}
private Expr som() { this = TSourceSome(result) }
diff --git a/csharp/ql/test/library-tests/cil/consistency/Handles.ql b/csharp/ql/test/library-tests/cil/consistency/Handles.ql
index a64ea94eb98..e67e4b29416 100644
--- a/csharp/ql/test/library-tests/cil/consistency/Handles.ql
+++ b/csharp/ql/test/library-tests/cil/consistency/Handles.ql
@@ -5,7 +5,7 @@ import dotnet
class MetadataEntity extends DotNet::NamedElement, @metadata_entity {
int getHandle() { metadata_handle(this, _, result) }
- predicate hasHandle() { exists(getHandle()) }
+ predicate hasHandle() { exists(this.getHandle()) }
Assembly getAssembly() { metadata_handle(this, result, _) }
}
diff --git a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.cs b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.cs
index 3b8a9ba7c7f..4125866a549 100644
--- a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.cs
+++ b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.cs
@@ -92,6 +92,19 @@ namespace My.Qltest
Sink(i);
}
+ void M15()
+ {
+ var d1 = new D();
+ d1.Field = new object();
+ var d2 = new D();
+ Apply2(d =>
+ {
+ Sink(d);
+ }, d1, d2);
+ Sink(d1.Field);
+ Sink(d2.Field2); // SPURIOUS FLOW
+ }
+
object StepArgRes(object x) { return null; }
void StepArgArg(object @in, object @out) { }
@@ -103,6 +116,7 @@ namespace My.Qltest
void StepQualArg(object @out) { }
object Field;
+ object Field2;
object StepFieldGetter() => throw null;
@@ -122,6 +136,8 @@ namespace My.Qltest
static S[] Map(S[] elements, Func f) => throw null;
+ static void Apply2(Action f, S s1, S s2) => throw null;
+
static void Parse(string s, out int i) => throw null;
static void Sink(object o) { }
diff --git a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected
index 62af20beb18..5a1c6b31a97 100644
--- a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected
+++ b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.expected
@@ -24,12 +24,12 @@ edges
| ExternalFlow.cs:54:36:54:47 | object creation of type Object : Object | ExternalFlow.cs:54:13:54:16 | [post] this access [element] : Object |
| ExternalFlow.cs:55:18:55:21 | this access [element] : Object | ExternalFlow.cs:55:18:55:41 | call to method StepElementGetter |
| ExternalFlow.cs:60:35:60:35 | o : Object | ExternalFlow.cs:60:47:60:47 | access to parameter o |
-| ExternalFlow.cs:60:64:60:75 | object creation of type Object : Object | ExternalFlow.cs:121:46:121:46 | s : Object |
+| ExternalFlow.cs:60:64:60:75 | object creation of type Object : Object | ExternalFlow.cs:135:46:135:46 | s : Object |
| ExternalFlow.cs:65:21:65:60 | call to method Apply : Object | ExternalFlow.cs:66:18:66:18 | access to local variable o |
| ExternalFlow.cs:65:45:65:56 | object creation of type Object : Object | ExternalFlow.cs:65:21:65:60 | call to method Apply : Object |
| ExternalFlow.cs:71:30:71:45 | { ..., ... } [element] : Object | ExternalFlow.cs:72:17:72:20 | access to local variable objs [element] : Object |
| ExternalFlow.cs:71:32:71:43 | object creation of type Object : Object | ExternalFlow.cs:71:30:71:45 | { ..., ... } [element] : Object |
-| ExternalFlow.cs:72:17:72:20 | access to local variable objs [element] : Object | ExternalFlow.cs:123:34:123:41 | elements [element] : Object |
+| ExternalFlow.cs:72:17:72:20 | access to local variable objs [element] : Object | ExternalFlow.cs:137:34:137:41 | elements [element] : Object |
| ExternalFlow.cs:72:23:72:23 | o : Object | ExternalFlow.cs:72:35:72:35 | access to parameter o |
| ExternalFlow.cs:77:24:77:58 | call to method Map [element] : Object | ExternalFlow.cs:78:18:78:21 | access to local variable objs [element] : Object |
| ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | ExternalFlow.cs:77:24:77:58 | call to method Map [element] : Object |
@@ -43,8 +43,29 @@ edges
| ExternalFlow.cs:90:21:90:34 | object creation of type String : String | ExternalFlow.cs:91:19:91:19 | access to local variable s : String |
| ExternalFlow.cs:91:19:91:19 | access to local variable s : String | ExternalFlow.cs:91:30:91:30 | SSA def(i) : Int32 |
| ExternalFlow.cs:91:30:91:30 | SSA def(i) : Int32 | ExternalFlow.cs:92:18:92:18 | (...) ... |
-| ExternalFlow.cs:121:46:121:46 | s : Object | ExternalFlow.cs:60:35:60:35 | o : Object |
-| ExternalFlow.cs:123:34:123:41 | elements [element] : Object | ExternalFlow.cs:72:23:72:23 | o : Object |
+| ExternalFlow.cs:98:13:98:14 | [post] access to local variable d1 [field Field] : Object | ExternalFlow.cs:103:16:103:17 | access to local variable d1 [field Field] : Object |
+| ExternalFlow.cs:98:13:98:14 | [post] access to local variable d1 [field Field] : Object | ExternalFlow.cs:104:18:104:19 | access to local variable d1 [field Field] : Object |
+| ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | ExternalFlow.cs:98:13:98:14 | [post] access to local variable d1 [field Field] : Object |
+| ExternalFlow.cs:100:20:100:20 | d : Object | ExternalFlow.cs:102:22:102:22 | access to parameter d |
+| ExternalFlow.cs:103:16:103:17 | access to local variable d1 [field Field] : Object | ExternalFlow.cs:103:20:103:21 | [post] access to local variable d2 [field Field2] : Object |
+| ExternalFlow.cs:103:16:103:17 | access to local variable d1 [field Field] : Object | ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object |
+| ExternalFlow.cs:103:20:103:21 | [post] access to local variable d2 [field Field2] : Object | ExternalFlow.cs:105:18:105:19 | access to local variable d2 [field Field2] : Object |
+| ExternalFlow.cs:104:18:104:19 | access to local variable d1 [field Field] : Object | ExternalFlow.cs:104:18:104:25 | access to field Field |
+| ExternalFlow.cs:105:18:105:19 | access to local variable d2 [field Field2] : Object | ExternalFlow.cs:105:18:105:26 | access to field Field2 |
+| ExternalFlow.cs:135:46:135:46 | s : Object | ExternalFlow.cs:60:35:60:35 | o : Object |
+| ExternalFlow.cs:137:34:137:41 | elements [element] : Object | ExternalFlow.cs:72:23:72:23 | o : Object |
+| ExternalFlow.cs:137:34:137:41 | elements [element] : Object | ExternalFlow.cs:72:23:72:23 | o : Object |
+| ExternalFlow.cs:137:34:137:41 | elements [element] : Object | ExternalFlow.cs:137:34:137:41 | elements [element] : Object |
+| ExternalFlow.cs:137:34:137:41 | elements [element] : Object | ExternalFlow.cs:137:34:137:41 | elements [element] : Object |
+| ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object | ExternalFlow.cs:100:20:100:20 | d : Object |
+| ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object | ExternalFlow.cs:100:20:100:20 | d : Object |
+| ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object | ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object |
+| ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object | ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object |
+| ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object | ExternalFlow.cs:139:52:139:53 | s2 [field Field2] : Object |
+| ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object | ExternalFlow.cs:139:52:139:53 | s2 [field Field2] : Object |
+| ExternalFlow.cs:139:52:139:53 | s2 [field Field2] : Object | ExternalFlow.cs:100:20:100:20 | d : Object |
+| ExternalFlow.cs:139:52:139:53 | s2 [field Field2] : Object | ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object |
+| ExternalFlow.cs:139:52:139:53 | s2 [field Field2] : Object | ExternalFlow.cs:139:52:139:53 | s2 [field Field2] : Object |
nodes
| ExternalFlow.cs:9:27:9:38 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |
| ExternalFlow.cs:10:18:10:33 | call to method StepArgRes | semmle.label | call to method StepArgRes |
@@ -104,8 +125,22 @@ nodes
| ExternalFlow.cs:91:19:91:19 | access to local variable s : String | semmle.label | access to local variable s : String |
| ExternalFlow.cs:91:30:91:30 | SSA def(i) : Int32 | semmle.label | SSA def(i) : Int32 |
| ExternalFlow.cs:92:18:92:18 | (...) ... | semmle.label | (...) ... |
-| ExternalFlow.cs:121:46:121:46 | s : Object | semmle.label | s : Object |
-| ExternalFlow.cs:123:34:123:41 | elements [element] : Object | semmle.label | elements [element] : Object |
+| ExternalFlow.cs:98:13:98:14 | [post] access to local variable d1 [field Field] : Object | semmle.label | [post] access to local variable d1 [field Field] : Object |
+| ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |
+| ExternalFlow.cs:100:20:100:20 | d : Object | semmle.label | d : Object |
+| ExternalFlow.cs:102:22:102:22 | access to parameter d | semmle.label | access to parameter d |
+| ExternalFlow.cs:103:16:103:17 | access to local variable d1 [field Field] : Object | semmle.label | access to local variable d1 [field Field] : Object |
+| ExternalFlow.cs:103:20:103:21 | [post] access to local variable d2 [field Field2] : Object | semmle.label | [post] access to local variable d2 [field Field2] : Object |
+| ExternalFlow.cs:104:18:104:19 | access to local variable d1 [field Field] : Object | semmle.label | access to local variable d1 [field Field] : Object |
+| ExternalFlow.cs:104:18:104:25 | access to field Field | semmle.label | access to field Field |
+| ExternalFlow.cs:105:18:105:19 | access to local variable d2 [field Field2] : Object | semmle.label | access to local variable d2 [field Field2] : Object |
+| ExternalFlow.cs:105:18:105:26 | access to field Field2 | semmle.label | access to field Field2 |
+| ExternalFlow.cs:135:46:135:46 | s : Object | semmle.label | s : Object |
+| ExternalFlow.cs:137:34:137:41 | elements [element] : Object | semmle.label | elements [element] : Object |
+| ExternalFlow.cs:137:34:137:41 | elements [element] : Object | semmle.label | elements [element] : Object |
+| ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object | semmle.label | s1 [field Field] : Object |
+| ExternalFlow.cs:139:46:139:47 | s1 [field Field] : Object | semmle.label | s1 [field Field] : Object |
+| ExternalFlow.cs:139:52:139:53 | s2 [field Field2] : Object | semmle.label | s2 [field Field2] : Object |
subpaths
invalidModelRow
#select
@@ -124,3 +159,6 @@ invalidModelRow
| ExternalFlow.cs:78:18:78:24 | (...) ... | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | ExternalFlow.cs:78:18:78:24 | (...) ... | $@ | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | object creation of type Object : Object |
| ExternalFlow.cs:85:18:85:25 | access to array element | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | ExternalFlow.cs:85:18:85:25 | access to array element | $@ | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | object creation of type Object : Object |
| ExternalFlow.cs:92:18:92:18 | (...) ... | ExternalFlow.cs:90:21:90:34 | object creation of type String : String | ExternalFlow.cs:92:18:92:18 | (...) ... | $@ | ExternalFlow.cs:90:21:90:34 | object creation of type String : String | object creation of type String : String |
+| ExternalFlow.cs:102:22:102:22 | access to parameter d | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | ExternalFlow.cs:102:22:102:22 | access to parameter d | $@ | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | object creation of type Object : Object |
+| ExternalFlow.cs:104:18:104:25 | access to field Field | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | ExternalFlow.cs:104:18:104:25 | access to field Field | $@ | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | object creation of type Object : Object |
+| ExternalFlow.cs:105:18:105:26 | access to field Field2 | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | ExternalFlow.cs:105:18:105:26 | access to field Field2 | $@ | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | object creation of type Object : Object |
diff --git a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ql b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ql
index d22956a1b0e..f164967c770 100644
--- a/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ql
+++ b/csharp/ql/test/library-tests/dataflow/external-models/ExternalFlow.ql
@@ -23,6 +23,8 @@ class SummaryModelTest extends SummaryModelCsv {
"My.Qltest;D;false;StepElementSetter;(System.Object);;Argument[0];Element of Argument[-1];value",
"My.Qltest;D;false;Apply<,>;(System.Func,S);;Argument[1];Parameter[0] of Argument[0];value",
"My.Qltest;D;false;Apply<,>;(System.Func,S);;ReturnValue of Argument[0];ReturnValue;value",
+ "My.Qltest;D;false;Apply2<>;(System.Action,S,S);;Field[My.Qltest.D.Field] of Argument[1];Parameter[0] of Argument[0];value",
+ "My.Qltest;D;false;Apply2<>;(System.Action,S,S);;Field[My.Qltest.D.Field2] of Argument[2];Parameter[0] of Argument[0];value",
"My.Qltest;D;false;Map<,>;(S[],System.Func);;Element of Argument[0];Parameter[0] of Argument[1];value",
"My.Qltest;D;false;Map<,>;(S[],System.Func);;ReturnValue of Argument[1];Element of ReturnValue;value",
"My.Qltest;D;false;Parse;(System.String,System.Int32);;Argument[0];Argument[1];taint"
diff --git a/csharp/ql/test/library-tests/dataflow/external-models/steps.expected b/csharp/ql/test/library-tests/dataflow/external-models/steps.expected
index f73872ed9be..84e3026c74f 100644
--- a/csharp/ql/test/library-tests/dataflow/external-models/steps.expected
+++ b/csharp/ql/test/library-tests/dataflow/external-models/steps.expected
@@ -8,6 +8,8 @@ summaryThroughStep
| Steps.cs:22:13:22:16 | this access | Steps.cs:22:13:22:30 | call to method StepQualRes | false |
| Steps.cs:23:13:23:25 | this access | Steps.cs:23:13:23:25 | call to method StepQualRes | false |
| Steps.cs:26:13:26:31 | this access | Steps.cs:26:25:26:30 | [post] access to local variable argOut | false |
+| Steps.cs:30:13:30:16 | this access | Steps.cs:30:13:30:16 | [post] this access | true |
+| Steps.cs:34:13:34:16 | this access | Steps.cs:34:13:34:16 | [post] this access | true |
| Steps.cs:41:29:41:29 | 0 | Steps.cs:41:13:41:30 | call to method StepGeneric | true |
| Steps.cs:42:30:42:34 | false | Steps.cs:42:13:42:35 | call to method StepGeneric2 | true |
| Steps.cs:44:36:44:43 | "string" | Steps.cs:44:13:44:44 | call to method StepOverride | true |
@@ -19,3 +21,6 @@ summarySetterStep
| Steps.cs:30:34:30:34 | 0 | Steps.cs:30:13:30:16 | [post] this access | Steps.cs:57:13:57:17 | field Field |
| Steps.cs:34:37:34:37 | 0 | Steps.cs:34:13:34:16 | [post] this access | Steps.cs:63:13:63:20 | property Property |
| Steps.cs:38:36:38:36 | 0 | Steps.cs:38:13:38:16 | [post] this access | file://:0:0:0:0 | element |
+clearsContent
+| Steps.cs:61:14:61:28 | StepFieldSetter | Steps.cs:57:13:57:17 | field Field | -1 |
+| Steps.cs:67:14:67:31 | StepPropertySetter | Steps.cs:63:13:63:20 | property Property | -1 |
diff --git a/csharp/ql/test/library-tests/dataflow/external-models/steps.ql b/csharp/ql/test/library-tests/dataflow/external-models/steps.ql
index b5643d27ca5..cab4c292a40 100644
--- a/csharp/ql/test/library-tests/dataflow/external-models/steps.ql
+++ b/csharp/ql/test/library-tests/dataflow/external-models/steps.ql
@@ -1,6 +1,7 @@
import csharp
import DataFlow
import semmle.code.csharp.dataflow.ExternalFlow
+import semmle.code.csharp.dataflow.FlowSummary
import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
import CsvValidation
@@ -40,3 +41,8 @@ query predicate summaryGetterStep(DataFlow::Node arg, DataFlow::Node out, Conten
query predicate summarySetterStep(DataFlow::Node arg, DataFlow::Node out, Content c) {
FlowSummaryImpl::Private::Steps::summarySetterStep(arg, c, out)
}
+
+query predicate clearsContent(SummarizedCallable c, DataFlow::Content k, int i) {
+ c.clearsContent(i, k) and
+ c.fromSource()
+}
diff --git a/csharp/ql/test/library-tests/dataflow/fields/A.cs b/csharp/ql/test/library-tests/dataflow/fields/A.cs
index d56ab3adc1e..663bbb1dab6 100644
--- a/csharp/ql/test/library-tests/dataflow/fields/A.cs
+++ b/csharp/ql/test/library-tests/dataflow/fields/A.cs
@@ -2,35 +2,35 @@ public class A
{
public void M1()
{
- var c = new C();
+ var c = Source(1);
var b = B.Make(c);
- Sink(b.c); // flow
+ Sink(b.c); // $ hasValueFlow=1
}
public void M2()
{
var b = new B();
- b.Set(new C1());
- Sink(b.Get()); // flow
- Sink((new B(new C())).Get()); // flow
+ b.Set(Source(2.1));
+ Sink(b.Get()); // $ hasValueFlow=2.1
+ Sink((new B(Source(2.2))).Get()); // $ hasValueFlow=2.2
}
public void M3()
{
var b1 = new B();
B b2;
- b2 = SetOnB(b1, new C2());
- Sink(b1.c); // no flow
- Sink(b2.c); // flow
+ b2 = SetOnB(b1, Source(3));
+ Sink(b1.c);
+ Sink(b2.c); // $ hasValueFlow=3
}
public void M4()
{
var b1 = new B();
B b2;
- b2 = SetOnBWrap(b1, new C2());
- Sink(b1.c); // no flow
- Sink(b2.c); // flow
+ b2 = SetOnBWrap(b1, Source(4));
+ Sink(b1.c);
+ Sink(b2.c); // $ hasValueFlow=4
}
public B SetOnBWrap(B b1, C c)
@@ -52,7 +52,7 @@ public class A
public void M5()
{
- var a = new A();
+ var a = Source(5);
C1 c1 = new C1();
c1.a = a;
M6(c1);
@@ -61,7 +61,7 @@ public class A
{
if (c is C1)
{
- Sink(((C1)c).a); // flow
+ Sink(((C1)c).a); // $ hasValueFlow=5
}
C cc;
if (c is C2)
@@ -80,13 +80,13 @@ public class A
public void M7(B b)
{
- b.Set(new C());
+ b.Set(Source(7));
}
public void M8()
{
var b = new B();
M7(b);
- Sink(b.c); // flow
+ Sink(b.c); // $ hasValueFlow=7
}
public class D
@@ -94,33 +94,33 @@ public class A
public B b;
public D(B b, bool x)
{
- b.c = new C();
- this.b = x ? b : new B();
+ b.c = Source(9.1);
+ this.b = x ? b : Source(9.2);
}
}
public void M9()
{
- var b = new B();
+ var b = Source(9.3);
var d = new D(b, R());
- Sink(d.b); // flow x2
- Sink(d.b.c); // flow
- Sink(b.c); // flow
+ Sink(d.b); // $ hasValueFlow=9.2 $ hasValueFlow=9.3
+ Sink(d.b.c); // $ hasValueFlow=9.1
+ Sink(b.c); // $ hasValueFlow=9.1
}
public void M10()
{
- var b = new B();
+ var b = Source(10);
var l1 = new MyList(b, new MyList(null, null));
var l2 = new MyList(null, l1);
var l3 = new MyList(null, l2);
Sink(l3.head); // no flow, b is nested beneath at least one .next
Sink(l3.next.head); // flow, the precise nesting depth isn't tracked
- Sink(l3.next.next.head); // flow
+ Sink(l3.next.next.head); // $ hasValueFlow=10
Sink(l3.next.next.next.head); // no flow
for (var l = l3; l != null; l = l.next)
{
- Sink(l.head); // flow
+ Sink(l.head); // $ hasValueFlow=10
}
}
@@ -160,4 +160,6 @@ public class A
this.next = next;
}
}
+
+ static T Source(object source) => throw null;
}
diff --git a/csharp/ql/test/library-tests/dataflow/fields/B.cs b/csharp/ql/test/library-tests/dataflow/fields/B.cs
index f25b8959d22..84c87e7298f 100644
--- a/csharp/ql/test/library-tests/dataflow/fields/B.cs
+++ b/csharp/ql/test/library-tests/dataflow/fields/B.cs
@@ -2,20 +2,20 @@ public class B
{
public void M1()
{
- var e = new Elem();
+ var e = Source(1);
var b1 = new Box1(e, null);
var b2 = new Box2(b1);
- Sink(b2.box1.elem1); // flow
+ Sink(b2.box1.elem1); // $ hasValueFlow=1
Sink(b2.box1.elem2); // no flow
}
public void M2()
{
- var e = new Elem();
+ var e = Source(2);
var b1 = new Box1(null, e);
var b2 = new Box2(b1);
Sink(b2.box1.elem1); // no flow
- Sink(b2.box1.elem2); // flow
+ Sink(b2.box1.elem2); // $ hasValueFlow=2
}
public static void Sink(object o) { }
@@ -41,4 +41,6 @@ public class B
this.box1 = b1;
}
}
+
+ static T Source(object source) => throw null;
}
diff --git a/csharp/ql/test/library-tests/dataflow/fields/C.cs b/csharp/ql/test/library-tests/dataflow/fields/C.cs
index da7b5f14fee..9ebe9ec27ed 100644
--- a/csharp/ql/test/library-tests/dataflow/fields/C.cs
+++ b/csharp/ql/test/library-tests/dataflow/fields/C.cs
@@ -1,11 +1,11 @@
public class C
{
- private Elem s1 = new Elem();
- private readonly Elem s2 = new Elem();
+ private Elem s1 = Source(1);
+ private readonly Elem s2 = Source(2);
private Elem s3;
- private static Elem s4 = new Elem();
- private Elem s5 { get; set; } = new Elem();
- private Elem s6 { get => new Elem(); set { } }
+ private static Elem s4 = Source(4);
+ private Elem s5 { get; set; } = Source(5);
+ private Elem s6 { get => Source(6); set { } }
void M1()
{
@@ -15,20 +15,22 @@ public class C
private C()
{
- this.s3 = new Elem();
+ this.s3 = Source(3);
}
public void M2()
{
- Sink(s1);
- Sink(s2);
- Sink(s3);
- Sink(s4);
- Sink(s5);
- Sink(s6);
+ Sink(s1); // $ hasValueFlow=1
+ Sink(s2); // $ hasValueFlow=2
+ Sink(s3); // $ hasValueFlow=3
+ Sink(s4); // $ hasValueFlow=4
+ Sink(s5); // $ hasValueFlow=5
+ Sink(s6); // $ hasValueFlow=6
}
public static void Sink(object o) { }
+ static T Source(object source) => throw null;
+
public class Elem { }
}
diff --git a/csharp/ql/test/library-tests/dataflow/fields/D.cs b/csharp/ql/test/library-tests/dataflow/fields/D.cs
index 505f56bd388..7a3fe985137 100644
--- a/csharp/ql/test/library-tests/dataflow/fields/D.cs
+++ b/csharp/ql/test/library-tests/dataflow/fields/D.cs
@@ -26,26 +26,28 @@ public class D
private void M()
{
- var o = new object();
+ var o = Source