diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 60b21a86163e..30cb9833a6a4 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -45,3 +45,5 @@ updates:
directory: "/"
schedule:
interval: weekly
+ exclude-paths:
+ - "misc/bazel/registry/**"
diff --git a/.github/workflows/compile-queries.yml b/.github/workflows/compile-queries.yml
deleted file mode 100644
index c8f6301bb531..000000000000
--- a/.github/workflows/compile-queries.yml
+++ /dev/null
@@ -1,78 +0,0 @@
-name: "Compile all queries using the latest stable CodeQL CLI"
-
-on:
- push:
- branches: # makes sure the cache gets populated - running on the branches people tend to merge into.
- - main
- - "rc/*"
- - "codeql-cli-*"
- pull_request:
- paths:
- - '**.ql'
- - '**.qll'
- - '**/qlpack.yml'
- - '**.dbscheme'
-
-permissions:
- contents: read
-
-jobs:
- detect-changes:
- if: github.repository_owner == 'github'
- runs-on: ubuntu-latest
- outputs:
- languages: ${{ steps.detect.outputs.languages }}
- steps:
- - uses: actions/checkout@v5
- - name: Detect changed languages
- id: detect
- run: |
- if [[ "${{ github.event_name }}" == "pull_request" ]]; then
- # For PRs, detect which languages have changes
- changed_files=$(gh pr view ${{ github.event.pull_request.number }} --json files --jq '.files.[].path')
- languages=()
- for lang in actions cpp csharp go java javascript python ql ruby rust swift; do
- if echo "$changed_files" | grep -qE "^($lang/|shared/)" ; then
- languages+=("$lang")
- fi
- done
- echo "languages=$(jq -c -n '$ARGS.positional' --args "${languages[@]}")" >> $GITHUB_OUTPUT
- else
- # For pushes to main/rc branches, run all languages
- echo 'languages=["actions","cpp","csharp","go","java","javascript","python","ql","ruby","rust","swift"]' >> $GITHUB_OUTPUT
- fi
- env:
- GH_TOKEN: ${{ github.token }}
-
- compile-queries:
- needs: detect-changes
- if: github.repository_owner == 'github' && needs.detect-changes.outputs.languages != '[]'
- runs-on: ubuntu-latest-xl
- strategy:
- fail-fast: false
- matrix:
- language: ${{ fromJson(needs.detect-changes.outputs.languages) }}
-
- steps:
- - uses: actions/checkout@v5
- - name: Setup CodeQL
- uses: ./.github/actions/fetch-codeql
- with:
- channel: 'release'
- - name: Cache compilation cache
- id: query-cache
- uses: ./.github/actions/cache-query-compilation
- with:
- key: ${{ matrix.language }}-queries
- - name: check formatting
- run: find shared ${{ matrix.language }}/ql -type f \( -name "*.qll" -o -name "*.ql" \) -print0 | xargs -0 -n 3000 -P 10 codeql query format -q --check-only
- - name: compile queries - check-only
- # run with --check-only if running in a PR (github.sha != main)
- if : ${{ github.event_name == 'pull_request' }}
- shell: bash
- run: codeql query compile -q -j0 ${{ matrix.language }}/ql/{src,examples} --keep-going --warnings=error --check-only --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500 --ram=56000
- - name: compile queries - full
- # do full compile if running on main - this populates the cache
- if : ${{ github.event_name != 'pull_request' }}
- shell: bash
- run: codeql query compile -q -j0 ${{ matrix.language }}/ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500 --ram=56000
diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml
deleted file mode 100644
index 39aadef09138..000000000000
--- a/.github/workflows/ruby-build.yml
+++ /dev/null
@@ -1,236 +0,0 @@
-name: "Ruby: Build"
-
-on:
- push:
- paths:
- - "ruby/**"
- - .github/workflows/ruby-build.yml
- - .github/actions/fetch-codeql/action.yml
- - codeql-workspace.yml
- - "shared/tree-sitter-extractor/**"
- branches:
- - main
- - "rc/*"
- pull_request:
- paths:
- - "ruby/**"
- - .github/workflows/ruby-build.yml
- - .github/actions/fetch-codeql/action.yml
- - codeql-workspace.yml
- - "shared/tree-sitter-extractor/**"
- branches:
- - main
- - "rc/*"
- workflow_dispatch:
- inputs:
- tag:
- description: "Version tag to create"
- required: false
-
-env:
- CARGO_TERM_COLOR: always
-
-defaults:
- run:
- working-directory: ruby
-
-permissions:
- contents: read
-
-jobs:
- build:
- strategy:
- fail-fast: false
- matrix:
- os: [ubuntu-latest, macos-latest, windows-latest]
-
- runs-on: ${{ matrix.os }}
-
- steps:
- - uses: actions/checkout@v5
- - name: Install GNU tar
- if: runner.os == 'macOS'
- run: |
- brew install gnu-tar
- echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
- - name: Prepare Windows
- if: runner.os == 'Windows'
- shell: powershell
- run: |
- git config --global core.longpaths true
- - uses: ./.github/actions/os-version
- id: os_version
- - name: Cache entire extractor
- uses: actions/cache@v3
- id: cache-extractor
- with:
- path: |
- target/release/codeql-extractor-ruby
- target/release/codeql-extractor-ruby.exe
- ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
- key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ruby/extractor/**/*.rs') }}
- - uses: actions/cache@v3
- if: steps.cache-extractor.outputs.cache-hit != 'true'
- with:
- path: |
- ~/.cargo/registry
- ~/.cargo/git
- target
- key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-rust-cargo-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/**/Cargo.lock') }}
- - name: Check formatting
- if: steps.cache-extractor.outputs.cache-hit != 'true'
- run: cd extractor && cargo fmt -- --check
- - name: Build
- if: steps.cache-extractor.outputs.cache-hit != 'true'
- run: cd extractor && cargo build --verbose
- - name: Run tests
- if: steps.cache-extractor.outputs.cache-hit != 'true'
- run: cd extractor && cargo test --verbose
- - name: Release build
- if: steps.cache-extractor.outputs.cache-hit != 'true'
- run: cd extractor && cargo build --release
- - name: Generate dbscheme
- if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}}
- run: ../target/release/codeql-extractor-ruby generate --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
- - uses: actions/upload-artifact@v4
- if: ${{ matrix.os == 'ubuntu-latest' }}
- with:
- name: ruby.dbscheme
- path: ruby/ql/lib/ruby.dbscheme
- - uses: actions/upload-artifact@v4
- if: ${{ matrix.os == 'ubuntu-latest' }}
- with:
- name: TreeSitter.qll
- path: ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
- - uses: actions/upload-artifact@v4
- with:
- name: extractor-${{ matrix.os }}
- path: |
- target/release/codeql-extractor-ruby
- target/release/codeql-extractor-ruby.exe
- retention-days: 1
- compile-queries:
- if: github.repository_owner == 'github'
- runs-on: ubuntu-latest-xl
- steps:
- - uses: actions/checkout@v5
- - name: Fetch CodeQL
- uses: ./.github/actions/fetch-codeql
- - name: Cache compilation cache
- id: query-cache
- uses: ./.github/actions/cache-query-compilation
- with:
- key: ruby-build
- - name: Build Query Pack
- run: |
- PACKS=${{ runner.temp }}/query-packs
- rm -rf $PACKS
- codeql pack create ../misc/suite-helpers --output "$PACKS"
- codeql pack create ../shared/regex --output "$PACKS"
- codeql pack create ../shared/ssa --output "$PACKS"
- codeql pack create ../shared/tutorial --output "$PACKS"
- codeql pack create ql/lib --output "$PACKS"
- codeql pack create -j0 ql/src --output "$PACKS" --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
- PACK_FOLDER=$(readlink -f "$PACKS"/codeql/ruby-queries/*)
- codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
- (cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;)
- - uses: actions/upload-artifact@v4
- with:
- name: codeql-ruby-queries
- path: |
- ${{ runner.temp }}/query-packs/*
- retention-days: 1
- include-hidden-files: true
-
- package:
- runs-on: ubuntu-latest
- needs: [build, compile-queries]
- steps:
- - uses: actions/checkout@v5
- - uses: actions/download-artifact@v4
- with:
- name: ruby.dbscheme
- path: ruby/ruby
- - uses: actions/download-artifact@v4
- with:
- name: extractor-ubuntu-latest
- path: ruby/linux64
- - uses: actions/download-artifact@v4
- with:
- name: extractor-windows-latest
- path: ruby/win64
- - uses: actions/download-artifact@v4
- 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/codeql-extractor-ruby ruby/tools/linux64/extractor
- cp osx64/codeql-extractor-ruby ruby/tools/osx64/extractor
- cp win64/codeql-extractor-ruby.exe ruby/tools/win64/extractor.exe
- chmod +x ruby/tools/{linux64,osx64}/extractor
- zip -rq codeql-ruby.zip ruby
- - uses: actions/upload-artifact@v4
- with:
- name: codeql-ruby-pack
- path: ruby/codeql-ruby.zip
- retention-days: 1
- include-hidden-files: true
- - uses: actions/download-artifact@v4
- 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@v4
- with:
- name: codeql-ruby-bundle
- path: ruby/codeql-ruby-bundle.zip
- retention-days: 1
- include-hidden-files: true
-
- 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@v5
- - name: Fetch CodeQL
- uses: ./.github/actions/fetch-codeql
-
- - name: Download Ruby bundle
- uses: actions/download-artifact@v4
- 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: Run QL test
- shell: bash
- run: |
- codeql test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" ruby/ql/test/library-tests/ast/constants/
- - name: Create database
- shell: bash
- run: |
- codeql database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root ruby/ql/test/library-tests/ast/constants/ ../database
- - name: Analyze database
- shell: bash
- run: |
- 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
deleted file mode 100644
index a88b23bf3a10..000000000000
--- a/.github/workflows/ruby-dataset-measure.yml
+++ /dev/null
@@ -1,75 +0,0 @@
-name: "Ruby: Collect database stats"
-
-on:
- push:
- branches:
- - main
- - "rc/*"
- paths:
- - ruby/ql/lib/ruby.dbscheme
- - .github/workflows/ruby-dataset-measure.yml
- pull_request:
- branches:
- - main
- - "rc/*"
- paths:
- - ruby/ql/lib/ruby.dbscheme
- - .github/workflows/ruby-dataset-measure.yml
- workflow_dispatch:
-
-permissions:
- contents: read
-
-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, ruby/ruby]
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v5
-
- - uses: ./.github/actions/fetch-codeql
-
- - uses: ./ruby/actions/create-extractor-pack
-
- - name: Checkout ${{ matrix.repo }}
- uses: actions/checkout@v5
- with:
- repository: ${{ matrix.repo }}
- path: ${{ github.workspace }}/repo
- - name: Create database
- run: |
- codeql database create \
- --search-path "${{ github.workspace }}" \
- --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@v4
- with:
- name: measurements-${{ hashFiles('stats/**') }}
- path: stats
- retention-days: 1
-
- merge:
- runs-on: ubuntu-latest
- needs: measure
- steps:
- - uses: actions/checkout@v5
- - uses: actions/download-artifact@v4
- with:
- path: stats
- - run: |
- python -m pip install --user lxml
- find stats -name 'stats.xml' | sort | xargs python ruby/scripts/merge_stats.py --output ruby/ql/lib/ruby.dbscheme.stats --normalise ruby_tokeninfo
- - uses: actions/upload-artifact@v4
- with:
- name: ruby.dbscheme.stats
- path: ruby/ql/lib/ruby.dbscheme.stats
diff --git a/.github/workflows/ruby-qltest-rtjo.yml b/.github/workflows/ruby-qltest-rtjo.yml
deleted file mode 100644
index 1d57c465538e..000000000000
--- a/.github/workflows/ruby-qltest-rtjo.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: "Ruby: Run RTJO Language Tests"
-
-on:
- pull_request:
- types:
- - opened
- - synchronize
- - reopened
- - labeled
-
-env:
- CARGO_TERM_COLOR: always
-
-defaults:
- run:
- working-directory: ruby
-
-permissions:
- contents: read
-
-jobs:
- qltest-rtjo:
- if: "github.repository_owner == 'github' && github.event.label.name == 'Run: RTJO Language Tests'"
- runs-on: ubuntu-latest-xl
- strategy:
- fail-fast: false
- steps:
- - uses: actions/checkout@v5
- - uses: ./.github/actions/fetch-codeql
- - uses: ./ruby/actions/create-extractor-pack
- - name: Cache compilation cache
- id: query-cache
- uses: ./.github/actions/cache-query-compilation
- with:
- key: ruby-qltest
- - name: Run QL tests
- run: |
- codeql test run --dynamic-join-order-mode=all --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
- env:
- GITHUB_TOKEN: ${{ github.token }}
diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml
deleted file mode 100644
index e178a5dfb6e0..000000000000
--- a/.github/workflows/ruby-qltest.yml
+++ /dev/null
@@ -1,73 +0,0 @@
-name: "Ruby: Run QL Tests"
-
-on:
- push:
- paths:
- - "ruby/**"
- - "shared/**"
- - .github/workflows/ruby-build.yml
- - .github/actions/fetch-codeql/action.yml
- - codeql-workspace.yml
- branches:
- - main
- - "rc/*"
- pull_request:
- paths:
- - "ruby/**"
- - "shared/**"
- - .github/workflows/ruby-qltest.yml
- - .github/actions/fetch-codeql/action.yml
- - codeql-workspace.yml
- branches:
- - main
- - "rc/*"
-
-env:
- CARGO_TERM_COLOR: always
-
-defaults:
- run:
- working-directory: ruby
-
-permissions:
- contents: read
-
-jobs:
- qlupgrade:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v5
- - uses: ./.github/actions/fetch-codeql
- - 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
- diff -q testdb/ruby.dbscheme ql/lib/ruby.dbscheme
- - name: Check DB downgrade scripts
- run: |
- echo >empty.trap
- rm -rf testdb; codeql dataset import -S ql/lib/ruby.dbscheme testdb empty.trap
- codeql resolve upgrades --format=lines --allow-downgrades --additional-packs downgrades \
- --dbscheme=ql/lib/ruby.dbscheme --target-dbscheme=downgrades/initial/ruby.dbscheme |
- xargs codeql execute upgrades testdb
- diff -q testdb/ruby.dbscheme downgrades/initial/ruby.dbscheme
- qltest:
- if: github.repository_owner == 'github'
- runs-on: ubuntu-latest-xl
- strategy:
- fail-fast: false
- steps:
- - uses: actions/checkout@v5
- - uses: ./.github/actions/fetch-codeql
- - uses: ./ruby/actions/create-extractor-pack
- - name: Cache compilation cache
- id: query-cache
- uses: ./.github/actions/cache-query-compilation
- with:
- key: ruby-qltest
- - name: Run QL tests
- run: |
- codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
- env:
- GITHUB_TOKEN: ${{ github.token }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index e8eed93499f2..0f2906dab310 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -7,9 +7,9 @@ repos:
rev: v3.2.0
hooks:
- id: trailing-whitespace
- exclude: /test/.*$(? bar.md\n | .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | sed -f config foo.md > bar.md\n | .github/workflows/artifactpoisoning71.yml:4:5:4:16 | workflow_run | workflow_run |
-| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | python test.py | .github/workflows/artifactpoisoning81.yml:3:5:3:23 | pull_request_target | pull_request_target |
-| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Uses Step | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
-| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | make snapshot | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
-| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | npm install | .github/workflows/artifactpoisoning96.yml:2:3:2:14 | workflow_run | workflow_run |
-| .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | .github/workflows/artifactpoisoning101.yml:4:3:4:21 | pull_request_target | pull_request_target |
-| .github/workflows/test18.yml:36:15:40:58 | Uses Step | .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Uses Step | .github/workflows/test18.yml:3:5:3:16 | workflow_run | workflow_run |
-| .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | ./gradlew buildScanPublishPrevious\n | .github/workflows/test25.yml:2:3:2:14 | workflow_run | workflow_run |
+| .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
+| .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning11.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning11.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning11.yml:38:11:38:77 | ./sonarcloud-data/x.py build -j$(nproc) --compiler gcc --skip-build | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning11.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning12.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning12.yml:13:9:32:6 | Uses Step | .github/workflows/artifactpoisoning12.yml:38:11:38:25 | python foo/x.py | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning12.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning21.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning21.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning21.yml:19:14:20:21 | sh foo/cmd\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning21.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning22.yml:13:9:17:6 | Uses Step | .github/workflows/artifactpoisoning22.yml:13:9:17:6 | Uses Step | .github/workflows/artifactpoisoning22.yml:18:14:18:19 | sh cmd | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning22.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning31.yml:13:9:15:6 | Run Step | .github/workflows/artifactpoisoning31.yml:13:9:15:6 | Run Step | .github/workflows/artifactpoisoning31.yml:19:14:19:22 | ./foo/cmd | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning31.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning32.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning32.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning32.yml:17:14:18:20 | ./bar/cmd\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning32.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning33.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning33.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning33.yml:17:14:18:20 | ./bar/cmd\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning33.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning34.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning34.yml:13:9:16:6 | Run Step | .github/workflows/artifactpoisoning34.yml:20:14:22:23 | npm install\nnpm run lint\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning34.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning41.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning41.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning41.yml:22:14:22:22 | ./foo/cmd | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning41.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning42.yml:4:3:4:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning71.yml:4:5:4:16 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning81.yml:3:5:3:23 | pull_request_target | pull_request_target |
+| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning96.yml:2:3:2:14 | workflow_run | workflow_run |
+| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/artifactpoisoning101.yml:4:3:4:21 | pull_request_target | pull_request_target |
+| .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/test18.yml:3:5:3:16 | workflow_run | workflow_run |
+| .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | Potential artifact poisoning; the artifact being consumed has contents that may be controlled by an external user ($@). | .github/workflows/test25.yml:2:3:2:14 | workflow_run | workflow_run |
diff --git a/cpp/ql/integration-tests/query-suite/cpp-code-scanning.qls.expected b/cpp/ql/integration-tests/query-suite/cpp-code-scanning.qls.expected
index 33c02079fff8..d4b805999500 100644
--- a/cpp/ql/integration-tests/query-suite/cpp-code-scanning.qls.expected
+++ b/cpp/ql/integration-tests/query-suite/cpp-code-scanning.qls.expected
@@ -7,10 +7,12 @@ ql/cpp/ql/src/Diagnostics/ExtractedFiles.ql
ql/cpp/ql/src/Diagnostics/ExtractionWarnings.ql
ql/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql
ql/cpp/ql/src/Likely Bugs/Arithmetic/BadAdditionOverflowCheck.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
ql/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql
ql/cpp/ql/src/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql
ql/cpp/ql/src/Likely Bugs/Format/SnprintfOverflow.ql
ql/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.ql
+ql/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql
ql/cpp/ql/src/Likely Bugs/Memory Management/AllocaInLoop.ql
ql/cpp/ql/src/Likely Bugs/Memory Management/PointerOverflow.ql
ql/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql
@@ -28,6 +30,7 @@ ql/cpp/ql/src/Security/CWE/CWE-120/VeryLikelyOverrunWrite.ql
ql/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
ql/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql
ql/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql
+ql/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql
ql/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
ql/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql
ql/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql
@@ -40,6 +43,7 @@ ql/cpp/ql/src/Security/CWE/CWE-367/TOCTOUFilesystemRace.ql
ql/cpp/ql/src/Security/CWE/CWE-416/IteratorToExpiredContainer.ql
ql/cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql
ql/cpp/ql/src/Security/CWE/CWE-416/UseOfUniquePointerAfterLifetimeEnds.ql
+ql/cpp/ql/src/Security/CWE/CWE-468/SuspiciousAddWithSizeof.ql
ql/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql
ql/cpp/ql/src/Security/CWE/CWE-611/XXE.ql
ql/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql
@@ -52,5 +56,6 @@ ql/cpp/ql/src/Summary/LinesOfUserCode.ql
ql/cpp/ql/src/Telemetry/CompilerErrors.ql
ql/cpp/ql/src/Telemetry/DatabaseQuality.ql
ql/cpp/ql/src/Telemetry/ExtractionMetrics.ql
+ql/cpp/ql/src/Telemetry/ExtractorInformation.ql
ql/cpp/ql/src/Telemetry/MissingIncludes.ql
ql/cpp/ql/src/Telemetry/SucceededIncludes.ql
diff --git a/cpp/ql/integration-tests/query-suite/cpp-security-and-quality.qls.expected b/cpp/ql/integration-tests/query-suite/cpp-security-and-quality.qls.expected
index 9ef67d525cd0..cb4e5f7b305a 100644
--- a/cpp/ql/integration-tests/query-suite/cpp-security-and-quality.qls.expected
+++ b/cpp/ql/integration-tests/query-suite/cpp-security-and-quality.qls.expected
@@ -160,6 +160,7 @@ ql/cpp/ql/src/Summary/LinesOfUserCode.ql
ql/cpp/ql/src/Telemetry/CompilerErrors.ql
ql/cpp/ql/src/Telemetry/DatabaseQuality.ql
ql/cpp/ql/src/Telemetry/ExtractionMetrics.ql
+ql/cpp/ql/src/Telemetry/ExtractorInformation.ql
ql/cpp/ql/src/Telemetry/MissingIncludes.ql
ql/cpp/ql/src/Telemetry/SucceededIncludes.ql
ql/cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql
diff --git a/cpp/ql/integration-tests/query-suite/cpp-security-extended.qls.expected b/cpp/ql/integration-tests/query-suite/cpp-security-extended.qls.expected
index f014b6d5dc51..7c5e3d98c5c7 100644
--- a/cpp/ql/integration-tests/query-suite/cpp-security-extended.qls.expected
+++ b/cpp/ql/integration-tests/query-suite/cpp-security-extended.qls.expected
@@ -93,5 +93,6 @@ ql/cpp/ql/src/Summary/LinesOfUserCode.ql
ql/cpp/ql/src/Telemetry/CompilerErrors.ql
ql/cpp/ql/src/Telemetry/DatabaseQuality.ql
ql/cpp/ql/src/Telemetry/ExtractionMetrics.ql
+ql/cpp/ql/src/Telemetry/ExtractorInformation.ql
ql/cpp/ql/src/Telemetry/MissingIncludes.ql
ql/cpp/ql/src/Telemetry/SucceededIncludes.ql
diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md
index de37c16751ac..5b5bc748c5dd 100644
--- a/cpp/ql/lib/CHANGELOG.md
+++ b/cpp/ql/lib/CHANGELOG.md
@@ -1,3 +1,31 @@
+## 9.0.0
+
+### Breaking Changes
+
+* The `SourceModelCsv`, `SinkModelCsv`, and `SummaryModelCsv` classes and the associated CSV parsing infrastructure have been removed from `ExternalFlow.qll`. New models should be added as `.model.yml` files in the `ext/` directory.
+
+### New Features
+
+* Added a subclass `MesonPrivateTestFile` of `ConfigurationTestFile` that represents files created by Meson to test the build configuration.
+* Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists.
+* Added a class `ConstructorDefaultFieldInit` to represent default field initializations.
+* Added a class `DataFlow::IndirectParameterNode` to represent the indirection of a parameter as a dataflow node.
+* Added a predicate `Node::asIndirectInstruction` which returns the `Instruction` that defines the indirect dataflow node, if any.
+* Added a class `IndirectUninitializedNode` to represent the indirection of an uninitialized local variable as a dataflow node.
+
+### Minor Analysis Improvements
+
+* Added `HttpReceiveHttpRequest`, `HttpReceiveRequestEntityBody`, and `HttpReceiveClientCertificate` from Win32's `http.h` as remote flow sources.
+* Added dataflow through members initialized via non-static data member initialization (NSDMI).
+
+## 8.0.3
+
+No user-facing changes.
+
+## 8.0.2
+
+No user-facing changes.
+
## 8.0.1
### Minor Analysis Improvements
diff --git a/cpp/ql/lib/change-notes/2026-04-07-autoconf.md b/cpp/ql/lib/change-notes/2026-04-07-autoconf.md
new file mode 100644
index 000000000000..9f04417b8e25
--- /dev/null
+++ b/cpp/ql/lib/change-notes/2026-04-07-autoconf.md
@@ -0,0 +1,4 @@
+---
+category: feature
+---
+* Added a subclass `AutoconfConfigureTestFile` of `ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.
diff --git a/cpp/ql/lib/change-notes/2026-04-14-throwing.md b/cpp/ql/lib/change-notes/2026-04-14-throwing.md
new file mode 100644
index 000000000000..6a15437e126e
--- /dev/null
+++ b/cpp/ql/lib/change-notes/2026-04-14-throwing.md
@@ -0,0 +1,5 @@
+---
+category: breaking
+---
+* The deprecated `NonThrowingFunction` class has been removed, use `NonCppThrowingFunction` instead.
+* The deprecated `ThrowingFunction` class has been removed, use `AlwaysSehThrowingFunction` instead.
diff --git a/cpp/ql/lib/change-notes/released/8.0.2.md b/cpp/ql/lib/change-notes/released/8.0.2.md
new file mode 100644
index 000000000000..8119db7ca7b0
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/8.0.2.md
@@ -0,0 +1,3 @@
+## 8.0.2
+
+No user-facing changes.
diff --git a/cpp/ql/lib/change-notes/released/8.0.3.md b/cpp/ql/lib/change-notes/released/8.0.3.md
new file mode 100644
index 000000000000..de146c6309ec
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/8.0.3.md
@@ -0,0 +1,3 @@
+## 8.0.3
+
+No user-facing changes.
diff --git a/cpp/ql/lib/change-notes/released/9.0.0.md b/cpp/ql/lib/change-notes/released/9.0.0.md
new file mode 100644
index 000000000000..2f97209a02d2
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/9.0.0.md
@@ -0,0 +1,19 @@
+## 9.0.0
+
+### Breaking Changes
+
+* The `SourceModelCsv`, `SinkModelCsv`, and `SummaryModelCsv` classes and the associated CSV parsing infrastructure have been removed from `ExternalFlow.qll`. New models should be added as `.model.yml` files in the `ext/` directory.
+
+### New Features
+
+* Added a subclass `MesonPrivateTestFile` of `ConfigurationTestFile` that represents files created by Meson to test the build configuration.
+* Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists.
+* Added a class `ConstructorDefaultFieldInit` to represent default field initializations.
+* Added a class `DataFlow::IndirectParameterNode` to represent the indirection of a parameter as a dataflow node.
+* Added a predicate `Node::asIndirectInstruction` which returns the `Instruction` that defines the indirect dataflow node, if any.
+* Added a class `IndirectUninitializedNode` to represent the indirection of an uninitialized local variable as a dataflow node.
+
+### Minor Analysis Improvements
+
+* Added `HttpReceiveHttpRequest`, `HttpReceiveRequestEntityBody`, and `HttpReceiveClientCertificate` from Win32's `http.h` as remote flow sources.
+* Added dataflow through members initialized via non-static data member initialization (NSDMI).
diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml
index 145ae8f5b473..fd5f4a48b3c1 100644
--- a/cpp/ql/lib/codeql-pack.release.yml
+++ b/cpp/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 8.0.1
+lastReleaseVersion: 9.0.0
diff --git a/cpp/ql/lib/ext/Windows.model.yml b/cpp/ql/lib/ext/Windows.model.yml
index a2ec30d95bda..6794e9a86641 100644
--- a/cpp/ql/lib/ext/Windows.model.yml
+++ b/cpp/ql/lib/ext/Windows.model.yml
@@ -31,6 +31,9 @@ extensions:
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*5]", "remote", "manual"]
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*6]", "remote", "manual"]
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[**8]", "remote", "manual"]
+ - ["", "", False, "HttpReceiveHttpRequest", "", "", "Argument[*3]", "remote", "manual"]
+ - ["", "", False, "HttpReceiveRequestEntityBody", "", "", "Argument[*3]", "remote", "manual"]
+ - ["", "", False, "HttpReceiveClientCertificate", "", "", "Argument[*3]", "remote", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
diff --git a/cpp/ql/lib/ext/ZMQ.model.yml b/cpp/ql/lib/ext/ZMQ.model.yml
new file mode 100644
index 000000000000..62c3bb1a3bfe
--- /dev/null
+++ b/cpp/ql/lib/ext/ZMQ.model.yml
@@ -0,0 +1,22 @@
+# ZeroMQ networking library models
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: sourceModel
+ data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
+ - ["", "", False, "zmq_recv", "", "", "Argument[*1]", "remote", "manual"]
+ - ["", "", False, "zmq_recvmsg", "", "", "Argument[*1]", "remote", "manual"]
+ - ["", "", False, "zmq_msg_recv", "", "", "Argument[*0]", "remote", "manual"]
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: sinkModel
+ data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
+ - ["", "", False, "zmq_send", "", "", "Argument[*1]", "remote-sink", "manual"]
+ - ["", "", False, "zmq_sendmsg", "", "", "Argument[*1]", "remote-sink", "manual"]
+ - ["", "", False, "zmq_msg_send", "", "", "Argument[*0]", "remote-sink", "manual"]
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: summaryModel
+ data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
+ - ["", "", False, "zmq_msg_init_data", "", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["", "", False, "zmq_msg_data", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"]
diff --git a/cpp/ql/lib/ext/allocation/Std.allocation.model.yml b/cpp/ql/lib/ext/allocation/Std.allocation.model.yml
index 16b3d5bcebad..227cc4176c0d 100644
--- a/cpp/ql/lib/ext/allocation/Std.allocation.model.yml
+++ b/cpp/ql/lib/ext/allocation/Std.allocation.model.yml
@@ -12,4 +12,7 @@ extensions:
- ["", "", False, "_malloca", "0", "", "", False]
- ["", "", False, "calloc", "1", "0", "", True]
- ["std", "", False, "calloc", "1", "0", "", True]
- - ["bsl", "", False, "calloc", "1", "0", "", True]
\ No newline at end of file
+ - ["bsl", "", False, "calloc", "1", "0", "", True]
+ - ["", "", False, "aligned_alloc", "1", "", "", True]
+ - ["std", "", False, "aligned_alloc", "1", "", "", True]
+ - ["bsl", "", False, "aligned_alloc", "1", "", "", True]
diff --git a/cpp/ql/lib/ext/getc.model.yml b/cpp/ql/lib/ext/getc.model.yml
new file mode 100644
index 000000000000..43958205e0b1
--- /dev/null
+++ b/cpp/ql/lib/ext/getc.model.yml
@@ -0,0 +1,19 @@
+# Models for getc and similar character-reading functions
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: sourceModel
+ data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
+ - ["", "", False, "getc", "", "", "ReturnValue", "remote", "manual"]
+ - ["", "", False, "getwc", "", "", "ReturnValue", "remote", "manual"]
+ - ["", "", False, "_getc_nolock", "", "", "ReturnValue", "remote", "manual"]
+ - ["", "", False, "_getwc_nolock", "", "", "ReturnValue", "remote", "manual"]
+ - ["", "", False, "getch", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "_getch", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "_getwch", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "_getch_nolock", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "_getwch_nolock", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "getchar", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "getwchar", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "_getchar_nolock", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "_getwchar_nolock", "", "", "ReturnValue", "local", "manual"]
diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml
index 286288140c49..dbf57d2b8699 100644
--- a/cpp/ql/lib/qlpack.yml
+++ b/cpp/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-all
-version: 8.0.1
+version: 9.0.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
diff --git a/cpp/ql/lib/semmle/code/cpp/ConfigurationTestFile.qll b/cpp/ql/lib/semmle/code/cpp/ConfigurationTestFile.qll
index fe89a556f74f..ae90caa0e637 100644
--- a/cpp/ql/lib/semmle/code/cpp/ConfigurationTestFile.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ConfigurationTestFile.qll
@@ -26,3 +26,26 @@ class CmakeTryCompileFile extends ConfigurationTestFile {
)
}
}
+
+/**
+ * A file created by Meson to test the system configuration.
+ */
+class MesonPrivateTestFile extends ConfigurationTestFile {
+ MesonPrivateTestFile() {
+ this.getBaseName() = "testfile.c" and
+ exists(Folder folder, Folder parent |
+ folder = this.getParentContainer() and
+ parent = folder.getParentContainer()
+ |
+ folder.getBaseName().matches("tmp%") and
+ parent.getBaseName() = "meson-private"
+ )
+ }
+}
+
+/**
+ * A file created by a GNU autoconf configure script to test the system configuration.
+ */
+class AutoconfConfigureTestFile extends ConfigurationTestFile {
+ AutoconfConfigureTestFile() { this.getBaseName().regexpMatch("conftest[0-9]*\\.c(pp)?") }
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/Function.qll b/cpp/ql/lib/semmle/code/cpp/Function.qll
index 10b156e3fb64..8d93ac0f2a3a 100644
--- a/cpp/ql/lib/semmle/code/cpp/Function.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Function.qll
@@ -524,6 +524,12 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
not exists(NewOrNewArrayExpr new | e = new.getAllocatorCall().getArgument(0))
)
}
+
+ /**
+ * Holds if this function has an ambiguous return type, meaning that zero or multiple return
+ * types for this function are present in the database (this can occur in `build-mode: none`).
+ */
+ predicate hasAmbiguousReturnType() { count(this.getType()) != 1 }
}
pragma[noinline]
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
index 023ce09c5c18..624465761c2c 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
@@ -163,12 +163,23 @@ predicate primitiveVariadicFormatter(
)
}
+/**
+ * Gets a function call whose target is a variadic formatter with the given
+ * `type`, `format` parameter index and `output` parameter index.
+ *
+ * Join-order helper for `callsVariadicFormatter`.
+ */
+pragma[nomagic]
+private predicate callsVariadicFormatterCall(FunctionCall fc, string type, int format, int output) {
+ variadicFormatter(fc.getTarget(), type, format, output)
+}
+
private predicate callsVariadicFormatter(
Function f, string type, int formatParamIndex, int outputParamIndex
) {
// calls a variadic formatter with `formatParamIndex`, `outputParamIndex` linked
exists(FunctionCall fc, int format, int output |
- variadicFormatter(pragma[only_bind_into](fc.getTarget()), type, format, output) and
+ callsVariadicFormatterCall(fc, type, format, output) and
fc.getEnclosingFunction() = f and
fc.getArgument(format) = f.getParameter(formatParamIndex).getAnAccess() and
fc.getArgument(output) = f.getParameter(outputParamIndex).getAnAccess()
@@ -176,7 +187,7 @@ private predicate callsVariadicFormatter(
or
// calls a variadic formatter with only `formatParamIndex` linked
exists(FunctionCall fc, string calledType, int format, int output |
- variadicFormatter(pragma[only_bind_into](fc.getTarget()), calledType, format, output) and
+ callsVariadicFormatterCall(fc, calledType, format, output) and
fc.getEnclosingFunction() = f and
fc.getArgument(format) = f.getParameter(formatParamIndex).getAnAccess() and
not fc.getArgument(output) = f.getParameter(_).getAnAccess() and
@@ -448,6 +459,13 @@ class FormatLiteral extends Literal instanceof StringLiteral {
*/
int getConvSpecOffset(int n) { result = this.getFormat().indexOf("%", n, 0) }
+ /**
+ * Gets the nth conversion specifier string.
+ */
+ private string getConvSpecString(int n) {
+ n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
+ }
+
/*
* Each of these predicates gets a regular expressions to match each individual
* parts of a conversion specifier.
@@ -513,22 +531,20 @@ class FormatLiteral extends Literal instanceof StringLiteral {
int n, string spec, string params, string flags, string width, string prec, string len,
string conv
) {
- exists(int offset, string fmt, string rst, string regexp |
- offset = this.getConvSpecOffset(n) and
- fmt = this.getFormat() and
- rst = fmt.substring(offset, fmt.length()) and
+ exists(string convSpec, string regexp |
+ convSpec = this.getConvSpecString(n) and
regexp = this.getConvSpecRegexp() and
(
- spec = rst.regexpCapture(regexp, 1) and
- params = rst.regexpCapture(regexp, 2) and
- flags = rst.regexpCapture(regexp, 3) and
- width = rst.regexpCapture(regexp, 4) and
- prec = rst.regexpCapture(regexp, 5) and
- len = rst.regexpCapture(regexp, 6) and
- conv = rst.regexpCapture(regexp, 7)
+ spec = convSpec.regexpCapture(regexp, 1) and
+ params = convSpec.regexpCapture(regexp, 2) and
+ flags = convSpec.regexpCapture(regexp, 3) and
+ width = convSpec.regexpCapture(regexp, 4) and
+ prec = convSpec.regexpCapture(regexp, 5) and
+ len = convSpec.regexpCapture(regexp, 6) and
+ conv = convSpec.regexpCapture(regexp, 7)
or
- spec = rst.regexpCapture(regexp, 1) and
- not exists(rst.regexpCapture(regexp, 2)) and
+ spec = convSpec.regexpCapture(regexp, 1) and
+ not exists(convSpec.regexpCapture(regexp, 2)) and
params = "" and
flags = "" and
width = "" and
@@ -543,12 +559,10 @@ class FormatLiteral extends Literal instanceof StringLiteral {
* Gets the nth conversion specifier (including the initial `%`).
*/
string getConvSpec(int n) {
- exists(int offset, string fmt, string rst, string regexp |
- offset = this.getConvSpecOffset(n) and
- fmt = this.getFormat() and
- rst = fmt.substring(offset, fmt.length()) and
+ exists(string convSpec, string regexp |
+ convSpec = this.getConvSpecString(n) and
regexp = this.getConvSpecRegexp() and
- result = rst.regexpCapture(regexp, 1)
+ result = convSpec.regexpCapture(regexp, 1)
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll
index f032ba4749e6..98280a522cfd 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll
@@ -194,6 +194,13 @@ class ScanfFormatLiteral extends Expr {
)
}
+ /**
+ * Gets the nth conversion specifier string.
+ */
+ private string getConvSpecString(int n) {
+ n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
+ }
+
/**
* Gets the regular expression to match each individual part of a conversion specifier.
*/
@@ -227,16 +234,14 @@ class ScanfFormatLiteral extends Expr {
* specifier.
*/
predicate parseConvSpec(int n, string spec, string width, string len, string conv) {
- exists(int offset, string fmt, string rst, string regexp |
- offset = this.getConvSpecOffset(n) and
- fmt = this.getFormat() and
- rst = fmt.substring(offset, fmt.length()) and
+ exists(string convSpec, string regexp |
+ convSpec = this.getConvSpecString(n) and
regexp = this.getConvSpecRegexp() and
(
- spec = rst.regexpCapture(regexp, 1) and
- width = rst.regexpCapture(regexp, 2) and
- len = rst.regexpCapture(regexp, 3) and
- conv = rst.regexpCapture(regexp, 4)
+ spec = convSpec.regexpCapture(regexp, 1) and
+ width = convSpec.regexpCapture(regexp, 2) and
+ len = convSpec.regexpCapture(regexp, 3) and
+ conv = convSpec.regexpCapture(regexp, 4)
)
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll
index 7cf3b937ac51..fb2108c2ac58 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll
@@ -1,15 +1,20 @@
/**
* INTERNAL use only. This is an experimental API subject to change without notice.
*
- * Provides classes and predicates for dealing with flow models specified in CSV format.
+ * Provides classes and predicates for dealing with flow models specified
+ * in data extension files.
*
- * The CSV specification has the following columns:
+ * The extensible relations have the following columns:
* - Sources:
- * `namespace; type; subtypes; name; signature; ext; output; kind`
+ * `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
* - Sinks:
- * `namespace; type; subtypes; name; signature; ext; input; kind`
+ * `namespace; type; subtypes; name; signature; ext; input; kind; provenance`
* - Summaries:
- * `namespace; type; subtypes; name; signature; ext; input; output; kind`
+ * `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance`
+ * - Barriers:
+ * `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
+ * - BarrierGuards:
+ * `namespace; type; subtypes; name; signature; ext; input; acceptingValue; kind; provenance`
*
* The interpretation of a row is similar to API-graphs with a left-to-right
* reading.
@@ -86,11 +91,23 @@
* value, and
* - flow from the _second_ indirection of the 0th argument to the first
* indirection of the return value, etc.
- * 8. The `kind` column is a tag that can be referenced from QL to determine to
+ * 8. The `acceptingValue` column of barrier guard models specifies the condition
+ * under which the guard blocks flow. It can be one of "true" or "false". In
+ * the future "no-exception", "not-zero", "null", "not-null" may be supported.
+ * 9. The `kind` column is a tag that can be referenced from QL to determine to
* which classes the interpreted elements should be added. For example, for
* sources "remote" indicates a default remote flow source, and for summaries
* "taint" indicates a default additional taint step and "value" indicates a
* globally applicable value-preserving step.
+ * 10. The `provenance` column is a tag to indicate the origin and verification of a model.
+ * The format is {origin}-{verification} or just "manual" where the origin describes
+ * the origin of the model and verification describes how the model has been verified.
+ * Some examples are:
+ * - "df-generated": The model has been generated by the model generator tool.
+ * - "df-manual": The model has been generated by the model generator and verified by a human.
+ * - "manual": The model has been written by hand.
+ * This information is used in a heuristic for dataflow analysis to determine, if a
+ * model or source code should be used for determining flow.
*/
import cpp
@@ -104,117 +121,9 @@ private import internal.FlowSummaryImpl::Private
private import internal.FlowSummaryImpl::Private::External
private import internal.ExternalFlowExtensions::Extensions as Extensions
private import codeql.mad.ModelValidation as SharedModelVal
-private import codeql.util.Unit
private import codeql.mad.static.ModelsAsData as SharedMaD
-/**
- * A unit class for adding additional source model rows.
- *
- * Extend this class to add additional source definitions.
- */
-class SourceModelCsv extends Unit {
- /** Holds if `row` specifies a source definition. */
- abstract predicate row(string row);
-}
-
-/**
- * A unit class for adding additional sink model rows.
- *
- * Extend this class to add additional sink definitions.
- */
-class SinkModelCsv extends Unit {
- /** Holds if `row` specifies a sink definition. */
- abstract predicate row(string row);
-}
-
-/**
- * A unit class for adding additional summary model rows.
- *
- * Extend this class to add additional flow summary definitions.
- */
-class SummaryModelCsv extends Unit {
- /** Holds if `row` specifies a summary definition. */
- abstract predicate row(string row);
-}
-
-/** Holds if `row` is a source model. */
-predicate sourceModel(string row) { any(SourceModelCsv s).row(row) }
-
-/** Holds if `row` is a sink model. */
-predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
-
-/** Holds if `row` is a summary model. */
-predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
-
private module MadInput implements SharedMaD::InputSig {
- /** Holds if a source model exists for the given parameters. */
- predicate additionalSourceModel(
- string namespace, string type, boolean subtypes, string name, string signature, string ext,
- string output, string kind, string provenance, string model
- ) {
- exists(string row |
- sourceModel(row) and
- row.splitAt(";", 0) = namespace and
- row.splitAt(";", 1) = type and
- row.splitAt(";", 2) = subtypes.toString() and
- subtypes = [true, false] and
- row.splitAt(";", 3) = name and
- row.splitAt(";", 4) = signature and
- row.splitAt(";", 5) = ext and
- row.splitAt(";", 6) = output and
- row.splitAt(";", 7) = kind
- ) and
- provenance = "manual" and
- model = ""
- }
-
- /** Holds if a sink model exists for the given parameters. */
- predicate additionalSinkModel(
- string namespace, string type, boolean subtypes, string name, string signature, string ext,
- string input, string kind, string provenance, string model
- ) {
- exists(string row |
- sinkModel(row) and
- row.splitAt(";", 0) = namespace and
- row.splitAt(";", 1) = type and
- row.splitAt(";", 2) = subtypes.toString() and
- subtypes = [true, false] and
- row.splitAt(";", 3) = name and
- row.splitAt(";", 4) = signature and
- row.splitAt(";", 5) = ext and
- row.splitAt(";", 6) = input and
- row.splitAt(";", 7) = kind
- ) and
- provenance = "manual" and
- model = ""
- }
-
- /**
- * Holds if a summary model exists for the given parameters.
- *
- * This predicate does not expand `@` to `*`s.
- */
- predicate additionalSummaryModel(
- string namespace, string type, boolean subtypes, string name, string signature, string ext,
- string input, string output, string kind, string provenance, string model
- ) {
- exists(string row |
- summaryModel(row) and
- row.splitAt(";", 0) = namespace and
- row.splitAt(";", 1) = type and
- row.splitAt(";", 2) = subtypes.toString() and
- subtypes = [true, false] and
- row.splitAt(";", 3) = name and
- row.splitAt(";", 4) = signature and
- row.splitAt(";", 5) = ext and
- row.splitAt(";", 6) = input and
- row.splitAt(";", 7) = output and
- row.splitAt(";", 8) = kind
- ) and
- provenance = "manual" and
- model = ""
- }
-
string namespaceSegmentSeparator() { result = "::" }
}
@@ -250,8 +159,8 @@ predicate summaryModel(
)
}
-/** Provides a query predicate to check the CSV data for validation errors. */
-module CsvValidation {
+/** Provides a query predicate to check the data for validation errors. */
+module ModelValidation {
private string getInvalidModelInput() {
exists(string pred, AccessPath input, string part |
sinkModel(_, _, _, _, _, _, input, _, _, _) and pred = "sink"
@@ -294,40 +203,6 @@ module CsvValidation {
private module KindVal = SharedModelVal::KindValidation;
- private string getInvalidModelSubtype() {
- exists(string pred, string row |
- sourceModel(row) and pred = "source"
- or
- sinkModel(row) and pred = "sink"
- or
- summaryModel(row) and pred = "summary"
- |
- exists(string b |
- b = row.splitAt(";", 2) and
- not b = ["true", "false"] and
- result = "Invalid boolean \"" + b + "\" in " + pred + " model."
- )
- )
- }
-
- private string getInvalidModelColumnCount() {
- exists(string pred, string row, int expect |
- sourceModel(row) and expect = 8 and pred = "source"
- or
- sinkModel(row) and expect = 8 and pred = "sink"
- or
- summaryModel(row) and expect = 9 and pred = "summary"
- |
- exists(int cols |
- cols = 1 + max(int n | exists(row.splitAt(";", n))) and
- cols != expect and
- result =
- "Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
- "."
- )
- )
- }
-
private string getInvalidModelSignature() {
exists(string pred, string namespace, string type, string name, string signature, string ext |
sourceModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "source"
@@ -366,13 +241,12 @@ module CsvValidation {
)
}
- /** Holds if some row in a CSV-based flow model appears to contain typos. */
+ /** Holds if some row in a MaD flow model appears to contain typos. */
query predicate invalidModelRow(string msg) {
msg =
[
getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(),
- getInvalidModelSubtype(), getInvalidModelColumnCount(), KindVal::getInvalidModelKind(),
- getIncorrectConstructorSummaryOutput()
+ KindVal::getInvalidModelKind(), getIncorrectConstructorSummaryOutput()
]
}
}
@@ -1026,7 +900,7 @@ private module Cached {
}
/**
- * Holds if `node` is specified as a source with the given kind in a CSV flow
+ * Holds if `node` is specified as a source with the given kind in a MaD flow
* model.
*/
cached
@@ -1037,7 +911,7 @@ private module Cached {
}
/**
- * Holds if `node` is specified as a sink with the given kind in a CSV flow
+ * Holds if `node` is specified as a sink with the given kind in a MaD flow
* model.
*/
cached
@@ -1073,13 +947,13 @@ private module Cached {
private predicate barrierGuardChecks(IRGuardCondition g, Expr e, boolean gv, TKindModelPair kmp) {
exists(
- SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingvalue,
+ SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingValue,
string kind, string model
|
- isBarrierGuardNode(n, acceptingvalue, kind, model) and
+ isBarrierGuardNode(n, acceptingValue, kind, model) and
n.asNode().asExpr() = e and
kmp = TMkPair(kind, model) and
- gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
+ gv = convertAcceptingValue(acceptingValue).asBooleanValue() and
n.asNode().(Private::ArgumentNode).getCall().asCallInstruction() = g
)
}
@@ -1096,14 +970,14 @@ private module Cached {
) {
exists(
SourceSinkInterpretationInput::InterpretNode interpretNode,
- Public::AcceptingValue acceptingvalue, string kind, string model, int indirectionIndex,
+ Public::AcceptingValue acceptingValue, string kind, string model, int indirectionIndex,
Private::ArgumentNode arg
|
- isBarrierGuardNode(interpretNode, acceptingvalue, kind, model) and
+ isBarrierGuardNode(interpretNode, acceptingValue, kind, model) and
arg = interpretNode.asNode() and
arg.asIndirectExpr(indirectionIndex) = e and
kmp = MkKindModelPairIntPair(TMkPair(kind, model), indirectionIndex) and
- gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
+ gv = convertAcceptingValue(acceptingValue).asBooleanValue() and
arg.getCall().asCallInstruction() = g
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll
index 1a572c221d9f..22c74c2aa714 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll
@@ -33,7 +33,7 @@ extensible predicate barrierModel(
*/
extensible predicate barrierGuardModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
- string input, string acceptingvalue, string kind, string provenance, QlBuiltins::ExtensionId madId
+ string input, string acceptingValue, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
index cce1b80e7fcb..d91dc41febeb 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
@@ -162,13 +162,13 @@ module SourceSinkInterpretationInput implements
}
predicate barrierGuardElement(
- Element e, string input, Public::AcceptingValue acceptingvalue, string kind,
+ Element e, string input, Public::AcceptingValue acceptingValue, string kind,
Public::Provenance provenance, string model
) {
exists(
string package, string type, boolean subtypes, string name, string signature, string ext
|
- barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingvalue, kind,
+ barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingValue, kind,
provenance, model) and
e = interpretElement(package, type, subtypes, name, signature, ext)
)
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll
index 4ef241e3d258..66a89490dd09 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll
@@ -585,12 +585,15 @@ class ConstructorDelegationInit extends ConstructorBaseInit, @ctordelegatinginit
/**
* An initialization of a member variable performed as part of a
- * constructor's explicit initializer list or implicit actions.
+ * constructor's initializer list or by default initialization.
+ *
* In the example below, member variable `b` is being initialized by
- * constructor parameter `a`:
+ * constructor parameter `a`, and `c` is initialized by default
+ * initialization:
* ```
* struct S {
* int b;
+ * int c = 3;
* S(int a): b(a) {}
* } s(2);
* ```
@@ -616,6 +619,28 @@ class ConstructorFieldInit extends ConstructorInit, @ctorfieldinit {
override predicate mayBeGloballyImpure() { this.getExpr().mayBeGloballyImpure() }
}
+/**
+ * An initialization of a member variable performed as part of a
+ * constructor's explicit initializer list.
+ */
+class ConstructorDirectFieldInit extends ConstructorFieldInit {
+ ConstructorDirectFieldInit() { exists(this.getChild(0)) }
+
+ override string getAPrimaryQlClass() { result = "ConstructorDirectFieldInit" }
+}
+
+/**
+ * An initialization of a member variable performed by default
+ * initialization.
+ */
+class ConstructorDefaultFieldInit extends ConstructorFieldInit {
+ ConstructorDefaultFieldInit() {
+ not exists(this.getChild(0)) and exists(this.getTarget().getInitializer())
+ }
+
+ override string getAPrimaryQlClass() { result = "ConstructorDefaultFieldInit" }
+}
+
/**
* A call to a destructor of a base class or field as part of a destructor's
* compiler-generated actions.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll
index 0d63558c956e..bce936552768 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll
@@ -238,7 +238,12 @@ private module TrackVirtualDispatch {
private import TypeTracking::TypeTrack::Graph
- private predicate edgePlus(PathNode n1, PathNode n2) = fastTC(edges/2)(n1, n2)
+ private predicate isSource(PathNode n) { n.isSource() }
+
+ private predicate isSink(PathNode n) { n.isSink() }
+
+ private predicate edgePlus(PathNode n1, PathNode n2) =
+ doublyBoundedFastTC(edges/2, isSource/1, isSink/1)(n1, n2)
/**
* Gets the most specific implementation of `mf` that may be called when the
@@ -255,6 +260,15 @@ private module TrackVirtualDispatch {
)
}
+ pragma[nomagic]
+ private MemberFunction mostSpecificForSource(PathNode p1, MemberFunction mf) {
+ p1.isSource() and
+ exists(Class derived |
+ qualifierSourceImpl(p1.getNode(), derived) and
+ result = mostSpecific(mf, derived)
+ )
+ }
+
/**
* Gets a possible pair of end-points `(p1, p2)` where:
* - `p1` is a derived-to-base conversion that converts from some
@@ -264,16 +278,16 @@ private module TrackVirtualDispatch {
* - `callable` is the most specific implementation that may be called when
* the qualifier has type `derived`.
*/
+ bindingset[p1, p2]
+ pragma[inline_late]
private predicate pairCand(
PathNode p1, PathNode p2, DataFlowPrivate::DataFlowCallable callable,
DataFlowPrivate::DataFlowCall call
) {
- exists(Class derived, MemberFunction mf |
- qualifierSourceImpl(p1.getNode(), derived) and
+ p2.isSink() and
+ exists(MemberFunction mf |
qualifierOfVirtualCallImpl(p2.getNode(), call.asCallInstruction(), mf) and
- p1.isSource() and
- p2.isSink() and
- callable.asSourceCallable() = mostSpecific(mf, derived)
+ callable.asSourceCallable() = mostSpecificForSource(p1, mf)
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowNodes.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowNodes.qll
index fe954c640d1b..bcf6a0d512c3 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowNodes.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowNodes.qll
@@ -321,6 +321,12 @@ module Public {
*/
Operand asIndirectOperand(int index) { hasOperandAndIndex(this, result, index) }
+ /**
+ * Gets the instruction that is indirectly tracked by this node behind
+ * `index` number of indirections.
+ */
+ Instruction asIndirectInstruction(int index) { hasInstructionAndIndex(this, result, index) }
+
/**
* Holds if this node is at index `i` in basic block `block`.
*
@@ -617,6 +623,25 @@ module Public {
*/
LocalVariable asUninitialized() { result = this.(UninitializedNode).getLocalVariable() }
+ /**
+ * Gets the uninitialized local variable corresponding to this node behind
+ * `index` number of indirections, if any.
+ */
+ LocalVariable asIndirectUninitialized(int index) {
+ exists(IndirectUninitializedNode indirectUninitializedNode |
+ this = indirectUninitializedNode and
+ indirectUninitializedNode.getIndirectionIndex() = index
+ |
+ result = indirectUninitializedNode.getLocalVariable()
+ )
+ }
+
+ /**
+ * Gets the uninitialized local variable corresponding to this node behind
+ * a number indirections, if any.
+ */
+ LocalVariable asIndirectUninitialized() { result = this.asIndirectUninitialized(_) }
+
/**
* Gets the positional parameter corresponding to the node that represents
* the value of the parameter after `index` number of loads, if any. For
@@ -761,16 +786,13 @@ module Public {
final override Type getType() { result = this.getPreUpdateNode().getType() }
}
- /**
- * The value of an uninitialized local variable, viewed as a node in a data
- * flow graph.
- */
- class UninitializedNode extends Node {
+ abstract private class AbstractUninitializedNode extends Node {
LocalVariable v;
+ int indirectionIndex;
- UninitializedNode() {
+ AbstractUninitializedNode() {
exists(SsaImpl::Definition def, SsaImpl::SourceVariable sv |
- def.getIndirectionIndex() = 0 and
+ def.getIndirectionIndex() = indirectionIndex and
def.getValue().asInstruction() instanceof UninitializedInstruction and
SsaImpl::defToNode(this, def, sv) and
v = sv.getBaseVariable().(SsaImpl::BaseIRVariable).getIRVariable().getAst()
@@ -781,6 +803,25 @@ module Public {
LocalVariable getLocalVariable() { result = v }
}
+ /**
+ * The value of an uninitialized local variable, viewed as a node in a data
+ * flow graph.
+ */
+ class UninitializedNode extends AbstractUninitializedNode {
+ UninitializedNode() { indirectionIndex = 0 }
+ }
+
+ /**
+ * The value of an uninitialized local variable behind one or more levels of
+ * indirection, viewed as a node in a data flow graph.
+ */
+ class IndirectUninitializedNode extends AbstractUninitializedNode {
+ IndirectUninitializedNode() { indirectionIndex > 0 }
+
+ /** Gets the indirection index of this node. */
+ int getIndirectionIndex() { result = indirectionIndex }
+ }
+
/**
* The value of a parameter at function entry, viewed as a node in a data
* flow graph. This includes both explicit parameters such as `x` in `f(x)`
@@ -795,6 +836,12 @@ module Public {
/** An explicit positional parameter, including `this`, but not `...`. */
final class DirectParameterNode = AbstractDirectParameterNode;
+ /**
+ * A node representing an indirection of a positional parameter,
+ * including `*this`, but not `*...`.
+ */
+ final class IndirectParameterNode = AbstractIndirectParameterNode;
+
final class ExplicitParameterNode = AbstractExplicitParameterNode;
/** An implicit `this` parameter. */
@@ -803,11 +850,6 @@ module Public {
{
ThisParameterInstructionNode() { instr.getIRVariable() instanceof IRThisVariable }
- override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
- pos.(DirectPosition).getArgumentIndex() = -1 and
- instr.getEnclosingFunction() = f
- }
-
override string toStringImpl() { result = "this" }
}
@@ -831,7 +873,11 @@ module Public {
/** Gets the parameter through which this value is assigned. */
Parameter getParameter() {
- result = this.getCallInstruction().getStaticCallTarget().getParameter(this.getArgumentIndex())
+ result =
+ this.getCallInstruction()
+ .getStaticCallTarget()
+ .(Function)
+ .getParameter(this.getArgumentIndex())
}
}
@@ -954,11 +1000,6 @@ module Public {
private import Public
-/**
- * A node representing an indirection of a parameter.
- */
-final class IndirectParameterNode = AbstractIndirectParameterNode;
-
/**
* A class that lifts pre-SSA dataflow nodes to regular dataflow nodes.
*/
@@ -1083,7 +1124,7 @@ class IndirectArgumentOutNode extends PostUpdateNodeImpl {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
- Function getStaticCallTarget() { result = this.getCallInstruction().getStaticCallTarget() }
+ Declaration getStaticCallTarget() { result = this.getCallInstruction().getStaticCallTarget() }
override string toStringImpl() {
exists(string prefix | if indirectionIndex > 0 then prefix = "" else prefix = "pointer to " |
@@ -1587,7 +1628,7 @@ abstract private class AbstractParameterNode extends Node {
* implicit `this` parameter is considered to have position `-1`, and
* pointer-indirection parameters are at further negative positions.
*/
- predicate isSourceParameterOf(Function f, ParameterPosition pos) { none() }
+ predicate isSourceParameterOf(Declaration f, ParameterPosition pos) { none() }
/**
* Holds if this node is the parameter of `sc` at the specified position. The
@@ -1613,6 +1654,11 @@ abstract private class AbstractParameterNode extends Node {
/** Gets the `Parameter` associated with this node, if it exists. */
Parameter getParameter() { none() } // overridden by subclasses
+
+ /**
+ * Holds if this node represents an implicit `this` parameter, if it exists.
+ */
+ predicate isThis() { none() } // overridden by subclasses
}
abstract private class AbstractIndirectParameterNode extends AbstractParameterNode {
@@ -1641,7 +1687,9 @@ private class IndirectInstructionParameterNode extends AbstractIndirectParameter
InitializeParameterInstruction init;
IndirectInstructionParameterNode() {
- IndirectInstruction.super.hasInstructionAndIndirectionIndex(init, _)
+ IndirectInstruction.super.hasInstructionAndIndirectionIndex(init, _) and
+ // We don't model catch parameters as parameter nodes
+ not exists(init.getParameter().getCatchBlock())
}
int getArgumentIndex() { init.hasIndex(result) }
@@ -1655,16 +1703,17 @@ private class IndirectInstructionParameterNode extends AbstractIndirectParameter
)
}
- /** Gets the parameter whose indirection is initialized. */
override Parameter getParameter() { result = init.getParameter() }
+ override predicate isThis() { init.hasIndex(-1) }
+
override DataFlowCallable getEnclosingCallable() {
result.asSourceCallable() = this.getFunction()
}
override Declaration getFunction() { result = init.getEnclosingFunction() }
- override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
+ override predicate isSourceParameterOf(Declaration f, ParameterPosition pos) {
this.getFunction() = f and
exists(int argumentIndex, int indirectionIndex |
indirectPositionHasArgumentIndexAndIndex(pos, argumentIndex, indirectionIndex) and
@@ -1692,6 +1741,18 @@ abstract class InstructionDirectParameterNode extends InstructionNode, AbstractD
* Gets the `IRVariable` that this parameter references.
*/
final IRVariable getIRVariable() { result = instr.getIRVariable() }
+
+ override predicate isThis() { instr.hasIndex(-1) }
+
+ override Parameter getParameter() { result = instr.getParameter() }
+
+ override predicate isSourceParameterOf(Declaration f, ParameterPosition pos) {
+ this.getFunction() = f and
+ exists(int argumentIndex |
+ pos.(DirectPosition).getArgumentIndex() = argumentIndex and
+ instr.hasIndex(argumentIndex)
+ )
+ }
}
abstract private class AbstractExplicitParameterNode extends AbstractDirectParameterNode { }
@@ -1700,15 +1761,12 @@ abstract private class AbstractExplicitParameterNode extends AbstractDirectParam
private class ExplicitParameterInstructionNode extends AbstractExplicitParameterNode,
InstructionDirectParameterNode
{
- ExplicitParameterInstructionNode() { exists(instr.getParameter()) }
-
- override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
- f.getParameter(pos.(DirectPosition).getArgumentIndex()) = instr.getParameter()
+ ExplicitParameterInstructionNode() {
+ // We don't model catch parameters as parameter nodes.
+ exists(instr.getParameter().getFunction())
}
override string toStringImpl() { result = instr.getParameter().toString() }
-
- override Parameter getParameter() { result = instr.getParameter() }
}
/**
@@ -1736,9 +1794,9 @@ private class DirectBodyLessParameterNode extends AbstractExplicitParameterNode,
{
DirectBodyLessParameterNode() { indirectionIndex = 0 }
- override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
+ override predicate isSourceParameterOf(Declaration f, ParameterPosition pos) {
this.getFunction() = f and
- f.getParameter(pos.(DirectPosition).getArgumentIndex()) = p
+ f.(Function).getParameter(pos.(DirectPosition).getArgumentIndex()) = p
}
override Parameter getParameter() { result = p }
@@ -1749,10 +1807,10 @@ private class IndirectBodyLessParameterNode extends AbstractIndirectParameterNod
{
IndirectBodyLessParameterNode() { not this instanceof DirectBodyLessParameterNode }
- override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
+ override predicate isSourceParameterOf(Declaration f, ParameterPosition pos) {
exists(int argumentPosition |
this.getFunction() = f and
- f.getParameter(argumentPosition) = p and
+ f.(Function).getParameter(argumentPosition) = p and
indirectPositionHasArgumentIndexAndIndex(pos, argumentPosition, indirectionIndex)
)
}
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 6dd953b16ab5..83f240ddae51 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
@@ -1170,7 +1170,7 @@ class DataFlowCall extends TDataFlowCall {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
- Function getStaticCallSourceTarget() { none() }
+ Declaration getStaticCallSourceTarget() { none() }
/**
* Gets the target of this call. We use the following strategy for deciding
@@ -1182,7 +1182,7 @@ class DataFlowCall extends TDataFlowCall {
* whether is it manual or generated.
*/
final DataFlowCallable getStaticCallTarget() {
- exists(Function target | target = this.getStaticCallSourceTarget() |
+ exists(Declaration target | target = this.getStaticCallSourceTarget() |
// Don't use the source callable if there is a manual model for the
// target
not exists(SummarizedCallable sc |
@@ -1242,7 +1242,7 @@ private class NormalCall extends DataFlowCall, TNormalCall {
override CallTargetOperand getCallTargetOperand() { result = call.getCallTargetOperand() }
- override Function getStaticCallSourceTarget() { result = call.getStaticCallTarget() }
+ override Declaration getStaticCallSourceTarget() { result = call.getStaticCallTarget() }
override ArgumentOperand getArgumentOperand(int index) { result = call.getArgumentOperand(index) }
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll
index 45a6755356b5..e4734f285fa7 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll
@@ -11,13 +11,18 @@ private import TypeFlow
private import semmle.code.cpp.ir.ValueNumbering
/**
- * Gets the C++ type of `this` in the member function `f`.
+ * Gets the C++ type of `this` in an `IRFunction` generated from `f`.
* The result is a glvalue if `isGLValue` is true, and
* a prvalue if `isGLValue` is false.
*/
bindingset[isGLValue]
-private CppType getThisType(Cpp::MemberFunction f, boolean isGLValue) {
- result.hasType(f.getTypeOfThis(), isGLValue)
+private CppType getThisType(Cpp::Declaration f, boolean isGLValue) {
+ result.hasType(f.(Cpp::MemberFunction).getTypeOfThis(), isGLValue)
+ or
+ exists(Cpp::PointerType pt |
+ pt.getBaseType() = f.(Cpp::Field).getDeclaringType() and
+ result.hasType(pt, isGLValue)
+ )
}
/**
@@ -175,7 +180,8 @@ private class PointerWrapperTypeIndirection extends Indirection instanceof Point
override predicate isAdditionalDereference(Instruction deref, Operand address) {
exists(CallInstruction call |
operandForFullyConvertedCall(getAUse(deref), call) and
- this = call.getStaticCallTarget().getClassAndName(["operator*", "operator->", "get"]) and
+ this =
+ call.getStaticCallTarget().(Function).getClassAndName(["operator*", "operator->", "get"]) and
address = call.getThisArgumentOperand()
)
}
@@ -194,7 +200,7 @@ private module IteratorIndirections {
override predicate isAdditionalWrite(Node0Impl value, Operand address, boolean certain) {
exists(CallInstruction call | call.getArgumentOperand(0) = value.asOperand() |
- this = call.getStaticCallTarget().getClassAndName("operator=") and
+ this = call.getStaticCallTarget().(Function).getClassAndName("operator=") and
address = call.getThisArgumentOperand() and
certain = false
)
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 8d3e960c3f87..b7dcd4d8f754 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
@@ -495,7 +495,7 @@ class FieldInstruction extends Instruction {
* `FunctionAddress` instruction.
*/
class FunctionInstruction extends Instruction {
- Language::Function funcSymbol;
+ Language::Declaration funcSymbol;
FunctionInstruction() { funcSymbol = Raw::getInstructionFunction(this) }
@@ -504,7 +504,7 @@ class FunctionInstruction extends Instruction {
/**
* Gets the function that this instruction references.
*/
- final Language::Function getFunctionSymbol() { result = funcSymbol }
+ final Language::Declaration getFunctionSymbol() { result = funcSymbol }
}
/**
@@ -1678,7 +1678,7 @@ class CallInstruction extends Instruction {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
- final Language::Function getStaticCallTarget() {
+ final Language::Declaration getStaticCallTarget() {
result = this.getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
}
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 8d3e960c3f87..b7dcd4d8f754 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
@@ -495,7 +495,7 @@ class FieldInstruction extends Instruction {
* `FunctionAddress` instruction.
*/
class FunctionInstruction extends Instruction {
- Language::Function funcSymbol;
+ Language::Declaration funcSymbol;
FunctionInstruction() { funcSymbol = Raw::getInstructionFunction(this) }
@@ -504,7 +504,7 @@ class FunctionInstruction extends Instruction {
/**
* Gets the function that this instruction references.
*/
- final Language::Function getFunctionSymbol() { result = funcSymbol }
+ final Language::Declaration getFunctionSymbol() { result = funcSymbol }
}
/**
@@ -1678,7 +1678,7 @@ class CallInstruction extends Instruction {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
- final Language::Function getStaticCallTarget() {
+ final Language::Declaration getStaticCallTarget() {
result = this.getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll
index 9e9a47a5b4f1..da8c394c845c 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll
@@ -15,6 +15,7 @@ private import TranslatedCall
private import TranslatedStmt
private import TranslatedFunction
private import TranslatedGlobalVar
+private import TranslatedNonStaticDataMember
private import TranslatedInitialization
TranslatedElement getInstructionTranslatedElement(Instruction instruction) {
@@ -45,6 +46,9 @@ module Raw {
or
not var.isFromUninstantiatedTemplate(_) and
var instanceof StaticInitializedStaticLocalVariable
+ or
+ not var.isFromUninstantiatedTemplate(_) and
+ var instanceof Field
) and
var.hasInitializer() and
(
@@ -64,6 +68,8 @@ module Raw {
getTranslatedFunction(decl).hasUserVariable(var, type)
or
getTranslatedVarInit(decl).hasUserVariable(var, type)
+ or
+ getTranslatedFieldInit(decl).hasUserVariable(var, type)
}
cached
@@ -110,7 +116,7 @@ module Raw {
}
cached
- Function getInstructionFunction(Instruction instruction) {
+ Declaration getInstructionFunction(Instruction instruction) {
result =
getInstructionTranslatedElement(instruction)
.getInstructionFunction(getInstructionTag(instruction))
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll
index 008637812573..c6214bf5e4f7 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll
@@ -130,27 +130,31 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff
}
/**
- * A `Call` or `NewOrNewArrayExpr` or `DeleteOrDeleteArrayExpr`.
+ * An expression that can have call side effects.
*
- * All kinds of expression invoke a function as part of their evaluation. This class provides a
- * way to treat both kinds of function similarly, and to get the invoked `Function`.
+ * All kinds of expressions invoke a function as part of their evaluation. This class provides a
+ * way to treat those expressions similarly, and to get the invoked `Declaration`.
*/
-class CallOrAllocationExpr extends Expr {
- CallOrAllocationExpr() {
+class ExprWithCallSideEffects extends Expr {
+ ExprWithCallSideEffects() {
this instanceof Call
or
this instanceof NewOrNewArrayExpr
or
this instanceof DeleteOrDeleteArrayExpr
+ or
+ this instanceof ConstructorDefaultFieldInit
}
- /** Gets the `Function` invoked by this expression, if known. */
- final Function getTarget() {
+ /** Gets the `Declaration` invoked by this expression, if known. */
+ final Declaration getTarget() {
result = this.(Call).getTarget()
or
result = this.(NewOrNewArrayExpr).getAllocator()
or
result = this.(DeleteOrDeleteArrayExpr).getDeallocator()
+ or
+ result = this.(ConstructorDefaultFieldInit).getTarget()
}
}
@@ -158,7 +162,7 @@ class CallOrAllocationExpr extends Expr {
* Returns the side effect opcode, if any, that represents any side effects not specifically modeled
* by an argument side effect.
*/
-Opcode getCallSideEffectOpcode(CallOrAllocationExpr expr) {
+Opcode getCallSideEffectOpcode(ExprWithCallSideEffects expr) {
not exists(expr.getTarget().(SideEffectFunction)) and result instanceof Opcode::CallSideEffect
or
exists(SideEffectFunction sideEffectFunction |
@@ -175,7 +179,7 @@ Opcode getCallSideEffectOpcode(CallOrAllocationExpr expr) {
/**
* Returns a side effect opcode for parameter index `i` of the specified call.
*
- * This predicate will return at most two results: one read side effect, and one write side effect.
+ * This predicate will yield at most two results: one read side effect, and one write side effect.
*/
Opcode getASideEffectOpcode(Call call, ParameterIndex i) {
exists(boolean buffer |
@@ -228,3 +232,14 @@ Opcode getASideEffectOpcode(Call call, ParameterIndex i) {
)
)
}
+
+/**
+ * Returns a side effect opcode for a default field initialization.
+ *
+ * This predicate will yield two results: one read side effect, and one write side effect.
+ */
+Opcode getDefaultFieldInitSideEffectOpcode() {
+ result instanceof Opcode::IndirectReadSideEffect
+ or
+ result instanceof Opcode::IndirectMayWriteSideEffect
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll
index 1a5c65d364de..bd012d4b9b4a 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll
@@ -10,6 +10,7 @@ private import SideEffects
private import TranslatedElement
private import TranslatedExpr
private import TranslatedFunction
+private import TranslatedInitialization
private import DefaultOptions as DefaultOptions
/**
@@ -348,7 +349,7 @@ class TranslatedExprCall extends TranslatedCallExpr {
class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
override FunctionCall expr;
- override Function getInstructionFunction(InstructionTag tag) {
+ override Declaration getInstructionFunction(InstructionTag tag) {
tag = CallTargetTag() and result = expr.getTarget()
}
@@ -429,6 +430,9 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi
or
expr instanceof DeleteOrDeleteArrayExpr and
result = getTranslatedDeleteOrDeleteArray(expr).getInstruction(CallTag())
+ or
+ expr instanceof ConstructorDefaultFieldInit and
+ result = getTranslatedConstructorFieldInitialization(expr).getInstruction(CallTag())
}
}
@@ -504,11 +508,25 @@ abstract class TranslatedSideEffect extends TranslatedElement {
abstract predicate sideEffectInstruction(Opcode opcode, CppType type);
}
+private class CallOrDefaultFieldInit extends Expr {
+ CallOrDefaultFieldInit() {
+ this instanceof Call
+ or
+ this instanceof ConstructorDefaultFieldInit
+ }
+
+ Declaration getTarget() {
+ result = this.(Call).getTarget()
+ or
+ result = this.(ConstructorDefaultFieldInit).getTarget()
+ }
+}
+
/**
* The IR translation of a single argument side effect for a call.
*/
abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
- Call call;
+ CallOrDefaultFieldInit callOrInit;
int index;
SideEffectOpcode sideEffectOpcode;
@@ -524,7 +542,7 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
result = "(read side effect for " + this.getArgString() + ")"
}
- override Call getPrimaryExpr() { result = call }
+ override Expr getPrimaryExpr() { result = callOrInit }
override predicate sortOrder(int group, int indexInGroup) {
indexInGroup = index and
@@ -586,9 +604,10 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
tag instanceof OnlyInstructionTag and
operandTag instanceof BufferSizeOperandTag and
result =
- getTranslatedExpr(call.getArgument(call.getTarget()
- .(SideEffectFunction)
- .getParameterSizeIndex(index)).getFullyConverted()).getResult()
+ getTranslatedExpr(callOrInit
+ .(Call)
+ .getArgument(callOrInit.getTarget().(SideEffectFunction).getParameterSizeIndex(index))
+ .getFullyConverted()).getResult()
}
/** Holds if this side effect is a write side effect, rather than a read side effect. */
@@ -616,7 +635,7 @@ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
Expr arg;
TranslatedArgumentExprSideEffect() {
- this = TTranslatedArgumentExprSideEffect(call, arg, index, sideEffectOpcode)
+ this = TTranslatedArgumentExprSideEffect(callOrInit, arg, index, sideEffectOpcode)
}
final override Locatable getAst() { result = arg }
@@ -640,28 +659,31 @@ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
* The IR translation of an argument side effect for `*this` on a call, where there is no `Expr`
* object that represents the `this` argument.
*
- * The applies only to constructor calls, as the AST has exploit qualifier `Expr`s for all other
- * calls to non-static member functions.
+ * This applies to constructor calls and default field initializations, as the AST has explicit
+ * qualifier `Expr`s for all other calls to non-static member functions.
*/
-class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect,
- TTranslatedStructorQualifierSideEffect
+class TranslatedImplicitThisQualifierSideEffect extends TranslatedArgumentSideEffect,
+ TTranslatedImplicitThisQualifierSideEffect
{
- TranslatedStructorQualifierSideEffect() {
- this = TTranslatedStructorQualifierSideEffect(call, sideEffectOpcode) and
+ TranslatedImplicitThisQualifierSideEffect() {
+ this = TTranslatedImplicitThisQualifierSideEffect(callOrInit, sideEffectOpcode) and
index = -1
}
- final override Locatable getAst() { result = call }
+ final override Locatable getAst() { result = callOrInit }
- final override Type getIndirectionType() { result = call.getTarget().getDeclaringType() }
+ final override Type getIndirectionType() { result = callOrInit.getTarget().getDeclaringType() }
final override string getArgString() { result = "this" }
final override Instruction getArgInstruction() {
exists(TranslatedStructorCall structorCall |
- structorCall.getExpr() = call and
+ structorCall.getExpr() = callOrInit and
result = structorCall.getQualifierResult()
)
+ or
+ callOrInit instanceof ConstructorDefaultFieldInit and
+ result = getTranslatedFunction(callOrInit.getEnclosingFunction()).getLoadThisInstruction()
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll
index ff8867db696b..be8bff5b05cc 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll
@@ -36,7 +36,8 @@ abstract class TranslatedCondition extends TranslatedElement {
final override Declaration getFunction() {
result = getEnclosingFunction(expr) or
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
- result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
+ result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable) or
+ result = getEnclosingVariable(expr).(Field)
}
final Type getResultType() { result = expr.getUnspecifiedType() }
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll
index c0fe9cd2207d..6de5c1ba21fd 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll
@@ -34,8 +34,11 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslated
or
result = entry.getDeclaration().(GlobalOrNamespaceVariable)
or
+ result = entry.getDeclaration().(Field)
+ or
not entry.getDeclaration() instanceof StaticInitializedStaticLocalVariable and
not entry.getDeclaration() instanceof GlobalOrNamespaceVariable and
+ not entry.getDeclaration() instanceof Field and
result = stmt.getEnclosingFunction()
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
index 9829388ef177..58456476f6a2 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
@@ -767,7 +767,7 @@ newtype TTranslatedElement =
expr = initList.getFieldExpr(field, position).getFullyConverted()
)
or
- exists(ConstructorFieldInit init |
+ exists(ConstructorDirectFieldInit init |
not ignoreExpr(init) and
ast = init and
field = init.getTarget() and
@@ -775,6 +775,14 @@ newtype TTranslatedElement =
position = -1
)
} or
+ // The initialization of a field via a default member initializer.
+ TTranslatedDefaultFieldInitialization(Expr ast, Field field) {
+ exists(ConstructorDefaultFieldInit init |
+ not ignoreExpr(init) and
+ ast = init and
+ field = init.getTarget()
+ )
+ } or
// The value initialization of a field due to an omitted member of an
// initializer list.
TTranslatedFieldValueInitialization(Expr ast, Field field) {
@@ -871,7 +879,7 @@ newtype TTranslatedElement =
// The declaration/initialization part of a `ConditionDeclExpr`
TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or
// The side effects of a `Call`
- TTranslatedCallSideEffects(CallOrAllocationExpr expr) {
+ TTranslatedCallSideEffects(ExprWithCallSideEffects expr) {
not ignoreExpr(expr) and
not ignoreSideEffects(expr)
} or
@@ -910,15 +918,23 @@ newtype TTranslatedElement =
} or
// Constructor calls lack a qualifier (`this`) expression, so we need to handle the side effects
// on `*this` without an `Expr`.
- TTranslatedStructorQualifierSideEffect(Call call, SideEffectOpcode opcode) {
+ TTranslatedImplicitThisQualifierSideEffect(ExprWithCallSideEffects call, SideEffectOpcode opcode) {
not ignoreExpr(call) and
not ignoreSideEffects(call) and
- call instanceof ConstructorCall and
- opcode = getASideEffectOpcode(call, -1)
+ (
+ call instanceof ConstructorCall and
+ opcode = getASideEffectOpcode(call, -1)
+ or
+ call instanceof ConstructorFieldInit and
+ opcode = getDefaultFieldInitSideEffectOpcode()
+ )
} or
// The side effect that initializes newly-allocated memory.
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
- TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) } or
+ TTranslatedStaticStorageDurationVarInit(Variable var) {
+ Raw::varHasIRFunc(var) and not var instanceof Field
+ } or
+ TTranslatedNonStaticDataMemberVarInit(Field var) { Raw::varHasIRFunc(var) } or
TTranslatedAssertionOperand(MacroInvocation mi, int index) { hasAssertionOperand(mi, index) }
/**
@@ -1179,7 +1195,7 @@ abstract class TranslatedElement extends TTranslatedElement {
* If the instruction specified by `tag` is a `FunctionInstruction`, gets the
* `Function` for that instruction.
*/
- Function getInstructionFunction(InstructionTag tag) { none() }
+ Declaration getInstructionFunction(InstructionTag tag) { none() }
/**
* If the instruction specified by `tag` is a `VariableInstruction`, gets the
@@ -1297,5 +1313,7 @@ abstract class TranslatedRootElement extends TranslatedElement {
this instanceof TTranslatedFunction
or
this instanceof TTranslatedStaticStorageDurationVarInit
+ or
+ this instanceof TTranslatedNonStaticDataMemberVarInit
}
}
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 2f7ffa636da3..9a437b905381 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
@@ -14,6 +14,7 @@ private import TranslatedFunction
private import TranslatedInitialization
private import TranslatedStmt
private import TranslatedGlobalVar
+private import TranslatedNonStaticDataMember
private import IRConstruction
import TranslatedCall
@@ -138,6 +139,8 @@ abstract class TranslatedExpr extends TranslatedElement {
result = getTranslatedFunction(getEnclosingFunction(expr))
or
result = getTranslatedVarInit(getEnclosingVariable(expr))
+ or
+ result = getTranslatedFieldInit(getEnclosingVariable(expr))
}
}
@@ -153,7 +156,10 @@ Declaration getEnclosingDeclaration0(Expr e) {
i.getExpr().getFullyConverted() = e and
v = i.getDeclaration()
|
- if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
+ if
+ v instanceof StaticInitializedStaticLocalVariable or
+ v instanceof GlobalOrNamespaceVariable or
+ v instanceof Field
then result = v
else result = e.getEnclosingDeclaration()
)
@@ -173,7 +179,10 @@ Variable getEnclosingVariable0(Expr e) {
i.getExpr().getFullyConverted() = e and
v = i.getDeclaration()
|
- if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
+ if
+ v instanceof StaticInitializedStaticLocalVariable or
+ v instanceof GlobalOrNamespaceVariable or
+ v instanceof Field
then result = v
else result = e.getEnclosingVariable()
)
@@ -826,6 +835,46 @@ class TranslatedPostfixCrementOperation extends TranslatedCrementOperation {
override Instruction getResult() { result = this.getLoadedOperand().getResult() }
}
+class TranslatedParamAccessForType extends TranslatedNonConstantExpr {
+ override ParamAccessForType expr;
+
+ TranslatedParamAccessForType() {
+ // Currently only needed for this parameter accesses.
+ expr.isThisAccess()
+ }
+
+ final override Instruction getFirstInstruction(EdgeKind kind) {
+ result = this.getInstruction(OnlyInstructionTag()) and
+ kind instanceof GotoEdge
+ }
+
+ override Instruction getALastInstructionInternal() {
+ result = this.getInstruction(OnlyInstructionTag())
+ }
+
+ final override TranslatedElement getChildInternal(int id) { none() }
+
+ override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
+ tag = OnlyInstructionTag() and
+ result = this.getParent().getChildSuccessor(this, kind)
+ }
+
+ override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
+
+ override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
+ tag = OnlyInstructionTag() and
+ opcode instanceof Opcode::CopyValue and
+ resultType = getTypeForPRValue(expr.getType())
+ }
+
+ override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
+ tag = OnlyInstructionTag() and
+ operandTag instanceof UnaryOperandTag and
+ result =
+ this.getEnclosingFunction().(TranslatedNonStaticDataMemberVarInit).getLoadThisInstruction()
+ }
+}
+
/**
* IR translation of an array access expression (e.g. `a[i]`). The array being accessed will either
* be a prvalue of pointer type (possibly due to an implicit array-to-pointer conversion), or a
@@ -1215,7 +1264,7 @@ class TranslatedFunctionAccess extends TranslatedNonConstantExpr {
resultType = this.getResultType()
}
- override Function getInstructionFunction(InstructionTag tag) {
+ override Declaration getInstructionFunction(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = expr.getTarget()
}
@@ -2498,7 +2547,7 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedDirect
any()
}
- override Function getInstructionFunction(InstructionTag tag) {
+ override Declaration getInstructionFunction(InstructionTag tag) {
tag = CallTargetTag() and result = expr.getAllocator()
}
@@ -2581,7 +2630,7 @@ class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, Trans
result = this.getFirstArgumentOrCallInstruction(kind)
}
- override Function getInstructionFunction(InstructionTag tag) {
+ override Declaration getInstructionFunction(InstructionTag tag) {
tag = CallTargetTag() and result = expr.getDeallocator()
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll
index b280dd7bc700..10c033131225 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll
@@ -148,7 +148,8 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
final override Declaration getFunction() {
result = getEnclosingFunction(expr) or
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
- result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
+ result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable) or
+ result = getEnclosingVariable(expr).(Field)
}
final override Locatable getAst() { result = expr }
@@ -514,8 +515,8 @@ TranslatedFieldInitialization getTranslatedConstructorFieldInitialization(Constr
}
/**
- * Represents the IR translation of the initialization of a field from an
- * element of an initializer list.
+ * The IR translation of the initialization of a field from an element of
+ * an initializer list.
*/
abstract class TranslatedFieldInitialization extends TranslatedElement {
Expr ast;
@@ -528,13 +529,11 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
final override Declaration getFunction() {
result = getEnclosingFunction(ast) or
result = getEnclosingVariable(ast).(GlobalOrNamespaceVariable) or
- result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable)
+ result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable) or
+ result = getEnclosingVariable(ast).(Field)
}
- final override Instruction getFirstInstruction(EdgeKind kind) {
- result = this.getInstruction(this.getFieldAddressTag()) and
- kind instanceof GotoEdge
- }
+ final Field getField() { result = field }
/**
* Gets the zero-based index describing the order in which this field is to be
@@ -542,6 +541,20 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
*/
final int getOrder() { result = field.getInitializationOrder() }
+ /** Gets the position in the initializer list, or `-1` if the initialization is implicit. */
+ int getPosition() { result = -1 }
+}
+
+/**
+ * The IR translation of the initialization of a field from an element of an initializer
+ * list where default initialization is not used.
+ */
+abstract class TranslatedNonDefaultFieldInitialization extends TranslatedFieldInitialization {
+ final override Instruction getFirstInstruction(EdgeKind kind) {
+ result = this.getInstruction(this.getFieldAddressTag()) and
+ kind instanceof GotoEdge
+ }
+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = this.getFieldAddressTag() and
opcode instanceof Opcode::FieldAddress and
@@ -559,18 +572,13 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
}
final InstructionTag getFieldAddressTag() { result = InitializerFieldAddressTag() }
-
- final Field getField() { result = field }
-
- /** Gets the position in the initializer list, or `-1` if the initialization is implicit. */
- int getPosition() { result = -1 }
}
/**
- * Represents the IR translation of the initialization of a field from an
- * explicit element in an initializer list.
+ * The IR translation of the initialization of a field from an explicit element in
+ * an initializer list.
*/
-class TranslatedExplicitFieldInitialization extends TranslatedFieldInitialization,
+class TranslatedExplicitFieldInitialization extends TranslatedNonDefaultFieldInitialization,
InitializationContext, TTranslatedExplicitFieldInitialization
{
Expr expr;
@@ -610,15 +618,81 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
override int getPosition() { result = position }
}
+/**
+ * The IR translation of the initialization of a field from an element of an initializer
+ * list where default initialization is used.
+ */
+class TranslatedDefaultFieldInitialization extends TranslatedFieldInitialization,
+ TTranslatedDefaultFieldInitialization
+{
+ TranslatedDefaultFieldInitialization() {
+ this = TTranslatedDefaultFieldInitialization(ast, field)
+ }
+
+ final override Instruction getFirstInstruction(EdgeKind kind) {
+ result = this.getInstruction(CallTargetTag()) and
+ kind instanceof GotoEdge
+ }
+
+ override Instruction getALastInstructionInternal() {
+ result = this.getSideEffects().getALastInstruction()
+ }
+
+ override TranslatedElement getLastChild() { result = this.getSideEffects() }
+
+ override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
+ tag = CallTargetTag() and
+ result = this.getInstruction(CallTag())
+ or
+ tag = CallTag() and
+ result = this.getSideEffects().getFirstInstruction(kind)
+ }
+
+ override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
+ child = this.getSideEffects() and
+ result = this.getParent().getChildSuccessor(this, kind)
+ }
+
+ override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
+ tag = CallTargetTag() and
+ opcode instanceof Opcode::FunctionAddress and
+ resultType = getFunctionGLValueType()
+ or
+ tag = CallTag() and
+ opcode instanceof Opcode::Call and
+ resultType = getVoidType()
+ }
+
+ override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
+ tag = CallTag() and
+ (
+ operandTag instanceof CallTargetOperandTag and
+ result = this.getInstruction(CallTargetTag())
+ or
+ operandTag instanceof ThisArgumentOperandTag and
+ result = getTranslatedFunction(this.getFunction()).getLoadThisInstruction()
+ )
+ }
+
+ override Declaration getInstructionFunction(InstructionTag tag) {
+ tag = CallTargetTag() and
+ result = field
+ }
+
+ override TranslatedElement getChild(int id) { id = 0 and result = this.getSideEffects() }
+
+ final TranslatedSideEffects getSideEffects() { result.getExpr() = ast }
+}
+
private string getZeroValue(Type type) {
if type instanceof FloatingPointType then result = "0.0" else result = "0"
}
/**
- * Represents the IR translation of the initialization of a field without a
- * corresponding element in the initializer list.
+ * The IR translation of the initialization of a field without a corresponding
+ * element in the initializer list.
*/
-class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
+class TranslatedFieldValueInitialization extends TranslatedNonDefaultFieldInitialization,
TTranslatedFieldValueInitialization
{
TranslatedFieldValueInitialization() { this = TTranslatedFieldValueInitialization(ast, field) }
@@ -628,7 +702,7 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
- TranslatedFieldInitialization.super.hasInstruction(opcode, tag, resultType)
+ TranslatedNonDefaultFieldInitialization.super.hasInstruction(opcode, tag, resultType)
or
tag = this.getFieldDefaultValueTag() and
opcode instanceof Opcode::Constant and
@@ -659,7 +733,8 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
- result = TranslatedFieldInitialization.super.getInstructionRegisterOperand(tag, operandTag)
+ result =
+ TranslatedNonDefaultFieldInitialization.super.getInstructionRegisterOperand(tag, operandTag)
or
tag = this.getFieldDefaultValueStoreTag() and
(
@@ -683,8 +758,8 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
}
/**
- * Represents the IR translation of the initialization of an array element from
- * an element of an initializer list.
+ * The IR translation of the initialization of an array element from an element
+ * of an initializer list.
*/
abstract class TranslatedElementInitialization extends TranslatedElement {
ArrayOrVectorAggregateLiteral initList;
@@ -701,6 +776,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
result = getEnclosingVariable(initList).(GlobalOrNamespaceVariable)
or
result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable)
+ or
+ result = getEnclosingVariable(initList).(Field)
}
final override Instruction getFirstInstruction(EdgeKind kind) {
@@ -759,8 +836,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
}
/**
- * Represents the IR translation of the initialization of an array element from
- * an explicit element in an initializer list.
+ * The IR translation of the initialization of an array element from an explicit
+ * element in an initializer list.
*/
class TranslatedExplicitElementInitialization extends TranslatedElementInitialization,
TTranslatedExplicitElementInitialization, InitializationContext
@@ -808,8 +885,8 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
}
/**
- * Represents the IR translation of the initialization of a range of array
- * elements without corresponding elements in the initializer list.
+ * The IR translation of the initialization of a range of array elements without
+ * corresponding elements in the initializer list.
*/
class TranslatedElementValueInitialization extends TranslatedElementInitialization,
TTranslatedElementValueInitialization
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedNonStaticDataMember.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedNonStaticDataMember.qll
new file mode 100644
index 000000000000..ff06ff3198ed
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedNonStaticDataMember.qll
@@ -0,0 +1,217 @@
+import semmle.code.cpp.ir.implementation.raw.internal.TranslatedElement
+private import TranslatedExpr
+private import cpp
+private import semmle.code.cpp.ir.implementation.internal.OperandTag
+private import semmle.code.cpp.ir.internal.TempVariableTag
+private import semmle.code.cpp.ir.internal.CppType
+private import TranslatedInitialization
+private import InstructionTag
+private import semmle.code.cpp.ir.internal.IRUtilities
+
+class TranslatedNonStaticDataMemberVarInit extends TranslatedRootElement,
+ TTranslatedNonStaticDataMemberVarInit, InitializationContext
+{
+ Field field;
+ Class cls;
+
+ TranslatedNonStaticDataMemberVarInit() {
+ this = TTranslatedNonStaticDataMemberVarInit(field) and
+ cls.getAMember() = field
+ }
+
+ override string toString() { result = cls.toString() + "::" + field.toString() }
+
+ final override Field getAst() { result = field }
+
+ final override Declaration getFunction() { result = field }
+
+ override Instruction getFirstInstruction(EdgeKind kind) {
+ result = this.getInstruction(EnterFunctionTag()) and
+ kind instanceof GotoEdge
+ }
+
+ override Instruction getALastInstructionInternal() {
+ result = this.getInstruction(ExitFunctionTag())
+ }
+
+ override TranslatedElement getChild(int n) {
+ n = 1 and
+ result = getTranslatedInitialization(field.getInitializer().getExpr().getFullyConverted())
+ }
+
+ override predicate hasInstruction(Opcode op, InstructionTag tag, CppType type) {
+ op instanceof Opcode::EnterFunction and
+ tag = EnterFunctionTag() and
+ type = getVoidType()
+ or
+ op instanceof Opcode::AliasedDefinition and
+ tag = AliasedDefinitionTag() and
+ type = getUnknownType()
+ or
+ op instanceof Opcode::InitializeNonLocal and
+ tag = InitializeNonLocalTag() and
+ type = getUnknownType()
+ or
+ tag = ThisAddressTag() and
+ op instanceof Opcode::VariableAddress and
+ type = getTypeForGLValue(any(UnknownType t))
+ or
+ tag = InitializerStoreTag() and
+ op instanceof Opcode::InitializeParameter and
+ type = this.getThisType()
+ or
+ tag = ThisLoadTag() and
+ op instanceof Opcode::Load and
+ type = this.getThisType()
+ or
+ tag = InitializerIndirectStoreTag() and
+ op instanceof Opcode::InitializeIndirection and
+ type = getTypeForPRValue(cls)
+ or
+ op instanceof Opcode::FieldAddress and
+ tag = InitializerFieldAddressTag() and
+ type = getTypeForGLValue(field.getType())
+ or
+ op instanceof Opcode::ReturnVoid and
+ tag = ReturnTag() and
+ type = getVoidType()
+ or
+ op instanceof Opcode::AliasedUse and
+ tag = AliasedUseTag() and
+ type = getVoidType()
+ or
+ op instanceof Opcode::ExitFunction and
+ tag = ExitFunctionTag() and
+ type = getVoidType()
+ }
+
+ override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
+ kind instanceof GotoEdge and
+ (
+ tag = EnterFunctionTag() and
+ result = this.getInstruction(AliasedDefinitionTag())
+ or
+ tag = AliasedDefinitionTag() and
+ result = this.getInstruction(InitializeNonLocalTag())
+ or
+ tag = InitializeNonLocalTag() and
+ result = this.getInstruction(ThisAddressTag())
+ or
+ tag = ThisAddressTag() and
+ result = this.getInstruction(InitializerStoreTag())
+ or
+ tag = InitializerStoreTag() and
+ result = this.getInstruction(ThisLoadTag())
+ or
+ tag = ThisLoadTag() and
+ result = this.getInstruction(InitializerIndirectStoreTag())
+ or
+ tag = InitializerIndirectStoreTag() and
+ result = this.getInstruction(InitializerFieldAddressTag())
+ )
+ or
+ tag = InitializerFieldAddressTag() and
+ result = this.getChild(1).getFirstInstruction(kind)
+ or
+ kind instanceof GotoEdge and
+ (
+ tag = ReturnTag() and
+ result = this.getInstruction(AliasedUseTag())
+ or
+ tag = AliasedUseTag() and
+ result = this.getInstruction(ExitFunctionTag())
+ )
+ }
+
+ override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
+ child = this.getChild(1) and
+ result = this.getInstruction(ReturnTag()) and
+ kind instanceof GotoEdge
+ }
+
+ final override CppType getInstructionMemoryOperandType(
+ InstructionTag tag, TypedOperandTag operandTag
+ ) {
+ tag = AliasedUseTag() and
+ operandTag instanceof SideEffectOperandTag and
+ result = getUnknownType()
+ }
+
+ override IRVariable getInstructionVariable(InstructionTag tag) {
+ (
+ tag = ThisAddressTag() or
+ tag = InitializerStoreTag() or
+ tag = InitializerIndirectStoreTag()
+ ) and
+ result = getIRTempVariable(field, ThisTempVar())
+ }
+
+ override Field getInstructionField(InstructionTag tag) {
+ tag = InitializerFieldAddressTag() and
+ result = field
+ }
+
+ override predicate hasTempVariable(TempVariableTag tag, CppType type) {
+ tag = ThisTempVar() and
+ type = this.getThisType()
+ }
+
+ /**
+ * Holds if this variable defines or accesses variable `var` with type `type`. This includes all
+ * parameters and local variables, plus any global variables or static data members that are
+ * directly accessed by the function.
+ */
+ final predicate hasUserVariable(Variable varUsed, CppType type) {
+ (
+ (
+ varUsed instanceof GlobalOrNamespaceVariable
+ or
+ varUsed instanceof StaticLocalVariable
+ or
+ varUsed instanceof MemberVariable and not varUsed instanceof Field
+ ) and
+ exists(VariableAccess access |
+ access.getTarget() = varUsed and
+ getEnclosingVariable(access) = field
+ )
+ or
+ field = varUsed
+ or
+ varUsed.(LocalScopeVariable).getEnclosingElement*() = field
+ or
+ varUsed.(Parameter).getCatchBlock().getEnclosingElement*() = field
+ ) and
+ type = getTypeForPRValue(getVariableType(varUsed))
+ }
+
+ override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
+ (
+ tag = InitializerStoreTag()
+ or
+ tag = ThisLoadTag()
+ ) and
+ operandTag instanceof AddressOperandTag and
+ result = this.getInstruction(ThisAddressTag())
+ or
+ (
+ tag = InitializerIndirectStoreTag() and
+ operandTag instanceof AddressOperandTag
+ or
+ tag = InitializerFieldAddressTag() and
+ operandTag instanceof UnaryOperandTag
+ ) and
+ result = this.getInstruction(ThisLoadTag())
+ }
+
+ override Instruction getTargetAddress() {
+ result = this.getInstruction(InitializerFieldAddressTag())
+ }
+
+ override Type getTargetType() { result = field.getUnspecifiedType() }
+
+ final Instruction getLoadThisInstruction() { result = this.getInstruction(ThisLoadTag()) }
+
+ private CppType getThisType() { result = getTypeForGLValue(cls) }
+}
+
+TranslatedNonStaticDataMemberVarInit getTranslatedFieldInit(Field field) { result.getAst() = field }
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 8d3e960c3f87..b7dcd4d8f754 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
@@ -495,7 +495,7 @@ class FieldInstruction extends Instruction {
* `FunctionAddress` instruction.
*/
class FunctionInstruction extends Instruction {
- Language::Function funcSymbol;
+ Language::Declaration funcSymbol;
FunctionInstruction() { funcSymbol = Raw::getInstructionFunction(this) }
@@ -504,7 +504,7 @@ class FunctionInstruction extends Instruction {
/**
* Gets the function that this instruction references.
*/
- final Language::Function getFunctionSymbol() { result = funcSymbol }
+ final Language::Declaration getFunctionSymbol() { result = funcSymbol }
}
/**
@@ -1678,7 +1678,7 @@ class CallInstruction extends Instruction {
/**
* Gets the `Function` that the call targets, if this is statically known.
*/
- final Language::Function getStaticCallTarget() {
+ final Language::Declaration getStaticCallTarget() {
result = this.getCallTarget().(FunctionAddressInstruction).getFunctionSymbol()
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll
index 09f0a0df9668..54dc0fa0ff64 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll
@@ -48,7 +48,6 @@ private import implementations.SqLite3
private import implementations.PostgreSql
private import implementations.System
private import implementations.StructuredExceptionHandling
-private import implementations.ZMQ
private import implementations.Win32CommandExecution
private import implementations.CA2AEX
private import implementations.CComBSTR
@@ -58,3 +57,4 @@ private import implementations.CAtlFileMapping
private import implementations.CAtlTemporaryFile
private import implementations.CRegKey
private import implementations.WinHttp
+private import implementations.Http
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 b5d120830352..c0e2c0c45381 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll
@@ -112,21 +112,3 @@ private class GetsFunction extends DataFlowFunction, ArrayFunction, AliasFunctio
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
}
-
-/**
- * A model for `getc` and similar functions that are flow sources.
- */
-private class GetcSource extends SourceModelCsv {
- override predicate row(string row) {
- row =
- [
- ";;false;getc;;;ReturnValue;remote", ";;false;getwc;;;ReturnValue;remote",
- ";;false;_getc_nolock;;;ReturnValue;remote", ";;false;_getwc_nolock;;;ReturnValue;remote",
- ";;false;getch;;;ReturnValue;local", ";;false;_getch;;;ReturnValue;local",
- ";;false;_getwch;;;ReturnValue;local", ";;false;_getch_nolock;;;ReturnValue;local",
- ";;false;_getwch_nolock;;;ReturnValue;local", ";;false;getchar;;;ReturnValue;local",
- ";;false;getwchar;;;ReturnValue;local", ";;false;_getchar_nolock;;;ReturnValue;local",
- ";;false;_getwchar_nolock;;;ReturnValue;local",
- ]
- }
-}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Http.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Http.qll
new file mode 100644
index 000000000000..a5fdd07c31fc
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Http.qll
@@ -0,0 +1,193 @@
+private import cpp
+private import semmle.code.cpp.ir.dataflow.FlowSteps
+private import semmle.code.cpp.dataflow.new.DataFlow
+
+private class HttpRequest extends Class {
+ HttpRequest() { this.hasGlobalName("_HTTP_REQUEST_V1") }
+}
+
+private class HttpRequestInheritingContent extends TaintInheritingContent, DataFlow::FieldContent {
+ HttpRequestInheritingContent() {
+ this.getAField().getDeclaringType() instanceof HttpRequest and
+ (
+ this.getAField().hasName("pRawUrl") and
+ this.getIndirectionIndex() = 2
+ or
+ this.getAField().hasName("CookedUrl") and
+ this.getIndirectionIndex() = 1
+ or
+ this.getAField().hasName("Headers") and
+ this.getIndirectionIndex() = 1
+ or
+ this.getAField().hasName("pEntityChunks") and
+ this.getIndirectionIndex() = 2
+ or
+ this.getAField().hasName("pSslInfo") and
+ this.getIndirectionIndex() = 2
+ )
+ }
+}
+
+private class HttpCookedUrl extends Class {
+ HttpCookedUrl() { this.hasGlobalName("_HTTP_COOKED_URL") }
+}
+
+private class HttpCookedUrlInheritingContent extends TaintInheritingContent, DataFlow::FieldContent {
+ HttpCookedUrlInheritingContent() {
+ this.getAField().getDeclaringType() instanceof HttpCookedUrl and
+ this.getAField().hasName(["pFullUrl", "pHost", "pAbsPath", "pQueryString"]) and
+ this.getIndirectionIndex() = 2
+ }
+}
+
+private class HttpRequestHeaders extends Class {
+ HttpRequestHeaders() { this.hasGlobalName("_HTTP_REQUEST_HEADERS") }
+}
+
+private class HttpRequestHeadersInheritingContent extends TaintInheritingContent,
+ DataFlow::FieldContent
+{
+ HttpRequestHeadersInheritingContent() {
+ this.getAField().getDeclaringType() instanceof HttpRequestHeaders and
+ (
+ this.getAField().hasName("KnownHeaders") and
+ this.getIndirectionIndex() = 1
+ or
+ this.getAField().hasName("pUnknownHeaders") and
+ this.getIndirectionIndex() = 2
+ )
+ }
+}
+
+private class HttpKnownHeader extends Class {
+ HttpKnownHeader() { this.hasGlobalName("_HTTP_KNOWN_HEADER") }
+}
+
+private class HttpKnownHeaderInheritingContent extends TaintInheritingContent,
+ DataFlow::FieldContent
+{
+ HttpKnownHeaderInheritingContent() {
+ this.getAField().getDeclaringType() instanceof HttpKnownHeader and
+ this.getAField().hasName("pRawValue") and
+ this.getIndirectionIndex() = 2
+ }
+}
+
+private class HttpUnknownHeader extends Class {
+ HttpUnknownHeader() { this.hasGlobalName("_HTTP_UNKNOWN_HEADER") }
+}
+
+private class HttpUnknownHeaderInheritingContent extends TaintInheritingContent,
+ DataFlow::FieldContent
+{
+ HttpUnknownHeaderInheritingContent() {
+ this.getAField().getDeclaringType() instanceof HttpUnknownHeader and
+ this.getAField().hasName(["pName", "pRawValue"]) and
+ this.getIndirectionIndex() = 2
+ }
+}
+
+private class HttpDataChunk extends Class {
+ HttpDataChunk() { this.hasGlobalName("_HTTP_DATA_CHUNK") }
+}
+
+private class HttpDataChunkInheritingContent extends TaintInheritingContent, DataFlow::FieldContent {
+ HttpDataChunkInheritingContent() {
+ this.getAField().getDeclaringType().(Union).getDeclaringType() instanceof HttpDataChunk and
+ (
+ this.getAField().hasName("FromMemory") and
+ this.getIndirectionIndex() = 1
+ or
+ this.getAField().hasName("FromFileHandle") and
+ this.getIndirectionIndex() = 1
+ or
+ this.getAField().hasName("FromFragmentCache") and
+ this.getIndirectionIndex() = 1
+ or
+ this.getAField().hasName("FromFragmentCacheEx") and
+ this.getIndirectionIndex() = 1
+ or
+ this.getAField().hasName("Trailers") and
+ this.getIndirectionIndex() = 1
+ )
+ }
+}
+
+private class FromMemory extends Class {
+ FromMemory() {
+ this.getDeclaringType().(Union).getDeclaringType() instanceof HttpDataChunk and
+ this.getAField().hasName("pBuffer")
+ }
+}
+
+private class FromMemoryInheritingContent extends TaintInheritingContent, DataFlow::FieldContent {
+ FromMemoryInheritingContent() {
+ this.getAField().getDeclaringType() instanceof FromMemory and
+ this.getAField().hasName("pBuffer") and
+ this.getIndirectionIndex() = 2
+ }
+}
+
+private class FromFileHandle extends Class {
+ FromFileHandle() {
+ this.getDeclaringType().(Union).getDeclaringType() instanceof HttpDataChunk and
+ this.getAField().hasName("FileHandle")
+ }
+}
+
+private class FromFileHandleInheritingContent extends TaintInheritingContent, DataFlow::FieldContent
+{
+ FromFileHandleInheritingContent() {
+ this.getAField().getDeclaringType() instanceof FromFileHandle and
+ this.getIndirectionIndex() = 1 and
+ this.getAField().hasName("FileHandle")
+ }
+}
+
+private class FromFragmentCacheOrCacheEx extends Class {
+ FromFragmentCacheOrCacheEx() {
+ this.getDeclaringType().(Union).getDeclaringType() instanceof HttpDataChunk and
+ this.getAField().hasName("pFragmentName")
+ }
+}
+
+private class FromFragmentCacheInheritingContent extends TaintInheritingContent,
+ DataFlow::FieldContent
+{
+ FromFragmentCacheInheritingContent() {
+ this.getAField().getDeclaringType() instanceof FromFragmentCacheOrCacheEx and
+ this.getIndirectionIndex() = 2 and
+ this.getAField().hasName("pFragmentName")
+ }
+}
+
+private class HttpSslInfo extends Class {
+ HttpSslInfo() { this.hasGlobalName("_HTTP_SSL_INFO") }
+}
+
+private class HttpSslInfoInheritingContent extends TaintInheritingContent, DataFlow::FieldContent {
+ HttpSslInfoInheritingContent() {
+ this.getAField().getDeclaringType() instanceof HttpSslInfo and
+ this.getAField().hasName(["pServerCertIssuer", "pServerCertSubject", "pClientCertInfo"]) and
+ this.getIndirectionIndex() = 2
+ }
+}
+
+private class HttpSslClientCertInfo extends Class {
+ HttpSslClientCertInfo() { this.hasGlobalName("_HTTP_SSL_CLIENT_CERT_INFO") }
+}
+
+private class HttpSslClientCertInfoInheritingContent extends TaintInheritingContent,
+ DataFlow::FieldContent
+{
+ HttpSslClientCertInfoInheritingContent() {
+ this.getAField().getDeclaringType() instanceof HttpSslClientCertInfo and
+ (
+ this.getAField().hasName("pCertEncoded") and
+ this.getIndirectionIndex() = 2
+ or
+ this.getAField().hasName("Token") and
+ this.getIndirectionIndex() = 1
+ )
+ }
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/ZMQ.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/ZMQ.qll
deleted file mode 100644
index 22f04cb9c82b..000000000000
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/ZMQ.qll
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Provides implementation classes modeling the ZeroMQ networking library.
- */
-
-import semmle.code.cpp.models.interfaces.FlowSource
-
-/**
- * Remote flow sources.
- */
-private class ZmqSource extends SourceModelCsv {
- override predicate row(string row) {
- row =
- [
- ";;false;zmq_recv;;;Argument[*1];remote", ";;false;zmq_recvmsg;;;Argument[*1];remote",
- ";;false;zmq_msg_recv;;;Argument[*0];remote",
- ]
- }
-}
-
-/**
- * Remote flow sinks.
- */
-private class ZmqSinks extends SinkModelCsv {
- override predicate row(string row) {
- row =
- [
- ";;false;zmq_send;;;Argument[*1];remote-sink",
- ";;false;zmq_sendmsg;;;Argument[*1];remote-sink",
- ";;false;zmq_msg_send;;;Argument[*0];remote-sink",
- ]
- }
-}
-
-/**
- * Flow steps.
- */
-private class ZmqSummaries extends SummaryModelCsv {
- override predicate row(string row) {
- row =
- [
- ";;false;zmq_msg_init_data;;;Argument[*1];Argument[*0];taint",
- ";;false;zmq_msg_data;;;Argument[*0];ReturnValue[*];taint",
- ]
- }
-}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll
index 85b9b66cd661..04826a487ca7 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/NonThrowing.qll
@@ -11,10 +11,3 @@ import semmle.code.cpp.models.Models
* The function may still raise a structured exception handling (SEH) exception.
*/
abstract class NonCppThrowingFunction extends Function { }
-
-/**
- * A function that is guaranteed to never throw.
- *
- * DEPRECATED: use `NonCppThrowingFunction` instead.
- */
-deprecated class NonThrowingFunction = NonCppThrowingFunction;
diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll
index 111b99533957..a781bab07c35 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll
@@ -10,19 +10,6 @@ import semmle.code.cpp.Function
import semmle.code.cpp.models.Models
import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
-/**
- * A function that is known to raise an exception.
- *
- * DEPRECATED: use `AlwaysSehThrowingFunction` instead.
- */
-abstract deprecated class ThrowingFunction extends Function {
- /**
- * Holds if this function may throw an exception during evaluation.
- * If `unconditional` is `true` the function always throws an exception.
- */
- abstract predicate mayThrowException(boolean unconditional);
-}
-
/**
* A function that unconditionally raises a structured exception handling (SEH) exception.
*/
diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md
index c29eaa31e448..a3f9d1836ade 100644
--- a/cpp/ql/src/CHANGELOG.md
+++ b/cpp/ql/src/CHANGELOG.md
@@ -1,3 +1,25 @@
+## 1.6.0
+
+### Query Metadata Changes
+
+* The `@security-severity` metadata of `cpp/cgi-xss` has been increased from 6.1 (medium) to 7.8 (high).
+
+### Minor Analysis Improvements
+
+* The "Extraction warnings" (`cpp/diagnostics/extraction-warnings`) diagnostics query no longer yields `ExtractionRecoverableWarning`s for `build-mode: none` databases. The results were found to significantly increase the sizes of the produced SARIF files, making them unprocessable in some cases.
+* Fixed an issue with the "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query causing false positive results in `build-mode: none` databases.
+* Fixed an issue with the "Uncontrolled format string" (`cpp/tainted-format-string`) query involving certain kinds of formatting function implementations.
+* Fixed an issue with the "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query causing false positive results in `build-mode: none` databases.
+* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in `build-mode: none` databases.
+
+## 1.5.15
+
+No user-facing changes.
+
+## 1.5.14
+
+No user-facing changes.
+
## 1.5.13
No user-facing changes.
diff --git a/cpp/ql/src/Diagnostics/ExtractionProblems.qll b/cpp/ql/src/Diagnostics/ExtractionProblems.qll
index b6dd835261d1..1199ca1c7f42 100644
--- a/cpp/ql/src/Diagnostics/ExtractionProblems.qll
+++ b/cpp/ql/src/Diagnostics/ExtractionProblems.qll
@@ -50,7 +50,7 @@ private newtype TExtractionProblem =
/**
* Superclass for the extraction problem hierarchy.
*/
-class ExtractionProblem extends TExtractionProblem {
+abstract class ExtractionProblem extends TExtractionProblem {
/** Gets the string representation of the problem. */
string toString() { none() }
@@ -65,6 +65,9 @@ class ExtractionProblem extends TExtractionProblem {
/** Gets the SARIF severity of this problem. */
int getSeverity() { none() }
+
+ /** Gets the `Compilation` the problem is associated with. */
+ abstract Compilation getCompilation();
}
/**
@@ -96,6 +99,8 @@ class ExtractionUnrecoverableError extends ExtractionProblem, TCompilationFailed
// [errors](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#_Toc10541338).
result = 2
}
+
+ override Compilation getCompilation() { result = c }
}
/**
@@ -122,6 +127,8 @@ class ExtractionRecoverableWarning extends ExtractionProblem, TReportableWarning
// [warnings](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#_Toc10541338).
result = 1
}
+
+ override Compilation getCompilation() { result = err.getCompilation() }
}
/**
@@ -148,4 +155,6 @@ class ExtractionUnknownProblem extends ExtractionProblem, TUnknownProblem {
// [warnings](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html#_Toc10541338).
result = 1
}
+
+ override Compilation getCompilation() { result = err.getCompilation() }
}
diff --git a/cpp/ql/src/Diagnostics/ExtractionWarnings.ql b/cpp/ql/src/Diagnostics/ExtractionWarnings.ql
index f32768734ca0..c0e9eb7d24be 100644
--- a/cpp/ql/src/Diagnostics/ExtractionWarnings.ql
+++ b/cpp/ql/src/Diagnostics/ExtractionWarnings.ql
@@ -10,7 +10,9 @@ import ExtractionProblems
from ExtractionProblem warning
where
- warning instanceof ExtractionRecoverableWarning and exists(warning.getFile().getRelativePath())
+ warning instanceof ExtractionRecoverableWarning and
+ exists(warning.getFile().getRelativePath()) and
+ not warning.getCompilation().buildModeNone()
or
warning instanceof ExtractionUnknownProblem
select warning,
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
index a54ac9020c8c..b05bd637dc2d 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
@@ -5,7 +5,7 @@
* @kind problem
* @problem.severity warning
* @security-severity 8.1
- * @precision medium
+ * @precision high
* @id cpp/integer-multiplication-cast-to-long
* @tags reliability
* security
@@ -218,7 +218,9 @@ where
// only report if we cannot prove that the result of the
// multiplication will be less (resp. greater) than the
// maximum (resp. minimum) number we can compute.
- overflows(me, t1)
+ overflows(me, t1) and
+ // exclude cases where the expression type may not have been extracted accurately
+ not me.getParent().(Call).getTarget().hasAmbiguousReturnType()
select me,
"Multiplication result may overflow '" + me.getType().toString() + "' before it is converted to '"
+ me.getFullyConverted().getType().toString() + "'."
diff --git a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql
index 33fe3a0b7a15..5842b9474f74 100644
--- a/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql
@@ -5,7 +5,7 @@
* @kind problem
* @problem.severity error
* @security-severity 7.5
- * @precision medium
+ * @precision high
* @id cpp/wrong-type-format-argument
* @tags reliability
* correctness
@@ -168,9 +168,11 @@ where
formatOtherArgType(ffc, n, expected, arg, actual) and
not actual.getUnspecifiedType().(IntegralType).getSize() = sizeof_IntType()
) and
+ // Exclude some cases where we're less confident the result is correct / clear / valuable
not arg.isAffectedByMacro() and
not arg.isFromUninstantiatedTemplate(_) and
not actual.stripType() instanceof ErroneousType and
+ not arg.getType().stripType().(RoutineType).getReturnType() instanceof ErroneousType and
not arg.(Call).mayBeFromImplicitlyDeclaredFunction() and
// Make sure that the format function definition is consistent
count(ffc.getTarget().getFormatParameterIndex()) = 1
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.qhelp b/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.qhelp
index 6ff60d383419..90a98e1bf573 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.qhelp
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.qhelp
@@ -14,6 +14,9 @@ function may behave unpredictably.
This may indicate a misspelled function name, or that the required header containing
the function declaration has not been included.
+Note: This query is not compatible with build mode: none databases, and produces
+no results on those databases.
+
Provide an explicit declaration of the function before invoking it.
@@ -26,4 +29,4 @@ the function declaration has not been included.
SEI CERT C Coding Standard: DCL31-C. Declare identifiers before using them
-
\ No newline at end of file
+
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql
index 6a55557cf70b..00b29efbd0f2 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql
@@ -5,7 +5,7 @@
* may lead to unpredictable behavior.
* @kind problem
* @problem.severity warning
- * @precision medium
+ * @precision high
* @id cpp/implicit-function-declaration
* @tags correctness
* maintainability
@@ -17,6 +17,11 @@ import TooFewArguments
import TooManyArguments
import semmle.code.cpp.commons.Exclusions
+/*
+ * This query is not compatible with build mode: none databases, and produces
+ * no results on those databases.
+ */
+
predicate locInfo(Locatable e, File file, int line, int col) {
e.getFile() = file and
e.getLocation().getStartLine() = line and
@@ -39,6 +44,7 @@ predicate isCompiledAsC(File f) {
from FunctionDeclarationEntry fdeIm, FunctionCall fc
where
isCompiledAsC(fdeIm.getFile()) and
+ not any(Compilation c).buildModeNone() and
not isFromMacroDefinition(fc) and
fdeIm.isImplicit() and
sameLocation(fdeIm, fc) and
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qll b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qll
index 2dced5d8d844..dbb457db505e 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qll
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qll
@@ -79,9 +79,7 @@ private predicate hasZeroParamDecl(Function f) {
// True if this file (or header) was compiled as a C file
private predicate isCompiledAsC(File f) {
- f.compiledAsC()
- or
- exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
+ exists(File src | src.compiledAsC() | src.getAnIncludedFile*() = f)
}
predicate mistypedFunctionArguments(FunctionCall fc, Function f, Parameter p) {
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qll b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qll
index 218a54b36c51..fd323513a49e 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qll
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qll
@@ -28,9 +28,7 @@ private predicate hasZeroParamDecl(Function f) {
/* Holds if this file (or header) was compiled as a C file. */
private predicate isCompiledAsC(File f) {
- f.compiledAsC()
- or
- exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
+ exists(File src | src.compiledAsC() | src.getAnIncludedFile*() = f)
}
/** Holds if `fc` is a call to `f` with too few arguments. */
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.qll b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.qll
index 7fba78b5550e..ab2a98ae3a55 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.qll
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.qll
@@ -19,9 +19,7 @@ private predicate hasZeroParamDecl(Function f) {
// True if this file (or header) was compiled as a C file
private predicate isCompiledAsC(File f) {
- f.compiledAsC()
- or
- exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
+ exists(File src | src.compiledAsC() | src.getAnIncludedFile*() = f)
}
predicate tooManyArguments(FunctionCall fc, Function f) {
diff --git a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql
index 994aba733d23..0e4a8f9741cd 100644
--- a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql
+++ b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql
@@ -4,7 +4,7 @@
* allows for a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
- * @security-severity 6.1
+ * @security-severity 7.8
* @precision high
* @id cpp/cgi-xss
* @tags security
diff --git a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql
index 37e3fa0c49f8..bf6f014672fb 100644
--- a/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql
+++ b/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql
@@ -23,13 +23,31 @@ import Flow::PathGraph
predicate isSource(FlowSource source, string sourceType) { sourceType = source.getSourceType() }
+/**
+ * Holds if `f` is a printf-like function or a (possibly nested) wrapper
+ * that forwards a format-string parameter to one.
+ *
+ * Functions that *implement* printf-like behavior (e.g. a custom
+ * `vsnprintf` variant) internally parse the caller-supplied format string
+ * and build small, bounded, local format strings such as `"%d"` or `"%ld"`
+ * for inner `sprintf` calls. Taint that reaches those inner calls via the
+ * parsed format specifier is not exploitable, so sinks inside such
+ * functions should be excluded.
+ */
+private predicate isPrintfImplementation(Function f) {
+ f instanceof PrintfLikeFunction
+ or
+ exists(PrintfLikeFunction printf | printf.wrapperFunction(f, _, _))
+}
+
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { isSource(node, _) }
predicate isSink(DataFlow::Node node) {
exists(PrintfLikeFunction printf |
printf.outermostWrapperFunctionCall([node.asExpr(), node.asIndirectExpr()], _)
- )
+ ) and
+ not isPrintfImplementation([node.asExpr(), node.asIndirectExpr()].getEnclosingFunction())
}
private predicate isArithmeticNonCharType(ArithmeticType type) {
diff --git a/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql b/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql
index 3f330807304f..7d9ef88adea1 100644
--- a/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql
+++ b/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql
@@ -6,7 +6,7 @@
* @kind problem
* @problem.severity warning
* @security-severity 7.8
- * @precision medium
+ * @precision high
* @tags reliability
* security
* external/cwe/cwe-190
diff --git a/cpp/ql/src/Security/CWE/CWE-468/SuspiciousAddWithSizeof.ql b/cpp/ql/src/Security/CWE/CWE-468/SuspiciousAddWithSizeof.ql
index d9c9df4fd918..d5a5cd8f6655 100644
--- a/cpp/ql/src/Security/CWE/CWE-468/SuspiciousAddWithSizeof.ql
+++ b/cpp/ql/src/Security/CWE/CWE-468/SuspiciousAddWithSizeof.ql
@@ -6,7 +6,7 @@
* @kind problem
* @problem.severity warning
* @security-severity 8.8
- * @precision medium
+ * @precision high
* @id cpp/suspicious-add-sizeof
* @tags security
* external/cwe/cwe-468
@@ -18,7 +18,8 @@ import IncorrectPointerScalingCommon
private predicate isCharSzPtrExpr(Expr e) {
exists(PointerType pt | pt = e.getFullyConverted().getUnspecifiedType() |
pt.getBaseType() instanceof CharType or
- pt.getBaseType() instanceof VoidType
+ pt.getBaseType() instanceof VoidType or
+ pt.getBaseType() instanceof ErroneousType // this could be char / void type in a successful compilation
)
}
diff --git a/cpp/ql/src/Telemetry/DatabaseQuality.qll b/cpp/ql/src/Telemetry/DatabaseQuality.qll
new file mode 100644
index 000000000000..043510529860
--- /dev/null
+++ b/cpp/ql/src/Telemetry/DatabaseQuality.qll
@@ -0,0 +1,48 @@
+import cpp
+import codeql.util.ReportStats
+
+/** A file that is included in the quality statistics. */
+private class RelevantFile extends File {
+ RelevantFile() { this.fromSource() and exists(this.getRelativePath()) }
+}
+
+module CallTargetStats implements StatsSig {
+ private class RelevantCall extends Call {
+ RelevantCall() { this.getFile() instanceof RelevantFile }
+ }
+
+ // We assume that calls with an implicit target are calls that could not be
+ // resolved. This is accurate in the vast majority of cases, but is inaccurate
+ // for calls that deliberately rely on implicitly declared functions.
+ private predicate hasImplicitTarget(RelevantCall call) {
+ call.getTarget().getADeclarationEntry().isImplicit()
+ }
+
+ int getNumberOfOk() { result = count(RelevantCall call | not hasImplicitTarget(call)) }
+
+ int getNumberOfNotOk() { result = count(RelevantCall call | hasImplicitTarget(call)) }
+
+ string getOkText() { result = "calls with call target" }
+
+ string getNotOkText() { result = "calls with missing call target" }
+}
+
+private class SourceExpr extends Expr {
+ SourceExpr() { this.getFile() instanceof RelevantFile }
+}
+
+private predicate hasGoodType(Expr e) { not e.getType() instanceof ErroneousType }
+
+module ExprTypeStats implements StatsSig {
+ int getNumberOfOk() { result = count(SourceExpr e | hasGoodType(e)) }
+
+ int getNumberOfNotOk() { result = count(SourceExpr e | not hasGoodType(e)) }
+
+ string getOkText() { result = "expressions with known type" }
+
+ string getNotOkText() { result = "expressions with unknown type" }
+}
+
+module CallTargetStatsReport = ReportStats;
+
+module ExprTypeStatsReport = ReportStats;
diff --git a/cpp/ql/src/Telemetry/ExtractorInformation.ql b/cpp/ql/src/Telemetry/ExtractorInformation.ql
new file mode 100644
index 000000000000..a82b3b86acee
--- /dev/null
+++ b/cpp/ql/src/Telemetry/ExtractorInformation.ql
@@ -0,0 +1,28 @@
+/**
+ * @name C/C++ extraction information
+ * @description Information about the extraction for a C/C++ database
+ * @kind metric
+ * @tags summary telemetry
+ * @id cpp/telemetry/extraction-information
+ */
+
+import cpp
+import DatabaseQuality
+
+from string key, float value
+where
+ (
+ CallTargetStatsReport::numberOfOk(key, value) or
+ CallTargetStatsReport::numberOfNotOk(key, value) or
+ CallTargetStatsReport::percentageOfOk(key, value) or
+ ExprTypeStatsReport::numberOfOk(key, value) or
+ ExprTypeStatsReport::numberOfNotOk(key, value) or
+ ExprTypeStatsReport::percentageOfOk(key, value)
+ ) and
+ /* Infinity */
+ value != 1.0 / 0.0 and
+ /* -Infinity */
+ value != -1.0 / 0.0 and
+ /* NaN */
+ value != 0.0 / 0.0
+select key, value
diff --git a/cpp/ql/src/change-notes/2026-03-23-implicit-function-declaration.md b/cpp/ql/src/change-notes/2026-03-23-implicit-function-declaration.md
new file mode 100644
index 000000000000..8c2c431ec24c
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-03-23-implicit-function-declaration.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query no longer produces results on `build mode: none` databases. These results were found to be very noisy and fundamentally imprecise in this mode.
diff --git a/cpp/ql/src/change-notes/2026-04-02-comparison-with-wider-type.md b/cpp/ql/src/change-notes/2026-04-02-comparison-with-wider-type.md
new file mode 100644
index 000000000000..c84e1dba404c
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-04-02-comparison-with-wider-type.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The "Comparison of narrow type with wide type in loop condition" (`cpp/comparison-with-wider-type`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
diff --git a/cpp/ql/src/change-notes/2026-04-02-implicit-function-declaration.md b/cpp/ql/src/change-notes/2026-04-02-implicit-function-declaration.md
new file mode 100644
index 000000000000..dd0dbd4bc7d9
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-04-02-implicit-function-declaration.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision.
diff --git a/cpp/ql/src/change-notes/2026-04-02-integer-multiplication-cast-to-long.md b/cpp/ql/src/change-notes/2026-04-02-integer-multiplication-cast-to-long.md
new file mode 100644
index 000000000000..cd6796b408f0
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-04-02-integer-multiplication-cast-to-long.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
diff --git a/cpp/ql/src/change-notes/2026-04-02-suspicious-add-sizeof.md b/cpp/ql/src/change-notes/2026-04-02-suspicious-add-sizeof.md
new file mode 100644
index 000000000000..040e89c13475
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-04-02-suspicious-add-sizeof.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
diff --git a/cpp/ql/src/change-notes/2026-04-02-wrong-type-format-argument.md b/cpp/ql/src/change-notes/2026-04-02-wrong-type-format-argument.md
new file mode 100644
index 000000000000..f8b9085dacc6
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-04-02-wrong-type-format-argument.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
diff --git a/cpp/ql/src/change-notes/2026-04-16-add-model-for-aligned-alloc.md b/cpp/ql/src/change-notes/2026-04-16-add-model-for-aligned-alloc.md
new file mode 100644
index 000000000000..af97cee7f9e4
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-04-16-add-model-for-aligned-alloc.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* Added `AllocationFunction` models for `aligned_alloc`, `std::aligned_alloc`, and `bsl::aligned_alloc`.
diff --git a/cpp/ql/src/change-notes/released/1.5.14.md b/cpp/ql/src/change-notes/released/1.5.14.md
new file mode 100644
index 000000000000..a165735f53db
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.5.14.md
@@ -0,0 +1,3 @@
+## 1.5.14
+
+No user-facing changes.
diff --git a/cpp/ql/src/change-notes/released/1.5.15.md b/cpp/ql/src/change-notes/released/1.5.15.md
new file mode 100644
index 000000000000..dd184231746a
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.5.15.md
@@ -0,0 +1,3 @@
+## 1.5.15
+
+No user-facing changes.
diff --git a/cpp/ql/src/change-notes/released/1.6.0.md b/cpp/ql/src/change-notes/released/1.6.0.md
new file mode 100644
index 000000000000..3bbb94806609
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.6.0.md
@@ -0,0 +1,13 @@
+## 1.6.0
+
+### Query Metadata Changes
+
+* The `@security-severity` metadata of `cpp/cgi-xss` has been increased from 6.1 (medium) to 7.8 (high).
+
+### Minor Analysis Improvements
+
+* The "Extraction warnings" (`cpp/diagnostics/extraction-warnings`) diagnostics query no longer yields `ExtractionRecoverableWarning`s for `build-mode: none` databases. The results were found to significantly increase the sizes of the produced SARIF files, making them unprocessable in some cases.
+* Fixed an issue with the "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query causing false positive results in `build-mode: none` databases.
+* Fixed an issue with the "Uncontrolled format string" (`cpp/tainted-format-string`) query involving certain kinds of formatting function implementations.
+* Fixed an issue with the "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query causing false positive results in `build-mode: none` databases.
+* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in `build-mode: none` databases.
diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml
index 63816b66f59f..c4f0b07d5336 100644
--- a/cpp/ql/src/codeql-pack.release.yml
+++ b/cpp/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 1.5.13
+lastReleaseVersion: 1.6.0
diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml
index 5fb03d534347..4648951796cc 100644
--- a/cpp/ql/src/qlpack.yml
+++ b/cpp/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-queries
-version: 1.5.13
+version: 1.6.1-dev
groups:
- cpp
- queries
diff --git a/cpp/ql/test/library-tests/ctorinits/ctors.expected b/cpp/ql/test/library-tests/ctorinits/ctors.expected
index 8a14ee6001ae..e8eba3385606 100644
--- a/cpp/ql/test/library-tests/ctorinits/ctors.expected
+++ b/cpp/ql/test/library-tests/ctorinits/ctors.expected
@@ -1,17 +1,17 @@
-| ctorinits.cpp:5:3:5:10 | NoisyInt | 0 | ConstructorFieldInit | ctorinits.cpp:5:29:5:42 | constructor init of field m_value | 1 | 0 |
-| ctorinits.cpp:13:3:13:11 | NoisyPair | 0 | ConstructorFieldInit | ctorinits.cpp:14:7:14:16 | constructor init of field m_fst | 1 | 0 |
-| ctorinits.cpp:13:3:13:11 | NoisyPair | 1 | ConstructorFieldInit | ctorinits.cpp:15:7:15:16 | constructor init of field m_snd | 1 | 0 |
+| ctorinits.cpp:5:3:5:10 | NoisyInt | 0 | ConstructorDirectFieldInit | ctorinits.cpp:5:29:5:42 | constructor init of field m_value | 1 | 0 |
+| ctorinits.cpp:13:3:13:11 | NoisyPair | 0 | ConstructorDirectFieldInit | ctorinits.cpp:14:7:14:16 | constructor init of field m_fst | 1 | 0 |
+| ctorinits.cpp:13:3:13:11 | NoisyPair | 1 | ConstructorDirectFieldInit | ctorinits.cpp:15:7:15:16 | constructor init of field m_snd | 1 | 0 |
| ctorinits.cpp:16:3:16:11 | NoisyPair | 0 | ConstructorDelegationInit | ctorinits.cpp:16:17:16:31 | call to NoisyPair | 2 | 2 |
| ctorinits.cpp:21:8:21:8 | NoisyTriple | 0 | ConstructorDirectInit | ctorinits.cpp:21:8:21:8 | call to NoisyPair | 0 | 0 |
-| ctorinits.cpp:21:8:21:8 | NoisyTriple | 1 | ConstructorFieldInit | ctorinits.cpp:21:8:21:8 | constructor init of field m_third | 1 | 0 |
-| ctorinits.cpp:28:2:28:9 | ArrayInt | 0 | ConstructorFieldInit | ctorinits.cpp:28:13:28:13 | constructor init of field m_array | 1 | 0 |
-| ctorinits.cpp:42:2:42:16 | ArrayMemberInit | 0 | ConstructorFieldInit | ctorinits.cpp:42:22:42:32 | constructor init of field xs | 1 | 4 |
+| ctorinits.cpp:21:8:21:8 | NoisyTriple | 1 | ConstructorDirectFieldInit | ctorinits.cpp:21:8:21:8 | constructor init of field m_third | 1 | 0 |
+| ctorinits.cpp:28:2:28:9 | ArrayInt | 0 | ConstructorDirectFieldInit | ctorinits.cpp:28:13:28:13 | constructor init of field m_array | 1 | 0 |
+| ctorinits.cpp:42:2:42:16 | ArrayMemberInit | 0 | ConstructorDirectFieldInit | ctorinits.cpp:42:22:42:32 | constructor init of field xs | 1 | 4 |
| ctorinits.cpp:65:3:65:15 | MultipleBases | 0 | ConstructorDirectInit | ctorinits.cpp:69:5:69:8 | call to A | 1 | 1 |
| ctorinits.cpp:65:3:65:15 | MultipleBases | 1 | ConstructorDirectInit | ctorinits.cpp:67:5:67:8 | call to B | 1 | 1 |
| ctorinits.cpp:65:3:65:15 | MultipleBases | 2 | ConstructorDirectInit | ctorinits.cpp:70:5:70:8 | call to C | 1 | 1 |
-| ctorinits.cpp:65:3:65:15 | MultipleBases | 3 | ConstructorFieldInit | ctorinits.cpp:68:5:68:8 | constructor init of field x | 1 | 1 |
-| ctorinits.cpp:65:3:65:15 | MultipleBases | 4 | ConstructorFieldInit | ctorinits.cpp:71:5:71:8 | constructor init of field y | 1 | 1 |
-| ctorinits.cpp:65:3:65:15 | MultipleBases | 5 | ConstructorFieldInit | ctorinits.cpp:66:5:66:8 | constructor init of field z | 1 | 1 |
+| ctorinits.cpp:65:3:65:15 | MultipleBases | 3 | ConstructorDirectFieldInit | ctorinits.cpp:68:5:68:8 | constructor init of field x | 1 | 1 |
+| ctorinits.cpp:65:3:65:15 | MultipleBases | 4 | ConstructorDirectFieldInit | ctorinits.cpp:71:5:71:8 | constructor init of field y | 1 | 1 |
+| ctorinits.cpp:65:3:65:15 | MultipleBases | 5 | ConstructorDirectFieldInit | ctorinits.cpp:66:5:66:8 | constructor init of field z | 1 | 1 |
| ctorinits.cpp:81:8:81:8 | VD | 0 | ConstructorVirtualInit | ctorinits.cpp:81:8:81:8 | call to VB | 0 | 0 |
| ctorinits.cpp:85:3:85:22 | VirtualAndNonVirtual | 0 | ConstructorVirtualInit | ctorinits.cpp:85:26:85:26 | call to VB | 0 | 0 |
| ctorinits.cpp:85:3:85:22 | VirtualAndNonVirtual | 1 | ConstructorDirectInit | ctorinits.cpp:85:26:85:26 | call to VD | 0 | 0 |
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected
index ff41f299f9c2..4e145427a362 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected
@@ -10,11 +10,13 @@ uniqueEnclosingCallable
| test.cpp:1158:18:1158:42 | ... , ... | Node should have one enclosing callable but has 0. |
| test.cpp:1158:23:1158:31 | recursion | Node should have one enclosing callable but has 0. |
| test.cpp:1158:35:1158:40 | call to source | Node should have one enclosing callable but has 0. |
+| test.cpp:1318:13:1318:18 | call to source | Node should have one enclosing callable but has 0. |
uniqueCallEnclosingCallable
| test.cpp:864:47:864:54 | call to source | Call should have one enclosing callable but has 0. |
| test.cpp:872:46:872:51 | call to source | Call should have one enclosing callable but has 0. |
| test.cpp:1158:18:1158:21 | call to sink | Call should have one enclosing callable but has 0. |
| test.cpp:1158:35:1158:40 | call to source | Call should have one enclosing callable but has 0. |
+| test.cpp:1318:13:1318:18 | call to source | Call should have one enclosing callable but has 0. |
uniqueType
uniqueNodeLocation
missingLocation
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected
index 03a106208a5b..5ee2ca86cbcf 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected
@@ -170,6 +170,7 @@ astFlow
| test.cpp:1308:7:1308:12 | call to source | test.cpp:1309:14:1309:16 | ... ++ |
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1313:8:1313:24 | ... ? ... : ... |
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1314:8:1314:8 | x |
+| test.cpp:1329:11:1329:16 | call to source | test.cpp:1330:10:1330:10 | i |
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
| true_upon_entry.cpp:33:11:33:16 | call to source | true_upon_entry.cpp:39:8:39:8 | x |
@@ -390,6 +391,8 @@ irFlow
| test.cpp:1308:7:1308:12 | call to source | test.cpp:1309:8:1309:16 | ... ++ |
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1313:8:1313:24 | ... ? ... : ... |
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1314:8:1314:8 | x |
+| test.cpp:1318:13:1318:18 | call to source | test.cpp:1327:10:1327:10 | i |
+| test.cpp:1329:11:1329:16 | call to source | test.cpp:1330:10:1330:10 | i |
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp
index e1c3ef98fb74..892d49b00855 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp
@@ -1312,4 +1312,20 @@ void crement_test2(bool b, int y) {
x = source();
sink(b ? (long)x++ : 0); // $ ir ast
sink(x); // $ ir ast
-}
\ No newline at end of file
+}
+
+struct nsdmi {
+ int i = source();
+
+ nsdmi() {}
+
+ nsdmi(int i) : i(i) {}
+};
+
+void nsdmi_test() {
+ nsdmi x;
+ sink(x.i); // $ ir MISSING: ast
+
+ nsdmi y(source());
+ sink(y.i); // $ ir ast
+}
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.expected
index 87ebdc9e83a3..2ba0cf2928b8 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.expected
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.expected
@@ -1,41 +1,5 @@
astTypeBugs
irTypeBugs
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary param] *0 in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary param] this in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] read: Argument[*0].Element in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] read: Argument[*0].Element[****] in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] read: Argument[*0].Element[***] in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] read: Argument[*0].Element[**] in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] read: Argument[*0].Element[*] in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] to write: Argument[this] in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] to write: Argument[this].Element in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] to write: Argument[this].Element[****] in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] to write: Argument[this].Element[***] in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] to write: Argument[this].Element[**] in iterator |
-| ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | ../../../include/iterator.h:21:3:21:10 | [summary] to write: Argument[this].Element[*] in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary param] *0 in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary param] this in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] read: Argument[*0].Element in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] read: Argument[*0].Element[****] in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] read: Argument[*0].Element[***] in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] read: Argument[*0].Element[**] in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] read: Argument[*0].Element[*] in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] to write: Argument[this] in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] to write: Argument[this].Element in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] to write: Argument[this].Element[****] in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] to write: Argument[this].Element[***] in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] to write: Argument[this].Element[**] in iterator |
-| ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | ../../../include/iterator.h:22:3:22:10 | [summary] to write: Argument[this].Element[*] in iterator |
-| ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | [summary param] this in operator* |
-| ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | [summary] read: Argument[this].Element in operator* |
-| ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | [summary] read: Argument[this].Element[*] in operator* |
-| ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | [summary] to write: ReturnValue[**] in operator* |
-| ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | ../../../include/iterator.h:30:18:30:26 | [summary] to write: ReturnValue[*] in operator* |
-| ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | [summary param] this in operator-> |
-| ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | [summary] read: Argument[this].Element in operator-> |
-| ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | [summary] read: Argument[this].Element[*] in operator-> |
-| ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | [summary] to write: ReturnValue[**] in operator-> |
-| ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | ../../../include/iterator.h:31:16:31:25 | [summary] to write: ReturnValue[*] in operator-> |
incorrectBaseType
| clang.cpp:22:8:22:20 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
| clang.cpp:23:17:23:29 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.ql
index 3e5f9165ef81..3fcf39ef1c55 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.ql
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/type-bugs.ql
@@ -17,9 +17,13 @@ import AstTest
module IrTest {
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
+ private import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes
query predicate irTypeBugs(Location location, Node node) {
exists(int n |
+ // Flow summary nodes don't have a type since we don't necessarily have
+ // the source code in the database.
+ not node instanceof FlowSummaryNode and
n = count(node.getType()) and
location = node.getLocation() and
n != 1
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected
index 1e46060c97ed..4142b09473a9 100644
--- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected
+++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected
@@ -4,121 +4,124 @@ models
| 3 | Source: ; ; false; GetCommandLineA; ; ; ReturnValue[*]; local; manual |
| 4 | Source: ; ; false; GetEnvironmentStringsA; ; ; ReturnValue[*]; local; manual |
| 5 | Source: ; ; false; GetEnvironmentVariableA; ; ; Argument[*1]; local; manual |
-| 6 | Source: ; ; false; MapViewOfFile2; ; ; ReturnValue[*]; local; manual |
-| 7 | Source: ; ; false; MapViewOfFile3; ; ; ReturnValue[*]; local; manual |
-| 8 | Source: ; ; false; MapViewOfFile3FromApp; ; ; ReturnValue[*]; local; manual |
-| 9 | Source: ; ; false; MapViewOfFile; ; ; ReturnValue[*]; local; manual |
-| 10 | Source: ; ; false; MapViewOfFileEx; ; ; ReturnValue[*]; local; manual |
-| 11 | Source: ; ; false; MapViewOfFileFromApp; ; ; ReturnValue[*]; local; manual |
-| 12 | Source: ; ; false; MapViewOfFileNuma2; ; ; ReturnValue[*]; local; manual |
-| 13 | Source: ; ; false; NtReadFile; ; ; Argument[*5]; local; manual |
-| 14 | Source: ; ; false; ReadFile; ; ; Argument[*1]; local; manual |
-| 15 | Source: ; ; false; ReadFileEx; ; ; Argument[*1]; local; manual |
-| 16 | Source: ; ; false; WinHttpQueryHeaders; ; ; Argument[*3]; remote; manual |
-| 17 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[**8]; remote; manual |
-| 18 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*5]; remote; manual |
-| 19 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*6]; remote; manual |
-| 20 | Source: ; ; false; WinHttpReadData; ; ; Argument[*1]; remote; manual |
-| 21 | Source: ; ; false; WinHttpReadDataEx; ; ; Argument[*1]; remote; manual |
-| 22 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
-| 23 | Source: Azure::Core::Http; RawResponse; true; ExtractBodyStream; ; ; ReturnValue[*]; remote; manual |
-| 24 | Source: Azure::Core::Http; RawResponse; true; GetBody; ; ; ReturnValue[*]; remote; manual |
-| 25 | Source: Azure::Core::Http; RawResponse; true; GetHeaders; ; ; ReturnValue[*]; remote; manual |
-| 26 | Source: Azure::Core::Http; Request; true; GetBodyStream; ; ; ReturnValue[*]; remote; manual |
-| 27 | Source: Azure::Core::Http; Request; true; GetHeader; ; ; ReturnValue; remote; manual |
-| 28 | Source: Azure::Core::Http; Request; true; GetHeaders; ; ; ReturnValue; remote; manual |
-| 29 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
-| 30 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
-| 31 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
-| 32 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
-| 33 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
-| 34 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
-| 35 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 36 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 37 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 38 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
-| 39 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 40 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
-| 41 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 42 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 43 | Summary: ; ; false; WinHttpCrackUrl; ; ; Argument[*0]; Argument[*3]; taint; manual |
-| 44 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
-| 45 | Summary: ; ; false; callWithNonTypeTemplate; (const T &); ; Argument[*0]; ReturnValue; value; manual |
-| 46 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
-| 47 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
-| 48 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
-| 49 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
-| 50 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
-| 51 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
-| 52 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
-| 53 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
-| 54 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
+| 6 | Source: ; ; false; HttpReceiveClientCertificate; ; ; Argument[*3]; remote; manual |
+| 7 | Source: ; ; false; HttpReceiveHttpRequest; ; ; Argument[*3]; remote; manual |
+| 8 | Source: ; ; false; HttpReceiveRequestEntityBody; ; ; Argument[*3]; remote; manual |
+| 9 | Source: ; ; false; MapViewOfFile2; ; ; ReturnValue[*]; local; manual |
+| 10 | Source: ; ; false; MapViewOfFile3; ; ; ReturnValue[*]; local; manual |
+| 11 | Source: ; ; false; MapViewOfFile3FromApp; ; ; ReturnValue[*]; local; manual |
+| 12 | Source: ; ; false; MapViewOfFile; ; ; ReturnValue[*]; local; manual |
+| 13 | Source: ; ; false; MapViewOfFileEx; ; ; ReturnValue[*]; local; manual |
+| 14 | Source: ; ; false; MapViewOfFileFromApp; ; ; ReturnValue[*]; local; manual |
+| 15 | Source: ; ; false; MapViewOfFileNuma2; ; ; ReturnValue[*]; local; manual |
+| 16 | Source: ; ; false; NtReadFile; ; ; Argument[*5]; local; manual |
+| 17 | Source: ; ; false; ReadFile; ; ; Argument[*1]; local; manual |
+| 18 | Source: ; ; false; ReadFileEx; ; ; Argument[*1]; local; manual |
+| 19 | Source: ; ; false; WinHttpQueryHeaders; ; ; Argument[*3]; remote; manual |
+| 20 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[**8]; remote; manual |
+| 21 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*5]; remote; manual |
+| 22 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*6]; remote; manual |
+| 23 | Source: ; ; false; WinHttpReadData; ; ; Argument[*1]; remote; manual |
+| 24 | Source: ; ; false; WinHttpReadDataEx; ; ; Argument[*1]; remote; manual |
+| 25 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
+| 26 | Source: Azure::Core::Http; RawResponse; true; ExtractBodyStream; ; ; ReturnValue[*]; remote; manual |
+| 27 | Source: Azure::Core::Http; RawResponse; true; GetBody; ; ; ReturnValue[*]; remote; manual |
+| 28 | Source: Azure::Core::Http; RawResponse; true; GetHeaders; ; ; ReturnValue[*]; remote; manual |
+| 29 | Source: Azure::Core::Http; Request; true; GetBodyStream; ; ; ReturnValue[*]; remote; manual |
+| 30 | Source: Azure::Core::Http; Request; true; GetHeader; ; ; ReturnValue; remote; manual |
+| 31 | Source: Azure::Core::Http; Request; true; GetHeaders; ; ; ReturnValue; remote; manual |
+| 32 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
+| 33 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
+| 34 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
+| 35 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
+| 36 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
+| 37 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
+| 38 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 39 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 40 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 41 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
+| 42 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 43 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
+| 44 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 45 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 46 | Summary: ; ; false; WinHttpCrackUrl; ; ; Argument[*0]; Argument[*3]; taint; manual |
+| 47 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
+| 48 | Summary: ; ; false; callWithNonTypeTemplate; (const T &); ; Argument[*0]; ReturnValue; value; manual |
+| 49 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
+| 50 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
+| 51 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
+| 52 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
+| 53 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 54 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 55 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
+| 56 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 57 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
edges
-| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:54 |
-| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:29 |
-| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:29 Sink:MaD:2 |
+| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:57 |
+| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 |
+| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 |
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:100:64:100:71 | *send_str | provenance | TaintFunction |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
-| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:54 |
-| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:53 |
-| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:50 |
-| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:51 |
-| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:52 |
+| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:57 |
+| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:56 |
+| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:53 |
+| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:54 |
+| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:55 |
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
-| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:26 |
+| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
-| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:50 |
+| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:53 |
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
-| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:51 |
+| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:54 |
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
-| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:52 |
+| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:55 |
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
-| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:273:62:273:64 | call to GetHeaders | provenance | Src:MaD:25 |
+| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:273:62:273:64 | call to GetHeaders | provenance | Src:MaD:28 |
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:10:274:29 | call to operator[] | provenance | |
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:14:274:29 | call to operator[] | provenance | |
-| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:277:45:277:47 | call to GetBody | provenance | Src:MaD:24 |
+| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:277:45:277:47 | call to GetBody | provenance | Src:MaD:27 |
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
| azure.cpp:278:10:278:13 | body | azure.cpp:278:10:278:13 | body | provenance | |
-| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:23 |
+| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 |
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
-| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:52 |
+| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:55 |
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
-| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:53 |
+| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:56 |
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
-| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:27 |
+| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 |
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
| azure.cpp:290:10:290:20 | headerValue | azure.cpp:290:10:290:20 | headerValue | provenance | |
-| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:293:58:293:67 | call to GetHeaders | provenance | Src:MaD:28 |
+| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:293:58:293:67 | call to GetHeaders | provenance | Src:MaD:31 |
| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:294:38:294:53 | call to operator[] | provenance | TaintFunction |
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
| azure.cpp:295:10:295:20 | contentType | azure.cpp:295:10:295:20 | contentType | provenance | |
-| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:48 |
-| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:47 |
-| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:49 |
+| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:51 |
+| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:50 |
+| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:52 |
| test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | |
| test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | |
-| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:22 |
+| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:25 |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:1 |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:17:24:17:24 | x | provenance | |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:21:27:21:27 | x | provenance | |
@@ -127,15 +130,15 @@ edges
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | |
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:1 |
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | |
-| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:48 |
+| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:51 |
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | |
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:1 |
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | |
-| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:47 |
+| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:50 |
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | |
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:1 |
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | |
-| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:49 |
+| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:52 |
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:1 |
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | |
@@ -143,16 +146,16 @@ edges
| test.cpp:46:30:46:32 | *arg [x] | test.cpp:47:12:47:19 | *arg [x] | provenance | |
| test.cpp:47:12:47:19 | *arg [x] | test.cpp:48:13:48:13 | *s [x] | provenance | |
| test.cpp:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:1 |
-| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:46 |
+| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:49 |
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | |
| test.cpp:56:2:56:2 | *s [post update] [x] | test.cpp:59:55:59:64 | *& ... [x] | provenance | |
| test.cpp:56:2:56:18 | ... = ... | test.cpp:56:2:56:2 | *s [post update] [x] | provenance | |
-| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:22 |
+| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:25 |
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | |
-| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
-| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
-| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
-| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
+| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:47 |
+| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:47 |
+| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:47 |
+| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:47 |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | |
@@ -161,7 +164,7 @@ edges
| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:1 |
| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:1 |
| test.cpp:88:22:88:22 | y | test.cpp:89:11:89:11 | y | provenance | Sink:MaD:1 |
-| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:22 |
+| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:25 |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:97:26:97:26 | x | provenance | |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:101:26:101:26 | x | provenance | |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:103:63:103:63 | x | provenance | |
@@ -170,28 +173,28 @@ edges
| test.cpp:101:26:101:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:103:63:103:63 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:104:62:104:62 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
-| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:45 |
-| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:22 |
+| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:48 |
+| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:25 |
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:118:44:118:44 | *x | provenance | |
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | |
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
-| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:45 |
-| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:30 |
+| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:48 |
+| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:33 |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:27:36:27:38 | *cmd | provenance | |
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | |
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:30:8:30:15 | * ... | provenance | |
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | provenance | |
-| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:30 |
+| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:33 |
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:4 |
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:36:10:36:13 | * ... | provenance | |
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | windows.cpp:41:10:41:13 | * ... | provenance | Src:MaD:5 |
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | |
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | |
-| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:34 |
-| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:34 |
+| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:37 |
+| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:37 |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | |
@@ -207,43 +210,43 @@ edges
| windows.cpp:159:12:159:55 | hEvent | windows.cpp:160:8:160:8 | c | provenance | |
| windows.cpp:159:35:159:46 | *lpOverlapped [hEvent] | windows.cpp:159:12:159:55 | hEvent | provenance | |
| windows.cpp:159:35:159:46 | *lpOverlapped [hEvent] | windows.cpp:159:12:159:55 | hEvent | provenance | |
-| windows.cpp:168:35:168:40 | ReadFile output argument | windows.cpp:170:10:170:16 | * ... | provenance | Src:MaD:14 |
-| windows.cpp:177:23:177:28 | ReadFileEx output argument | windows.cpp:179:10:179:16 | * ... | provenance | Src:MaD:15 |
-| windows.cpp:189:21:189:26 | ReadFile output argument | windows.cpp:190:5:190:56 | *... = ... | provenance | Src:MaD:14 |
+| windows.cpp:168:35:168:40 | ReadFile output argument | windows.cpp:170:10:170:16 | * ... | provenance | Src:MaD:17 |
+| windows.cpp:177:23:177:28 | ReadFileEx output argument | windows.cpp:179:10:179:16 | * ... | provenance | Src:MaD:18 |
+| windows.cpp:189:21:189:26 | ReadFile output argument | windows.cpp:190:5:190:56 | *... = ... | provenance | Src:MaD:17 |
| windows.cpp:190:5:190:14 | *overlapped [post update] [*hEvent] | windows.cpp:192:53:192:63 | *& ... [*hEvent] | provenance | |
| windows.cpp:190:5:190:56 | *... = ... | windows.cpp:190:5:190:14 | *overlapped [post update] [*hEvent] | provenance | |
| windows.cpp:192:53:192:63 | *& ... [*hEvent] | windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | provenance | |
-| windows.cpp:198:21:198:26 | ReadFile output argument | windows.cpp:199:5:199:57 | ... = ... | provenance | Src:MaD:14 |
+| windows.cpp:198:21:198:26 | ReadFile output argument | windows.cpp:199:5:199:57 | ... = ... | provenance | Src:MaD:17 |
| windows.cpp:199:5:199:14 | *overlapped [post update] [hEvent] | windows.cpp:201:53:201:63 | *& ... [hEvent] | provenance | |
| windows.cpp:199:5:199:57 | ... = ... | windows.cpp:199:5:199:14 | *overlapped [post update] [hEvent] | provenance | |
| windows.cpp:201:53:201:63 | *& ... [hEvent] | windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | provenance | |
-| windows.cpp:209:84:209:89 | NtReadFile output argument | windows.cpp:211:10:211:16 | * ... | provenance | Src:MaD:13 |
-| windows.cpp:286:23:286:35 | *call to MapViewOfFile | windows.cpp:286:23:286:35 | *call to MapViewOfFile | provenance | Src:MaD:9 |
+| windows.cpp:209:84:209:89 | NtReadFile output argument | windows.cpp:211:10:211:16 | * ... | provenance | Src:MaD:16 |
+| windows.cpp:286:23:286:35 | *call to MapViewOfFile | windows.cpp:286:23:286:35 | *call to MapViewOfFile | provenance | Src:MaD:12 |
| windows.cpp:286:23:286:35 | *call to MapViewOfFile | windows.cpp:287:20:287:52 | *pMapView | provenance | |
| windows.cpp:287:20:287:52 | *pMapView | windows.cpp:289:10:289:16 | * ... | provenance | |
-| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | provenance | Src:MaD:6 |
+| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | provenance | Src:MaD:9 |
| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | windows.cpp:294:20:294:52 | *pMapView | provenance | |
| windows.cpp:294:20:294:52 | *pMapView | windows.cpp:296:10:296:16 | * ... | provenance | |
-| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | provenance | Src:MaD:7 |
+| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | provenance | Src:MaD:10 |
| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | windows.cpp:303:20:303:52 | *pMapView | provenance | |
| windows.cpp:303:20:303:52 | *pMapView | windows.cpp:305:10:305:16 | * ... | provenance | |
-| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | provenance | Src:MaD:8 |
+| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | provenance | Src:MaD:11 |
| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | windows.cpp:312:20:312:52 | *pMapView | provenance | |
| windows.cpp:312:20:312:52 | *pMapView | windows.cpp:314:10:314:16 | * ... | provenance | |
-| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | provenance | Src:MaD:10 |
+| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | provenance | Src:MaD:13 |
| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | windows.cpp:319:20:319:52 | *pMapView | provenance | |
| windows.cpp:319:20:319:52 | *pMapView | windows.cpp:321:10:321:16 | * ... | provenance | |
-| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | provenance | Src:MaD:11 |
+| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | provenance | Src:MaD:14 |
| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | windows.cpp:326:20:326:52 | *pMapView | provenance | |
| windows.cpp:326:20:326:52 | *pMapView | windows.cpp:328:10:328:16 | * ... | provenance | |
-| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:12 |
+| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:15 |
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:333:20:333:52 | *pMapView | provenance | |
| windows.cpp:333:20:333:52 | *pMapView | windows.cpp:335:10:335:16 | * ... | provenance | |
-| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:33 |
+| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:36 |
| windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | |
-| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:31 |
+| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:34 |
| windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | |
-| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:32 |
+| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:35 |
| windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | |
| windows.cpp:403:26:403:36 | *lpParameter [x] | windows.cpp:405:10:405:25 | *lpParameter [x] | provenance | |
| windows.cpp:405:10:405:25 | *lpParameter [x] | windows.cpp:406:8:406:8 | *s [x] | provenance | |
@@ -262,17 +265,17 @@ edges
| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | provenance | |
| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | provenance | |
| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | provenance | |
-| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:39 |
-| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:35 |
-| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:36 |
-| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:37 |
+| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:42 |
+| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:38 |
+| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:39 |
+| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:40 |
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | provenance | |
-| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:38 |
+| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:41 |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | provenance | |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | provenance | |
-| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:41 |
-| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:42 |
-| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:40 |
+| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:44 |
+| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:45 |
+| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:43 |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | provenance | |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:533:11:533:16 | call to source | provenance | |
@@ -284,51 +287,68 @@ edges
| windows.cpp:533:11:533:16 | call to source | windows.cpp:573:40:573:41 | *& ... | provenance | |
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | windows.cpp:538:10:538:23 | access to array | provenance | |
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | provenance | |
-| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:39 |
+| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:42 |
| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | windows.cpp:543:10:543:23 | access to array | provenance | |
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | provenance | |
-| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:35 |
+| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:38 |
| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | windows.cpp:548:10:548:23 | access to array | provenance | |
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | provenance | |
-| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:36 |
+| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:39 |
| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | windows.cpp:553:10:553:23 | access to array | provenance | |
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | provenance | |
-| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:37 |
+| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:40 |
| windows.cpp:559:5:559:24 | ... = ... | windows.cpp:561:39:561:44 | *buffer | provenance | |
| windows.cpp:559:17:559:24 | call to source | windows.cpp:559:5:559:24 | ... = ... | provenance | |
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:562:10:562:19 | *src_string [*Buffer] | provenance | |
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:563:40:563:50 | *& ... [*Buffer] | provenance | |
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | provenance | |
-| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:40 |
+| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:43 |
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:10:562:29 | access to array | provenance | |
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:21:562:26 | *Buffer | provenance | |
| windows.cpp:562:21:562:26 | *Buffer | windows.cpp:562:10:562:29 | access to array | provenance | |
| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | windows.cpp:564:10:564:20 | *dest_string [*Buffer] | provenance | |
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | provenance | |
-| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:38 |
+| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:41 |
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:10:564:30 | access to array | provenance | |
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:22:564:27 | *Buffer | provenance | |
| windows.cpp:564:22:564:27 | *Buffer | windows.cpp:564:10:564:30 | access to array | provenance | |
| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | windows.cpp:569:10:569:23 | access to array | provenance | |
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | provenance | |
-| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:41 |
+| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:44 |
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | windows.cpp:574:10:574:23 | access to array | provenance | |
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | provenance | |
-| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:42 |
-| windows.cpp:645:45:645:50 | WinHttpReadData output argument | windows.cpp:647:10:647:16 | * ... | provenance | Src:MaD:20 |
-| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | windows.cpp:654:10:654:16 | * ... | provenance | Src:MaD:21 |
-| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | windows.cpp:661:10:661:16 | * ... | provenance | Src:MaD:16 |
-| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | windows.cpp:673:10:673:29 | * ... | provenance | Src:MaD:18 |
-| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | windows.cpp:671:10:671:16 | * ... | provenance | Src:MaD:19 |
-| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | windows.cpp:675:10:675:27 | * ... | provenance | Src:MaD:17 |
-| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | provenance | MaD:43 |
+| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:45 |
+| windows.cpp:645:45:645:50 | WinHttpReadData output argument | windows.cpp:647:10:647:16 | * ... | provenance | Src:MaD:23 |
+| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | windows.cpp:654:10:654:16 | * ... | provenance | Src:MaD:24 |
+| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | windows.cpp:661:10:661:16 | * ... | provenance | Src:MaD:19 |
+| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | windows.cpp:673:10:673:29 | * ... | provenance | Src:MaD:21 |
+| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | windows.cpp:671:10:671:16 | * ... | provenance | Src:MaD:22 |
+| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | windows.cpp:675:10:675:27 | * ... | provenance | Src:MaD:20 |
+| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | provenance | MaD:46 |
| windows.cpp:728:5:728:28 | ... = ... | windows.cpp:729:35:729:35 | *x | provenance | |
| windows.cpp:728:12:728:28 | call to source | windows.cpp:728:5:728:28 | ... = ... | provenance | |
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | provenance | |
-| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | provenance | MaD:43 |
+| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | provenance | MaD:46 |
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:731:10:731:36 | * ... | provenance | |
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:733:10:733:35 | * ... | provenance | |
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:735:10:735:37 | * ... | provenance | |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:901:15:901:53 | *& ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:905:10:905:31 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:907:10:907:42 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:909:10:909:57 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:911:10:911:60 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:912:54:912:63 | FileHandle | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:914:10:914:70 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:916:10:916:72 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:918:10:918:64 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:920:10:920:51 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:922:10:922:52 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:924:10:924:63 | * ... | provenance | Src:MaD:7 |
+| windows.cpp:901:15:901:53 | *& ... | windows.cpp:903:10:903:11 | * ... | provenance | |
+| windows.cpp:929:70:929:75 | HttpReceiveRequestEntityBody output argument | windows.cpp:931:10:931:16 | * ... | provenance | Src:MaD:8 |
+| windows.cpp:936:70:936:78 | HttpReceiveClientCertificate output argument | windows.cpp:937:15:937:48 | *& ... | provenance | Src:MaD:6 |
+| windows.cpp:936:70:936:78 | HttpReceiveClientCertificate output argument | windows.cpp:941:10:941:31 | * ... | provenance | Src:MaD:6 |
+| windows.cpp:937:15:937:48 | *& ... | windows.cpp:939:10:939:11 | * ... | provenance | |
nodes
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer |
| asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer |
@@ -636,6 +656,26 @@ nodes
| windows.cpp:731:10:731:36 | * ... | semmle.label | * ... |
| windows.cpp:733:10:733:35 | * ... | semmle.label | * ... |
| windows.cpp:735:10:735:37 | * ... | semmle.label | * ... |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | semmle.label | HttpReceiveHttpRequest output argument |
+| windows.cpp:901:15:901:53 | *& ... | semmle.label | *& ... |
+| windows.cpp:903:10:903:11 | * ... | semmle.label | * ... |
+| windows.cpp:905:10:905:31 | * ... | semmle.label | * ... |
+| windows.cpp:907:10:907:42 | * ... | semmle.label | * ... |
+| windows.cpp:909:10:909:57 | * ... | semmle.label | * ... |
+| windows.cpp:911:10:911:60 | * ... | semmle.label | * ... |
+| windows.cpp:912:54:912:63 | FileHandle | semmle.label | FileHandle |
+| windows.cpp:914:10:914:70 | * ... | semmle.label | * ... |
+| windows.cpp:916:10:916:72 | * ... | semmle.label | * ... |
+| windows.cpp:918:10:918:64 | * ... | semmle.label | * ... |
+| windows.cpp:920:10:920:51 | * ... | semmle.label | * ... |
+| windows.cpp:922:10:922:52 | * ... | semmle.label | * ... |
+| windows.cpp:924:10:924:63 | * ... | semmle.label | * ... |
+| windows.cpp:929:70:929:75 | HttpReceiveRequestEntityBody output argument | semmle.label | HttpReceiveRequestEntityBody output argument |
+| windows.cpp:931:10:931:16 | * ... | semmle.label | * ... |
+| windows.cpp:936:70:936:78 | HttpReceiveClientCertificate output argument | semmle.label | HttpReceiveClientCertificate output argument |
+| windows.cpp:937:15:937:48 | *& ... | semmle.label | *& ... |
+| windows.cpp:939:10:939:11 | * ... | semmle.label | * ... |
+| windows.cpp:941:10:941:31 | * ... | semmle.label | * ... |
subpaths
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | azure.cpp:257:16:257:21 | Read output argument |
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected
index c683d8539a07..b46aa87af6fe 100644
--- a/cpp/ql/test/library-tests/dataflow/external-models/sources.expected
+++ b/cpp/ql/test/library-tests/dataflow/external-models/sources.expected
@@ -32,3 +32,6 @@
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | remote |
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | remote |
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | remote |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | remote |
+| windows.cpp:929:70:929:75 | HttpReceiveRequestEntityBody output argument | remote |
+| windows.cpp:936:70:936:78 | HttpReceiveClientCertificate output argument | remote |
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.ql b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.ql
index a162349b7cdf..63e6520c56f2 100644
--- a/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.ql
+++ b/cpp/ql/test/library-tests/dataflow/external-models/validatemodels.ql
@@ -1,2 +1,2 @@
import cpp
-import semmle.code.cpp.dataflow.ExternalFlow::CsvValidation
+import semmle.code.cpp.dataflow.ExternalFlow::ModelValidation
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp
index 2900af9034c8..f098f7344e43 100644
--- a/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp
+++ b/cpp/ql/test/library-tests/dataflow/external-models/windows.cpp
@@ -734,4 +734,210 @@ void test_winhttp_crack_url() {
sink(urlComponents.lpszExtraInfo);
sink(*urlComponents.lpszExtraInfo); // $ ir
}
+}
+
+using HTTP_REQUEST_ID = ULONGLONG;
+using HTTP_CONNECTION_ID = ULONGLONG;
+using HTTP_URL_CONTEXT = ULONGLONG;
+using HTTP_RAW_CONNECTION_ID = ULONGLONG;
+
+typedef struct _HTTP_VERSION {
+ USHORT MajorVersion;
+ USHORT MinorVersion;
+} HTTP_VERSION, *PHTTP_VERSION;
+
+typedef enum _HTTP_VERB {
+ HttpVerbUnparsed = 0
+} HTTP_VERB, *PHTTP_VERB;
+
+typedef struct _HTTP_COOKED_URL {
+ USHORT FullUrlLength;
+ USHORT HostLength;
+ USHORT AbsPathLength;
+ USHORT QueryStringLength;
+ PCWSTR pFullUrl;
+ PCWSTR pHost;
+ PCWSTR pAbsPath;
+ PCWSTR pQueryString;
+} HTTP_COOKED_URL, *PHTTP_COOKED_URL;
+
+typedef struct _HTTP_TRANSPORT_ADDRESS {
+ struct sockaddr* pRemoteAddress;
+ struct sockaddr* pLocalAddress;
+} HTTP_TRANSPORT_ADDRESS, *PHTTP_TRANSPORT_ADDRESS;
+
+typedef struct _HTTP_KNOWN_HEADER {
+ USHORT RawValueLength;
+ PCSTR pRawValue;
+} HTTP_KNOWN_HEADER, *PHTTP_KNOWN_HEADER;
+
+typedef struct _HTTP_UNKNOWN_HEADER {
+ USHORT NameLength;
+ USHORT RawValueLength;
+ PCSTR pName;
+ PCSTR pRawValue;
+} HTTP_UNKNOWN_HEADER, *PHTTP_UNKNOWN_HEADER;
+
+typedef struct _HTTP_REQUEST_HEADERS {
+ USHORT UnknownHeaderCount;
+ PHTTP_UNKNOWN_HEADER pUnknownHeaders;
+ USHORT TrailerCount;
+ PHTTP_UNKNOWN_HEADER pTrailers;
+ HTTP_KNOWN_HEADER KnownHeaders[41];
+} HTTP_REQUEST_HEADERS, *PHTTP_REQUEST_HEADERS;
+
+typedef struct _HTTP_BYTE_RANGE {
+ ULONGLONG StartingOffset;
+ ULONGLONG Length;
+} HTTP_BYTE_RANGE, *PHTTP_BYTE_RANGE;
+
+typedef struct _HTTP_DATA_CHUNK {
+ int DataChunkType;
+ union {
+ struct {
+ PVOID pBuffer;
+ ULONG BufferLength;
+ } FromMemory;
+ struct {
+ HTTP_BYTE_RANGE ByteRange;
+ HANDLE FileHandle;
+ } FromFileHandle;
+ struct {
+ USHORT FragmentNameLength;
+ PCWSTR pFragmentName;
+ } FromFragmentCache;
+ struct {
+ HTTP_BYTE_RANGE ByteRange;
+ PCWSTR pFragmentName;
+ } FromFragmentCacheEx;
+ struct {
+ USHORT TrailerCount;
+ PHTTP_UNKNOWN_HEADER pTrailers;
+ } Trailers;
+ };
+} HTTP_DATA_CHUNK, *PHTTP_DATA_CHUNK;
+
+typedef struct _HTTP_SSL_CLIENT_CERT_INFO {
+ ULONG CertFlags;
+ ULONG CertEncodedSize;
+ char* pCertEncoded;
+ HANDLE Token;
+ BOOL CertDeniedByMapper;
+} HTTP_SSL_CLIENT_CERT_INFO, *PHTTP_SSL_CLIENT_CERT_INFO;
+
+typedef struct _HTTP_SSL_INFO {
+ USHORT ServerCertKeySize;
+ USHORT ConnectionKeySize;
+ ULONG ServerCertIssuerSize;
+ ULONG ServerCertSubjectSize;
+ PCSTR pServerCertIssuer;
+ PCSTR pServerCertSubject;
+ PHTTP_SSL_CLIENT_CERT_INFO pClientCertInfo;
+ ULONG SslClientCertNegotiated;
+} HTTP_SSL_INFO, *PHTTP_SSL_INFO;
+
+typedef struct _HTTP_REQUEST_V1 {
+ ULONG Flags;
+ HTTP_CONNECTION_ID ConnectionId;
+ HTTP_REQUEST_ID RequestId;
+ HTTP_URL_CONTEXT UrlContext;
+ HTTP_VERSION Version;
+ HTTP_VERB Verb;
+ USHORT UnknownVerbLength;
+ USHORT RawUrlLength;
+ PCSTR pUnknownVerb;
+ PCSTR pRawUrl;
+ HTTP_COOKED_URL CookedUrl;
+ HTTP_TRANSPORT_ADDRESS Address;
+ HTTP_REQUEST_HEADERS Headers;
+ ULONGLONG BytesReceived;
+ USHORT EntityChunkCount;
+ PHTTP_DATA_CHUNK pEntityChunks;
+ HTTP_RAW_CONNECTION_ID RawConnectionId;
+ PHTTP_SSL_INFO pSslInfo;
+} HTTP_REQUEST_V1, *PHTTP_REQUEST_V1;
+
+using HTTP_REQUEST = HTTP_REQUEST_V1;
+using PHTTP_REQUEST = PHTTP_REQUEST_V1;
+
+ULONG HttpReceiveHttpRequest(
+ HANDLE RequestQueueHandle,
+ HTTP_REQUEST_ID RequestId,
+ ULONG Flags,
+ PHTTP_REQUEST RequestBuffer,
+ ULONG RequestBufferLength,
+ PULONG BytesReturned,
+ LPOVERLAPPED Overlapped
+);
+
+ULONG HttpReceiveRequestEntityBody(
+ HANDLE RequestQueueHandle,
+ HTTP_REQUEST_ID RequestId,
+ ULONG Flags,
+ PVOID EntityBuffer,
+ ULONG EntityBufferLength,
+ PULONG BytesReturned,
+ LPOVERLAPPED Overlapped
+);
+
+ULONG HttpReceiveClientCertificate(
+ HANDLE RequestQueueHandle,
+ HTTP_CONNECTION_ID ConnectionId,
+ ULONG Flags,
+ PHTTP_SSL_CLIENT_CERT_INFO SslClientCertInfo,
+ ULONG SslClientCertInfoSize,
+ PULONG BytesReceived,
+ LPOVERLAPPED Overlapped
+);
+
+void sink(PCWSTR);
+void sink(HANDLE);
+
+void test_http_server_api(HANDLE hRequestQueue) {
+ {
+ HTTP_REQUEST requestBuffer;
+ ULONG bytesReturned;
+ ULONG result = HttpReceiveHttpRequest(hRequestQueue, 0, 0, &requestBuffer, sizeof(requestBuffer), &bytesReturned, nullptr);
+ char* p = reinterpret_cast(&requestBuffer);
+ sink(p);
+ sink(*p); // $ ir
+ sink(requestBuffer.pRawUrl);
+ sink(*requestBuffer.pRawUrl); // $ ir
+ sink(requestBuffer.CookedUrl.pFullUrl);
+ sink(*requestBuffer.CookedUrl.pFullUrl); // $ ir
+ sink(requestBuffer.Headers.KnownHeaders[0].pRawValue);
+ sink(*requestBuffer.Headers.KnownHeaders[0].pRawValue); // $ ir
+ sink(requestBuffer.Headers.pUnknownHeaders[0].pRawValue);
+ sink(*requestBuffer.Headers.pUnknownHeaders[0].pRawValue); // $ ir
+ sink(requestBuffer.pEntityChunks->FromFileHandle.FileHandle); // $ ir
+ sink(requestBuffer.pEntityChunks->FromFragmentCache.pFragmentName);
+ sink(*requestBuffer.pEntityChunks->FromFragmentCache.pFragmentName); // $ ir
+ sink(requestBuffer.pEntityChunks->FromFragmentCacheEx.pFragmentName);
+ sink(*requestBuffer.pEntityChunks->FromFragmentCacheEx.pFragmentName); // $ ir
+ sink(requestBuffer.pEntityChunks->FromMemory.pBuffer);
+ sink(*(char*)requestBuffer.pEntityChunks->FromMemory.pBuffer); // $ ir
+ sink(requestBuffer.pSslInfo->pServerCertIssuer);
+ sink(*requestBuffer.pSslInfo->pServerCertIssuer); // $ ir
+ sink(requestBuffer.pSslInfo->pServerCertSubject);
+ sink(*requestBuffer.pSslInfo->pServerCertSubject); // $ ir
+ sink(requestBuffer.pSslInfo->pClientCertInfo->pCertEncoded);
+ sink(*requestBuffer.pSslInfo->pClientCertInfo->pCertEncoded); // $ ir
+ }
+ {
+ char buffer[1024];
+ ULONG bytesReturned;
+ ULONG result = HttpReceiveRequestEntityBody(hRequestQueue, 0, 0, buffer, sizeof(buffer), &bytesReturned, nullptr);
+ sink(buffer);
+ sink(*buffer); // $ ir
+ }
+ {
+ HTTP_SSL_CLIENT_CERT_INFO certInfo;
+ ULONG bytesReceived;
+ ULONG result = HttpReceiveClientCertificate(hRequestQueue, 0, 0, &certInfo, sizeof(certInfo), &bytesReceived, nullptr);
+ char* p = reinterpret_cast(&certInfo);
+ sink(p);
+ sink(*p); // $ ir
+ sink(certInfo.pCertEncoded);
+ sink(*certInfo.pCertEncoded); // $ ir
+ }
}
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/dataflow/fields/C.cpp b/cpp/ql/test/library-tests/dataflow/fields/C.cpp
index 6e5165caa9a1..0c0929282729 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/C.cpp
+++ b/cpp/ql/test/library-tests/dataflow/fields/C.cpp
@@ -27,7 +27,7 @@ class C
void func()
{
sink(s1); // $ ast,ir
- sink(s2); // $ MISSING: ast,ir
+ sink(s2); // $ ir MISSING: ast
sink(s3); // $ ast,ir
sink(s4); // $ MISSING: ast,ir
}
diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected
index cc8cd2826bf3..2e38382150f4 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected
+++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected
@@ -187,23 +187,34 @@ edges
| B.cpp:46:7:46:10 | *this [post update] [*box1, elem2] | B.cpp:44:5:44:8 | *this [Return] [*box1, elem2] | provenance | |
| B.cpp:46:7:46:21 | *... = ... [elem1] | B.cpp:46:7:46:10 | *this [post update] [*box1, elem1] | provenance | |
| B.cpp:46:7:46:21 | *... = ... [elem2] | B.cpp:46:7:46:10 | *this [post update] [*box1, elem2] | provenance | |
+| C.cpp:10:15:10:16 | *s2 [post update] [s2] | C.cpp:10:15:10:16 | *this [Return] [s2] | provenance | |
+| C.cpp:10:15:10:16 | *this [Return] [s2] | C.cpp:22:3:22:3 | s2 output argument [s2] | provenance | |
+| C.cpp:10:20:10:29 | new | C.cpp:10:15:10:16 | *s2 [post update] [s2] | provenance | |
+| C.cpp:10:20:10:29 | new | C.cpp:10:20:10:29 | new | provenance | |
| C.cpp:18:12:18:18 | *new [s1] | C.cpp:19:5:19:5 | *c [s1] | provenance | |
+| C.cpp:18:12:18:18 | *new [s2] | C.cpp:19:5:19:5 | *c [s2] | provenance | |
| C.cpp:18:12:18:18 | *new [s3] | C.cpp:19:5:19:5 | *c [s3] | provenance | |
| C.cpp:18:12:18:18 | call to C [s1] | C.cpp:18:12:18:18 | *new [s1] | provenance | |
+| C.cpp:18:12:18:18 | call to C [s2] | C.cpp:18:12:18:18 | *new [s2] | provenance | |
| C.cpp:18:12:18:18 | call to C [s3] | C.cpp:18:12:18:18 | *new [s3] | provenance | |
| C.cpp:19:5:19:5 | *c [s1] | C.cpp:27:8:27:11 | *this [s1] | provenance | |
+| C.cpp:19:5:19:5 | *c [s2] | C.cpp:27:8:27:11 | *this [s2] | provenance | |
| C.cpp:19:5:19:5 | *c [s3] | C.cpp:27:8:27:11 | *this [s3] | provenance | |
| C.cpp:22:3:22:3 | *C [post update] [s1] | C.cpp:22:3:22:3 | *this [Return] [s1] | provenance | |
| C.cpp:22:3:22:3 | *this [Return] [s1] | C.cpp:18:12:18:18 | call to C [s1] | provenance | |
+| C.cpp:22:3:22:3 | *this [Return] [s2] | C.cpp:18:12:18:18 | call to C [s2] | provenance | |
| C.cpp:22:3:22:3 | *this [Return] [s3] | C.cpp:18:12:18:18 | call to C [s3] | provenance | |
+| C.cpp:22:3:22:3 | s2 output argument [s2] | C.cpp:22:3:22:3 | *this [Return] [s2] | provenance | |
| C.cpp:22:12:22:21 | new | C.cpp:22:3:22:3 | *C [post update] [s1] | provenance | |
| C.cpp:22:12:22:21 | new | C.cpp:22:12:22:21 | new | provenance | |
| C.cpp:24:5:24:8 | *this [post update] [s3] | C.cpp:22:3:22:3 | *this [Return] [s3] | provenance | |
| C.cpp:24:5:24:25 | ... = ... | C.cpp:24:5:24:8 | *this [post update] [s3] | provenance | |
| C.cpp:24:16:24:25 | new | C.cpp:24:5:24:25 | ... = ... | provenance | |
| C.cpp:27:8:27:11 | *this [s1] | C.cpp:29:10:29:11 | *this [s1] | provenance | |
+| C.cpp:27:8:27:11 | *this [s2] | C.cpp:30:10:30:11 | *this [s2] | provenance | |
| C.cpp:27:8:27:11 | *this [s3] | C.cpp:31:10:31:11 | *this [s3] | provenance | |
| C.cpp:29:10:29:11 | *this [s1] | C.cpp:29:10:29:11 | s1 | provenance | |
+| C.cpp:30:10:30:11 | *this [s2] | C.cpp:30:10:30:11 | s2 | provenance | |
| C.cpp:31:10:31:11 | *this [s3] | C.cpp:31:10:31:11 | s3 | provenance | |
| D.cpp:10:11:10:17 | *this [elem] | D.cpp:10:30:10:33 | *this [elem] | provenance | |
| D.cpp:10:30:10:33 | *this [elem] | D.cpp:10:30:10:33 | elem | provenance | |
@@ -1116,24 +1127,36 @@ nodes
| B.cpp:46:7:46:10 | *this [post update] [*box1, elem2] | semmle.label | *this [post update] [*box1, elem2] |
| B.cpp:46:7:46:21 | *... = ... [elem1] | semmle.label | *... = ... [elem1] |
| B.cpp:46:7:46:21 | *... = ... [elem2] | semmle.label | *... = ... [elem2] |
+| C.cpp:10:15:10:16 | *s2 [post update] [s2] | semmle.label | *s2 [post update] [s2] |
+| C.cpp:10:15:10:16 | *this [Return] [s2] | semmle.label | *this [Return] [s2] |
+| C.cpp:10:20:10:29 | new | semmle.label | new |
+| C.cpp:10:20:10:29 | new | semmle.label | new |
| C.cpp:18:12:18:18 | *new [s1] | semmle.label | *new [s1] |
+| C.cpp:18:12:18:18 | *new [s2] | semmle.label | *new [s2] |
| C.cpp:18:12:18:18 | *new [s3] | semmle.label | *new [s3] |
| C.cpp:18:12:18:18 | call to C [s1] | semmle.label | call to C [s1] |
+| C.cpp:18:12:18:18 | call to C [s2] | semmle.label | call to C [s2] |
| C.cpp:18:12:18:18 | call to C [s3] | semmle.label | call to C [s3] |
| C.cpp:19:5:19:5 | *c [s1] | semmle.label | *c [s1] |
+| C.cpp:19:5:19:5 | *c [s2] | semmle.label | *c [s2] |
| C.cpp:19:5:19:5 | *c [s3] | semmle.label | *c [s3] |
| C.cpp:22:3:22:3 | *C [post update] [s1] | semmle.label | *C [post update] [s1] |
| C.cpp:22:3:22:3 | *this [Return] [s1] | semmle.label | *this [Return] [s1] |
+| C.cpp:22:3:22:3 | *this [Return] [s2] | semmle.label | *this [Return] [s2] |
| C.cpp:22:3:22:3 | *this [Return] [s3] | semmle.label | *this [Return] [s3] |
+| C.cpp:22:3:22:3 | s2 output argument [s2] | semmle.label | s2 output argument [s2] |
| C.cpp:22:12:22:21 | new | semmle.label | new |
| C.cpp:22:12:22:21 | new | semmle.label | new |
| C.cpp:24:5:24:8 | *this [post update] [s3] | semmle.label | *this [post update] [s3] |
| C.cpp:24:5:24:25 | ... = ... | semmle.label | ... = ... |
| C.cpp:24:16:24:25 | new | semmle.label | new |
| C.cpp:27:8:27:11 | *this [s1] | semmle.label | *this [s1] |
+| C.cpp:27:8:27:11 | *this [s2] | semmle.label | *this [s2] |
| C.cpp:27:8:27:11 | *this [s3] | semmle.label | *this [s3] |
| C.cpp:29:10:29:11 | *this [s1] | semmle.label | *this [s1] |
| C.cpp:29:10:29:11 | s1 | semmle.label | s1 |
+| C.cpp:30:10:30:11 | *this [s2] | semmle.label | *this [s2] |
+| C.cpp:30:10:30:11 | s2 | semmle.label | s2 |
| C.cpp:31:10:31:11 | *this [s3] | semmle.label | *this [s3] |
| C.cpp:31:10:31:11 | s3 | semmle.label | s3 |
| D.cpp:10:11:10:17 | *getElem | semmle.label | *getElem |
@@ -1958,6 +1981,7 @@ subpaths
| B.cpp:9:10:9:24 | elem1 | B.cpp:6:15:6:24 | new | B.cpp:9:10:9:24 | elem1 | elem1 flows from $@ | B.cpp:6:15:6:24 | new | new |
| B.cpp:19:10:19:24 | elem2 | B.cpp:15:15:15:27 | new | B.cpp:19:10:19:24 | elem2 | elem2 flows from $@ | B.cpp:15:15:15:27 | new | new |
| C.cpp:29:10:29:11 | s1 | C.cpp:22:12:22:21 | new | C.cpp:29:10:29:11 | s1 | s1 flows from $@ | C.cpp:22:12:22:21 | new | new |
+| C.cpp:30:10:30:11 | s2 | C.cpp:10:20:10:29 | new | C.cpp:30:10:30:11 | s2 | s2 flows from $@ | C.cpp:10:20:10:29 | new | new |
| C.cpp:31:10:31:11 | s3 | C.cpp:24:16:24:25 | new | C.cpp:31:10:31:11 | s3 | s3 flows from $@ | C.cpp:24:16:24:25 | new | new |
| D.cpp:22:10:22:33 | call to getElem | D.cpp:28:15:28:24 | new | D.cpp:22:10:22:33 | call to getElem | call to getElem flows from $@ | D.cpp:28:15:28:24 | new | new |
| D.cpp:22:10:22:33 | call to getElem | D.cpp:35:15:35:24 | new | D.cpp:22:10:22:33 | call to getElem | call to getElem flows from $@ | D.cpp:35:15:35:24 | new | new |
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/FlowSummaryNode.ql b/cpp/ql/test/library-tests/dataflow/models-as-data/FlowSummaryNode.ql
deleted file mode 100644
index 7b551515b460..000000000000
--- a/cpp/ql/test/library-tests/dataflow/models-as-data/FlowSummaryNode.ql
+++ /dev/null
@@ -1,20 +0,0 @@
-import testModels
-private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
-private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
-private import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes
-
-string describe(DataFlow::Node n) {
- n instanceof ParameterNode and result = "ParameterNode"
- or
- n instanceof PostUpdateNode and result = "PostUpdateNode"
- or
- n instanceof ArgumentNode and result = "ArgumentNode"
- or
- n instanceof ReturnNode and result = "ReturnNode"
- or
- n instanceof OutNode and result = "OutNode"
-}
-
-from FlowSummaryNode n
-select n, concat(describe(n), ", "), concat(n.getSummarizedCallable().toString(), ", "),
- concat(n.getEnclosingCallable().toString(), ", ")
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/SummaryCall.expected b/cpp/ql/test/library-tests/dataflow/models-as-data/SummaryCall.expected
deleted file mode 100644
index 54bd0ca489a4..000000000000
--- a/cpp/ql/test/library-tests/dataflow/models-as-data/SummaryCall.expected
+++ /dev/null
@@ -1,267 +0,0 @@
-summaryCalls
-| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0ReturnToReturn in madCallArg0ReturnToReturn |
-| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0ReturnToReturnFirst in madCallArg0ReturnToReturnFirst |
-| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0WithValue in madCallArg0WithValue |
-summarizedCallables
-| tests.cpp:144:5:144:19 | madArg0ToReturn |
-| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
-| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
-| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
-| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
-| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
-| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
-| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
-| tests.cpp:153:5:153:18 | madArgsComplex |
-| tests.cpp:154:5:154:14 | madArgsAny |
-| tests.cpp:155:5:155:28 | madAndImplementedComplex |
-| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
-| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
-| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
-| tests.cpp:163:13:163:32 | madArg0ToReturnField |
-| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
-| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
-| tests.cpp:284:7:284:19 | madArg0ToSelf |
-| tests.cpp:285:6:285:20 | madSelfToReturn |
-| tests.cpp:287:7:287:20 | madArg0ToField |
-| tests.cpp:288:6:288:21 | madFieldToReturn |
-| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
-| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
-| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
-| tests.cpp:436:6:436:25 | madCallArg0WithValue |
-| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
-| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
-| tests.cpp:471:5:471:17 | receive_array |
-sourceCallables
-| tests.cpp:3:5:3:10 | source |
-| tests.cpp:4:6:4:14 | sourcePtr |
-| tests.cpp:5:6:5:19 | sourceIndirect |
-| tests.cpp:6:6:6:9 | sink |
-| tests.cpp:6:15:6:17 | val |
-| tests.cpp:7:6:7:9 | sink |
-| tests.cpp:7:16:7:18 | ptr |
-| tests.cpp:11:5:11:18 | localMadSource |
-| tests.cpp:12:5:12:19 | remoteMadSource |
-| tests.cpp:13:5:13:14 | notASource |
-| tests.cpp:14:5:14:22 | localMadSourceVoid |
-| tests.cpp:15:5:15:25 | localMadSourceHasBody |
-| tests.cpp:16:6:16:28 | remoteMadSourceIndirect |
-| tests.cpp:17:7:17:35 | remoteMadSourceDoubleIndirect |
-| tests.cpp:18:6:18:32 | remoteMadSourceIndirectArg0 |
-| tests.cpp:18:39:18:39 | x |
-| tests.cpp:18:47:18:47 | y |
-| tests.cpp:19:6:19:32 | remoteMadSourceIndirectArg1 |
-| tests.cpp:19:39:19:39 | x |
-| tests.cpp:19:47:19:47 | y |
-| tests.cpp:20:5:20:22 | remoteMadSourceVar |
-| tests.cpp:21:6:21:31 | remoteMadSourceVarIndirect |
-| tests.cpp:24:6:24:28 | namespaceLocalMadSource |
-| tests.cpp:25:6:25:31 | namespaceLocalMadSourceVar |
-| tests.cpp:28:7:28:30 | namespace2LocalMadSource |
-| tests.cpp:31:6:31:19 | localMadSource |
-| tests.cpp:33:5:33:27 | namespaceLocalMadSource |
-| tests.cpp:35:6:35:17 | test_sources |
-| tests.cpp:50:6:50:6 | v |
-| tests.cpp:51:7:51:16 | v_indirect |
-| tests.cpp:52:6:52:13 | v_direct |
-| tests.cpp:63:6:63:6 | a |
-| tests.cpp:63:9:63:9 | b |
-| tests.cpp:63:12:63:12 | c |
-| tests.cpp:63:15:63:15 | d |
-| tests.cpp:75:6:75:6 | e |
-| tests.cpp:85:6:85:26 | remoteMadSourceParam0 |
-| tests.cpp:85:32:85:32 | x |
-| tests.cpp:92:6:92:16 | madSinkArg0 |
-| tests.cpp:92:22:92:22 | x |
-| tests.cpp:93:6:93:13 | notASink |
-| tests.cpp:93:19:93:19 | x |
-| tests.cpp:94:6:94:16 | madSinkArg1 |
-| tests.cpp:94:22:94:22 | x |
-| tests.cpp:94:29:94:29 | y |
-| tests.cpp:95:6:95:17 | madSinkArg01 |
-| tests.cpp:95:23:95:23 | x |
-| tests.cpp:95:30:95:30 | y |
-| tests.cpp:95:37:95:37 | z |
-| tests.cpp:96:6:96:17 | madSinkArg02 |
-| tests.cpp:96:23:96:23 | x |
-| tests.cpp:96:30:96:30 | y |
-| tests.cpp:96:37:96:37 | z |
-| tests.cpp:97:6:97:24 | madSinkIndirectArg0 |
-| tests.cpp:97:31:97:31 | x |
-| tests.cpp:98:6:98:30 | madSinkDoubleIndirectArg0 |
-| tests.cpp:98:38:98:38 | x |
-| tests.cpp:99:5:99:14 | madSinkVar |
-| tests.cpp:100:6:100:23 | madSinkVarIndirect |
-| tests.cpp:102:6:102:15 | test_sinks |
-| tests.cpp:116:6:116:6 | a |
-| tests.cpp:117:7:117:11 | a_ptr |
-| tests.cpp:132:6:132:18 | madSinkParam0 |
-| tests.cpp:132:24:132:24 | x |
-| tests.cpp:138:8:138:8 | operator= |
-| tests.cpp:138:8:138:8 | operator= |
-| tests.cpp:138:8:138:18 | MyContainer |
-| tests.cpp:139:6:139:10 | value |
-| tests.cpp:140:6:140:11 | value2 |
-| tests.cpp:141:7:141:9 | ptr |
-| tests.cpp:144:5:144:19 | madArg0ToReturn |
-| tests.cpp:144:25:144:25 | x |
-| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
-| tests.cpp:145:34:145:34 | x |
-| tests.cpp:146:5:146:15 | notASummary |
-| tests.cpp:146:21:146:21 | x |
-| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
-| tests.cpp:147:34:147:34 | x |
-| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
-| tests.cpp:148:34:148:34 | x |
-| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
-| tests.cpp:149:41:149:41 | x |
-| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
-| tests.cpp:150:37:150:37 | x |
-| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
-| tests.cpp:151:32:151:32 | x |
-| tests.cpp:151:40:151:40 | y |
-| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
-| tests.cpp:152:47:152:47 | x |
-| tests.cpp:152:55:152:55 | y |
-| tests.cpp:153:5:153:18 | madArgsComplex |
-| tests.cpp:153:25:153:25 | a |
-| tests.cpp:153:33:153:33 | b |
-| tests.cpp:153:40:153:40 | c |
-| tests.cpp:153:47:153:47 | d |
-| tests.cpp:154:5:154:14 | madArgsAny |
-| tests.cpp:154:20:154:20 | a |
-| tests.cpp:154:28:154:28 | b |
-| tests.cpp:155:5:155:28 | madAndImplementedComplex |
-| tests.cpp:155:34:155:34 | a |
-| tests.cpp:155:41:155:41 | b |
-| tests.cpp:155:48:155:48 | c |
-| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
-| tests.cpp:160:38:160:39 | mc |
-| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
-| tests.cpp:161:47:161:48 | mc |
-| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
-| tests.cpp:162:46:162:47 | mc |
-| tests.cpp:163:13:163:32 | madArg0ToReturnField |
-| tests.cpp:163:38:163:38 | x |
-| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
-| tests.cpp:164:47:164:47 | x |
-| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
-| tests.cpp:165:46:165:46 | x |
-| tests.cpp:167:13:167:30 | madFieldToFieldVar |
-| tests.cpp:168:13:168:38 | madFieldToIndirectFieldVar |
-| tests.cpp:169:14:169:39 | madIndirectFieldToFieldVar |
-| tests.cpp:171:6:171:19 | test_summaries |
-| tests.cpp:174:6:174:6 | a |
-| tests.cpp:174:9:174:9 | b |
-| tests.cpp:174:12:174:12 | c |
-| tests.cpp:174:15:174:15 | d |
-| tests.cpp:174:18:174:18 | e |
-| tests.cpp:175:7:175:11 | a_ptr |
-| tests.cpp:218:14:218:16 | mc1 |
-| tests.cpp:218:19:218:21 | mc2 |
-| tests.cpp:237:15:237:18 | rtn1 |
-| tests.cpp:240:14:240:17 | rtn2 |
-| tests.cpp:241:7:241:14 | rtn2_ptr |
-| tests.cpp:267:7:267:7 | operator= |
-| tests.cpp:267:7:267:7 | operator= |
-| tests.cpp:267:7:267:13 | MyClass |
-| tests.cpp:270:6:270:26 | memberRemoteMadSource |
-| tests.cpp:271:7:271:39 | memberRemoteMadSourceIndirectArg0 |
-| tests.cpp:271:46:271:46 | x |
-| tests.cpp:272:6:272:29 | memberRemoteMadSourceVar |
-| tests.cpp:273:7:273:21 | qualifierSource |
-| tests.cpp:274:7:274:26 | qualifierFieldSource |
-| tests.cpp:277:7:277:23 | memberMadSinkArg0 |
-| tests.cpp:277:29:277:29 | x |
-| tests.cpp:278:6:278:21 | memberMadSinkVar |
-| tests.cpp:279:7:279:19 | qualifierSink |
-| tests.cpp:280:7:280:23 | qualifierArg0Sink |
-| tests.cpp:280:29:280:29 | x |
-| tests.cpp:281:7:281:24 | qualifierFieldSink |
-| tests.cpp:284:7:284:19 | madArg0ToSelf |
-| tests.cpp:284:25:284:25 | x |
-| tests.cpp:285:6:285:20 | madSelfToReturn |
-| tests.cpp:286:6:286:16 | notASummary |
-| tests.cpp:287:7:287:20 | madArg0ToField |
-| tests.cpp:287:26:287:26 | x |
-| tests.cpp:288:6:288:21 | madFieldToReturn |
-| tests.cpp:290:6:290:8 | val |
-| tests.cpp:293:7:293:7 | MyDerivedClass |
-| tests.cpp:293:7:293:7 | operator= |
-| tests.cpp:293:7:293:7 | operator= |
-| tests.cpp:293:7:293:20 | MyDerivedClass |
-| tests.cpp:295:6:295:28 | subtypeRemoteMadSource1 |
-| tests.cpp:296:6:296:21 | subtypeNonSource |
-| tests.cpp:297:6:297:28 | subtypeRemoteMadSource2 |
-| tests.cpp:300:9:300:15 | source2 |
-| tests.cpp:301:6:301:9 | sink |
-| tests.cpp:301:19:301:20 | mc |
-| tests.cpp:304:8:304:8 | operator= |
-| tests.cpp:304:8:304:8 | operator= |
-| tests.cpp:304:8:304:14 | MyClass |
-| tests.cpp:307:8:307:33 | namespaceMemberMadSinkArg0 |
-| tests.cpp:307:39:307:39 | x |
-| tests.cpp:308:15:308:46 | namespaceStaticMemberMadSinkArg0 |
-| tests.cpp:308:52:308:52 | x |
-| tests.cpp:309:7:309:31 | namespaceMemberMadSinkVar |
-| tests.cpp:310:14:310:44 | namespaceStaticMemberMadSinkVar |
-| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
-| tests.cpp:317:22:317:28 | source3 |
-| tests.cpp:319:6:319:23 | test_class_members |
-| tests.cpp:320:10:320:11 | mc |
-| tests.cpp:320:14:320:16 | mc2 |
-| tests.cpp:320:19:320:21 | mc3 |
-| tests.cpp:320:24:320:26 | mc4 |
-| tests.cpp:320:29:320:31 | mc5 |
-| tests.cpp:320:34:320:36 | mc6 |
-| tests.cpp:320:39:320:41 | mc7 |
-| tests.cpp:320:44:320:46 | mc8 |
-| tests.cpp:320:49:320:51 | mc9 |
-| tests.cpp:320:54:320:57 | mc10 |
-| tests.cpp:320:60:320:63 | mc11 |
-| tests.cpp:321:11:321:13 | ptr |
-| tests.cpp:321:17:321:23 | mc4_ptr |
-| tests.cpp:322:17:322:19 | mdc |
-| tests.cpp:323:23:323:25 | mnc |
-| tests.cpp:323:28:323:31 | mnc2 |
-| tests.cpp:324:24:324:31 | mnc2_ptr |
-| tests.cpp:330:6:330:6 | a |
-| tests.cpp:429:8:429:8 | operator= |
-| tests.cpp:429:8:429:8 | operator= |
-| tests.cpp:429:8:429:14 | intPair |
-| tests.cpp:430:6:430:10 | first |
-| tests.cpp:431:6:431:11 | second |
-| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
-| tests.cpp:434:37:434:43 | fun_ptr |
-| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
-| tests.cpp:435:46:435:52 | fun_ptr |
-| tests.cpp:436:6:436:25 | madCallArg0WithValue |
-| tests.cpp:436:34:436:40 | fun_ptr |
-| tests.cpp:436:53:436:57 | value |
-| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
-| tests.cpp:437:45:437:51 | fun_ptr |
-| tests.cpp:437:64:437:68 | value |
-| tests.cpp:439:5:439:14 | getTainted |
-| tests.cpp:440:6:440:13 | useValue |
-| tests.cpp:440:19:440:19 | x |
-| tests.cpp:441:6:441:17 | dontUseValue |
-| tests.cpp:441:23:441:23 | x |
-| tests.cpp:443:6:443:27 | test_function_pointers |
-| tests.cpp:456:19:456:19 | X |
-| tests.cpp:457:8:457:35 | StructWithTypedefInParameter |
-| tests.cpp:457:8:457:35 | StructWithTypedefInParameter |
-| tests.cpp:458:12:458:15 | Type |
-| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
-| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
-| tests.cpp:459:45:459:45 | x |
-| tests.cpp:459:45:459:45 | x |
-| tests.cpp:462:6:462:37 | test_parameter_ref_to_return_ref |
-| tests.cpp:463:6:463:6 | x |
-| tests.cpp:464:36:464:36 | s |
-| tests.cpp:465:6:465:6 | y |
-| tests.cpp:469:7:469:9 | INT |
-| tests.cpp:471:5:471:17 | receive_array |
-| tests.cpp:471:23:471:23 | a |
-| tests.cpp:473:6:473:23 | test_receive_array |
-| tests.cpp:474:6:474:6 | x |
-| tests.cpp:475:6:475:10 | array |
-| tests.cpp:476:6:476:6 | y |
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/SummaryCall.ql b/cpp/ql/test/library-tests/dataflow/models-as-data/SummaryCall.ql
deleted file mode 100644
index 1b569040028e..000000000000
--- a/cpp/ql/test/library-tests/dataflow/models-as-data/SummaryCall.ql
+++ /dev/null
@@ -1,9 +0,0 @@
-import testModels
-private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
-private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
-
-query predicate summaryCalls(SummaryCall c) { any() }
-
-query predicate summarizedCallables(SummarizedCallable c) { any() }
-
-query predicate sourceCallables(SourceCallable c) { c.getLocation().getFile().toString() != "" }
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/consistency.expected b/cpp/ql/test/library-tests/dataflow/models-as-data/consistency.expected
deleted file mode 100644
index c89f4455bc59..000000000000
--- a/cpp/ql/test/library-tests/dataflow/models-as-data/consistency.expected
+++ /dev/null
@@ -1,29 +0,0 @@
-uniqueEnclosingCallable
-uniqueCallEnclosingCallable
-uniqueType
-uniqueNodeLocation
-missingLocation
-uniqueNodeToString
-parameterCallable
-localFlowIsLocal
-readStepIsLocal
-storeStepIsLocal
-compatibleTypesReflexive
-unreachableNodeCCtx
-localCallNodes
-postIsNotPre
-postHasUniquePre
-uniquePostUpdate
-postIsInSameCallable
-reverseRead
-argHasPostUpdate
-postWithInFlow
-viableImplInCallContextTooLarge
-uniqueParameterNodeAtPosition
-uniqueParameterNodePosition
-uniqueContentApprox
-identityLocalStep
-missingArgumentCall
-multipleArgumentCall
-lambdaCallEnclosingCallableMismatch
-speculativeStepAlreadyHasModel
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/consistency.ql b/cpp/ql/test/library-tests/dataflow/models-as-data/consistency.ql
deleted file mode 100644
index 1af8d69a3563..000000000000
--- a/cpp/ql/test/library-tests/dataflow/models-as-data/consistency.ql
+++ /dev/null
@@ -1,2 +0,0 @@
-import testModels
-import semmle.code.cpp.ir.dataflow.internal.DataFlowImplConsistency::Consistency
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/interpretElement.ql b/cpp/ql/test/library-tests/dataflow/models-as-data/interpretElement.ql
deleted file mode 100644
index ccf0c3f886dc..000000000000
--- a/cpp/ql/test/library-tests/dataflow/models-as-data/interpretElement.ql
+++ /dev/null
@@ -1,18 +0,0 @@
-import utils.test.InlineExpectationsTest
-import testModels
-
-module InterpretElementTest implements TestSig {
- string getARelevantTag() { result = "interpretElement" }
-
- predicate hasActualResult(Location location, string element, string tag, string value) {
- exists(Element e |
- e = interpretElement(_, _, _, _, _, _) and
- location = e.getLocation() and
- element = e.toString() and
- tag = "interpretElement" and
- value = ""
- )
- }
-}
-
-import MakeTest
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/taint.ql b/cpp/ql/test/library-tests/dataflow/models-as-data/taint.ql
deleted file mode 100644
index 8c362d78e3e7..000000000000
--- a/cpp/ql/test/library-tests/dataflow/models-as-data/taint.ql
+++ /dev/null
@@ -1,32 +0,0 @@
-import utils.test.dataflow.FlowTestCommon
-import testModels
-
-module IRTest {
- private import semmle.code.cpp.ir.IR
- private import semmle.code.cpp.ir.dataflow.TaintTracking
-
- /** Common data flow configuration to be used by tests. */
- module TestAllocationConfig implements DataFlow::ConfigSig {
- predicate isSource(DataFlow::Node source) {
- source instanceof FlowSource
- or
- source.asExpr().(FunctionCall).getTarget().getName() =
- ["source", "source2", "source3", "sourcePtr"]
- or
- source.asIndirectExpr(1).(FunctionCall).getTarget().getName() = "sourceIndirect"
- }
-
- predicate isSink(DataFlow::Node sink) {
- sinkNode(sink, "test-sink")
- or
- exists(FunctionCall call |
- call.getTarget().getName() = "sink" and
- sink.asExpr() = call.getAnArgument()
- )
- }
- }
-
- module IRFlow = TaintTracking::Global;
-}
-
-import MakeTest>
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/FlowSummaryNode.expected b/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.expected
similarity index 50%
rename from cpp/ql/test/library-tests/dataflow/models-as-data/FlowSummaryNode.expected
rename to cpp/ql/test/library-tests/dataflow/models-as-data/testModels.expected
index 756e9a7e22a5..0faf016ee410 100644
--- a/cpp/ql/test/library-tests/dataflow/models-as-data/FlowSummaryNode.expected
+++ b/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.expected
@@ -1,3 +1,301 @@
+uniqueEnclosingCallable
+uniqueCallEnclosingCallable
+uniqueType
+uniqueNodeLocation
+missingLocation
+uniqueNodeToString
+parameterCallable
+localFlowIsLocal
+readStepIsLocal
+storeStepIsLocal
+compatibleTypesReflexive
+unreachableNodeCCtx
+localCallNodes
+postIsNotPre
+postHasUniquePre
+uniquePostUpdate
+postIsInSameCallable
+reverseRead
+argHasPostUpdate
+postWithInFlow
+viableImplInCallContextTooLarge
+uniqueParameterNodeAtPosition
+uniqueParameterNodePosition
+uniqueContentApprox
+identityLocalStep
+missingArgumentCall
+multipleArgumentCall
+lambdaCallEnclosingCallableMismatch
+speculativeStepAlreadyHasModel
+testFailures
+summaryCalls
+| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0ReturnToReturn in madCallArg0ReturnToReturn |
+| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0ReturnToReturnFirst in madCallArg0ReturnToReturnFirst |
+| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0WithValue in madCallArg0WithValue |
+summarizedCallables
+| tests.cpp:144:5:144:19 | madArg0ToReturn |
+| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
+| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
+| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
+| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
+| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
+| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
+| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
+| tests.cpp:153:5:153:18 | madArgsComplex |
+| tests.cpp:154:5:154:14 | madArgsAny |
+| tests.cpp:155:5:155:28 | madAndImplementedComplex |
+| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
+| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
+| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
+| tests.cpp:163:13:163:32 | madArg0ToReturnField |
+| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
+| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
+| tests.cpp:284:7:284:19 | madArg0ToSelf |
+| tests.cpp:285:6:285:20 | madSelfToReturn |
+| tests.cpp:287:7:287:20 | madArg0ToField |
+| tests.cpp:288:6:288:21 | madFieldToReturn |
+| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
+| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
+| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
+| tests.cpp:436:6:436:25 | madCallArg0WithValue |
+| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
+| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
+| tests.cpp:471:5:471:17 | receive_array |
+sourceCallables
+| tests.cpp:3:5:3:10 | source |
+| tests.cpp:4:6:4:14 | sourcePtr |
+| tests.cpp:5:6:5:19 | sourceIndirect |
+| tests.cpp:6:6:6:9 | sink |
+| tests.cpp:6:15:6:17 | val |
+| tests.cpp:7:6:7:9 | sink |
+| tests.cpp:7:16:7:18 | ptr |
+| tests.cpp:11:5:11:18 | localMadSource |
+| tests.cpp:12:5:12:19 | remoteMadSource |
+| tests.cpp:13:5:13:14 | notASource |
+| tests.cpp:14:5:14:22 | localMadSourceVoid |
+| tests.cpp:15:5:15:25 | localMadSourceHasBody |
+| tests.cpp:16:6:16:28 | remoteMadSourceIndirect |
+| tests.cpp:17:7:17:35 | remoteMadSourceDoubleIndirect |
+| tests.cpp:18:6:18:32 | remoteMadSourceIndirectArg0 |
+| tests.cpp:18:39:18:39 | x |
+| tests.cpp:18:47:18:47 | y |
+| tests.cpp:19:6:19:32 | remoteMadSourceIndirectArg1 |
+| tests.cpp:19:39:19:39 | x |
+| tests.cpp:19:47:19:47 | y |
+| tests.cpp:20:5:20:22 | remoteMadSourceVar |
+| tests.cpp:21:6:21:31 | remoteMadSourceVarIndirect |
+| tests.cpp:24:6:24:28 | namespaceLocalMadSource |
+| tests.cpp:25:6:25:31 | namespaceLocalMadSourceVar |
+| tests.cpp:28:7:28:30 | namespace2LocalMadSource |
+| tests.cpp:31:6:31:19 | localMadSource |
+| tests.cpp:33:5:33:27 | namespaceLocalMadSource |
+| tests.cpp:35:6:35:17 | test_sources |
+| tests.cpp:50:6:50:6 | v |
+| tests.cpp:51:7:51:16 | v_indirect |
+| tests.cpp:52:6:52:13 | v_direct |
+| tests.cpp:63:6:63:6 | a |
+| tests.cpp:63:9:63:9 | b |
+| tests.cpp:63:12:63:12 | c |
+| tests.cpp:63:15:63:15 | d |
+| tests.cpp:75:6:75:6 | e |
+| tests.cpp:85:6:85:26 | remoteMadSourceParam0 |
+| tests.cpp:85:32:85:32 | x |
+| tests.cpp:92:6:92:16 | madSinkArg0 |
+| tests.cpp:92:22:92:22 | x |
+| tests.cpp:93:6:93:13 | notASink |
+| tests.cpp:93:19:93:19 | x |
+| tests.cpp:94:6:94:16 | madSinkArg1 |
+| tests.cpp:94:22:94:22 | x |
+| tests.cpp:94:29:94:29 | y |
+| tests.cpp:95:6:95:17 | madSinkArg01 |
+| tests.cpp:95:23:95:23 | x |
+| tests.cpp:95:30:95:30 | y |
+| tests.cpp:95:37:95:37 | z |
+| tests.cpp:96:6:96:17 | madSinkArg02 |
+| tests.cpp:96:23:96:23 | x |
+| tests.cpp:96:30:96:30 | y |
+| tests.cpp:96:37:96:37 | z |
+| tests.cpp:97:6:97:24 | madSinkIndirectArg0 |
+| tests.cpp:97:31:97:31 | x |
+| tests.cpp:98:6:98:30 | madSinkDoubleIndirectArg0 |
+| tests.cpp:98:38:98:38 | x |
+| tests.cpp:99:5:99:14 | madSinkVar |
+| tests.cpp:100:6:100:23 | madSinkVarIndirect |
+| tests.cpp:102:6:102:15 | test_sinks |
+| tests.cpp:116:6:116:6 | a |
+| tests.cpp:117:7:117:11 | a_ptr |
+| tests.cpp:132:6:132:18 | madSinkParam0 |
+| tests.cpp:132:24:132:24 | x |
+| tests.cpp:138:8:138:8 | operator= |
+| tests.cpp:138:8:138:8 | operator= |
+| tests.cpp:138:8:138:18 | MyContainer |
+| tests.cpp:139:6:139:10 | value |
+| tests.cpp:140:6:140:11 | value2 |
+| tests.cpp:141:7:141:9 | ptr |
+| tests.cpp:144:5:144:19 | madArg0ToReturn |
+| tests.cpp:144:25:144:25 | x |
+| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
+| tests.cpp:145:34:145:34 | x |
+| tests.cpp:146:5:146:15 | notASummary |
+| tests.cpp:146:21:146:21 | x |
+| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
+| tests.cpp:147:34:147:34 | x |
+| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
+| tests.cpp:148:34:148:34 | x |
+| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
+| tests.cpp:149:41:149:41 | x |
+| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
+| tests.cpp:150:37:150:37 | x |
+| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
+| tests.cpp:151:32:151:32 | x |
+| tests.cpp:151:40:151:40 | y |
+| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
+| tests.cpp:152:47:152:47 | x |
+| tests.cpp:152:55:152:55 | y |
+| tests.cpp:153:5:153:18 | madArgsComplex |
+| tests.cpp:153:25:153:25 | a |
+| tests.cpp:153:33:153:33 | b |
+| tests.cpp:153:40:153:40 | c |
+| tests.cpp:153:47:153:47 | d |
+| tests.cpp:154:5:154:14 | madArgsAny |
+| tests.cpp:154:20:154:20 | a |
+| tests.cpp:154:28:154:28 | b |
+| tests.cpp:155:5:155:28 | madAndImplementedComplex |
+| tests.cpp:155:34:155:34 | a |
+| tests.cpp:155:41:155:41 | b |
+| tests.cpp:155:48:155:48 | c |
+| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
+| tests.cpp:160:38:160:39 | mc |
+| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
+| tests.cpp:161:47:161:48 | mc |
+| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
+| tests.cpp:162:46:162:47 | mc |
+| tests.cpp:163:13:163:32 | madArg0ToReturnField |
+| tests.cpp:163:38:163:38 | x |
+| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
+| tests.cpp:164:47:164:47 | x |
+| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
+| tests.cpp:165:46:165:46 | x |
+| tests.cpp:167:13:167:30 | madFieldToFieldVar |
+| tests.cpp:168:13:168:38 | madFieldToIndirectFieldVar |
+| tests.cpp:169:14:169:39 | madIndirectFieldToFieldVar |
+| tests.cpp:171:6:171:19 | test_summaries |
+| tests.cpp:174:6:174:6 | a |
+| tests.cpp:174:9:174:9 | b |
+| tests.cpp:174:12:174:12 | c |
+| tests.cpp:174:15:174:15 | d |
+| tests.cpp:174:18:174:18 | e |
+| tests.cpp:175:7:175:11 | a_ptr |
+| tests.cpp:218:14:218:16 | mc1 |
+| tests.cpp:218:19:218:21 | mc2 |
+| tests.cpp:237:15:237:18 | rtn1 |
+| tests.cpp:240:14:240:17 | rtn2 |
+| tests.cpp:241:7:241:14 | rtn2_ptr |
+| tests.cpp:267:7:267:7 | operator= |
+| tests.cpp:267:7:267:7 | operator= |
+| tests.cpp:267:7:267:13 | MyClass |
+| tests.cpp:270:6:270:26 | memberRemoteMadSource |
+| tests.cpp:271:7:271:39 | memberRemoteMadSourceIndirectArg0 |
+| tests.cpp:271:46:271:46 | x |
+| tests.cpp:272:6:272:29 | memberRemoteMadSourceVar |
+| tests.cpp:273:7:273:21 | qualifierSource |
+| tests.cpp:274:7:274:26 | qualifierFieldSource |
+| tests.cpp:277:7:277:23 | memberMadSinkArg0 |
+| tests.cpp:277:29:277:29 | x |
+| tests.cpp:278:6:278:21 | memberMadSinkVar |
+| tests.cpp:279:7:279:19 | qualifierSink |
+| tests.cpp:280:7:280:23 | qualifierArg0Sink |
+| tests.cpp:280:29:280:29 | x |
+| tests.cpp:281:7:281:24 | qualifierFieldSink |
+| tests.cpp:284:7:284:19 | madArg0ToSelf |
+| tests.cpp:284:25:284:25 | x |
+| tests.cpp:285:6:285:20 | madSelfToReturn |
+| tests.cpp:286:6:286:16 | notASummary |
+| tests.cpp:287:7:287:20 | madArg0ToField |
+| tests.cpp:287:26:287:26 | x |
+| tests.cpp:288:6:288:21 | madFieldToReturn |
+| tests.cpp:290:6:290:8 | val |
+| tests.cpp:293:7:293:7 | MyDerivedClass |
+| tests.cpp:293:7:293:7 | operator= |
+| tests.cpp:293:7:293:7 | operator= |
+| tests.cpp:293:7:293:20 | MyDerivedClass |
+| tests.cpp:295:6:295:28 | subtypeRemoteMadSource1 |
+| tests.cpp:296:6:296:21 | subtypeNonSource |
+| tests.cpp:297:6:297:28 | subtypeRemoteMadSource2 |
+| tests.cpp:300:9:300:15 | source2 |
+| tests.cpp:301:6:301:9 | sink |
+| tests.cpp:301:19:301:20 | mc |
+| tests.cpp:304:8:304:8 | operator= |
+| tests.cpp:304:8:304:8 | operator= |
+| tests.cpp:304:8:304:14 | MyClass |
+| tests.cpp:307:8:307:33 | namespaceMemberMadSinkArg0 |
+| tests.cpp:307:39:307:39 | x |
+| tests.cpp:308:15:308:46 | namespaceStaticMemberMadSinkArg0 |
+| tests.cpp:308:52:308:52 | x |
+| tests.cpp:309:7:309:31 | namespaceMemberMadSinkVar |
+| tests.cpp:310:14:310:44 | namespaceStaticMemberMadSinkVar |
+| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
+| tests.cpp:317:22:317:28 | source3 |
+| tests.cpp:319:6:319:23 | test_class_members |
+| tests.cpp:320:10:320:11 | mc |
+| tests.cpp:320:14:320:16 | mc2 |
+| tests.cpp:320:19:320:21 | mc3 |
+| tests.cpp:320:24:320:26 | mc4 |
+| tests.cpp:320:29:320:31 | mc5 |
+| tests.cpp:320:34:320:36 | mc6 |
+| tests.cpp:320:39:320:41 | mc7 |
+| tests.cpp:320:44:320:46 | mc8 |
+| tests.cpp:320:49:320:51 | mc9 |
+| tests.cpp:320:54:320:57 | mc10 |
+| tests.cpp:320:60:320:63 | mc11 |
+| tests.cpp:321:11:321:13 | ptr |
+| tests.cpp:321:17:321:23 | mc4_ptr |
+| tests.cpp:322:17:322:19 | mdc |
+| tests.cpp:323:23:323:25 | mnc |
+| tests.cpp:323:28:323:31 | mnc2 |
+| tests.cpp:324:24:324:31 | mnc2_ptr |
+| tests.cpp:330:6:330:6 | a |
+| tests.cpp:429:8:429:8 | operator= |
+| tests.cpp:429:8:429:8 | operator= |
+| tests.cpp:429:8:429:14 | intPair |
+| tests.cpp:430:6:430:10 | first |
+| tests.cpp:431:6:431:11 | second |
+| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
+| tests.cpp:434:37:434:43 | fun_ptr |
+| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
+| tests.cpp:435:46:435:52 | fun_ptr |
+| tests.cpp:436:6:436:25 | madCallArg0WithValue |
+| tests.cpp:436:34:436:40 | fun_ptr |
+| tests.cpp:436:53:436:57 | value |
+| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
+| tests.cpp:437:45:437:51 | fun_ptr |
+| tests.cpp:437:64:437:68 | value |
+| tests.cpp:439:5:439:14 | getTainted |
+| tests.cpp:440:6:440:13 | useValue |
+| tests.cpp:440:19:440:19 | x |
+| tests.cpp:441:6:441:17 | dontUseValue |
+| tests.cpp:441:23:441:23 | x |
+| tests.cpp:443:6:443:27 | test_function_pointers |
+| tests.cpp:456:19:456:19 | X |
+| tests.cpp:457:8:457:35 | StructWithTypedefInParameter |
+| tests.cpp:457:8:457:35 | StructWithTypedefInParameter |
+| tests.cpp:458:12:458:15 | Type |
+| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
+| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
+| tests.cpp:459:45:459:45 | x |
+| tests.cpp:459:45:459:45 | x |
+| tests.cpp:462:6:462:37 | test_parameter_ref_to_return_ref |
+| tests.cpp:463:6:463:6 | x |
+| tests.cpp:464:36:464:36 | s |
+| tests.cpp:465:6:465:6 | y |
+| tests.cpp:469:7:469:9 | INT |
+| tests.cpp:471:5:471:17 | receive_array |
+| tests.cpp:471:23:471:23 | a |
+| tests.cpp:473:6:473:23 | test_receive_array |
+| tests.cpp:474:6:474:6 | x |
+| tests.cpp:475:6:475:10 | array |
+| tests.cpp:476:6:476:6 | y |
+flowSummaryNode
| tests.cpp:144:5:144:19 | [summary param] 0 in madArg0ToReturn | ParameterNode | madArg0ToReturn | madArg0ToReturn |
| tests.cpp:144:5:144:19 | [summary] to write: ReturnValue in madArg0ToReturn | ReturnNode | madArg0ToReturn | madArg0ToReturn |
| tests.cpp:145:6:145:28 | [summary param] 0 in madArg0ToReturnIndirect | ParameterNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.ext.yml b/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.ext.yml
new file mode 100644
index 000000000000..952612234731
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.ext.yml
@@ -0,0 +1,84 @@
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: sourceModel
+ data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
+ - ["", "", False, "localMadSource", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "remoteMadSource", "", "", "ReturnValue", "remote", "manual"]
+ - ["", "", False, "localMadSourceVoid", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "localMadSourceHasBody", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "remoteMadSourceIndirect", "", "", "ReturnValue[*]", "remote", "manual"]
+ - ["", "", False, "remoteMadSourceDoubleIndirect", "", "", "ReturnValue[**]", "remote", "manual"]
+ - ["", "", False, "remoteMadSourceIndirectArg0", "", "", "Argument[*0]", "remote", "manual"]
+ - ["", "", False, "remoteMadSourceIndirectArg1", "", "", "Argument[*1]", "remote", "manual"]
+ - ["", "", False, "remoteMadSourceVar", "", "", "", "remote", "manual"]
+ - ["", "", False, "remoteMadSourceVarIndirect", "", "", "*", "remote", "manual"] # we can't express this source/sink correctly at present, "*" is not a valid access path
+ - ["", "", False, "remoteMadSourceParam0", "", "", "Parameter[0]", "remote", "manual"]
+ - ["MyNamespace", "", False, "namespaceLocalMadSource", "", "", "ReturnValue", "local", "manual"]
+ - ["MyNamespace", "", False, "namespaceLocalMadSourceVar", "", "", "", "local", "manual"]
+ - ["MyNamespace::MyNamespace2", "", False, "namespace2LocalMadSource", "", "", "ReturnValue", "local", "manual"]
+ - ["", "MyClass", True, "memberRemoteMadSource", "", "", "ReturnValue", "remote", "manual"]
+ - ["", "MyClass", True, "memberRemoteMadSourceIndirectArg0", "", "", "Argument[*0]", "remote", "manual"]
+ - ["", "MyClass", True, "memberRemoteMadSourceVar", "", "", "", "remote", "manual"]
+ - ["", "MyClass", True, "subtypeRemoteMadSource1", "", "", "ReturnValue", "remote", "manual"]
+ - ["", "MyClass", False, "subtypeNonSource", "", "", "ReturnValue", "remote", "manual"] # the tests define this in MyDerivedClass, so it should *not* be recongized as a source
+ - ["", "MyClass", True, "qualifierSource", "", "", "Argument[-1]", "remote", "manual"]
+ - ["", "MyClass", True, "qualifierFieldSource", "", "", "Argument[-1].val", "remote", "manual"]
+ - ["", "MyDerivedClass", False, "subtypeRemoteMadSource2", "", "", "ReturnValue", "remote", "manual"]
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: sinkModel
+ data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
+ - ["", "", False, "madSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
+ - ["", "", False, "madSinkArg1", "", "", "Argument[1]", "test-sink", "manual"]
+ - ["", "", False, "madSinkArg01", "", "", "Argument[0..1]", "test-sink", "manual"]
+ - ["", "", False, "madSinkArg02", "", "", "Argument[0,2]", "test-sink", "manual"]
+ - ["", "", False, "madSinkIndirectArg0", "", "", "Argument[*0]", "test-sink", "manual"]
+ - ["", "", False, "madSinkDoubleIndirectArg0", "", "", "Argument[**0]", "test-sink", "manual"]
+ - ["", "", False, "madSinkVar", "", "", "", "test-sink", "manual"]
+ - ["", "", False, "madSinkVarIndirect", "", "", "*", "test-sink", "manual"] # we can't express this source/sink correctly at present, "*" is not a valid access path
+ - ["", "", False, "madSinkParam0", "", "", "Parameter[0]", "test-sink", "manual"]
+ - ["", "MyClass", True, "memberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
+ - ["", "MyClass", True, "memberMadSinkVar", "", "", "", "test-sink", "manual"]
+ - ["", "MyClass", True, "qualifierSink", "", "", "Argument[-1]", "test-sink", "manual"]
+ - ["", "MyClass", True, "qualifierArg0Sink", "", "", "Argument[-1..0]", "test-sink", "manual"]
+ - ["", "MyClass", True, "qualifierFieldSink", "", "", "Argument[-1].val", "test-sink", "manual"]
+ - ["MyNamespace", "MyClass", True, "namespaceMemberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
+ - ["MyNamespace", "MyClass", True, "namespaceStaticMemberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
+ - ["MyNamespace", "MyClass", True, "namespaceMemberMadSinkVar", "", "", "", "test-sink", "manual"]
+ - ["MyNamespace", "MyClass", True, "namespaceStaticMemberMadSinkVar", "", "", "", "test-sink", "manual"]
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: summaryModel
+ data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
+ - ["", "", False, "madArg0ToReturn", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madArg0ToReturnIndirect", "", "", "Argument[0]", "ReturnValue[*]", "taint", "manual"]
+ - ["", "", False, "madArg0ToReturnValueFlow", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
+ - ["", "", False, "madArg0IndirectToReturn", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madArg0DoubleIndirectToReturn", "", "", "Argument[**0]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madArg0NotIndirectToReturn", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madArg0ToArg1Indirect", "", "", "Argument[0]", "Argument[*1]", "taint", "manual"]
+ - ["", "", False, "madArg0IndirectToArg1Indirect", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ - ["", "", False, "madArgsComplex", "", "", "Argument[*0..1,2]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madAndImplementedComplex", "", "", "Argument[2]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madArgsAny", "", "", "Argument", "ReturnValue", "taint", "manual"] # we can't express this source/sink correctly at present, "Argument" is not a valid input
+ - ["", "", False, "madArg0FieldToReturn", "", "", "Argument[0].Field[value]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madArg0IndirectFieldToReturn", "", "", "Argument[*0].Field[value]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madArg0FieldIndirectToReturn", "", "", "Argument[0].Field[*ptr]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madArg0ToReturnField", "", "", "Argument[0]", "ReturnValue.Field[value]", "taint", "manual"]
+ - ["", "", False, "madArg0ToReturnIndirectField", "", "", "Argument[0]", "ReturnValue[*].Field[value]", "taint", "manual"]
+ - ["", "", False, "madArg0ToReturnFieldIndirect", "", "", "Argument[0]", "ReturnValue.Field[*ptr]", "taint", "manual"]
+ - ["", "", False, "madFieldToFieldVar", "", "", "Field[value]", "Field[value2]", "taint", "manual"] # we can't express this source/sink correctly at present, "Field[value]" is not a valid input and "Field[value2]" is not a valid output
+ - ["", "", False, "madFieldToIndirectFieldVar", "", "", "Field[value]", "Field[*ptr]", "taint", "manual"] # we can't express this source/sink correctly at present, "Field[value]" is not a valid input and "Field[*ptr]" is not a valid output
+ - ["", "", False, "madIndirectFieldToFieldVar", "", "", "Field[value]", "Field[value2]", "taint", "manual"] # we can't express this source/sink correctly at present, "Field[value]" is not a valid input and "Field[value2]" is not a valid output
+ - ["", "MyClass", True, "madArg0ToSelf", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["", "MyClass", True, "madSelfToReturn", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
+ - ["", "MyClass", True, "madArg0ToField", "", "", "Argument[0]", "Argument[-1].Field[val]", "taint", "manual"]
+ - ["", "MyClass", True, "madFieldToReturn", "", "", "Argument[-1].Field[val]", "ReturnValue", "taint", "manual"]
+ - ["MyNamespace", "MyClass", True, "namespaceMadSelfToReturn", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
+ - ["", "", False, "madCallArg0ReturnToReturn", "", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"]
+ - ["", "", False, "madCallArg0ReturnToReturnFirst", "", "", "Argument[0].ReturnValue", "ReturnValue.Field[first]", "value", "manual"]
+ - ["", "", False, "madCallArg0WithValue", "", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"]
+ - ["", "", False, "madCallReturnValueIgnoreFunction", "", "", "Argument[1]", "ReturnValue", "value", "manual"]
+ - ["", "StructWithTypedefInParameter", True, "parameter_ref_to_return_ref", "(const T &)", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"]
+ - ["", "", False, "receive_array", "(int[20])", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.ql b/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.ql
new file mode 100644
index 000000000000..4b89b7da4093
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.ql
@@ -0,0 +1,74 @@
+import semmle.code.cpp.ir.dataflow.internal.DataFlowImplConsistency::Consistency
+import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes
+import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
+import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
+import semmle.code.cpp.security.FlowSources
+import utils.test.dataflow.FlowTestCommon
+
+module InterpretElementTest implements TestSig {
+ string getARelevantTag() { result = "interpretElement" }
+
+ predicate hasActualResult(Location location, string element, string tag, string value) {
+ exists(Element e |
+ e = interpretElement(_, _, _, _, _, _) and
+ location = e.getLocation() and
+ element = e.toString() and
+ tag = "interpretElement" and
+ value = ""
+ )
+ }
+}
+
+query predicate summaryCalls(SummaryCall c) { any() }
+
+query predicate summarizedCallables(SummarizedCallable c) { any() }
+
+query predicate sourceCallables(SourceCallable c) { c.getLocation().getFile().toString() != "" }
+
+module IRTest {
+ private import semmle.code.cpp.ir.IR
+ private import semmle.code.cpp.ir.dataflow.TaintTracking
+
+ /** Common data flow configuration to be used by tests. */
+ module TestAllocationConfig implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node source) {
+ source instanceof FlowSource
+ or
+ source.asExpr().(FunctionCall).getTarget().getName() =
+ ["source", "source2", "source3", "sourcePtr"]
+ or
+ source.asIndirectExpr(1).(FunctionCall).getTarget().getName() = "sourceIndirect"
+ }
+
+ predicate isSink(DataFlow::Node sink) {
+ sinkNode(sink, "test-sink")
+ or
+ exists(FunctionCall call |
+ call.getTarget().getName() = "sink" and
+ sink.asExpr() = call.getAnArgument()
+ )
+ }
+ }
+
+ module IRFlow = TaintTracking::Global;
+}
+
+import MakeTest, InterpretElementTest>>
+
+string describe(DataFlow::Node n) {
+ n instanceof ParameterNode and result = "ParameterNode"
+ or
+ n instanceof PostUpdateNode and result = "PostUpdateNode"
+ or
+ n instanceof ArgumentNode and result = "ArgumentNode"
+ or
+ n instanceof ReturnNode and result = "ReturnNode"
+ or
+ n instanceof OutNode and result = "OutNode"
+}
+
+query predicate flowSummaryNode(FlowSummaryNode n, string str1, string str2, string str3) {
+ str1 = concat(describe(n), ", ") and
+ str2 = concat(n.getSummarizedCallable().toString(), ", ") and
+ str3 = concat(n.getEnclosingCallable().toString(), ", ")
+}
diff --git a/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.qll b/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.qll
deleted file mode 100644
index e8d1393fc4a7..000000000000
--- a/cpp/ql/test/library-tests/dataflow/models-as-data/testModels.qll
+++ /dev/null
@@ -1,105 +0,0 @@
-import semmle.code.cpp.security.FlowSources
-
-/**
- * Models-as-data source models for this test.
- */
-private class TestSources extends SourceModelCsv {
- override predicate row(string row) {
- row =
- [
- ";;false;localMadSource;;;ReturnValue;local",
- ";;false;remoteMadSource;;;ReturnValue;remote",
- ";;false;localMadSourceVoid;;;ReturnValue;local",
- ";;false;localMadSourceHasBody;;;ReturnValue;local",
- ";;false;remoteMadSourceIndirect;;;ReturnValue[*];remote",
- ";;false;remoteMadSourceDoubleIndirect;;;ReturnValue[**];remote",
- ";;false;remoteMadSourceIndirectArg0;;;Argument[*0];remote",
- ";;false;remoteMadSourceIndirectArg1;;;Argument[*1];remote",
- ";;false;remoteMadSourceVar;;;;remote",
- ";;false;remoteMadSourceVarIndirect;;;*;remote", // not correctly expressed
- ";;false;remoteMadSourceParam0;;;Parameter[0];remote",
- "MyNamespace;;false;namespaceLocalMadSource;;;ReturnValue;local",
- "MyNamespace;;false;namespaceLocalMadSourceVar;;;;local",
- "MyNamespace::MyNamespace2;;false;namespace2LocalMadSource;;;ReturnValue;local",
- ";MyClass;true;memberRemoteMadSource;;;ReturnValue;remote",
- ";MyClass;true;memberRemoteMadSourceIndirectArg0;;;Argument[*0];remote",
- ";MyClass;true;memberRemoteMadSourceVar;;;;remote",
- ";MyClass;true;subtypeRemoteMadSource1;;;ReturnValue;remote",
- ";MyClass;false;subtypeNonSource;;;ReturnValue;remote", // the tests define this in MyDerivedClass, so it should *not* be recongized as a source
- ";MyClass;true;qualifierSource;;;Argument[-1];remote",
- ";MyClass;true;qualifierFieldSource;;;Argument[-1].val;remote",
- ";MyDerivedClass;false;subtypeRemoteMadSource2;;;ReturnValue;remote",
- ]
- }
-}
-
-/**
- * Models-as-data sink models for this test.
- */
-private class TestSinks extends SinkModelCsv {
- override predicate row(string row) {
- row =
- [
- ";;false;madSinkArg0;;;Argument[0];test-sink",
- ";;false;madSinkArg1;;;Argument[1];test-sink",
- ";;false;madSinkArg01;;;Argument[0..1];test-sink",
- ";;false;madSinkArg02;;;Argument[0,2];test-sink",
- ";;false;madSinkIndirectArg0;;;Argument[*0];test-sink",
- ";;false;madSinkDoubleIndirectArg0;;;Argument[**0];test-sink",
- ";;false;madSinkVar;;;;test-sink",
- ";;false;madSinkVarIndirect;;;*;test-sink", // not correctly expressed
- ";;false;madSinkParam0;;;Parameter[0];test-sink",
- ";MyClass;true;memberMadSinkArg0;;;Argument[0];test-sink",
- ";MyClass;true;memberMadSinkVar;;;;test-sink",
- ";MyClass;true;qualifierSink;;;Argument[-1];test-sink",
- ";MyClass;true;qualifierArg0Sink;;;Argument[-1..0];test-sink",
- ";MyClass;true;qualifierFieldSink;;;Argument[-1].val;test-sink",
- "MyNamespace;MyClass;true;namespaceMemberMadSinkArg0;;;Argument[0];test-sink",
- "MyNamespace;MyClass;true;namespaceStaticMemberMadSinkArg0;;;Argument[0];test-sink",
- "MyNamespace;MyClass;true;namespaceMemberMadSinkVar;;;;test-sink",
- "MyNamespace;MyClass;true;namespaceStaticMemberMadSinkVar;;;;test-sink",
- ]
- }
-}
-
-/**
- * Models-as-data summary models for this test.
- */
-private class TestSummaries extends SummaryModelCsv {
- override predicate row(string row) {
- row =
- [
- ";;false;madArg0ToReturn;;;Argument[0];ReturnValue;taint",
- ";;false;madArg0ToReturnIndirect;;;Argument[0];ReturnValue[*];taint",
- ";;false;madArg0ToReturnValueFlow;;;Argument[0];ReturnValue;value",
- ";;false;madArg0IndirectToReturn;;;Argument[*0];ReturnValue;taint",
- ";;false;madArg0DoubleIndirectToReturn;;;Argument[**0];ReturnValue;taint",
- ";;false;madArg0NotIndirectToReturn;;;Argument[0];ReturnValue;taint",
- ";;false;madArg0ToArg1Indirect;;;Argument[0];Argument[*1];taint",
- ";;false;madArg0IndirectToArg1Indirect;;;Argument[*0];Argument[*1];taint",
- ";;false;madArgsComplex;;;Argument[*0..1,2];ReturnValue;taint",
- ";;false;madAndImplementedComplex;;;Argument[2];ReturnValue;taint",
- ";;false;madArgsAny;;;Argument;ReturnValue;taint", // (syntax not supported)
- ";;false;madArg0FieldToReturn;;;Argument[0].Field[value];ReturnValue;taint",
- ";;false;madArg0IndirectFieldToReturn;;;Argument[*0].Field[value];ReturnValue;taint",
- ";;false;madArg0FieldIndirectToReturn;;;Argument[0].Field[*ptr];ReturnValue;taint",
- ";;false;madArg0ToReturnField;;;Argument[0];ReturnValue.Field[value];taint",
- ";;false;madArg0ToReturnIndirectField;;;Argument[0];ReturnValue[*].Field[value];taint",
- ";;false;madArg0ToReturnFieldIndirect;;;Argument[0];ReturnValue.Field[*ptr];taint",
- ";;false;madFieldToFieldVar;;;Field[value];Field[value2];taint",
- ";;false;madFieldToIndirectFieldVar;;;Field[value];Field[*ptr];taint",
- ";;false;madIndirectFieldToFieldVar;;;;Field[value];Field[value2];taint", // not correctly expressed
- ";MyClass;true;madArg0ToSelf;;;Argument[0];Argument[-1];taint",
- ";MyClass;true;madSelfToReturn;;;Argument[-1];ReturnValue;taint",
- ";MyClass;true;madArg0ToField;;;Argument[0];Argument[-1].Field[val];taint",
- ";MyClass;true;madFieldToReturn;;;Argument[-1].Field[val];ReturnValue;taint",
- "MyNamespace;MyClass;true;namespaceMadSelfToReturn;;;Argument[-1];ReturnValue;taint",
- ";;false;madCallArg0ReturnToReturn;;;Argument[0].ReturnValue;ReturnValue;value",
- ";;false;madCallArg0ReturnToReturnFirst;;;Argument[0].ReturnValue;ReturnValue.Field[first];value",
- ";;false;madCallArg0WithValue;;;Argument[1];Argument[0].Parameter[0];value",
- ";;false;madCallReturnValueIgnoreFunction;;;Argument[1];ReturnValue;value",
- ";StructWithTypedefInParameter;true;parameter_ref_to_return_ref;(const T &);;Argument[*0];ReturnValue[*];value",
- ";;false;receive_array;(int[20]);;Argument[*0];ReturnValue;taint"
- ]
- }
-}
diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
index 45666a3b50b8..c3e46114edf4 100644
--- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
+++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
@@ -277,7 +277,7 @@ bad_asts.cpp:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const Point &
# 19| :
-# 19| getInitializer(0): [ConstructorFieldInit] constructor init of field x
+# 19| getInitializer(0): [ConstructorDirectFieldInit] constructor init of field x
# 19| Type = [IntType] int
# 19| ValueCategory = prvalue
# 19| getExpr(): [ReferenceFieldAccess] x
@@ -289,7 +289,7 @@ bad_asts.cpp:
# 19| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 19| Type = [SpecifiedType] const Point
# 19| ValueCategory = lvalue
-# 19| getInitializer(1): [ConstructorFieldInit] constructor init of field y
+# 19| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field y
# 19| Type = [IntType] int
# 19| ValueCategory = prvalue
# 19| getExpr(): [ReferenceFieldAccess] y
@@ -8986,20 +8986,20 @@ ir.cpp:
# 658| [Constructor] void C::C()
# 658| :
# 658| :
-# 659| getInitializer(0): [ConstructorFieldInit] constructor init of field m_a
+# 659| getInitializer(0): [ConstructorDirectFieldInit] constructor init of field m_a
# 659| Type = [IntType] int
# 659| ValueCategory = prvalue
# 659| getExpr(): [Literal] 1
# 659| Type = [IntType] int
# 659| Value = [Literal] 1
# 659| ValueCategory = prvalue
-# 663| getInitializer(1): [ConstructorFieldInit] constructor init of field m_b
+# 663| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field m_b
# 663| Type = [Struct] String
# 663| ValueCategory = prvalue
# 663| getExpr(): [ConstructorCall] call to String
# 663| Type = [VoidType] void
# 663| ValueCategory = prvalue
-# 660| getInitializer(2): [ConstructorFieldInit] constructor init of field m_c
+# 660| getInitializer(2): [ConstructorDirectFieldInit] constructor init of field m_c
# 660| Type = [PlainCharType] char
# 660| ValueCategory = prvalue
# 660| getExpr(): [Literal] 3
@@ -9011,14 +9011,14 @@ ir.cpp:
# 660| Type = [PlainCharType] char
# 660| Value = [CStyleCast] 3
# 660| ValueCategory = prvalue
-# 661| getInitializer(3): [ConstructorFieldInit] constructor init of field m_e
+# 661| getInitializer(3): [ConstructorDirectFieldInit] constructor init of field m_e
# 661| Type = [VoidPointerType] void *
# 661| ValueCategory = prvalue
# 661| getExpr(): [Literal] 0
# 661| Type = [VoidPointerType] void *
# 661| Value = [Literal] 0
# 661| ValueCategory = prvalue
-# 662| getInitializer(4): [ConstructorFieldInit] constructor init of field m_f
+# 662| getInitializer(4): [ConstructorDirectFieldInit] constructor init of field m_f
# 662| Type = [Struct] String
# 662| ValueCategory = prvalue
# 662| getExpr(): [ConstructorCall] call to String
@@ -9474,7 +9474,7 @@ ir.cpp:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const Base &
# 745| :
-# 745| getInitializer(0): [ConstructorFieldInit] constructor init of field base_s
+# 745| getInitializer(0): [ConstructorDirectFieldInit] constructor init of field base_s
# 745| Type = [Struct] String
# 745| ValueCategory = prvalue
# 745| getExpr(): [ConstructorCall] call to String
@@ -9485,7 +9485,7 @@ ir.cpp:
# 748| [Constructor] void Base::Base()
# 748| :
# 748| :
-# 748| getInitializer(0): [ConstructorFieldInit] constructor init of field base_s
+# 748| getInitializer(0): [ConstructorDirectFieldInit] constructor init of field base_s
# 748| Type = [Struct] String
# 748| ValueCategory = prvalue
# 748| getExpr(): [ConstructorCall] call to String
@@ -9593,7 +9593,7 @@ ir.cpp:
# 757| getInitializer(0): [ConstructorDirectInit] call to Base
# 757| Type = [VoidType] void
# 757| ValueCategory = prvalue
-# 757| getInitializer(1): [ConstructorFieldInit] constructor init of field middle_s
+# 757| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field middle_s
# 757| Type = [Struct] String
# 757| ValueCategory = prvalue
# 757| getExpr(): [ConstructorCall] call to String
@@ -9704,7 +9704,7 @@ ir.cpp:
# 766| getInitializer(0): [ConstructorDirectInit] call to Middle
# 766| Type = [VoidType] void
# 766| ValueCategory = prvalue
-# 766| getInitializer(1): [ConstructorFieldInit] constructor init of field derived_s
+# 766| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field derived_s
# 766| Type = [Struct] String
# 766| ValueCategory = prvalue
# 766| getExpr(): [ConstructorCall] call to String
@@ -9743,7 +9743,7 @@ ir.cpp:
# 775| getInitializer(0): [ConstructorVirtualInit] call to Base
# 775| Type = [VoidType] void
# 775| ValueCategory = prvalue
-# 775| getInitializer(1): [ConstructorFieldInit] constructor init of field middlevb1_s
+# 775| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field middlevb1_s
# 775| Type = [Struct] String
# 775| ValueCategory = prvalue
# 775| getExpr(): [ConstructorCall] call to String
@@ -9782,7 +9782,7 @@ ir.cpp:
# 784| getInitializer(0): [ConstructorVirtualInit] call to Base
# 784| Type = [VoidType] void
# 784| ValueCategory = prvalue
-# 784| getInitializer(1): [ConstructorFieldInit] constructor init of field middlevb2_s
+# 784| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field middlevb2_s
# 784| Type = [Struct] String
# 784| ValueCategory = prvalue
# 784| getExpr(): [ConstructorCall] call to String
@@ -9827,7 +9827,7 @@ ir.cpp:
# 793| getInitializer(2): [ConstructorDirectInit] call to MiddleVB2
# 793| Type = [VoidType] void
# 793| ValueCategory = prvalue
-# 793| getInitializer(3): [ConstructorFieldInit] constructor init of field derivedvb_s
+# 793| getInitializer(3): [ConstructorDirectFieldInit] constructor init of field derivedvb_s
# 793| Type = [Struct] String
# 793| ValueCategory = prvalue
# 793| getExpr(): [ConstructorCall] call to String
@@ -15190,7 +15190,7 @@ ir.cpp:
# 1508| getInitializer(0): [ConstructorInit] constructor init
# 1508| Type = [Struct] Inheritance_Test_B
# 1508| ValueCategory = prvalue
-# 1508| getInitializer(1): [ConstructorFieldInit] constructor init of field x
+# 1508| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field x
# 1508| Type = [IntType] int
# 1508| ValueCategory = prvalue
# 1508| getExpr(): [Literal] 42
@@ -15414,7 +15414,7 @@ ir.cpp:
# 1533| [Constructor] void StructuredBindingDataMemberMemberStruct::StructuredBindingDataMemberMemberStruct()
# 1533| :
# 1533| :
-# 1533| getInitializer(0): [ConstructorFieldInit] constructor init of field x
+# 1533| getInitializer(0): [ConstructorDefaultFieldInit] constructor init of field x
# 1533| Type = [IntType] int
# 1533| ValueCategory = prvalue
# 1533| getEntryPoint(): [BlockStmt] { ... }
@@ -15434,25 +15434,25 @@ ir.cpp:
# 1537| [Constructor] void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct()
# 1537| :
# 1537| :
-# 1537| getInitializer(0): [ConstructorFieldInit] constructor init of field i
+# 1537| getInitializer(0): [ConstructorDefaultFieldInit] constructor init of field i
# 1537| Type = [IntType] int
# 1537| ValueCategory = prvalue
-# 1537| getInitializer(1): [ConstructorFieldInit] constructor init of field d
+# 1537| getInitializer(1): [ConstructorDefaultFieldInit] constructor init of field d
# 1537| Type = [DoubleType] double
# 1537| ValueCategory = prvalue
-# 1537| getInitializer(2): [ConstructorFieldInit] constructor init of field r
+# 1537| getInitializer(2): [ConstructorDefaultFieldInit] constructor init of field r
# 1537| Type = [LValueReferenceType] int &
# 1537| ValueCategory = prvalue
-# 1537| getInitializer(3): [ConstructorFieldInit] constructor init of field p
+# 1537| getInitializer(3): [ConstructorDefaultFieldInit] constructor init of field p
# 1537| Type = [IntPointerType] int *
# 1537| ValueCategory = prvalue
-# 1537| getInitializer(4): [ConstructorFieldInit] constructor init of field xs
+# 1537| getInitializer(4): [ConstructorDefaultFieldInit] constructor init of field xs
# 1537| Type = [CTypedefType,NestedTypedefType] ArrayType
# 1537| ValueCategory = prvalue
-# 1537| getInitializer(5): [ConstructorFieldInit] constructor init of field r_alt
+# 1537| getInitializer(5): [ConstructorDefaultFieldInit] constructor init of field r_alt
# 1537| Type = [CTypedefType,NestedTypedefType] RefType
# 1537| ValueCategory = prvalue
-# 1537| getInitializer(6): [ConstructorFieldInit] constructor init of field m
+# 1537| getInitializer(6): [ConstructorDirectFieldInit] constructor init of field m
# 1537| Type = [Struct] StructuredBindingDataMemberMemberStruct
# 1537| ValueCategory = prvalue
# 1537| getExpr(): [ConstructorCall] call to StructuredBindingDataMemberMemberStruct
@@ -15465,7 +15465,7 @@ ir.cpp:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const StructuredBindingDataMemberStruct &
# 1537| :
-# 1537| getInitializer(0): [ConstructorFieldInit] constructor init of field i
+# 1537| getInitializer(0): [ConstructorDirectFieldInit] constructor init of field i
# 1537| Type = [IntType] int
# 1537| ValueCategory = prvalue
# 1537| getExpr(): [ReferenceFieldAccess] i
@@ -15477,7 +15477,7 @@ ir.cpp:
# 1537| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1537| Type = [SpecifiedType] const StructuredBindingDataMemberStruct
# 1537| ValueCategory = lvalue
-# 1537| getInitializer(1): [ConstructorFieldInit] constructor init of field d
+# 1537| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field d
# 1537| Type = [DoubleType] double
# 1537| ValueCategory = prvalue
# 1537| getExpr(): [ReferenceFieldAccess] d
@@ -15489,7 +15489,7 @@ ir.cpp:
# 1537| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1537| Type = [SpecifiedType] const StructuredBindingDataMemberStruct
# 1537| ValueCategory = lvalue
-# 1537| getInitializer(2): [ConstructorFieldInit] constructor init of field b
+# 1537| getInitializer(2): [ConstructorDirectFieldInit] constructor init of field b
# 1537| Type = [IntType] unsigned int
# 1537| ValueCategory = prvalue
# 1537| getExpr(): [ReferenceFieldAccess] b
@@ -15501,7 +15501,7 @@ ir.cpp:
# 1537| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1537| Type = [SpecifiedType] const StructuredBindingDataMemberStruct
# 1537| ValueCategory = lvalue
-# 1537| getInitializer(3): [ConstructorFieldInit] constructor init of field r
+# 1537| getInitializer(3): [ConstructorDirectFieldInit] constructor init of field r
# 1537| Type = [LValueReferenceType] int &
# 1537| ValueCategory = prvalue
# 1537| getExpr(): [ReferenceFieldAccess] r
@@ -15513,7 +15513,7 @@ ir.cpp:
# 1537| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1537| Type = [SpecifiedType] const StructuredBindingDataMemberStruct
# 1537| ValueCategory = lvalue
-# 1537| getInitializer(4): [ConstructorFieldInit] constructor init of field p
+# 1537| getInitializer(4): [ConstructorDirectFieldInit] constructor init of field p
# 1537| Type = [IntPointerType] int *
# 1537| ValueCategory = prvalue
# 1537| getExpr(): [ReferenceFieldAccess] p
@@ -15525,7 +15525,7 @@ ir.cpp:
# 1537| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1537| Type = [SpecifiedType] const StructuredBindingDataMemberStruct
# 1537| ValueCategory = lvalue
-# 1537| getInitializer(5): [ConstructorFieldInit] constructor init of field xs
+# 1537| getInitializer(5): [ConstructorDirectFieldInit] constructor init of field xs
# 1537| Type = [CTypedefType,NestedTypedefType] ArrayType
# 1537| ValueCategory = prvalue
# 1537| getExpr(): [ReferenceFieldAccess] xs
@@ -15537,7 +15537,7 @@ ir.cpp:
# 1537| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1537| Type = [SpecifiedType] const StructuredBindingDataMemberStruct
# 1537| ValueCategory = lvalue
-# 1537| getInitializer(6): [ConstructorFieldInit] constructor init of field r_alt
+# 1537| getInitializer(6): [ConstructorDirectFieldInit] constructor init of field r_alt
# 1537| Type = [CTypedefType,NestedTypedefType] RefType
# 1537| ValueCategory = prvalue
# 1537| getExpr(): [ReferenceFieldAccess] r_alt
@@ -15549,7 +15549,7 @@ ir.cpp:
# 1537| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1537| Type = [SpecifiedType] const StructuredBindingDataMemberStruct
# 1537| ValueCategory = lvalue
-# 1537| getInitializer(7): [ConstructorFieldInit] constructor init of field m
+# 1537| getInitializer(7): [ConstructorDirectFieldInit] constructor init of field m
# 1537| Type = [Struct] StructuredBindingDataMemberMemberStruct
# 1537| ValueCategory = prvalue
# 1537| getExpr(): [ReferenceFieldAccess] m
@@ -15918,13 +15918,13 @@ ir.cpp:
# 1590| [Constructor] void StructuredBindingTupleRefGet::StructuredBindingTupleRefGet()
# 1590| :
# 1590| :
-# 1590| getInitializer(0): [ConstructorFieldInit] constructor init of field i
+# 1590| getInitializer(0): [ConstructorDefaultFieldInit] constructor init of field i
# 1590| Type = [IntType] int
# 1590| ValueCategory = prvalue
-# 1590| getInitializer(1): [ConstructorFieldInit] constructor init of field d
+# 1590| getInitializer(1): [ConstructorDefaultFieldInit] constructor init of field d
# 1590| Type = [DoubleType] double
# 1590| ValueCategory = prvalue
-# 1590| getInitializer(2): [ConstructorFieldInit] constructor init of field r
+# 1590| getInitializer(2): [ConstructorDefaultFieldInit] constructor init of field r
# 1590| Type = [LValueReferenceType] int &
# 1590| ValueCategory = prvalue
# 1590| getEntryPoint(): [BlockStmt] { ... }
@@ -15934,7 +15934,7 @@ ir.cpp:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const StructuredBindingTupleRefGet &
# 1590| :
-# 1590| getInitializer(0): [ConstructorFieldInit] constructor init of field i
+# 1590| getInitializer(0): [ConstructorDirectFieldInit] constructor init of field i
# 1590| Type = [IntType] int
# 1590| ValueCategory = prvalue
# 1590| getExpr(): [ReferenceFieldAccess] i
@@ -15946,7 +15946,7 @@ ir.cpp:
# 1590| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1590| Type = [SpecifiedType] const StructuredBindingTupleRefGet
# 1590| ValueCategory = lvalue
-# 1590| getInitializer(1): [ConstructorFieldInit] constructor init of field d
+# 1590| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field d
# 1590| Type = [DoubleType] double
# 1590| ValueCategory = prvalue
# 1590| getExpr(): [ReferenceFieldAccess] d
@@ -15958,7 +15958,7 @@ ir.cpp:
# 1590| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 1590| Type = [SpecifiedType] const StructuredBindingTupleRefGet
# 1590| ValueCategory = lvalue
-# 1590| getInitializer(2): [ConstructorFieldInit] constructor init of field r
+# 1590| getInitializer(2): [ConstructorDirectFieldInit] constructor init of field r
# 1590| Type = [LValueReferenceType] int &
# 1590| ValueCategory = prvalue
# 1590| getExpr(): [ReferenceFieldAccess] r
@@ -16327,10 +16327,10 @@ ir.cpp:
# 1657| [Constructor] void StructuredBindingTupleNoRefGet::StructuredBindingTupleNoRefGet()
# 1657| :
# 1657| :
-# 1657| getInitializer(0): [ConstructorFieldInit] constructor init of field i
+# 1657| getInitializer(0): [ConstructorDefaultFieldInit] constructor init of field i
# 1657| Type = [IntType] int
# 1657| ValueCategory = prvalue
-# 1657| getInitializer(1): [ConstructorFieldInit] constructor init of field r
+# 1657| getInitializer(1): [ConstructorDefaultFieldInit] constructor init of field r
# 1657| Type = [LValueReferenceType] int &
# 1657| ValueCategory = prvalue
# 1657| getEntryPoint(): [BlockStmt] { ... }
@@ -19817,7 +19817,7 @@ ir.cpp:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const ClassWithDestructor &
# 2188| :
-# 2188| getInitializer(0): [ConstructorFieldInit] constructor init of field x
+# 2188| getInitializer(0): [ConstructorDirectFieldInit] constructor init of field x
# 2188| Type = [CharPointerType] char *
# 2188| ValueCategory = prvalue
# 2188| getExpr(): [ReferenceFieldAccess] x
@@ -25642,6 +25642,168 @@ ir.cpp:
# 2884| Type = [VoidType] void
# 2884| ValueCategory = prvalue
# 2886| getStmt(6): [ReturnStmt] return ...
+# 2889| [CopyAssignmentOperator] StructInit& StructInit::operator=(StructInit const&)
+# 2889| :
+#-----| getParameter(0): [Parameter] (unnamed parameter 0)
+#-----| Type = [LValueReferenceType] const StructInit &
+# 2889| [MoveAssignmentOperator] StructInit& StructInit::operator=(StructInit&&)
+# 2889| :
+#-----| getParameter(0): [Parameter] (unnamed parameter 0)
+#-----| Type = [RValueReferenceType] StructInit &&
+# 2889| [CopyConstructor] void StructInit::StructInit(StructInit const&)
+# 2889| :
+#-----| getParameter(0): [Parameter] (unnamed parameter 0)
+#-----| Type = [LValueReferenceType] const StructInit &
+# 2889| [MoveConstructor] void StructInit::StructInit(StructInit&&)
+# 2889| :
+#-----| getParameter(0): [Parameter] (unnamed parameter 0)
+#-----| Type = [RValueReferenceType] StructInit &&
+# 2897| [Constructor] void StructInit::StructInit(int)
+# 2897| :
+# 2897| getParameter(0): [Parameter] j
+# 2897| Type = [IntType] int
+# 2897| :
+# 2897| getInitializer(0): [ConstructorDefaultFieldInit] constructor init of field i
+# 2897| Type = [IntType] int
+# 2897| ValueCategory = prvalue
+# 2897| getInitializer(1): [ConstructorDirectFieldInit] constructor init of field j
+# 2897| Type = [IntType] int
+# 2897| ValueCategory = prvalue
+# 2897| getExpr(): [VariableAccess] j
+# 2897| Type = [IntType] int
+# 2897| ValueCategory = prvalue(load)
+# 2897| getInitializer(2): [ConstructorDefaultFieldInit] constructor init of field k
+# 2897| Type = [IntType] int
+# 2897| ValueCategory = prvalue
+# 2897| getInitializer(3): [ConstructorDefaultFieldInit] constructor init of field l
+# 2897| Type = [IntType] int
+# 2897| ValueCategory = prvalue
+# 2897| getInitializer(4): [ConstructorDefaultFieldInit] constructor init of field m
+# 2897| Type = [IntType] int
+# 2897| ValueCategory = prvalue
+# 2897| getInitializer(5): [ConstructorDirectFieldInit] constructor init of field n
+# 2897| Type = [IntType] int
+# 2897| ValueCategory = prvalue
+# 2897| getExpr(): [FunctionCall] call to get_val
+# 2897| Type = [IntType] int
+# 2897| ValueCategory = prvalue
+# 2897| getQualifier(): [ThisExpr] this
+# 2897| Type = [PointerType] StructInit *
+# 2897| ValueCategory = prvalue(load)
+# 2897| getEntryPoint(): [BlockStmt] { ... }
+# 2897| getStmt(0): [ReturnStmt] return ...
+# 2899| [Constructor] void StructInit::StructInit()
+# 2899| :
+# 2899| :
+# 2899| getInitializer(0): [ConstructorDirectFieldInit] constructor init of field i
+# 2899| Type = [IntType] int
+# 2899| ValueCategory = prvalue
+# 2899| getExpr(): [Literal] 41
+# 2899| Type = [IntType] int
+# 2899| Value = [Literal] 41
+# 2899| ValueCategory = prvalue
+# 2899| getInitializer(1): [ConstructorDefaultFieldInit] constructor init of field j
+# 2899| Type = [IntType] int
+# 2899| ValueCategory = prvalue
+# 2899| getInitializer(2): [ConstructorDirectFieldInit] constructor init of field k
+# 2899| Type = [IntType] int
+# 2899| ValueCategory = prvalue
+# 2899| getExpr(): [Literal] 41
+# 2899| Type = [IntType] int
+# 2899| Value = [Literal] 41
+# 2899| ValueCategory = prvalue
+# 2899| getInitializer(3): [ConstructorDefaultFieldInit] constructor init of field l
+# 2899| Type = [IntType] int
+# 2899| ValueCategory = prvalue
+# 2899| getInitializer(4): [ConstructorDefaultFieldInit] constructor init of field m
+# 2899| Type = [IntType] int
+# 2899| ValueCategory = prvalue
+# 2899| getInitializer(5): [ConstructorDefaultFieldInit] constructor init of field n
+# 2899| Type = [IntType] int
+# 2899| ValueCategory = prvalue
+# 2899| getEntryPoint(): [BlockStmt] { ... }
+# 2899| getStmt(0): [ReturnStmt] return ...
+# 2901| [MemberFunction] int StructInit::get_val()
+# 2901| :
+# 2901| getEntryPoint(): [BlockStmt] { ... }
+# 2901| getStmt(0): [ReturnStmt] return ...
+# 2901| getExpr(): [ImplicitThisFieldAccess,PointerFieldAccess] k
+# 2901| Type = [IntType] int
+# 2901| ValueCategory = prvalue(load)
+# 2901| getQualifier(): [ThisExpr] this
+# 2901| Type = [PointerType] StructInit *
+# 2901| ValueCategory = prvalue(load)
+# 2905| [Constructor] void StructInitFromTemplate::StructInitFromTemplate()
+# 2905| :
+# 2905| :
+# 2905| getInitializer(0): [ConstructorDefaultFieldInit] constructor init of field t
+# 2905| Type = [IntType] int
+# 2905| ValueCategory = prvalue
+# 2905| getEntryPoint(): [BlockStmt] { ... }
+# 2905| getStmt(0): [ReturnStmt] return ...
+# 2909| [GlobalVariable] StructInitFromTemplate StructInitFromTemplateVar
+#-----| getInitializer(): [Initializer] initializer for StructInitFromTemplateVar
+#-----| getExpr(): [ConstructorCall] call to StructInitFromTemplate
+#-----| Type = [VoidType] void
+#-----| ValueCategory = prvalue
+#-----| getExpr().getFullyConverted(): [TemporaryObjectExpr] temporary object
+#-----| Type = [ClassTemplateInstantiation,Struct] StructInitFromTemplate
+#-----| ValueCategory = prvalue(load)
+# 2912| [GlobalVariable,VariableTemplateInstantiation] double VariableTemplate
+# 2912| getInitializer(): [Initializer] initializer for VariableTemplate
+# 2912| getExpr(): [Literal] 42
+# 2912| Type = [IntType] int
+# 2912| Value = [Literal] 42
+# 2912| ValueCategory = prvalue
+# 2912| getExpr().getFullyConverted(): [CStyleCast] (double)...
+# 2912| Conversion = [IntegralToFloatingPointConversion] integral to floating point conversion
+# 2912| Type = [DoubleType] double
+# 2912| Value = [CStyleCast] 42.0
+# 2912| ValueCategory = prvalue
+# 2915| [TemplateFunction,TopLevelFunction] T VariableTemplateFunc(T)
+# 2915| :
+# 2915| getParameter(0): [Parameter] x
+# 2915| Type = [TypeTemplateParameter] T
+# 2915| getEntryPoint(): [BlockStmt] { ... }
+# 2916| getStmt(0): [ReturnStmt] return ...
+# 2916| getExpr(): [AddExpr] ... + ...
+# 2916| Type = [UnknownType] unknown
+# 2916| ValueCategory = prvalue
+# 2916| getLeftOperand(): [VariableAccess] VariableTemplate
+# 2916| Type = [UnknownType] unknown
+# 2916| ValueCategory = lvalue
+# 2916| getRightOperand(): [VariableAccess] x
+# 2916| Type = [TypeTemplateParameter] T
+# 2916| ValueCategory = lvalue
+# 2915| [FunctionTemplateInstantiation,TopLevelFunction] double VariableTemplateFunc(double)
+# 2915| :
+# 2915| getParameter(0): [Parameter] x
+# 2915| Type = [DoubleType] double
+# 2915| getEntryPoint(): [BlockStmt] { ... }
+# 2916| getStmt(0): [ReturnStmt] return ...
+# 2916| getExpr(): [AddExpr] ... + ...
+# 2916| Type = [DoubleType] double
+# 2916| ValueCategory = prvalue
+# 2916| getLeftOperand(): [VariableAccess] VariableTemplate
+# 2916| Type = [DoubleType] double
+# 2916| Value = [VariableAccess] 42.0
+# 2916| ValueCategory = prvalue(load)
+# 2916| getRightOperand(): [VariableAccess] x
+# 2916| Type = [DoubleType] double
+# 2916| ValueCategory = prvalue(load)
+# 2919| [GlobalVariable] int VariableTemplateFuncUse
+# 2919| getInitializer(): [Initializer] initializer for VariableTemplateFuncUse
+# 2919| getExpr(): [FunctionCall] call to VariableTemplateFunc
+# 2919| Type = [DoubleType] double
+# 2919| ValueCategory = prvalue
+# 2919| getArgument(0): [Literal] 2.299999999999999822
+# 2919| Type = [DoubleType] double
+# 2919| Value = [Literal] 2.299999999999999822
+# 2919| ValueCategory = prvalue
+# 2919| getExpr().getFullyConverted(): [CStyleCast] (int)...
+# 2919| Conversion = [FloatingPointToIntegralConversion] floating point to integral conversion
+# 2919| Type = [IntType] int
+# 2919| ValueCategory = prvalue
ir23.cpp:
# 1| [TopLevelFunction] bool consteval_1()
# 1| :
@@ -50386,7 +50548,7 @@ perf-regression.cpp:
# 6| [Constructor] void Big::Big()
# 6| :
# 6| :
-# 6| getInitializer(0): [ConstructorFieldInit] constructor init of field buffer
+# 6| getInitializer(0): [ConstructorDirectFieldInit] constructor init of field buffer
# 6| Type = [ArrayType] char[1073741824]
# 6| ValueCategory = prvalue
# 6| getExpr(): [ArrayAggregateLiteral] {...}
diff --git a/cpp/ql/test/library-tests/ir/ir/PrintConfig.qll b/cpp/ql/test/library-tests/ir/ir/PrintConfig.qll
index aa23cf423add..6e98d23bcf47 100644
--- a/cpp/ql/test/library-tests/ir/ir/PrintConfig.qll
+++ b/cpp/ql/test/library-tests/ir/ir/PrintConfig.qll
@@ -20,5 +20,7 @@ predicate shouldDumpDeclaration(Declaration decl) {
decl.(GlobalOrNamespaceVariable).hasInitializer()
or
decl.(StaticLocalVariable).hasInitializer()
+ or
+ decl.(Field).hasInitializer()
)
}
diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
index 369cc9495a2b..66810913e5d3 100644
--- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
+++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
@@ -12361,35 +12361,111 @@ ir.cpp:
# 1533| void StructuredBindingDataMemberMemberStruct::StructuredBindingDataMemberMemberStruct()
# 1533| Block 0
-# 1533| v1533_1(void) = EnterFunction :
-# 1533| m1533_2(unknown) = AliasedDefinition :
-# 1533| m1533_3(unknown) = InitializeNonLocal :
-# 1533| m1533_4(unknown) = Chi : total:m1533_2, partial:m1533_3
-# 1533| r1533_5(glval) = VariableAddress[#this] :
-# 1533| m1533_6(glval) = InitializeParameter[#this] : &:r1533_5
-# 1533| r1533_7(glval) = Load[#this] : &:r1533_5, m1533_6
-# 1533| m1533_8(StructuredBindingDataMemberMemberStruct) = InitializeIndirection[#this] : &:r1533_7
-# 1533| v1533_9(void) = NoOp :
-# 1533| v1533_10(void) = ReturnIndirection[#this] : &:r1533_7, m1533_8
-# 1533| v1533_11(void) = ReturnVoid :
-# 1533| v1533_12(void) = AliasedUse : m1533_3
-# 1533| v1533_13(void) = ExitFunction :
+# 1533| v1533_1(void) = EnterFunction :
+# 1533| m1533_2(unknown) = AliasedDefinition :
+# 1533| m1533_3(unknown) = InitializeNonLocal :
+# 1533| m1533_4(unknown) = Chi : total:m1533_2, partial:m1533_3
+# 1533| r1533_5(glval) = VariableAddress[#this] :
+# 1533| m1533_6(glval) = InitializeParameter[#this] : &:r1533_5
+# 1533| r1533_7(glval) = Load[#this] : &:r1533_5, m1533_6
+# 1533| m1533_8(StructuredBindingDataMemberMemberStruct) = InitializeIndirection[#this] : &:r1533_7
+# 1533| m1533_9(unknown) = Chi : total:m1533_4, partial:m1533_8
+# 1533| r1533_10(glval) = FunctionAddress[x] :
+# 1533| v1533_11(void) = Call[x] : func:r1533_10, this:r1533_7
+# 1533| m1533_12(unknown) = ^CallSideEffect : ~m1533_9
+# 1533| m1533_13(unknown) = Chi : total:m1533_9, partial:m1533_12
+# 1533| v1533_14(void) = ^IndirectReadSideEffect[-1] : &:r1533_7, ~m1533_13
+# 1533| m1533_15(StructuredBindingDataMemberMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1533_7
+# 1533| m1533_16(unknown) = Chi : total:m1533_13, partial:m1533_15
+# 1533| v1533_17(void) = NoOp :
+# 1533| v1533_18(void) = ReturnIndirection[#this] : &:r1533_7, ~m1533_16
+# 1533| v1533_19(void) = ReturnVoid :
+# 1533| v1533_20(void) = AliasedUse : ~m1533_16
+# 1533| v1533_21(void) = ExitFunction :
+
+# 1534| int StructuredBindingDataMemberMemberStruct::x
+# 1534| Block 0
+# 1534| v1534_1(void) = EnterFunction :
+# 1534| m1534_2(unknown) = AliasedDefinition :
+# 1534| m1534_3(unknown) = InitializeNonLocal :
+# 1534| m1534_4(unknown) = Chi : total:m1534_2, partial:m1534_3
+# 1534| r1534_5(glval) = VariableAddress[#this] :
+# 1534| m1534_6(glval) = InitializeParameter[#this] : &:r1534_5
+# 1534| r1534_7(glval) = Load[#this] : &:r1534_5, m1534_6
+# 1534| m1534_8(StructuredBindingDataMemberMemberStruct) = InitializeIndirection[#this] : &:r1534_7
+# 1534| r1534_9(glval) = FieldAddress[x] : r1534_7
+# 1534| r1534_10(int) = Constant[5] :
+# 1534| m1534_11(int) = Store[?] : &:r1534_9, r1534_10
+# 1534| m1534_12(unknown) = Chi : total:m1534_8, partial:m1534_11
+# 1534| v1534_13(void) = ReturnVoid :
+# 1534| v1534_14(void) = AliasedUse : m1534_3
+# 1534| v1534_15(void) = ExitFunction :
# 1537| void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct()
# 1537| Block 0
-# 1537| v1537_1(void) = EnterFunction :
-# 1537| m1537_2(unknown) = AliasedDefinition :
-# 1537| m1537_3(unknown) = InitializeNonLocal :
-# 1537| m1537_4(unknown) = Chi : total:m1537_2, partial:m1537_3
-# 1537| r1537_5(glval) = VariableAddress[#this] :
-# 1537| m1537_6(glval) = InitializeParameter[#this] : &:r1537_5
-# 1537| r1537_7(glval) = Load[#this] : &:r1537_5, m1537_6
-# 1537| m1537_8(StructuredBindingDataMemberStruct) = InitializeIndirection[#this] : &:r1537_7
-# 1537| v1537_9(void) = NoOp :
-# 1537| v1537_10(void) = ReturnIndirection[#this] : &:r1537_7, m1537_8
-# 1537| v1537_11(void) = ReturnVoid :
-# 1537| v1537_12(void) = AliasedUse : m1537_3
-# 1537| v1537_13(void) = ExitFunction :
+# 1537| v1537_1(void) = EnterFunction :
+# 1537| m1537_2(unknown) = AliasedDefinition :
+# 1537| m1537_3(unknown) = InitializeNonLocal :
+# 1537| m1537_4(unknown) = Chi : total:m1537_2, partial:m1537_3
+# 1537| r1537_5(glval) = VariableAddress[#this] :
+# 1537| m1537_6(glval) = InitializeParameter[#this] : &:r1537_5
+# 1537| r1537_7(glval) = Load[#this] : &:r1537_5, m1537_6
+# 1537| m1537_8(StructuredBindingDataMemberStruct) = InitializeIndirection[#this] : &:r1537_7
+# 1537| m1537_9(unknown) = Chi : total:m1537_4, partial:m1537_8
+# 1537| r1537_10(glval) = FunctionAddress[i] :
+# 1537| v1537_11(void) = Call[i] : func:r1537_10, this:r1537_7
+# 1537| m1537_12(unknown) = ^CallSideEffect : ~m1537_9
+# 1537| m1537_13(unknown) = Chi : total:m1537_9, partial:m1537_12
+# 1537| v1537_14(void) = ^IndirectReadSideEffect[-1] : &:r1537_7, ~m1537_13
+# 1537| m1537_15(StructuredBindingDataMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1537_7
+# 1537| m1537_16(unknown) = Chi : total:m1537_13, partial:m1537_15
+# 1537| r1537_17(glval) = FunctionAddress[d] :
+# 1537| v1537_18(void) = Call[d] : func:r1537_17, this:r1537_7
+# 1537| m1537_19(unknown) = ^CallSideEffect : ~m1537_16
+# 1537| m1537_20(unknown) = Chi : total:m1537_16, partial:m1537_19
+# 1537| v1537_21(void) = ^IndirectReadSideEffect[-1] : &:r1537_7, ~m1537_20
+# 1537| m1537_22(StructuredBindingDataMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1537_7
+# 1537| m1537_23(unknown) = Chi : total:m1537_20, partial:m1537_22
+# 1537| r1537_24(glval) = FunctionAddress[r] :
+# 1537| v1537_25(void) = Call[r] : func:r1537_24, this:r1537_7
+# 1537| m1537_26(unknown) = ^CallSideEffect : ~m1537_23
+# 1537| m1537_27(unknown) = Chi : total:m1537_23, partial:m1537_26
+# 1537| v1537_28(void) = ^IndirectReadSideEffect[-1] : &:r1537_7, ~m1537_27
+# 1537| m1537_29(StructuredBindingDataMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1537_7
+# 1537| m1537_30(unknown) = Chi : total:m1537_27, partial:m1537_29
+# 1537| r1537_31(glval) = FunctionAddress[p] :
+# 1537| v1537_32(void) = Call[p] : func:r1537_31, this:r1537_7
+# 1537| m1537_33(unknown) = ^CallSideEffect : ~m1537_30
+# 1537| m1537_34(unknown) = Chi : total:m1537_30, partial:m1537_33
+# 1537| v1537_35(void) = ^IndirectReadSideEffect[-1] : &:r1537_7, ~m1537_34
+# 1537| m1537_36(StructuredBindingDataMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1537_7
+# 1537| m1537_37(unknown) = Chi : total:m1537_34, partial:m1537_36
+# 1537| r1537_38(glval) = FunctionAddress[xs] :
+# 1537| v1537_39(void) = Call[xs] : func:r1537_38, this:r1537_7
+# 1537| m1537_40(unknown) = ^CallSideEffect : ~m1537_37
+# 1537| m1537_41(unknown) = Chi : total:m1537_37, partial:m1537_40
+# 1537| v1537_42(void) = ^IndirectReadSideEffect[-1] : &:r1537_7, ~m1537_41
+# 1537| m1537_43(StructuredBindingDataMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1537_7
+# 1537| m1537_44(unknown) = Chi : total:m1537_41, partial:m1537_43
+# 1537| r1537_45(glval) = FunctionAddress[r_alt] :
+# 1537| v1537_46(void) = Call[r_alt] : func:r1537_45, this:r1537_7
+# 1537| m1537_47(unknown) = ^CallSideEffect : ~m1537_44
+# 1537| m1537_48(unknown) = Chi : total:m1537_44, partial:m1537_47
+# 1537| v1537_49(void) = ^IndirectReadSideEffect[-1] : &:r1537_7, ~m1537_48
+# 1537| m1537_50(StructuredBindingDataMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1537_7
+# 1537| m1537_51(unknown) = Chi : total:m1537_48, partial:m1537_50
+# 1537| r1537_52(glval) = FieldAddress[m] : r1537_7
+# 1537| r1537_53(glval) = FunctionAddress[StructuredBindingDataMemberMemberStruct] :
+# 1537| v1537_54(void) = Call[StructuredBindingDataMemberMemberStruct] : func:r1537_53, this:r1537_52
+# 1537| m1537_55(unknown) = ^CallSideEffect : ~m1537_51
+# 1537| m1537_56(unknown) = Chi : total:m1537_51, partial:m1537_55
+# 1537| m1537_57(StructuredBindingDataMemberMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1537_52
+# 1537| m1537_58(unknown) = Chi : total:m1537_56, partial:m1537_57
+# 1537| v1537_59(void) = NoOp :
+# 1537| v1537_60(void) = ReturnIndirection[#this] : &:r1537_7, ~m1537_58
+# 1537| v1537_61(void) = ReturnVoid :
+# 1537| v1537_62(void) = AliasedUse : ~m1537_58
+# 1537| v1537_63(void) = ExitFunction :
# 1537| void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct(StructuredBindingDataMemberStruct const&)
# 1537| Block 0
@@ -12476,6 +12552,130 @@ ir.cpp:
# 1537| v1537_76(void) = AliasedUse : m1537_3
# 1537| v1537_77(void) = ExitFunction :
+# 1540| int StructuredBindingDataMemberStruct::i
+# 1540| Block 0
+# 1540| v1540_1(void) = EnterFunction :
+# 1540| m1540_2(unknown) = AliasedDefinition :
+# 1540| m1540_3(unknown) = InitializeNonLocal :
+# 1540| m1540_4(unknown) = Chi : total:m1540_2, partial:m1540_3
+# 1540| r1540_5(glval) = VariableAddress[#this] :
+# 1540| m1540_6(glval) = InitializeParameter[#this] : &:r1540_5
+# 1540| r1540_7(glval) = Load[#this] : &:r1540_5, m1540_6
+# 1540| m1540_8(StructuredBindingDataMemberStruct) = InitializeIndirection[#this] : &:r1540_7
+# 1540| r1540_9(glval) = FieldAddress[i] : r1540_7
+# 1540| r1540_10(int) = Constant[1] :
+# 1540| m1540_11(int) = Store[?] : &:r1540_9, r1540_10
+# 1540| m1540_12(unknown) = Chi : total:m1540_8, partial:m1540_11
+# 1540| v1540_13(void) = ReturnVoid :
+# 1540| v1540_14(void) = AliasedUse : m1540_3
+# 1540| v1540_15(void) = ExitFunction :
+
+# 1541| double StructuredBindingDataMemberStruct::d
+# 1541| Block 0
+# 1541| v1541_1(void) = EnterFunction :
+# 1541| m1541_2(unknown) = AliasedDefinition :
+# 1541| m1541_3(unknown) = InitializeNonLocal :
+# 1541| m1541_4(unknown) = Chi : total:m1541_2, partial:m1541_3
+# 1541| r1541_5(glval) = VariableAddress[#this] :
+# 1541| m1541_6(glval) = InitializeParameter[#this] : &:r1541_5
+# 1541| r1541_7(glval) = Load[#this] : &:r1541_5, m1541_6
+# 1541| m1541_8(StructuredBindingDataMemberStruct) = InitializeIndirection[#this] : &:r1541_7
+# 1541| r1541_9(glval) = FieldAddress[d] : r1541_7
+# 1541| r1541_10(double) = Constant[2.0] :
+# 1541| m1541_11(double) = Store[?] : &:r1541_9, r1541_10
+# 1541| m1541_12(unknown) = Chi : total:m1541_8, partial:m1541_11
+# 1541| v1541_13(void) = ReturnVoid :
+# 1541| v1541_14(void) = AliasedUse : m1541_3
+# 1541| v1541_15(void) = ExitFunction :
+
+# 1543| int& StructuredBindingDataMemberStruct::r
+# 1543| Block 0
+# 1543| v1543_1(void) = EnterFunction :
+# 1543| m1543_2(unknown) = AliasedDefinition :
+# 1543| m1543_3(unknown) = InitializeNonLocal :
+# 1543| m1543_4(unknown) = Chi : total:m1543_2, partial:m1543_3
+# 1543| r1543_5(glval) = VariableAddress[#this] :
+# 1543| m1543_6(glval) = InitializeParameter[#this] : &:r1543_5
+# 1543| r1543_7(glval) = Load[#this] : &:r1543_5, m1543_6
+# 1543| m1543_8(StructuredBindingDataMemberStruct) = InitializeIndirection[#this] : &:r1543_7
+# 1543| m1543_9(unknown) = Chi : total:m1543_4, partial:m1543_8
+# 1543| r1543_10(glval) = FieldAddress[r] : r1543_7
+# 1543| r1543_11(StructuredBindingDataMemberStruct *) = CopyValue : r1543_7
+# 1543| r1543_12(glval) = FieldAddress[i] : r1543_11
+#-----| r0_1(int &) = CopyValue : r1543_12
+#-----| m0_2(int &) = Store[?] : &:r1543_10, r0_1
+#-----| m0_3(unknown) = Chi : total:m1543_9, partial:m0_2
+# 1543| v1543_13(void) = ReturnVoid :
+# 1543| v1543_14(void) = AliasedUse : ~m0_3
+# 1543| v1543_15(void) = ExitFunction :
+
+# 1544| int* StructuredBindingDataMemberStruct::p
+# 1544| Block 0
+# 1544| v1544_1(void) = EnterFunction :
+# 1544| m1544_2(unknown) = AliasedDefinition :
+# 1544| m1544_3(unknown) = InitializeNonLocal :
+# 1544| m1544_4(unknown) = Chi : total:m1544_2, partial:m1544_3
+# 1544| r1544_5(glval) = VariableAddress[#this] :
+# 1544| m1544_6(glval) = InitializeParameter[#this] : &:r1544_5
+# 1544| r1544_7(glval) = Load[#this] : &:r1544_5, m1544_6
+# 1544| m1544_8(StructuredBindingDataMemberStruct) = InitializeIndirection[#this] : &:r1544_7
+# 1544| m1544_9(unknown) = Chi : total:m1544_4, partial:m1544_8
+# 1544| r1544_10(glval) = FieldAddress[p] : r1544_7
+# 1544| r1544_11(StructuredBindingDataMemberStruct *) = CopyValue : r1544_7
+# 1544| r1544_12(glval) = FieldAddress[i] : r1544_11
+# 1544| r1544_13(int *) = CopyValue : r1544_12
+# 1544| m1544_14(int *) = Store[?] : &:r1544_10, r1544_13
+# 1544| m1544_15(unknown) = Chi : total:m1544_9, partial:m1544_14
+# 1544| v1544_16(void) = ReturnVoid :
+# 1544| v1544_17(void) = AliasedUse : ~m1544_15
+# 1544| v1544_18(void) = ExitFunction :
+
+# 1545| StructuredBindingDataMemberStruct::ArrayType StructuredBindingDataMemberStruct::xs
+# 1545| Block 0
+# 1545| v1545_1(void) = EnterFunction :
+# 1545| m1545_2(unknown) = AliasedDefinition :
+# 1545| m1545_3(unknown) = InitializeNonLocal :
+# 1545| m1545_4(unknown) = Chi : total:m1545_2, partial:m1545_3
+# 1545| r1545_5(glval) = VariableAddress[#this] :
+# 1545| m1545_6(glval) = InitializeParameter[#this] : &:r1545_5
+# 1545| r1545_7(glval) = Load[#this] : &:r1545_5, m1545_6
+# 1545| m1545_8(StructuredBindingDataMemberStruct) = InitializeIndirection[#this] : &:r1545_7
+# 1545| r1545_9(glval) = FieldAddress[xs] : r1545_7
+# 1545| r1545_10(int) = Constant[0] :
+# 1545| r1545_11(glval) = PointerAdd[4] : r1545_9, r1545_10
+# 1545| r1545_12(int) = Constant[1] :
+# 1545| m1545_13(int) = Store[?] : &:r1545_11, r1545_12
+# 1545| m1545_14(unknown) = Chi : total:m1545_8, partial:m1545_13
+# 1545| r1545_15(int) = Constant[1] :
+# 1545| r1545_16(glval) = PointerAdd[4] : r1545_9, r1545_15
+# 1545| r1545_17(int) = Constant[2] :
+# 1545| m1545_18(int) = Store[?] : &:r1545_16, r1545_17
+# 1545| m1545_19(unknown) = Chi : total:m1545_14, partial:m1545_18
+# 1545| v1545_20(void) = ReturnVoid :
+# 1545| v1545_21(void) = AliasedUse : m1545_3
+# 1545| v1545_22(void) = ExitFunction :
+
+# 1546| StructuredBindingDataMemberStruct::RefType StructuredBindingDataMemberStruct::r_alt
+# 1546| Block 0
+# 1546| v1546_1(void) = EnterFunction :
+# 1546| m1546_2(unknown) = AliasedDefinition :
+# 1546| m1546_3(unknown) = InitializeNonLocal :
+# 1546| m1546_4(unknown) = Chi : total:m1546_2, partial:m1546_3
+# 1546| r1546_5(glval) = VariableAddress[#this] :
+# 1546| m1546_6(glval) = InitializeParameter[#this] : &:r1546_5
+# 1546| r1546_7(glval) = Load[#this] : &:r1546_5, m1546_6
+# 1546| m1546_8(StructuredBindingDataMemberStruct) = InitializeIndirection[#this] : &:r1546_7
+# 1546| m1546_9(unknown) = Chi : total:m1546_4, partial:m1546_8
+# 1546| r1546_10(glval) = FieldAddress[r_alt] : r1546_7
+# 1546| r1546_11(StructuredBindingDataMemberStruct *) = CopyValue : r1546_7
+# 1546| r1546_12(glval) = FieldAddress[i] : r1546_11
+#-----| r0_1(int &) = CopyValue : r1546_12
+#-----| m0_2(int &) = Store[?] : &:r1546_10, r0_1
+#-----| m0_3(unknown) = Chi : total:m1546_9, partial:m0_2
+# 1546| v1546_13(void) = ReturnVoid :
+# 1546| v1546_14(void) = AliasedUse : ~m0_3
+# 1546| v1546_15(void) = ExitFunction :
+
# 1550| void data_member_structured_binding()
# 1550| Block 0
# 1550| v1550_1(void) = EnterFunction :
@@ -12484,15 +12684,16 @@ ir.cpp:
# 1550| m1550_4(unknown) = Chi : total:m1550_2, partial:m1550_3
# 1551| r1551_1(glval) = VariableAddress[s] :
# 1551| m1551_2(StructuredBindingDataMemberStruct) = Uninitialized[s] : &:r1551_1
-# 1551| r1551_3(glval) = FunctionAddress[StructuredBindingDataMemberStruct] :
-# 1551| v1551_4(void) = Call[StructuredBindingDataMemberStruct] : func:r1551_3, this:r1551_1
-# 1551| m1551_5(unknown) = ^CallSideEffect : ~m1550_4
-# 1551| m1551_6(unknown) = Chi : total:m1550_4, partial:m1551_5
-# 1551| m1551_7(StructuredBindingDataMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1551_1
-# 1551| m1551_8(StructuredBindingDataMemberStruct) = Chi : total:m1551_2, partial:m1551_7
+# 1551| m1551_3(unknown) = Chi : total:m1550_4, partial:m1551_2
+# 1551| r1551_4(glval) = FunctionAddress[StructuredBindingDataMemberStruct] :
+# 1551| v1551_5(void) = Call[StructuredBindingDataMemberStruct] : func:r1551_4, this:r1551_1
+# 1551| m1551_6(unknown) = ^CallSideEffect : ~m1551_3
+# 1551| m1551_7(unknown) = Chi : total:m1551_3, partial:m1551_6
+# 1551| m1551_8(StructuredBindingDataMemberStruct) = ^IndirectMayWriteSideEffect[-1] : &:r1551_1
+# 1551| m1551_9(unknown) = Chi : total:m1551_7, partial:m1551_8
# 1554| r1554_1(glval) = VariableAddress[(unnamed local variable)] :
# 1554| r1554_2(glval) = VariableAddress[s] :
-# 1554| r1554_3(StructuredBindingDataMemberStruct) = Load[s] : &:r1554_2, m1551_8
+# 1554| r1554_3(StructuredBindingDataMemberStruct) = Load[s] : &:r1554_2, ~m1551_9
# 1554| m1554_4(StructuredBindingDataMemberStruct) = Store[(unnamed local variable)] : &:r1554_1, r1554_3
# 1554| r1554_5(glval) = VariableAddress[i] :
# 1554| r1554_6(glval) = VariableAddress[(unnamed local variable)] :
@@ -12549,7 +12750,7 @@ ir.cpp:
# 1558| r1558_2(glval) = VariableAddress[r] :
# 1558| r1558_3(int &) = Load[r] : &:r1558_2, m1554_22
# 1558| m1558_4(int) = Store[?] : &:r1558_3, r1558_1
-# 1558| m1558_5(unknown) = Chi : total:m1551_6, partial:m1558_4
+# 1558| m1558_5(unknown) = Chi : total:m1551_9, partial:m1558_4
# 1559| r1559_1(int) = Constant[6] :
# 1559| r1559_2(glval) = VariableAddress[p] :
# 1559| r1559_3(int *&) = Load[p] : &:r1559_2, m1554_26
@@ -12574,7 +12775,7 @@ ir.cpp:
# 1562| m1562_5(int) = Store[w] : &:r1562_1, r1562_4
# 1566| r1566_1(glval) = VariableAddress[unnamed_local_variable] :
# 1566| r1566_2(glval) = VariableAddress[s] :
-# 1566| r1566_3(StructuredBindingDataMemberStruct) = Load[s] : &:r1566_2, m1551_8
+# 1566| r1566_3(StructuredBindingDataMemberStruct) = Load[s] : &:r1566_2, ~m1559_7
# 1566| m1566_4(StructuredBindingDataMemberStruct) = Store[unnamed_local_variable] : &:r1566_1, r1566_3
# 1567| r1567_1(glval) = VariableAddress[i] :
# 1567| r1567_2(glval) = VariableAddress[unnamed_local_variable] :
@@ -12652,19 +12853,41 @@ ir.cpp:
# 1590| void StructuredBindingTupleRefGet::StructuredBindingTupleRefGet()
# 1590| Block 0
-# 1590| v1590_1(void) = EnterFunction :
-# 1590| m1590_2(unknown) = AliasedDefinition :
-# 1590| m1590_3(unknown) = InitializeNonLocal :
-# 1590| m1590_4(unknown) = Chi : total:m1590_2, partial:m1590_3
-# 1590| r1590_5(glval) = VariableAddress[#this] :
-# 1590| m1590_6(glval) = InitializeParameter[#this] : &:r1590_5
-# 1590| r1590_7(glval) = Load[#this] : &:r1590_5, m1590_6
-# 1590| m1590_8(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1590_7
-# 1590| v1590_9(void) = NoOp :
-# 1590| v1590_10(void) = ReturnIndirection[#this] : &:r1590_7, m1590_8
-# 1590| v1590_11(void) = ReturnVoid :
-# 1590| v1590_12(void) = AliasedUse : m1590_3
-# 1590| v1590_13(void) = ExitFunction :
+# 1590| v1590_1(void) = EnterFunction :
+# 1590| m1590_2(unknown) = AliasedDefinition :
+# 1590| m1590_3(unknown) = InitializeNonLocal :
+# 1590| m1590_4(unknown) = Chi : total:m1590_2, partial:m1590_3
+# 1590| r1590_5(glval) = VariableAddress[#this] :
+# 1590| m1590_6(glval) = InitializeParameter[#this] : &:r1590_5
+# 1590| r1590_7(glval) = Load[#this] : &:r1590_5, m1590_6
+# 1590| m1590_8(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1590_7
+# 1590| m1590_9(unknown) = Chi : total:m1590_4, partial:m1590_8
+# 1590| r1590_10(glval) = FunctionAddress[i] :
+# 1590| v1590_11(void) = Call[i] : func:r1590_10, this:r1590_7
+# 1590| m1590_12(unknown) = ^CallSideEffect : ~m1590_9
+# 1590| m1590_13(unknown) = Chi : total:m1590_9, partial:m1590_12
+# 1590| v1590_14(void) = ^IndirectReadSideEffect[-1] : &:r1590_7, ~m1590_13
+# 1590| m1590_15(StructuredBindingTupleRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1590_7
+# 1590| m1590_16(unknown) = Chi : total:m1590_13, partial:m1590_15
+# 1590| r1590_17(glval) = FunctionAddress[d] :
+# 1590| v1590_18(void) = Call[d] : func:r1590_17, this:r1590_7
+# 1590| m1590_19(unknown) = ^CallSideEffect : ~m1590_16
+# 1590| m1590_20(unknown) = Chi : total:m1590_16, partial:m1590_19
+# 1590| v1590_21(void) = ^IndirectReadSideEffect[-1] : &:r1590_7, ~m1590_20
+# 1590| m1590_22(StructuredBindingTupleRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1590_7
+# 1590| m1590_23(unknown) = Chi : total:m1590_20, partial:m1590_22
+# 1590| r1590_24(glval) = FunctionAddress[r] :
+# 1590| v1590_25(void) = Call[r] : func:r1590_24, this:r1590_7
+# 1590| m1590_26(unknown) = ^CallSideEffect : ~m1590_23
+# 1590| m1590_27(unknown) = Chi : total:m1590_23, partial:m1590_26
+# 1590| v1590_28(void) = ^IndirectReadSideEffect[-1] : &:r1590_7, ~m1590_27
+# 1590| m1590_29(StructuredBindingTupleRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1590_7
+# 1590| m1590_30(unknown) = Chi : total:m1590_27, partial:m1590_29
+# 1590| v1590_31(void) = NoOp :
+# 1590| v1590_32(void) = ReturnIndirection[#this] : &:r1590_7, ~m1590_30
+# 1590| v1590_33(void) = ReturnVoid :
+# 1590| v1590_34(void) = AliasedUse : ~m1590_30
+# 1590| v1590_35(void) = ExitFunction :
# 1590| void StructuredBindingTupleRefGet::StructuredBindingTupleRefGet(StructuredBindingTupleRefGet const&)
# 1590| Block 0
@@ -12711,6 +12934,63 @@ ir.cpp:
# 1590| v1590_36(void) = AliasedUse : m1590_3
# 1590| v1590_37(void) = ExitFunction :
+# 1591| int StructuredBindingTupleRefGet::i
+# 1591| Block 0
+# 1591| v1591_1(void) = EnterFunction :
+# 1591| m1591_2(unknown) = AliasedDefinition :
+# 1591| m1591_3(unknown) = InitializeNonLocal :
+# 1591| m1591_4(unknown) = Chi : total:m1591_2, partial:m1591_3
+# 1591| r1591_5(glval) = VariableAddress[#this] :
+# 1591| m1591_6(glval) = InitializeParameter[#this] : &:r1591_5
+# 1591| r1591_7(glval) = Load[#this] : &:r1591_5, m1591_6
+# 1591| m1591_8(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1591_7
+# 1591| r1591_9(glval) = FieldAddress[i] : r1591_7
+# 1591| r1591_10(int) = Constant[1] :
+# 1591| m1591_11(int) = Store[?] : &:r1591_9, r1591_10
+# 1591| m1591_12(unknown) = Chi : total:m1591_8, partial:m1591_11
+# 1591| v1591_13(void) = ReturnVoid :
+# 1591| v1591_14(void) = AliasedUse : m1591_3
+# 1591| v1591_15(void) = ExitFunction :
+
+# 1592| double StructuredBindingTupleRefGet::d
+# 1592| Block 0
+# 1592| v1592_1(void) = EnterFunction :
+# 1592| m1592_2(unknown) = AliasedDefinition :
+# 1592| m1592_3(unknown) = InitializeNonLocal :
+# 1592| m1592_4(unknown) = Chi : total:m1592_2, partial:m1592_3
+# 1592| r1592_5(glval) = VariableAddress[#this] :
+# 1592| m1592_6(glval) = InitializeParameter[#this] : &:r1592_5
+# 1592| r1592_7(glval) = Load[#this] : &:r1592_5, m1592_6
+# 1592| m1592_8(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1592_7
+# 1592| r1592_9(glval) = FieldAddress[d] : r1592_7
+# 1592| r1592_10(double) = Constant[2.200000000000000178] :
+# 1592| m1592_11(double) = Store[?] : &:r1592_9, r1592_10
+# 1592| m1592_12(unknown) = Chi : total:m1592_8, partial:m1592_11
+# 1592| v1592_13(void) = ReturnVoid :
+# 1592| v1592_14(void) = AliasedUse : m1592_3
+# 1592| v1592_15(void) = ExitFunction :
+
+# 1593| int& StructuredBindingTupleRefGet::r
+# 1593| Block 0
+# 1593| v1593_1(void) = EnterFunction :
+# 1593| m1593_2(unknown) = AliasedDefinition :
+# 1593| m1593_3(unknown) = InitializeNonLocal :
+# 1593| m1593_4(unknown) = Chi : total:m1593_2, partial:m1593_3
+# 1593| r1593_5(glval) = VariableAddress[#this] :
+# 1593| m1593_6(glval) = InitializeParameter[#this] : &:r1593_5
+# 1593| r1593_7(glval) = Load[#this] : &:r1593_5, m1593_6
+# 1593| m1593_8(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1593_7
+# 1593| m1593_9(unknown) = Chi : total:m1593_4, partial:m1593_8
+# 1593| r1593_10(glval) = FieldAddress[r] : r1593_7
+# 1593| r1593_11(StructuredBindingTupleRefGet *) = CopyValue : r1593_7
+# 1593| r1593_12(glval) = FieldAddress[i] : r1593_11
+#-----| r0_1(int &) = CopyValue : r1593_12
+#-----| m0_2(int &) = Store[?] : &:r1593_10, r0_1
+#-----| m0_3(unknown) = Chi : total:m1593_9, partial:m0_2
+# 1593| v1593_13(void) = ReturnVoid :
+# 1593| v1593_14(void) = AliasedUse : ~m0_3
+# 1593| v1593_15(void) = ExitFunction :
+
# 1618| std::tuple_element::type& StructuredBindingTupleRefGet::get()
# 1618| Block 0
# 1618| v1618_1(void) = EnterFunction :
@@ -12787,22 +13067,23 @@ ir.cpp:
# 1630| m1630_4(unknown) = Chi : total:m1630_2, partial:m1630_3
# 1631| r1631_1(glval) = VariableAddress[t] :
# 1631| m1631_2(StructuredBindingTupleRefGet) = Uninitialized[t] : &:r1631_1
-# 1631| r1631_3(glval) = FunctionAddress[StructuredBindingTupleRefGet] :
-# 1631| v1631_4(void) = Call[StructuredBindingTupleRefGet] : func:r1631_3, this:r1631_1
-# 1631| m1631_5(unknown) = ^CallSideEffect : ~m1630_4
-# 1631| m1631_6(unknown) = Chi : total:m1630_4, partial:m1631_5
-# 1631| m1631_7(StructuredBindingTupleRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1631_1
-# 1631| m1631_8(StructuredBindingTupleRefGet) = Chi : total:m1631_2, partial:m1631_7
+# 1631| m1631_3(unknown) = Chi : total:m1630_4, partial:m1631_2
+# 1631| r1631_4(glval) = FunctionAddress[StructuredBindingTupleRefGet] :
+# 1631| v1631_5(void) = Call[StructuredBindingTupleRefGet] : func:r1631_4, this:r1631_1
+# 1631| m1631_6(unknown) = ^CallSideEffect : ~m1631_3
+# 1631| m1631_7(unknown) = Chi : total:m1631_3, partial:m1631_6
+# 1631| m1631_8(StructuredBindingTupleRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1631_1
+# 1631| m1631_9(unknown) = Chi : total:m1631_7, partial:m1631_8
# 1634| r1634_1(glval) = VariableAddress[(unnamed local variable)] :
# 1634| r1634_2(glval) = VariableAddress[t] :
-# 1634| r1634_3(StructuredBindingTupleRefGet) = Load[t] : &:r1634_2, m1631_8
+# 1634| r1634_3(StructuredBindingTupleRefGet) = Load[t] : &:r1634_2, ~m1631_9
# 1634| m1634_4(StructuredBindingTupleRefGet) = Store[(unnamed local variable)] : &:r1634_1, r1634_3
# 1634| r1634_5(glval) = VariableAddress[i] :
# 1634| r1634_6(glval) = VariableAddress[(unnamed local variable)] :
# 1634| r1634_7(glval) = FunctionAddress[get] :
# 1634| r1634_8(int &) = Call[get] : func:r1634_7, this:r1634_6
-# 1634| m1634_9(unknown) = ^CallSideEffect : ~m1631_6
-# 1634| m1634_10(unknown) = Chi : total:m1631_6, partial:m1634_9
+# 1634| m1634_9(unknown) = ^CallSideEffect : ~m1631_9
+# 1634| m1634_10(unknown) = Chi : total:m1631_9, partial:m1634_9
# 1634| v1634_11(void) = ^IndirectReadSideEffect[-1] : &:r1634_6, m1634_4
# 1634| m1634_12(StructuredBindingTupleRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1634_6
# 1634| m1634_13(StructuredBindingTupleRefGet) = Chi : total:m1634_4, partial:m1634_12
@@ -12869,7 +13150,7 @@ ir.cpp:
# 1640| m1640_5(int) = Store[w] : &:r1640_1, r1640_4
# 1644| r1644_1(glval) = VariableAddress[unnamed_local_variable] :
# 1644| r1644_2(glval) = VariableAddress[t] :
-# 1644| r1644_3(StructuredBindingTupleRefGet) = Load[t] : &:r1644_2, m1631_8
+# 1644| r1644_3(StructuredBindingTupleRefGet) = Load[t] : &:r1644_2, ~m1638_6
# 1644| m1644_4(StructuredBindingTupleRefGet) = Store[unnamed_local_variable] : &:r1644_1, r1644_3
# 1645| r1645_1(glval) = VariableAddress[i] :
# 1645| r1645_2(glval) = VariableAddress[unnamed_local_variable] :
@@ -12948,19 +13229,73 @@ ir.cpp:
# 1657| void StructuredBindingTupleNoRefGet::StructuredBindingTupleNoRefGet()
# 1657| Block 0
-# 1657| v1657_1(void) = EnterFunction :
-# 1657| m1657_2(unknown) = AliasedDefinition :
-# 1657| m1657_3(unknown) = InitializeNonLocal :
-# 1657| m1657_4(unknown) = Chi : total:m1657_2, partial:m1657_3
-# 1657| r1657_5(glval) = VariableAddress[#this] :
-# 1657| m1657_6(glval) = InitializeParameter[#this] : &:r1657_5
-# 1657| r1657_7(glval) = Load[#this] : &:r1657_5, m1657_6
-# 1657| m1657_8(StructuredBindingTupleNoRefGet) = InitializeIndirection[#this] : &:r1657_7
-# 1657| v1657_9(void) = NoOp :
-# 1657| v1657_10(void) = ReturnIndirection[#this] : &:r1657_7, m1657_8
-# 1657| v1657_11(void) = ReturnVoid :
-# 1657| v1657_12(void) = AliasedUse : m1657_3
-# 1657| v1657_13(void) = ExitFunction :
+# 1657| v1657_1(void) = EnterFunction :
+# 1657| m1657_2(unknown) = AliasedDefinition :
+# 1657| m1657_3(unknown) = InitializeNonLocal :
+# 1657| m1657_4(unknown) = Chi : total:m1657_2, partial:m1657_3
+# 1657| r1657_5(glval) = VariableAddress[#this] :
+# 1657| m1657_6(glval) = InitializeParameter[#this] : &:r1657_5
+# 1657| r1657_7(glval) = Load[#this] : &:r1657_5, m1657_6
+# 1657| m1657_8(StructuredBindingTupleNoRefGet) = InitializeIndirection[#this] : &:r1657_7
+# 1657| m1657_9(unknown) = Chi : total:m1657_4, partial:m1657_8
+# 1657| r1657_10(glval) = FunctionAddress[i] :
+# 1657| v1657_11(void) = Call[i] : func:r1657_10, this:r1657_7
+# 1657| m1657_12(unknown) = ^CallSideEffect : ~m1657_9
+# 1657| m1657_13(unknown) = Chi : total:m1657_9, partial:m1657_12
+# 1657| v1657_14(void) = ^IndirectReadSideEffect[-1] : &:r1657_7, ~m1657_13
+# 1657| m1657_15(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1657_7
+# 1657| m1657_16(unknown) = Chi : total:m1657_13, partial:m1657_15
+# 1657| r1657_17(glval) = FunctionAddress[r] :
+# 1657| v1657_18(void) = Call[r] : func:r1657_17, this:r1657_7
+# 1657| m1657_19(unknown) = ^CallSideEffect : ~m1657_16
+# 1657| m1657_20(unknown) = Chi : total:m1657_16, partial:m1657_19
+# 1657| v1657_21(void) = ^IndirectReadSideEffect[-1] : &:r1657_7, ~m1657_20
+# 1657| m1657_22(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1657_7
+# 1657| m1657_23(unknown) = Chi : total:m1657_20, partial:m1657_22
+# 1657| v1657_24(void) = NoOp :
+# 1657| v1657_25(void) = ReturnIndirection[#this] : &:r1657_7, ~m1657_23
+# 1657| v1657_26(void) = ReturnVoid :
+# 1657| v1657_27(void) = AliasedUse : ~m1657_23
+# 1657| v1657_28(void) = ExitFunction :
+
+# 1658| int StructuredBindingTupleNoRefGet::i
+# 1658| Block 0
+# 1658| v1658_1(void) = EnterFunction :
+# 1658| m1658_2(unknown) = AliasedDefinition :
+# 1658| m1658_3(unknown) = InitializeNonLocal :
+# 1658| m1658_4(unknown) = Chi : total:m1658_2, partial:m1658_3
+# 1658| r1658_5(glval) = VariableAddress[#this] :
+# 1658| m1658_6(glval) = InitializeParameter[#this] : &:r1658_5
+# 1658| r1658_7(glval) = Load[#this] : &:r1658_5, m1658_6
+# 1658| m1658_8(StructuredBindingTupleNoRefGet) = InitializeIndirection[#this] : &:r1658_7
+# 1658| r1658_9(glval) = FieldAddress[i] : r1658_7
+# 1658| r1658_10(int) = Constant[1] :
+# 1658| m1658_11(int) = Store[?] : &:r1658_9, r1658_10
+# 1658| m1658_12(unknown) = Chi : total:m1658_8, partial:m1658_11
+# 1658| v1658_13(void) = ReturnVoid :
+# 1658| v1658_14(void) = AliasedUse : m1658_3
+# 1658| v1658_15(void) = ExitFunction :
+
+# 1659| int& StructuredBindingTupleNoRefGet::r
+# 1659| Block 0
+# 1659| v1659_1(void) = EnterFunction :
+# 1659| m1659_2(unknown) = AliasedDefinition :
+# 1659| m1659_3(unknown) = InitializeNonLocal :
+# 1659| m1659_4(unknown) = Chi : total:m1659_2, partial:m1659_3
+# 1659| r1659_5(glval) = VariableAddress[#this] :
+# 1659| m1659_6(glval) = InitializeParameter[#this] : &:r1659_5
+# 1659| r1659_7(glval) = Load[#this] : &:r1659_5, m1659_6
+# 1659| m1659_8(StructuredBindingTupleNoRefGet) = InitializeIndirection[#this] : &:r1659_7
+# 1659| m1659_9(unknown) = Chi : total:m1659_4, partial:m1659_8
+# 1659| r1659_10(glval) = FieldAddress[r] : r1659_7
+# 1659| r1659_11(StructuredBindingTupleNoRefGet *) = CopyValue : r1659_7
+# 1659| r1659_12(glval) = FieldAddress[i] : r1659_11
+#-----| r0_1(int &) = CopyValue : r1659_12
+#-----| m0_2(int &) = Store[?] : &:r1659_10, r0_1
+#-----| m0_3(unknown) = Chi : total:m1659_9, partial:m0_2
+# 1659| v1659_13(void) = ReturnVoid :
+# 1659| v1659_14(void) = AliasedUse : ~m0_3
+# 1659| v1659_15(void) = ExitFunction :
# 1684| std::tuple_element::type StructuredBindingTupleNoRefGet::get()
# 1684| Block 0
@@ -13038,12 +13373,13 @@ ir.cpp:
# 1696| m1696_4(unknown) = Chi : total:m1696_2, partial:m1696_3
# 1697| r1697_1(glval) = VariableAddress[t] :
# 1697| m1697_2(StructuredBindingTupleNoRefGet) = Uninitialized[t] : &:r1697_1
-# 1697| r1697_3(glval) = FunctionAddress[StructuredBindingTupleNoRefGet] :
-# 1697| v1697_4(void) = Call[StructuredBindingTupleNoRefGet] : func:r1697_3, this:r1697_1
-# 1697| m1697_5(unknown) = ^CallSideEffect : ~m1696_4
-# 1697| m1697_6(unknown) = Chi : total:m1696_4, partial:m1697_5
-# 1697| m1697_7(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1697_1
-# 1697| m1697_8(StructuredBindingTupleNoRefGet) = Chi : total:m1697_2, partial:m1697_7
+# 1697| m1697_3(unknown) = Chi : total:m1696_4, partial:m1697_2
+# 1697| r1697_4(glval) = FunctionAddress[StructuredBindingTupleNoRefGet] :
+# 1697| v1697_5(void) = Call[StructuredBindingTupleNoRefGet] : func:r1697_4, this:r1697_1
+# 1697| m1697_6(unknown) = ^CallSideEffect : ~m1697_3
+# 1697| m1697_7(unknown) = Chi : total:m1697_3, partial:m1697_6
+# 1697| m1697_8(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1697_1
+# 1697| m1697_9(unknown) = Chi : total:m1697_7, partial:m1697_8
# 1700| r1700_1(glval) = VariableAddress[(unnamed local variable)] :
# 1700| r1700_2(glval) = VariableAddress[t] :
# 1700| r1700_3(StructuredBindingTupleNoRefGet &) = CopyValue : r1700_2
@@ -13055,11 +13391,11 @@ ir.cpp:
# 1700| r1700_9(glval) = CopyValue : r1700_8
# 1700| r1700_10(glval) = FunctionAddress[get] :
# 1700| r1700_11(int) = Call[get] : func:r1700_10, this:r1700_9
-# 1700| m1700_12(unknown) = ^CallSideEffect : ~m1697_6
-# 1700| m1700_13(unknown) = Chi : total:m1697_6, partial:m1700_12
-# 1700| v1700_14(void) = ^IndirectReadSideEffect[-1] : &:r1700_9, m1697_8
+# 1700| m1700_12(unknown) = ^CallSideEffect : ~m1697_9
+# 1700| m1700_13(unknown) = Chi : total:m1697_9, partial:m1700_12
+# 1700| v1700_14(void) = ^IndirectReadSideEffect[-1] : &:r1700_9, ~m1700_13
# 1700| m1700_15(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1700_9
-# 1700| m1700_16(StructuredBindingTupleNoRefGet) = Chi : total:m1697_8, partial:m1700_15
+# 1700| m1700_16(unknown) = Chi : total:m1700_13, partial:m1700_15
# 1700| m1700_17(int) = Store[#temp1700:16] : &:r1700_6, r1700_11
# 1700| r1700_18(int &) = CopyValue : r1700_6
# 1700| m1700_19(int &&) = Store[i] : &:r1700_5, r1700_18
@@ -13069,11 +13405,11 @@ ir.cpp:
# 1700| r1700_23(glval) = CopyValue : r1700_22
# 1700| r1700_24(glval) = FunctionAddress[get] :
# 1700| r1700_25(int &) = Call[get] : func:r1700_24, this:r1700_23
-# 1700| m1700_26(unknown) = ^CallSideEffect : ~m1700_13
-# 1700| m1700_27(unknown) = Chi : total:m1700_13, partial:m1700_26
-# 1700| v1700_28(void) = ^IndirectReadSideEffect[-1] : &:r1700_23, m1700_16
+# 1700| m1700_26(unknown) = ^CallSideEffect : ~m1700_16
+# 1700| m1700_27(unknown) = Chi : total:m1700_16, partial:m1700_26
+# 1700| v1700_28(void) = ^IndirectReadSideEffect[-1] : &:r1700_23, ~m1700_27
# 1700| m1700_29(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1700_23
-# 1700| m1700_30(StructuredBindingTupleNoRefGet) = Chi : total:m1700_16, partial:m1700_29
+# 1700| m1700_30(unknown) = Chi : total:m1700_27, partial:m1700_29
# 1700| r1700_31(glval) = CopyValue : r1700_25
# 1700| r1700_32(int &) = CopyValue : r1700_31
# 1700| m1700_33(int &) = Store[r] : &:r1700_20, r1700_32
@@ -13083,11 +13419,11 @@ ir.cpp:
# 1700| r1700_37(glval) = CopyValue : r1700_36
# 1700| r1700_38(glval) = FunctionAddress[get] :
# 1700| r1700_39(int &&) = Call[get] : func:r1700_38, this:r1700_37
-# 1700| m1700_40(unknown) = ^CallSideEffect : ~m1700_27
-# 1700| m1700_41(unknown) = Chi : total:m1700_27, partial:m1700_40
-# 1700| v1700_42(void) = ^IndirectReadSideEffect[-1] : &:r1700_37, m1700_30
+# 1700| m1700_40(unknown) = ^CallSideEffect : ~m1700_30
+# 1700| m1700_41(unknown) = Chi : total:m1700_30, partial:m1700_40
+# 1700| v1700_42(void) = ^IndirectReadSideEffect[-1] : &:r1700_37, ~m1700_41
# 1700| m1700_43(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1700_37
-# 1700| m1700_44(StructuredBindingTupleNoRefGet) = Chi : total:m1700_30, partial:m1700_43
+# 1700| m1700_44(unknown) = Chi : total:m1700_41, partial:m1700_43
# 1700| r1700_45(glval) = CopyValue : r1700_39
# 1700| r1700_46(int &) = CopyValue : r1700_45
# 1700| m1700_47(int &&) = Store[rv] : &:r1700_34, r1700_46
@@ -13112,7 +13448,7 @@ ir.cpp:
# 1704| r1704_3(int &) = Load[r] : &:r1704_2, m1700_33
# 1704| r1704_4(glval) = CopyValue : r1704_3
# 1704| m1704_5(int) = Store[?] : &:r1704_4, r1704_1
-# 1704| m1704_6(unknown) = Chi : total:m1700_41, partial:m1704_5
+# 1704| m1704_6(unknown) = Chi : total:m1700_44, partial:m1704_5
# 1705| r1705_1(glval) = VariableAddress[rr] :
# 1705| r1705_2(glval) = VariableAddress[r] :
# 1705| r1705_3(int &) = Load[r] : &:r1705_2, m1700_33
@@ -13137,9 +13473,9 @@ ir.cpp:
# 1711| r1711_7(int) = Call[get] : func:r1711_6, this:r1711_5
# 1711| m1711_8(unknown) = ^CallSideEffect : ~m1704_6
# 1711| m1711_9(unknown) = Chi : total:m1704_6, partial:m1711_8
-# 1711| v1711_10(void) = ^IndirectReadSideEffect[-1] : &:r1711_5, m1700_44
+# 1711| v1711_10(void) = ^IndirectReadSideEffect[-1] : &:r1711_5, ~m1711_9
# 1711| m1711_11(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1711_5
-# 1711| m1711_12(StructuredBindingTupleNoRefGet) = Chi : total:m1700_44, partial:m1711_11
+# 1711| m1711_12(unknown) = Chi : total:m1711_9, partial:m1711_11
# 1711| m1711_13(int) = Store[#temp1711:20] : &:r1711_2, r1711_7
# 1711| r1711_14(int &) = CopyValue : r1711_2
# 1711| m1711_15(int &&) = Store[i] : &:r1711_1, r1711_14
@@ -13149,11 +13485,11 @@ ir.cpp:
# 1712| r1712_4(glval) = CopyValue : r1712_3
# 1712| r1712_5(glval) = FunctionAddress[get] :
# 1712| r1712_6(int &) = Call[get] : func:r1712_5, this:r1712_4
-# 1712| m1712_7(unknown) = ^CallSideEffect : ~m1711_9
-# 1712| m1712_8(unknown) = Chi : total:m1711_9, partial:m1712_7
-# 1712| v1712_9(void) = ^IndirectReadSideEffect[-1] : &:r1712_4, m1711_12
+# 1712| m1712_7(unknown) = ^CallSideEffect : ~m1711_12
+# 1712| m1712_8(unknown) = Chi : total:m1711_12, partial:m1712_7
+# 1712| v1712_9(void) = ^IndirectReadSideEffect[-1] : &:r1712_4, ~m1712_8
# 1712| m1712_10(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1712_4
-# 1712| m1712_11(StructuredBindingTupleNoRefGet) = Chi : total:m1711_12, partial:m1712_10
+# 1712| m1712_11(unknown) = Chi : total:m1712_8, partial:m1712_10
# 1712| r1712_12(glval) = CopyValue : r1712_6
# 1712| r1712_13(int &) = CopyValue : r1712_12
# 1712| m1712_14(int &) = Store[r] : &:r1712_1, r1712_13
@@ -13163,11 +13499,11 @@ ir.cpp:
# 1713| r1713_4(glval) = CopyValue : r1713_3
# 1713| r1713_5(glval) = FunctionAddress[get] :
# 1713| r1713_6(int &&) = Call[get] : func:r1713_5, this:r1713_4
-# 1713| m1713_7(unknown) = ^CallSideEffect : ~m1712_8
-# 1713| m1713_8(unknown) = Chi : total:m1712_8, partial:m1713_7
-# 1713| v1713_9(void) = ^IndirectReadSideEffect[-1] : &:r1713_4, m1712_11
+# 1713| m1713_7(unknown) = ^CallSideEffect : ~m1712_11
+# 1713| m1713_8(unknown) = Chi : total:m1712_11, partial:m1713_7
+# 1713| v1713_9(void) = ^IndirectReadSideEffect[-1] : &:r1713_4, ~m1713_8
# 1713| m1713_10(StructuredBindingTupleNoRefGet) = ^IndirectMayWriteSideEffect[-1] : &:r1713_4
-# 1713| m1713_11(StructuredBindingTupleNoRefGet) = Chi : total:m1712_11, partial:m1713_10
+# 1713| m1713_11(unknown) = Chi : total:m1713_8, partial:m1713_10
# 1713| r1713_12(glval) = CopyValue : r1713_6
# 1713| r1713_13(int &) = CopyValue : r1713_12
# 1713| m1713_14(int &&) = Store[rv] : &:r1713_1, r1713_13
@@ -13192,7 +13528,7 @@ ir.cpp:
# 1717| r1717_3(int &) = Load[r] : &:r1717_2, m1712_14
# 1717| r1717_4(glval) = CopyValue : r1717_3
# 1717| m1717_5(int) = Store[?] : &:r1717_4, r1717_1
-# 1717| m1717_6(unknown) = Chi : total:m1713_8, partial:m1717_5
+# 1717| m1717_6(unknown) = Chi : total:m1713_11, partial:m1717_5
# 1718| r1718_1(glval) = VariableAddress[rr] :
# 1718| r1718_2(glval) = VariableAddress[r] :
# 1718| r1718_3(int &) = Load[r] : &:r1718_2, m1712_14
@@ -21066,6 +21402,376 @@ ir.cpp:
# 2867| v2867_14(void) = ReturnVoid :
#-----| Goto -> Block 1
+# 2890| int StructInit::i
+# 2890| Block 0
+# 2890| v2890_1(void) = EnterFunction :
+# 2890| m2890_2(unknown) = AliasedDefinition :
+# 2890| m2890_3(unknown) = InitializeNonLocal :
+# 2890| m2890_4(unknown) = Chi : total:m2890_2, partial:m2890_3
+# 2890| r2890_5(glval) = VariableAddress[#this] :
+# 2890| m2890_6(glval) = InitializeParameter[#this] : &:r2890_5
+# 2890| r2890_7(glval) = Load[#this] : &:r2890_5, m2890_6
+# 2890| m2890_8(StructInit) = InitializeIndirection[#this] : &:r2890_7
+# 2890| r2890_9(glval) = FieldAddress[i] : r2890_7
+# 2890| r2890_10(int) = Constant[42] :
+# 2890| m2890_11(int) = Store[?] : &:r2890_9, r2890_10
+# 2890| m2890_12(unknown) = Chi : total:m2890_8, partial:m2890_11
+# 2890| v2890_13(void) = ReturnVoid :
+# 2890| v2890_14(void) = AliasedUse : m2890_3
+# 2890| v2890_15(void) = ExitFunction :
+
+# 2891| int StructInit::j
+# 2891| Block 0
+# 2891| v2891_1(void) = EnterFunction :
+# 2891| m2891_2(unknown) = AliasedDefinition :
+# 2891| m2891_3(unknown) = InitializeNonLocal :
+# 2891| m2891_4(unknown) = Chi : total:m2891_2, partial:m2891_3
+# 2891| r2891_5(glval) = VariableAddress[#this] :
+# 2891| m2891_6(glval) = InitializeParameter[#this] : &:r2891_5
+# 2891| r2891_7(glval) = Load[#this] : &:r2891_5, m2891_6
+# 2891| m2891_8(StructInit) = InitializeIndirection[#this] : &:r2891_7
+# 2891| r2891_9(glval) = FieldAddress[j] : r2891_7
+# 2891| r2891_10(int) = Constant[42] :
+# 2891| m2891_11(int) = Store[?] : &:r2891_9, r2891_10
+# 2891| m2891_12(unknown) = Chi : total:m2891_8, partial:m2891_11
+# 2891| v2891_13(void) = ReturnVoid :
+# 2891| v2891_14(void) = AliasedUse : m2891_3
+# 2891| v2891_15(void) = ExitFunction :
+
+# 2892| int StructInit::k
+# 2892| Block 0
+# 2892| v2892_1(void) = EnterFunction :
+# 2892| m2892_2(unknown) = AliasedDefinition :
+# 2892| m2892_3(unknown) = InitializeNonLocal :
+# 2892| m2892_4(unknown) = Chi : total:m2892_2, partial:m2892_3
+# 2892| r2892_5(glval) = VariableAddress[#this] :
+# 2892| m2892_6(glval) = InitializeParameter[#this] : &:r2892_5
+# 2892| r2892_7(glval) = Load[#this] : &:r2892_5, m2892_6
+# 2892| m2892_8(StructInit) = InitializeIndirection[#this] : &:r2892_7
+# 2892| r2892_9(glval) = FieldAddress[k] : r2892_7
+# 2892| r2892_10(int) = Constant[42] :
+# 2892| m2892_11(int) = Store[?] : &:r2892_9, r2892_10
+# 2892| m2892_12(unknown) = Chi : total:m2892_8, partial:m2892_11
+# 2892| v2892_13(void) = ReturnVoid :
+# 2892| v2892_14(void) = AliasedUse : m2892_3
+# 2892| v2892_15(void) = ExitFunction :
+
+# 2893| int StructInit::l
+# 2893| Block 0
+# 2893| v2893_1(void) = EnterFunction :
+# 2893| m2893_2(unknown) = AliasedDefinition :
+# 2893| m2893_3(unknown) = InitializeNonLocal :
+# 2893| m2893_4(unknown) = Chi : total:m2893_2, partial:m2893_3
+# 2893| r2893_5(glval) = VariableAddress[#this] :
+# 2893| m2893_6(glval) = InitializeParameter[#this] : &:r2893_5
+# 2893| r2893_7(glval) = Load[#this] : &:r2893_5, m2893_6
+# 2893| m2893_8(StructInit) = InitializeIndirection[#this] : &:r2893_7
+# 2893| r2893_9(glval) = FieldAddress[l] : r2893_7
+# 2893| r2893_10(StructInit *) = CopyValue : r2893_7
+# 2893| r2893_11(glval) = FieldAddress[k] : r2893_10
+# 2893| r2893_12(int) = Load[?] : &:r2893_11, ~m2893_8
+# 2893| m2893_13(int) = Store[?] : &:r2893_9, r2893_12
+# 2893| m2893_14(unknown) = Chi : total:m2893_8, partial:m2893_13
+# 2893| v2893_15(void) = ReturnVoid :
+# 2893| v2893_16(void) = AliasedUse : m2893_3
+# 2893| v2893_17(void) = ExitFunction :
+
+# 2894| int StructInit::m
+# 2894| Block 0
+# 2894| v2894_1(void) = EnterFunction :
+# 2894| m2894_2(unknown) = AliasedDefinition :
+# 2894| m2894_3(unknown) = InitializeNonLocal :
+# 2894| m2894_4(unknown) = Chi : total:m2894_2, partial:m2894_3
+# 2894| r2894_5(glval) = VariableAddress[#this] :
+# 2894| m2894_6(glval) = InitializeParameter[#this] : &:r2894_5
+# 2894| r2894_7(glval) = Load[#this] : &:r2894_5, m2894_6
+# 2894| m2894_8(StructInit) = InitializeIndirection[#this] : &:r2894_7
+# 2894| r2894_9(glval) = FieldAddress[m] : r2894_7
+# 2894| r2894_10(StructInit *) = CopyValue : r2894_7
+# 2894| r2894_11(glval) = FunctionAddress[get_val] :
+# 2894| r2894_12(int) = Call[get_val] : func:r2894_11, this:r2894_10
+# 2894| m2894_13(unknown) = ^CallSideEffect : ~m2894_4
+# 2894| m2894_14(unknown) = Chi : total:m2894_4, partial:m2894_13
+# 2894| v2894_15(void) = ^IndirectReadSideEffect[-1] : &:r2894_10, ~m2894_8
+# 2894| m2894_16(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2894_10
+# 2894| m2894_17(unknown) = Chi : total:m2894_8, partial:m2894_16
+# 2894| m2894_18(int) = Store[?] : &:r2894_9, r2894_12
+# 2894| m2894_19(unknown) = Chi : total:m2894_17, partial:m2894_18
+# 2894| v2894_20(void) = ReturnVoid :
+# 2894| v2894_21(void) = AliasedUse : ~m2894_14
+# 2894| v2894_22(void) = ExitFunction :
+
+# 2895| int StructInit::n
+# 2895| Block 0
+# 2895| v2895_1(void) = EnterFunction :
+# 2895| m2895_2(unknown) = AliasedDefinition :
+# 2895| m2895_3(unknown) = InitializeNonLocal :
+# 2895| m2895_4(unknown) = Chi : total:m2895_2, partial:m2895_3
+# 2895| r2895_5(glval) = VariableAddress[#this] :
+# 2895| m2895_6(glval) = InitializeParameter[#this] : &:r2895_5
+# 2895| r2895_7(glval) = Load[#this] : &:r2895_5, m2895_6
+# 2895| m2895_8(StructInit) = InitializeIndirection[#this] : &:r2895_7
+# 2895| r2895_9(glval) = FieldAddress[n] : r2895_7
+# 2895| r2895_10(int) = Constant[42] :
+# 2895| m2895_11(int) = Store[?] : &:r2895_9, r2895_10
+# 2895| m2895_12(unknown) = Chi : total:m2895_8, partial:m2895_11
+# 2895| v2895_13(void) = ReturnVoid :
+# 2895| v2895_14(void) = AliasedUse : m2895_3
+# 2895| v2895_15(void) = ExitFunction :
+
+# 2897| void StructInit::StructInit(int)
+# 2897| Block 0
+# 2897| v2897_1(void) = EnterFunction :
+# 2897| m2897_2(unknown) = AliasedDefinition :
+# 2897| m2897_3(unknown) = InitializeNonLocal :
+# 2897| m2897_4(unknown) = Chi : total:m2897_2, partial:m2897_3
+# 2897| r2897_5(glval) = VariableAddress[#this] :
+# 2897| m2897_6(glval) = InitializeParameter[#this] : &:r2897_5
+# 2897| r2897_7(glval) = Load[#this] : &:r2897_5, m2897_6
+# 2897| m2897_8(StructInit) = InitializeIndirection[#this] : &:r2897_7
+# 2897| m2897_9(unknown) = Chi : total:m2897_4, partial:m2897_8
+# 2897| r2897_10(glval) = VariableAddress[j] :
+# 2897| m2897_11(int) = InitializeParameter[j] : &:r2897_10
+# 2897| r2897_12(glval) = FunctionAddress[i] :
+# 2897| v2897_13(void) = Call[i] : func:r2897_12, this:r2897_7
+# 2897| m2897_14(unknown) = ^CallSideEffect : ~m2897_9
+# 2897| m2897_15(unknown) = Chi : total:m2897_9, partial:m2897_14
+# 2897| v2897_16(void) = ^IndirectReadSideEffect[-1] : &:r2897_7, ~m2897_15
+# 2897| m2897_17(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2897_7
+# 2897| m2897_18(unknown) = Chi : total:m2897_15, partial:m2897_17
+# 2897| r2897_19(glval) = FieldAddress[j] : r2897_7
+# 2897| r2897_20(glval) = VariableAddress[j] :
+# 2897| r2897_21(int) = Load[j] : &:r2897_20, m2897_11
+# 2897| m2897_22(int) = Store[?] : &:r2897_19, r2897_21
+# 2897| m2897_23(unknown) = Chi : total:m2897_18, partial:m2897_22
+# 2897| r2897_24(glval) = FunctionAddress[k] :
+# 2897| v2897_25(void) = Call[k] : func:r2897_24, this:r2897_7
+# 2897| m2897_26(unknown) = ^CallSideEffect : ~m2897_23
+# 2897| m2897_27(unknown) = Chi : total:m2897_23, partial:m2897_26
+# 2897| v2897_28(void) = ^IndirectReadSideEffect[-1] : &:r2897_7, ~m2897_27
+# 2897| m2897_29(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2897_7
+# 2897| m2897_30(unknown) = Chi : total:m2897_27, partial:m2897_29
+# 2897| r2897_31(glval) = FunctionAddress[l] :
+# 2897| v2897_32(void) = Call[l] : func:r2897_31, this:r2897_7
+# 2897| m2897_33(unknown) = ^CallSideEffect : ~m2897_30
+# 2897| m2897_34(unknown) = Chi : total:m2897_30, partial:m2897_33
+# 2897| v2897_35(void) = ^IndirectReadSideEffect[-1] : &:r2897_7, ~m2897_34
+# 2897| m2897_36(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2897_7
+# 2897| m2897_37(unknown) = Chi : total:m2897_34, partial:m2897_36
+# 2897| r2897_38(glval) = FunctionAddress[m] :
+# 2897| v2897_39(void) = Call[m] : func:r2897_38, this:r2897_7
+# 2897| m2897_40(unknown) = ^CallSideEffect : ~m2897_37
+# 2897| m2897_41(unknown) = Chi : total:m2897_37, partial:m2897_40
+# 2897| v2897_42(void) = ^IndirectReadSideEffect[-1] : &:r2897_7, ~m2897_41
+# 2897| m2897_43(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2897_7
+# 2897| m2897_44(unknown) = Chi : total:m2897_41, partial:m2897_43
+# 2897| r2897_45(glval) = FieldAddress[n] : r2897_7
+# 2897| r2897_46(glval) = VariableAddress[#this] :
+# 2897| r2897_47(StructInit *) = Load[#this] : &:r2897_46, m2897_6
+# 2897| r2897_48(glval) = FunctionAddress[get_val] :
+# 2897| r2897_49(int) = Call[get_val] : func:r2897_48, this:r2897_47
+# 2897| m2897_50(unknown) = ^CallSideEffect : ~m2897_44
+# 2897| m2897_51(unknown) = Chi : total:m2897_44, partial:m2897_50
+# 2897| v2897_52(void) = ^IndirectReadSideEffect[-1] : &:r2897_47, ~m2897_51
+# 2897| m2897_53(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2897_47
+# 2897| m2897_54(unknown) = Chi : total:m2897_51, partial:m2897_53
+# 2897| m2897_55(int) = Store[?] : &:r2897_45, r2897_49
+# 2897| m2897_56(unknown) = Chi : total:m2897_54, partial:m2897_55
+# 2897| v2897_57(void) = NoOp :
+# 2897| v2897_58(void) = ReturnIndirection[#this] : &:r2897_7, ~m2897_56
+# 2897| v2897_59(void) = ReturnVoid :
+# 2897| v2897_60(void) = AliasedUse : ~m2897_56
+# 2897| v2897_61(void) = ExitFunction :
+
+# 2899| void StructInit::StructInit()
+# 2899| Block 0
+# 2899| v2899_1(void) = EnterFunction :
+# 2899| m2899_2(unknown) = AliasedDefinition :
+# 2899| m2899_3(unknown) = InitializeNonLocal :
+# 2899| m2899_4(unknown) = Chi : total:m2899_2, partial:m2899_3
+# 2899| r2899_5(glval) = VariableAddress[#this] :
+# 2899| m2899_6(glval) = InitializeParameter[#this] : &:r2899_5
+# 2899| r2899_7(glval) = Load[#this] : &:r2899_5, m2899_6
+# 2899| m2899_8(StructInit) = InitializeIndirection[#this] : &:r2899_7
+# 2899| m2899_9(unknown) = Chi : total:m2899_4, partial:m2899_8
+# 2899| r2899_10(glval) = FieldAddress[i] : r2899_7
+# 2899| r2899_11(int) = Constant[41] :
+# 2899| m2899_12(int) = Store[?] : &:r2899_10, r2899_11
+# 2899| m2899_13(unknown) = Chi : total:m2899_9, partial:m2899_12
+# 2899| r2899_14(glval) = FunctionAddress[j] :
+# 2899| v2899_15(void) = Call[j] : func:r2899_14, this:r2899_7
+# 2899| m2899_16(unknown) = ^CallSideEffect : ~m2899_13
+# 2899| m2899_17(unknown) = Chi : total:m2899_13, partial:m2899_16
+# 2899| v2899_18(void) = ^IndirectReadSideEffect[-1] : &:r2899_7, ~m2899_17
+# 2899| m2899_19(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2899_7
+# 2899| m2899_20(unknown) = Chi : total:m2899_17, partial:m2899_19
+# 2899| r2899_21(glval) = FieldAddress[k] : r2899_7
+# 2899| r2899_22(int) = Constant[41] :
+# 2899| m2899_23(int) = Store[?] : &:r2899_21, r2899_22
+# 2899| m2899_24(unknown) = Chi : total:m2899_20, partial:m2899_23
+# 2899| r2899_25(glval) = FunctionAddress[l] :
+# 2899| v2899_26(void) = Call[l] : func:r2899_25, this:r2899_7
+# 2899| m2899_27(unknown) = ^CallSideEffect : ~m2899_24
+# 2899| m2899_28(unknown) = Chi : total:m2899_24, partial:m2899_27
+# 2899| v2899_29(void) = ^IndirectReadSideEffect[-1] : &:r2899_7, ~m2899_28
+# 2899| m2899_30(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2899_7
+# 2899| m2899_31(unknown) = Chi : total:m2899_28, partial:m2899_30
+# 2899| r2899_32(glval) = FunctionAddress[m] :
+# 2899| v2899_33(void) = Call[m] : func:r2899_32, this:r2899_7
+# 2899| m2899_34(unknown) = ^CallSideEffect : ~m2899_31
+# 2899| m2899_35(unknown) = Chi : total:m2899_31, partial:m2899_34
+# 2899| v2899_36(void) = ^IndirectReadSideEffect[-1] : &:r2899_7, ~m2899_35
+# 2899| m2899_37(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2899_7
+# 2899| m2899_38(unknown) = Chi : total:m2899_35, partial:m2899_37
+# 2899| r2899_39(glval) = FunctionAddress[n] :
+# 2899| v2899_40(void) = Call[n] : func:r2899_39, this:r2899_7
+# 2899| m2899_41(unknown) = ^CallSideEffect : ~m2899_38
+# 2899| m2899_42(unknown) = Chi : total:m2899_38, partial:m2899_41
+# 2899| v2899_43(void) = ^IndirectReadSideEffect[-1] : &:r2899_7, ~m2899_42
+# 2899| m2899_44(StructInit) = ^IndirectMayWriteSideEffect[-1] : &:r2899_7
+# 2899| m2899_45(unknown) = Chi : total:m2899_42, partial:m2899_44
+# 2899| v2899_46(void) = NoOp :
+# 2899| v2899_47(void) = ReturnIndirection[#this] : &:r2899_7, ~m2899_45
+# 2899| v2899_48(void) = ReturnVoid :
+# 2899| v2899_49(void) = AliasedUse : ~m2899_45
+# 2899| v2899_50(void) = ExitFunction :
+
+# 2901| int StructInit::get_val()
+# 2901| Block 0
+# 2901| v2901_1(void) = EnterFunction :
+# 2901| m2901_2(unknown) = AliasedDefinition :
+# 2901| m2901_3(unknown) = InitializeNonLocal :
+# 2901| m2901_4(unknown) = Chi : total:m2901_2, partial:m2901_3
+# 2901| r2901_5(glval) = VariableAddress[#this] :
+# 2901| m2901_6(glval