diff --git a/.bazelrc b/.bazelrc
index 8687f4406cb9..e34a363a16fc 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -11,6 +11,9 @@ build --compilation_mode opt
common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
build --repo_env=CC=clang --repo_env=CXX=clang++
+# The standalone Linux toolchain uses gold, which does not support the
+# LLD-specific -z nostart-stop-gc workaround enabled by rules_swift.
+build:linux --features=-swift.lld_gc_workaround
# Disable Android SDK auto-detection (we don't use it, and rules_android has Bazel 9 compatibility issues)
build --repo_env=ANDROID_HOME=
diff --git a/.bazelversion b/.bazelversion
index f7ee06693c17..3b74042132a6 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-9.0.0
+9.3.1
diff --git a/.gitattributes b/.gitattributes
index 610342ef78b1..a46131cc4cdf 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -75,6 +75,9 @@
/ruby/extractor/cargo-bazel-lock.json linguist-generated=true
/ruby/extractor/cargo-bazel-lock.json -merge
+# GitHub Agentic Workflows compiled output
+.github/workflows/*.lock.yml linguist-generated=true
+
# auto-generated files for the C# build
/csharp/paket.lock linguist-generated=true
# needs eol=crlf, as `paket` touches this file and saves it as crlf
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 30cb9833a6a4..ba6cb914193f 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -4,16 +4,22 @@ updates:
directory: "ruby"
schedule:
interval: "daily"
+ cooldown:
+ default-days: 7
- package-ecosystem: "cargo"
directory: "ql"
schedule:
interval: "daily"
+ cooldown:
+ default-days: 7
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
+ cooldown:
+ default-days: 7
ignore:
- dependency-name: '*'
update-types: ['version-update:semver-patch', 'version-update:semver-minor']
@@ -22,6 +28,8 @@ updates:
directory: "go/extractor"
schedule:
interval: "daily"
+ cooldown:
+ default-days: 7
allow:
- dependency-name: "golang.org/x/mod"
- dependency-name: "golang.org/x/tools"
@@ -36,6 +44,8 @@ updates:
directory: "go/ql/test"
schedule:
interval: "monthly"
+ cooldown:
+ default-days: 7
ignore:
- dependency-name: "*"
reviewers:
@@ -45,5 +55,7 @@ updates:
directory: "/"
schedule:
interval: weekly
+ cooldown:
+ default-days: 7
exclude-paths:
- "misc/bazel/registry/**"
diff --git a/.github/instructions/expected-files.instructions.md b/.github/instructions/expected-files.instructions.md
index b76119d70282..17cf22f93a03 100644
--- a/.github/instructions/expected-files.instructions.md
+++ b/.github/instructions/expected-files.instructions.md
@@ -1,4 +1,4 @@
---
applyTo: "**/*.expected"
---
-Ignore these files. These are generated to be correct by running the tests, and should not be edited manually.
+Do not edit these files directly. They are generated by running the tests. If a `.expected` file has a non-empty `testFailures `section it should not be committed - you may want to update the inline expectation comments in the corresponding test source file (e.g. marking expected results as `MISSING` / `SPURIOUS`) then re-run the test.
diff --git a/.github/instructions/ql-files.instructions.md b/.github/instructions/ql-files.instructions.md
deleted file mode 100644
index 4d331807e06e..000000000000
--- a/.github/instructions/ql-files.instructions.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-applyTo: "**/*.ql,**/*.qll"
----
-When reviewing these QL files, do not make any comment on the code itself. You don't understand the QL programming language well enough yet. You can only make comments about the following aspects:
-* comments (lines starting with `//` or block comments enclosed in `/* ... */`): you can suggest improvements to the clarity of comments, or point out spelling mistakes
-* typos in identifiers
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 65f820799716..83dabb7302dd 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -38,6 +38,10 @@ Swift:
- swift/**/*
- change-notes/**/*swift*
+Unified:
+ - unified/**/*
+ - change-notes/**/*unified*
+
Actions:
- actions/**/*
- change-notes/**/*actions*
diff --git a/.github/skills/bazel/SKILL.md b/.github/skills/bazel/SKILL.md
new file mode 100644
index 000000000000..af5d1ab82359
--- /dev/null
+++ b/.github/skills/bazel/SKILL.md
@@ -0,0 +1,174 @@
+---
+name: bazel
+description: Conventions for editing Bazel files in the github/codeql repository: the shared `misc/bazel` helpers, `codeql_platform_select` and the `{CODEQL_PLATFORM}` packaging placeholder, adding `MODULE.bazel` dependencies, and the `semmle_code` stub that keeps the standalone build working. Use when editing any `BUILD.bazel`, `*.bzl`, `MODULE.bazel` or `.bazelrc` here, and before validating such an edit.
+---
+
+# Bazel in the codeql repository
+
+A bzlmod module named `ql`, repo name `@codeql` ([`MODULE.bazel`](../../../MODULE.bazel)). It builds standalone, and is
+also consumed by an internal module; standalone builds replace that module with a stub.
+
+## Traps
+
+Things that will waste your time or produce a wrong edit here. Read this section even if you skip the rest.
+
+* **`//...` does not work.** `bazel build //...`, and even `bazel query //...`, fail at the repo root: the patched
+ modules under [`misc/bazel/registry`](../../../misc/bazel/registry) are real packages referencing repos that are not
+ visible from the main repo, and [`.bazelrc`](../../../.bazelrc) notes separately that transitions break `...` builds.
+ The error names a registry directory unrelated to your edit, so it is easy to misdiagnose. **Validate the specific
+ target or package you changed**, not a recursive pattern.
+* **There is no `MODULE.bazel.lock`, deliberately.** [`.bazelrc`](../../../.bazelrc) sets `--lockfile_mode=off` because
+ the workspace-relative module override makes a lockfile unstable. Do not add one, and do not "fix" its absence.
+* **`linux_arm64` vs `linux-arm64`.** The keyword argument and config setting use an underscore; the platform *string*
+ substituted into paths and zip names uses a hyphen. They are not interchangeable.
+* **Do not stub your way out of a missing internal dependency.** See [Building standalone](#building-standalone) for the
+ one narrow case where extending the stub is correct.
+
+## Conventions
+
+* **Copy a neighboring target rather than inventing a shape.** Packaging is not uniform: some packages use the
+ `codeql_*` wrappers, others still use `pkg_files` directly. Copy the closest *working* neighbor, and prefer the
+ wrapper for new code.
+* **Pin anything fetched over the network** with `sha256` or `integrity`. Bazel only *warns* on an unpinned download, so
+ nothing fails loudly, but the build stops being reproducible and a retagged upstream release silently changes what you
+ build. `lfs_archive` is the exception: content is pinned by git object.
+* **Format with `bazel run //misc/bazel/buildifier`.** It rewrites in place, so do not hand-tune formatting. Also wired
+ as a `pre-commit` hook ([`.pre-commit-config.yaml`](../../../.pre-commit-config.yaml)).
+
+## Where new code goes
+
+Bazel's own macro / rule / repository-rule distinction applies as usual. What is repo-specific:
+
+| Adding | Goes in |
+| --- | --- |
+| a new packaging shape | extend [`misc/bazel/pkg.bzl`](../../../misc/bazel/pkg.bzl), do not fork `pkg_files` |
+| a new OS or arch split | [`misc/bazel/os.bzl`](../../../misc/bazel/os.bzl), do not hand-roll a `select()` over `@platforms//` |
+| a fetch of something external | a repository rule ([`lfs.bzl`](../../../misc/bazel/lfs.bzl), [`ripunzip.bzl`](../../../misc/ripunzip/ripunzip.bzl)), not a `genrule` |
+| a wrapper used by one language | next to that language ([`swift/rules.bzl`](../../../swift/rules.bzl)) |
+| a wrapper used across languages | `misc/bazel/` |
+
+Prefer inline rules in `BUILD.bazel`. A `.bzl` file earns its `load()` only when the shape repeats across packages or a
+value must be computed: [`rust.bzl`](../../../misc/bazel/rust.bzl) is worth it because every Rust binary that ships in a
+pack must get the same universal-binary wrapper and symbols test, and forgetting either is a release bug. A local
+debugging aid opts out and declares a plain `rust_binary`; see `swift-syntax-parse` in
+[`unified/swift-syntax-rs/BUILD.bazel`](../../../unified/swift-syntax-rs/BUILD.bazel). The `_gen_binaries` list in
+[`go/BUILD.bazel`](../../../go/BUILD.bazel) does not earn a `.bzl`, because it is shared within a single file, where a
+local variable does the job.
+
+Macros here are typically a thin public wrapper around a private rule (`codeql_csharp_binary`, `swift_cc_binary`). Keep
+the rule narrow and the ergonomics in the macro. Each macro decorates the caller's `name` to mint its helper targets,
+for example `internal/` or `single_arch/`. Their visibility is that macro's choice (private, package
+default, or the caller's own), so read the macro instead of assuming. When an error names a target you cannot find in
+any source file, a macro minted it: grep the suffix under `misc/bazel/`.
+
+## Shared helpers
+
+Frequently-used pieces, so you load the existing one instead of rewriting it. Read the file for its actual exports.
+
+| `load()` path | Covers |
+| --- | --- |
+| `//misc/bazel:pkg.bzl` | CodeQL packs and packaging |
+| `//misc/bazel:os.bzl` | platform and architecture selection |
+| `//misc/bazel:lfs.bzl` | on-demand git-LFS repositories |
+| `//misc/bazel:rust.bzl` | Rust binary wrapper |
+| `//misc/bazel:csharp.bzl` | C# binary/library/test wrappers |
+| `//misc/bazel:utils.bzl` | `select_os`; prefer `os.bzl`'s `os_select` in new code |
+
+[`defs.bzl`](../../../defs.bzl) at the root exports `codeql_platform` for *dependent* modules. It is not the way to get
+the platform string here; use `os.bzl`.
+
+## Platform selection
+
+[`codeql_platform_select`](../../../misc/bazel/os.bzl) takes one keyword argument per CodeQL platform: `linux64`,
+`linux_arm64`, `osx64` and `win64`. `otherwise` supplies the value for whichever of those you leave unset; it is **not**
+a `//conditions:default`. If you only care about the OS, use `os_select`, which gives Linux the same value on both
+architectures and has a `posix` shorthand for the shared Linux/macOS value.
+
+In a macro (no `ctx`) it returns a `select()`:
+
+```python
+load("//misc/bazel:os.bzl", "codeql_platform_select")
+load("//misc/bazel:pkg.bzl", "codeql_pkg_files")
+
+codeql_pkg_files(
+ name = "extractor-arch",
+ exes = codeql_platform_select(
+ otherwise = ["//unified/extractor"],
+ win64 = ["//unified/extractor-unsupported-os:extractor"],
+ ),
+ prefix = "tools/{CODEQL_PLATFORM}",
+)
+```
+
+If implementation code needs to *branch* on the value rather than pass it through, pass `ctx` and add
+`OS_DETECTION_ATTRS` to the rule's attributes. The value is then resolved eagerly instead of being an opaque `select()`:
+
+```python
+load("//misc/bazel:os.bzl", "OS_DETECTION_ATTRS", "os_select")
+
+def _impl(ctx):
+ ext = os_select(ctx, windows = ".exe", posix = "")
+ ...
+
+my_rule = rule(
+ implementation = _impl,
+ attrs = {"src": attr.label()} | OS_DETECTION_ATTRS,
+)
+```
+
+## Packs
+
+`codeql_pack` assembles the files that become an extractor pack. See [`unified/BUILD.bazel`](../../../unified/BUILD.bazel)
+for a minimal complete example and [`pkg.bzl`](../../../misc/bazel/pkg.bzl) for the arguments. The non-obvious parts:
+
+* **`{CODEQL_PLATFORM}` in a destination path is the routing mechanism**, not just a substitution. A path containing it
+ is *arch-specific* and lands in the per-architecture zip; every other path is *common*. So `prefix =
+ "tools/{CODEQL_PLATFORM}"` both places the file and marks it arch-specific. `arch_overrides` forces named
+ destinations into the arch-specific part without a placeholder.
+* **`codeql_pkg_files` splits `srcs` (plain) from `exes` (mode 755)** and **rejects `attributes =`** with an explicit
+ error. Use `exes` rather than hand-rolling `pkg_attributes(mode = "755")`.
+* **`pkg_dirs` and `pkg_symlinks` are unsupported** and fail at analysis time.
+* `codeql_pack` also generates an installer and an `install` alias, hence `bazel run //unified:install`. Pass
+ `installer_alias = None` if one package defines several packs.
+* `codeql_pack_group` exists for bundling packs into distribution zips, but nothing in this repo instantiates it.
+
+## Adding a dependency
+
+In order of preference:
+
+1. **A [Bazel Central Registry](https://registry.bazel.build/) module.** Add a `bazel_dep` in
+ [`MODULE.bazel`](../../../MODULE.bazel).
+2. **A patched upstream module.** Add it under [`misc/bazel/registry`](../../../misc/bazel/registry), which `.bazelrc`
+ puts ahead of the BCR. Put patches in `modules///patches`, rename the version with a `-codeql.N`
+ suffix, and run [`fix.py`](../../../misc/bazel/registry/fix.py) to realign the metadata.
+3. **A raw archive.** Use `http_archive` via `use_repo_rule`, or a repository rule. Copy an adjacent declaration and
+ keep its checksum field populated.
+
+Vendored Rust crates under [`misc/bazel/3rdparty`](../../../misc/bazel/3rdparty) are generated. Regenerate with
+[`update_cargo_deps.sh`](../../../misc/bazel/3rdparty/update_cargo_deps.sh) rather than editing, and keep the
+`use_repo` lists in sync, which `bazel mod tidy` does for module extensions.
+
+## Building standalone
+
+[`MODULE.bazel`](../../../MODULE.bazel) declares `semmle_code` with a `local_path_override` pointing at `..`, which
+resolves when this repo is checked out inside the internal module. [`.bazelrc`](../../../.bazelrc), which Bazel reads
+when invoked in *this* workspace, overrides that with a stub. This line is the whole reason a standalone build resolves:
+
+```
+common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
+```
+
+Do not change either the override path or the `local_path_override`; they work as a pair.
+
+[`misc/bazel/semmle_code_stub`](../../../misc/bazel/semmle_code_stub) is an otherwise empty module supplying no-op
+versions of the internal helpers that shared `.bzl` files load *unconditionally*. That is its only job, and it is small
+enough to read.
+
+**Extend the stub only when a `.bzl` file every standalone target loads gains a new internal `load()`**, which breaks
+package loading outright, for everyone. Prefer not needing one. **Never add a stub so that an internal-only target
+appears to build**: some targets depend on internal libraries (`grep -rl @semmle_code --include=*.bazel` finds them) and
+are correctly unbuildable here. Unlike a `load()`, such a dependency only fails when that target is actually requested.
+
+[`.bazelrc.internal`](../../../.bazelrc.internal) is **not** read here; it carries settings for the internal build. A
+setting needed by both has to be written in both files, with paths differing because this repo sits at a different depth
+there.
diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml
index 70b78ce72944..d29bd00486be 100644
--- a/.github/workflows/check-change-note.yml
+++ b/.github/workflows/check-change-note.yml
@@ -1,10 +1,11 @@
name: Check change note
permissions:
+ contents: read
pull-requests: read
on:
- pull_request_target:
+ pull_request:
types: [labeled, unlabeled, opened, synchronize, reopened, ready_for_review]
paths:
- "*/ql/src/**/*.ql"
@@ -23,7 +24,7 @@ jobs:
env:
REPO: ${{ github.repository }}
PULL_REQUEST_NUMBER: ${{ github.event.number }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_TOKEN: ${{ github.token }}
runs-on: ubuntu-latest
steps:
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 64b46b00a228..99028b8011cb 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -34,7 +34,7 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 10.0.100
+ dotnet-version: 10.0.201
- name: Checkout repository
uses: actions/checkout@v5
diff --git a/.github/workflows/csharp-qltest.yml b/.github/workflows/csharp-qltest.yml
index fc8bc218fe76..38ba6b9afacf 100644
--- a/.github/workflows/csharp-qltest.yml
+++ b/.github/workflows/csharp-qltest.yml
@@ -5,6 +5,10 @@ on:
paths:
- "csharp/**"
- "shared/**"
+ - "!shared/tree-sitter-extractor/**"
+ - "!shared/yeast/**"
+ - "!shared/yeast-macros/**"
+ - "!shared/yeast-schema/**"
- "misc/bazel/**"
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
@@ -16,6 +20,10 @@ on:
paths:
- "csharp/**"
- "shared/**"
+ - "!shared/tree-sitter-extractor/**"
+ - "!shared/yeast/**"
+ - "!shared/yeast-macros/**"
+ - "!shared/yeast-schema/**"
- "misc/bazel/**"
- .github/workflows/csharp-qltest.yml
- .github/actions/fetch-codeql/action.yml
@@ -43,14 +51,14 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 10.0.100
+ dotnet-version: 10.0.201
- name: Extractor unit tests
run: |
dotnet tool restore
- dotnet test -p:RuntimeFrameworkVersion=10.0.0 extractor/Semmle.Util.Tests
- dotnet test -p:RuntimeFrameworkVersion=10.0.0 extractor/Semmle.Extraction.Tests
- dotnet test -p:RuntimeFrameworkVersion=10.0.0 autobuilder/Semmle.Autobuild.CSharp.Tests
- dotnet test -p:RuntimeFrameworkVersion=10.0.0 autobuilder/Semmle.Autobuild.Cpp.Tests
+ dotnet test -p:RuntimeFrameworkVersion=10.0.5 extractor/Semmle.Util.Tests
+ dotnet test -p:RuntimeFrameworkVersion=10.0.5 extractor/Semmle.Extraction.Tests
+ dotnet test -p:RuntimeFrameworkVersion=10.0.5 autobuilder/Semmle.Autobuild.CSharp.Tests
+ dotnet test -p:RuntimeFrameworkVersion=10.0.5 autobuilder/Semmle.Autobuild.Cpp.Tests
shell: bash
stubgentest:
runs-on: ubuntu-latest
diff --git a/.github/workflows/csv-coverage-pr-artifacts.yml b/.github/workflows/csv-coverage-pr-artifacts.yml
index c62de00535e2..e27ccc7312cb 100644
--- a/.github/workflows/csv-coverage-pr-artifacts.yml
+++ b/.github/workflows/csv-coverage-pr-artifacts.yml
@@ -47,10 +47,10 @@ jobs:
git checkout HEAD^1
git log -1 --format='%H'
working-directory: base
- - name: Set up Python 3.8
+ - name: Set up Python 3.12
uses: actions/setup-python@v4
with:
- python-version: 3.8
+ python-version: "3.12"
- name: Download CodeQL CLI
uses: ./merge/.github/actions/fetch-codeql
- name: Generate CSV files on merge commit of the PR
diff --git a/.github/workflows/csv-coverage-pr-comment.yml b/.github/workflows/csv-coverage-pr-comment.yml
index 534725815b4b..ba07ccd5fc4c 100644
--- a/.github/workflows/csv-coverage-pr-comment.yml
+++ b/.github/workflows/csv-coverage-pr-comment.yml
@@ -25,10 +25,10 @@ jobs:
run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql)
uses: actions/checkout@v5
- - name: Set up Python 3.8
+ - name: Set up Python 3.12
uses: actions/setup-python@v4
with:
- python-version: 3.8
+ python-version: "3.12"
- name: Check coverage difference file and comment
env:
diff --git a/.github/workflows/csv-coverage-timeseries.yml b/.github/workflows/csv-coverage-timeseries.yml
index 11bc06bee602..1433aaa41758 100644
--- a/.github/workflows/csv-coverage-timeseries.yml
+++ b/.github/workflows/csv-coverage-timeseries.yml
@@ -20,10 +20,10 @@ jobs:
with:
path: codeqlModels
fetch-depth: 0
- - name: Set up Python 3.8
+ - name: Set up Python 3.12
uses: actions/setup-python@v4
with:
- python-version: 3.8
+ python-version: "3.12"
- name: Download CodeQL CLI
uses: ./script/.github/actions/fetch-codeql
- name: Build modeled package list
diff --git a/.github/workflows/csv-coverage-update.yml b/.github/workflows/csv-coverage-update.yml
index 9f7a0b778dab..3bab9977ccd3 100644
--- a/.github/workflows/csv-coverage-update.yml
+++ b/.github/workflows/csv-coverage-update.yml
@@ -25,10 +25,10 @@ jobs:
with:
path: ql
fetch-depth: 0
- - name: Set up Python 3.8
+ - name: Set up Python 3.12
uses: actions/setup-python@v4
with:
- python-version: 3.8
+ python-version: "3.12"
- name: Download CodeQL CLI
uses: ./ql/.github/actions/fetch-codeql
- name: Generate coverage files
diff --git a/.github/workflows/csv-coverage.yml b/.github/workflows/csv-coverage.yml
index a1224456410a..9a51710a7115 100644
--- a/.github/workflows/csv-coverage.yml
+++ b/.github/workflows/csv-coverage.yml
@@ -24,10 +24,10 @@ jobs:
with:
path: codeqlModels
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}
- - name: Set up Python 3.8
+ - name: Set up Python 3.12
uses: actions/setup-python@v4
with:
- python-version: 3.8
+ python-version: "3.12"
- name: Download CodeQL CLI
uses: ./script/.github/actions/fetch-codeql
- name: Build modeled package list
diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml
index 6578f09b8dfc..5a3bc9342855 100644
--- a/.github/workflows/go-tests.yml
+++ b/.github/workflows/go-tests.yml
@@ -5,6 +5,10 @@ on:
- "go/**"
- "!go/documentation/**"
- "shared/**"
+ - "!shared/tree-sitter-extractor/**"
+ - "!shared/yeast/**"
+ - "!shared/yeast-macros/**"
+ - "!shared/yeast-schema/**"
- .github/workflows/go-tests.yml
- .github/actions/**
- codeql-workspace.yml
diff --git a/.github/workflows/label-external-contributions.yml b/.github/workflows/label-external-contributions.yml
new file mode 100644
index 000000000000..81ed030b94fc
--- /dev/null
+++ b/.github/workflows/label-external-contributions.yml
@@ -0,0 +1,122 @@
+name: Label external contributions
+
+on:
+ schedule:
+ - cron: "7,22,37,52 * * * *"
+ workflow_dispatch:
+
+permissions: {}
+
+concurrency:
+ group: label-external-contributions
+ cancel-in-progress: false
+
+jobs:
+ label:
+ if: >-
+ github.repository == 'github/codeql' &&
+ github.ref_name == github.event.repository.default_branch
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ permissions:
+ pull-requests: write
+
+ steps:
+ - name: Create organization membership token
+ id: membership-token
+ uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
+ with:
+ client-id: ${{ vars.CODEQL_ORG_MEMBERS_APP_CLIENT_ID }}
+ private-key: ${{ secrets.CODEQL_ORG_MEMBERS_APP_PRIVATE_KEY }}
+ owner: ${{ github.repository_owner }}
+ permission-members: read
+
+ - name: Label external contributions
+ env:
+ API_URL: ${{ github.api_url }}
+ GH_TOKEN: ${{ github.token }}
+ MEMBERS_TOKEN: ${{ steps.membership-token.outputs.token }}
+ ORG: ${{ github.repository_owner }}
+ REPO: ${{ github.repository }}
+ run: |
+ set -euo pipefail
+
+ label="external-contribution"
+ updated_cutoff=$(date -u -d "1 hour ago" "+%Y-%m-%dT%H:%M:%SZ")
+
+ while IFS= read -r pr_number; do
+ if [[ ! "$pr_number" =~ ^[1-9][0-9]*$ ]]; then
+ echo "Skipping malformed pull request number."
+ continue
+ fi
+
+ pr_json=$(gh api "repos/$REPO/pulls/$pr_number")
+ if ! jq -e \
+ --arg repo "$REPO" \
+ --arg label "$label" \
+ '.state == "open" and
+ .draft == false and
+ .base.repo.full_name == $repo and
+ (.head.repo.full_name | type == "string") and
+ .head.repo.full_name != $repo and
+ .user.type == "User" and
+ (.user.login | type == "string" and length > 0) and
+ (any(.labels[]?; .name == $label) | not)' \
+ >/dev/null <<<"$pr_json"; then
+ continue
+ fi
+
+ author=$(jq -r '.user.login' <<<"$pr_json")
+ events=$(gh api --paginate \
+ "repos/$REPO/issues/$pr_number/events?per_page=100" |
+ jq -cs 'add')
+
+ if jq -e --arg label "$label" \
+ 'any(.[]; .event == "labeled" and .label.name == $label)' \
+ >/dev/null <<<"$events"; then
+ continue
+ fi
+
+ if ! membership_status=$(curl \
+ --silent \
+ --show-error \
+ --output /dev/null \
+ --write-out '%{http_code}' \
+ --connect-timeout 10 \
+ --max-time 30 \
+ --header "Accept: application/vnd.github+json" \
+ --header "Authorization: Bearer $MEMBERS_TOKEN" \
+ --header "X-GitHub-Api-Version: 2022-11-28" \
+ "$API_URL/orgs/$ORG/members/$author"); then
+ echo "::error::Membership check failed for pull request #$pr_number."
+ exit 1
+ fi
+
+ case "$membership_status" in
+ 204)
+ echo "Pull request #$pr_number was opened by an organization member; skipping."
+ continue
+ ;;
+ 404)
+ ;;
+ *)
+ echo "::error::Membership check for pull request #$pr_number returned HTTP $membership_status."
+ exit 1
+ ;;
+ esac
+
+ jq -n --arg label "$label" '{labels: [$label]}' |
+ gh api --method POST \
+ "repos/$REPO/issues/$pr_number/labels" \
+ --input - \
+ >/dev/null
+ echo "Labelled pull request #$pr_number."
+ done < <(
+ gh api --method GET --paginate "repos/$REPO/issues" \
+ -f state=open \
+ -f since="$updated_cutoff" \
+ -f sort=updated \
+ -f direction=desc \
+ -f per_page=100 |
+ jq -r '.[] | select(.pull_request != null) | .number'
+ )
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index 512fa40d2e3a..e3f464331790 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -1,15 +1,144 @@
name: "Pull Request Labeler"
+
on:
-- pull_request_target
+ schedule:
+ # Reconcile recently updated PRs promptly, including unapproved forks and
+ # conflicted PRs for which pull_request workflows do not run.
+ - cron: "7,22,37,52 * * * *"
+ # Reconcile one stable shard of all open PRs each hour to recover from
+ # delayed or missed scheduled runs.
+ - cron: "12 * * * *"
+ workflow_dispatch:
+ inputs:
+ pr_number:
+ description: "Open pull request number to reconcile"
+ required: true
+ type: string
+
+permissions: {}
-permissions:
- contents: read
- pull-requests: write
+concurrency:
+ group: pull-request-labeler
+ cancel-in-progress: false
jobs:
triage:
+ if: github.ref_name == github.event.repository.default_branch
runs-on: ubuntu-latest
+ timeout-minutes: 30
+ permissions:
+ contents: read
+ pull-requests: write
steps:
- - uses: actions/labeler@v4
- with:
- repo-token: "${{ secrets.GITHUB_TOKEN }}"
+ - uses: actions/checkout@v5
+ with:
+ persist-credentials: false
+ sparse-checkout: .github/labeler.yml
+ sparse-checkout-cone-mode: false
+
+ - name: Collect pull requests to reconcile
+ id: collect
+ env:
+ GH_TOKEN: ${{ github.token }}
+ REPO: ${{ github.repository }}
+ EVENT_NAME: ${{ github.event_name }}
+ SCHEDULE: ${{ github.event.schedule }}
+ REQUESTED_PR: ${{ inputs.pr_number }}
+ run: |
+ set -euo pipefail
+
+ if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
+ if [[ ! "$REQUESTED_PR" =~ ^[1-9][0-9]*$ ]]; then
+ echo "Invalid pull request number: $REQUESTED_PR"
+ exit 1
+ fi
+
+ pr_json=$(gh api "repos/$REPO/pulls/$REQUESTED_PR")
+ candidates=$(jq -c '[{
+ number: .number,
+ head_sha: .head.sha
+ }]' <<<"$pr_json")
+ else
+ pulls_json=$(gh api --paginate \
+ "repos/$REPO/pulls?state=open&sort=updated&direction=desc&per_page=100" |
+ jq -cs 'add')
+
+ if [ "$SCHEDULE" = "12 * * * *" ]; then
+ shard=$(( ($(date -u +%s) / 3600) % 6 ))
+ candidates=$(jq -c --argjson shard "$shard" \
+ '[.[] | select((.number % 6) == $shard) | {
+ number: .number,
+ head_sha: .head.sha
+ }]' <<<"$pulls_json")
+ else
+ cutoff=$(date -u -d "1 hour ago" "+%Y-%m-%dT%H:%M:%SZ")
+ # Hourly shards reconcile any candidates beyond this API budget.
+ candidates=$(jq -c --arg cutoff "$cutoff" \
+ '[.[] | select(.updated_at >= $cutoff) | {
+ number: .number,
+ head_sha: .head.sha
+ }][0:100]' <<<"$pulls_json")
+ fi
+ fi
+
+ echo "Collected $(jq 'length' <<<"$candidates") pull request(s)."
+ {
+ echo "candidates<> "$GITHUB_OUTPUT"
+
+ - name: Validate pull request state
+ id: validate
+ env:
+ GH_TOKEN: ${{ github.token }}
+ REPO: ${{ github.repository }}
+ CANDIDATES: ${{ steps.collect.outputs.candidates }}
+ run: |
+ set -euo pipefail
+
+ valid_numbers=()
+ while IFS=$'\t' read -r pr_number expected_sha; do
+ if [[ ! "$pr_number" =~ ^[1-9][0-9]*$ ]] ||
+ [[ ! "$expected_sha" =~ ^[0-9a-f]{40}$ ]]; then
+ echo "Skipping malformed pull request candidate."
+ continue
+ fi
+
+ if ! pr_json=$(gh api "repos/$REPO/pulls/$pr_number"); then
+ echo "Pull request #$pr_number could not be fetched; skipping."
+ continue
+ fi
+
+ if ! jq -e \
+ --arg repo "$REPO" \
+ --arg sha "$expected_sha" \
+ '.state == "open" and
+ .base.repo.full_name == $repo and
+ .head.sha == $sha and
+ (.head.repo.full_name | type == "string")' \
+ >/dev/null <<<"$pr_json"; then
+ echo "Pull request #$pr_number changed or is no longer open; skipping."
+ continue
+ fi
+
+ valid_numbers+=("$pr_number")
+ done < <(jq -r '.[] | [.number, .head_sha] | @tsv' <<<"$CANDIDATES")
+
+ if [ "${#valid_numbers[@]}" -eq 0 ]; then
+ echo "has_prs=false" >> "$GITHUB_OUTPUT"
+ exit 0
+ fi
+
+ {
+ echo "has_prs=true"
+ echo "pr_numbers<> "$GITHUB_OUTPUT"
+
+ - uses: actions/labeler@v4
+ if: steps.validate.outputs.has_prs == 'true'
+ with:
+ repo-token: "${{ github.token }}"
+ pr-number: ${{ steps.validate.outputs.pr_numbers }}
diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml
index e05a7c39c4b8..4885b614fb56 100644
--- a/.github/workflows/ql-for-ql-build.yml
+++ b/.github/workflows/ql-for-ql-build.yml
@@ -24,9 +24,8 @@ jobs:
fetch-depth: 0
- name: Find codeql
id: find-codeql
- uses: github/codeql-action/init@main
+ uses: github/codeql-action/setup-codeql@main
with:
- languages: javascript # does not matter
tools: nightly
- uses: ./.github/actions/os-version
id: os_version
@@ -61,7 +60,7 @@ jobs:
- name: Make database and analyze
run: |
./ql/target/release/buramu | tee deprecated.blame # Add a blame file for the extractor to parse.
- ${CODEQL} database create -l=ql ${DB} --search-path "${{ github.workspace }}"
+ ${CODEQL} database create --threads=0 -l=ql ${DB} --search-path "${{ github.workspace }}"
${CODEQL} database analyze -j0 --format=sarif-latest --output=ql-for-ql.sarif ${DB} ql/ql/src/codeql-suites/ql-code-scanning.qls --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
diff --git a/.github/workflows/ql-for-ql-dataset_measure.yml b/.github/workflows/ql-for-ql-dataset_measure.yml
index b4561c04a965..21c27b9efb79 100644
--- a/.github/workflows/ql-for-ql-dataset_measure.yml
+++ b/.github/workflows/ql-for-ql-dataset_measure.yml
@@ -17,8 +17,6 @@ permissions:
jobs:
measure:
- env:
- CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI
strategy:
matrix:
repo:
@@ -29,9 +27,7 @@ jobs:
- name: Find codeql
id: find-codeql
- uses: github/codeql-action/init@main
- with:
- languages: javascript # does not matter
+ uses: github/codeql-action/setup-codeql@main
- uses: ./.github/actions/os-version
id: os_version
- uses: actions/cache@v3
diff --git a/.github/workflows/ql-for-ql-tests.yml b/.github/workflows/ql-for-ql-tests.yml
index e21860519041..0454fe043fd3 100644
--- a/.github/workflows/ql-for-ql-tests.yml
+++ b/.github/workflows/ql-for-ql-tests.yml
@@ -27,9 +27,8 @@ jobs:
- uses: actions/checkout@v5
- name: Find codeql
id: find-codeql
- uses: github/codeql-action/init@main
+ uses: github/codeql-action/setup-codeql@main
with:
- languages: javascript # does not matter
tools: nightly
- uses: ./.github/actions/os-version
id: os_version
@@ -54,7 +53,7 @@ jobs:
key: ql-for-ql-tests
- name: Run QL tests
run: |
- "${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}" --consistency-queries ql/ql/consistency-queries --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" ql/ql/test
+ "${CODEQL}" test run --threads=0 --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}" --consistency-queries ql/ql/consistency-queries --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" ql/ql/test
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
@@ -73,9 +72,8 @@ jobs:
echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
- name: Find codeql
id: find-codeql
- uses: github/codeql-action/init@main
+ uses: github/codeql-action/setup-codeql@main
with:
- languages: javascript # does not matter
tools: nightly
- uses: ./.github/actions/os-version
id: os_version
@@ -102,7 +100,7 @@ jobs:
- name: Run a single QL tests - Unix
if: runner.os != 'Windows'
run: |
- "${CODEQL}" test run --check-databases --search-path "${{ github.workspace }}" ql/ql/test/queries/style/DeadCode/DeadCode.qlref
+ "${CODEQL}" test run --threads=0 --check-databases --search-path "${{ github.workspace }}" ql/ql/test/queries/style/DeadCode/DeadCode.qlref
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Run a single QL tests - Windows
@@ -110,4 +108,4 @@ jobs:
shell: pwsh
run: |
$Env:PATH += ";$(dirname ${{ steps.find-codeql.outputs.codeql-path }})"
- codeql test run --check-databases --search-path "${{ github.workspace }}" ql/ql/test/queries/style/DeadCode/DeadCode.qlref
+ codeql test run --threads=0 --check-databases --search-path "${{ github.workspace }}" ql/ql/test/queries/style/DeadCode/DeadCode.qlref
diff --git a/.github/workflows/query-list.yml b/.github/workflows/query-list.yml
index 8c736379f8a6..53857b5ae12c 100644
--- a/.github/workflows/query-list.yml
+++ b/.github/workflows/query-list.yml
@@ -26,10 +26,10 @@ jobs:
uses: actions/checkout@v5
with:
path: codeql
- - name: Set up Python 3.8
+ - name: Set up Python 3.12
uses: actions/setup-python@v4
with:
- python-version: 3.8
+ python-version: "3.12"
- name: Download CodeQL CLI
# Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo
uses: ./codeql/.github/actions/fetch-codeql
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 34f5efb74ba6..6782733f7d2d 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -7,6 +7,9 @@ on:
- "misc/bazel/**"
- "misc/codegen/**"
- "shared/**"
+ - "!shared/yeast/**"
+ - "!shared/yeast-macros/**"
+ - "!shared/yeast-schema/**"
- "MODULE.bazel"
- .github/workflows/rust.yml
- .github/actions/**
diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml
index 4a5613f988e5..968015606401 100644
--- a/.github/workflows/swift.yml
+++ b/.github/workflows/swift.yml
@@ -7,6 +7,10 @@ on:
- "misc/bazel/**"
- "misc/codegen/**"
- "shared/**"
+ - "!shared/tree-sitter-extractor/**"
+ - "!shared/yeast/**"
+ - "!shared/yeast-macros/**"
+ - "!shared/yeast-schema/**"
- "*.bazel*"
- .github/workflows/swift.yml
- .github/actions/**
@@ -54,6 +58,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
+ - uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted
with:
diff --git a/.github/workflows/update-rust-analyzer.lock.yml b/.github/workflows/update-rust-analyzer.lock.yml
new file mode 100644
index 000000000000..6a403c04f04c
--- /dev/null
+++ b/.github/workflows/update-rust-analyzer.lock.yml
@@ -0,0 +1,1824 @@
+# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"89825e14c90fc1af478d2ac55eb66b5a0df973d37da033c508e957ec5cea2543","body_hash":"ba6be270b77cdf21fed3489d4d8178200f5de7cfbab7ab7c273de57ad45f2383","compiler_version":"v0.88.7","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.80"}}
+# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"5e508589e03a7757a7e05b26e834292f5445bfb6","version":"v0.88.7"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.14","digest":"sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.14@sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14","digest":"sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14@sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.14","digest":"sha256:3a379c5e96e29499c815e9dd2a71334d01c326a9b73991c76544fda9cae35c34","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.14@sha256:3a379c5e96e29499c815e9dd2a71334d01c326a9b73991c76544fda9cae35c34"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.14","digest":"sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.14@sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.18","digest":"sha256:85b940556a8faa4e1fdbef124bfd75f2c4ebd855a10b88a1c3b6f3e97f6f1a53","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.18@sha256:85b940556a8faa4e1fdbef124bfd75f2c4ebd855a10b88a1c3b6f3e97f6f1a53"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"}],"mcp_servers":[{"name":"safeoutputs","tools":["create_pull_request","missing_data","missing_tool","noop"]}]}
+# This file was automatically generated by gh-aw (v0.88.7). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
+#
+# ___ _ _
+# / _ \ | | (_)
+# | |_| | __ _ ___ _ __ | |_ _ ___
+# | _ |/ _` |/ _ \ '_ \| __| |/ __|
+# | | | | (_| | __/ | | | |_| | (__
+# \_| |_/\__, |\___|_| |_|\__|_|\___|
+# __/ |
+# _ _ |___/
+# | | | | / _| |
+# | | | | ___ _ __ _ __| |_| | _____ ____
+# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
+# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
+# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
+#
+#
+# To update this file, edit the corresponding .md file and run:
+# gh aw compile
+# Not all edits will cause changes to this file.
+#
+# For more information: https://github.github.com/gh-aw/introduction/overview/
+#
+# Update the rust-analyzer version used by the Rust extractor and prepare a pull request.
+#
+# Intent: Keep the Rust extractor on the latest compatible rust-analyzer version with a reviewable, validated pull request.
+#
+# Secrets used:
+# - GH_AW_CI_TRIGGER_TOKEN
+# - GH_AW_DEFAULT_OTLP_HEADERS
+# - GH_AW_GITHUB_MCP_SERVER_TOKEN
+# - GH_AW_GITHUB_TOKEN
+# - GITHUB_TOKEN
+#
+# Custom actions used:
+# - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+# - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
+# - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
+# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+# - github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.7
+#
+# Container images used:
+# - ghcr.io/github/gh-aw-firewall/agent:0.28.14@sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14@sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5
+# - ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.14@sha256:3a379c5e96e29499c815e9dd2a71334d01c326a9b73991c76544fda9cae35c34
+# - ghcr.io/github/gh-aw-firewall/squid:0.28.14@sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5
+# - ghcr.io/github/gh-aw-mcpg:v0.4.18@sha256:85b940556a8faa4e1fdbef124bfd75f2c4ebd855a10b88a1c3b6f3e97f6f1a53
+# - ghcr.io/github/gh-aw-node@sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23
+# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699
+
+name: "Update rust-analyzer"
+on:
+ # roles: # Roles processed as role check in pre-activation job
+ # - admin # Roles processed as role check in pre-activation job
+ # - maintainer # Roles processed as role check in pre-activation job
+ # - write # Roles processed as role check in pre-activation job
+ workflow_dispatch:
+ inputs:
+ aw_context:
+ default: ""
+ description: "Agent caller context (used internally by Agentic Workflows)."
+ required: false
+ type: string
+
+permissions: {}
+
+concurrency:
+ cancel-in-progress: false
+ group: update-rust-analyzer
+
+run-name: "Update rust-analyzer"
+
+env:
+ OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}
+ OTEL_SERVICE_NAME: gh-aw.update-rust-analyzer
+ OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=Update%20rust-analyzer,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot'
+ OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}
+ GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]'
+ GH_AW_OTLP_IF_MISSING: ignore
+
+jobs:
+ activation:
+ runs-on: ubuntu-slim
+ permissions:
+ actions: read
+ contents: read
+ env:
+ GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
+ outputs:
+ comment_id: ""
+ comment_repo: ""
+ daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }}
+ daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }}
+ daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }}
+ daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }}
+ engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
+ lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
+ model: ${{ steps.generate_aw_info.outputs.model }}
+ oauth_token_check_failed: ${{ steps.check-oauth-tokens.outputs.oauth_token_check_failed == 'true' }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.7
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/update-rust-analyzer.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.80"
+ GH_AW_INFO_AWF_VERSION: "v0.28.14"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Mask OTLP telemetry headers
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
+ - name: Generate agentic run info
+ id: generate_aw_info
+ env:
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'auto' }}
+ GH_AW_INFO_VERSION: "1.0.80"
+ GH_AW_INFO_AGENT_VERSION: "1.0.80"
+ GH_AW_INFO_CLI_VERSION: "v0.88.7"
+ GH_AW_INFO_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_INFO_EXPERIMENTAL: "false"
+ GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
+ GH_AW_INFO_STAGED: "false"
+ GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","github-actions","rust","bazel","python"]'
+ GH_AW_INFO_FIREWALL_ENABLED: "true"
+ GH_AW_INFO_AWF_VERSION: "v0.28.14"
+ GH_AW_INFO_AWMG_VERSION: ""
+ GH_AW_INFO_FIREWALL_TYPE: "squid"
+ GH_AW_INFO_AGENT_RUNTIME: ""
+ GH_AW_INFO_FRONTMATTER_EMOJI: "š¦"
+ GH_AW_COMPILED_STRICT: "true"
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs'));
+ await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+ with:
+ key: agentic-workflow-usage-updaterustanalyzer-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-updaterustanalyzer-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs'));
+ await main();
+ - name: Check daily workflow token guardrail
+ id: daily-effective-workflow-guardrail
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_WORKFLOW_ID: "update-rust-analyzer"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "false"
+ GH_AW_HAS_LABEL_COMMAND: "false"
+ GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs'));
+ await main();
+ - name: Check for OAuth tokens
+ id: check-oauth-tokens
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh"
+ env:
+ GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
+ GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
+ - name: Checkout .github and .agents folders
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ persist-credentials: false
+ sparse-checkout: |
+ .github
+ .agents
+ .claude
+ .codex
+ .gemini
+ .pi
+ sparse-checkout-cone-mode: true
+ fetch-depth: 1
+ - name: Save agent config folders for base branch restoration
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .github"
+ GH_AW_AGENT_FILES: "AGENTS.md"
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
+ - name: Check workflow lock file
+ id: check-lock-file
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_WORKFLOW_FILE: "update-rust-analyzer.lock.yml"
+ GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs'));
+ await main();
+ - name: Check compile-agentic version
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_COMPILED_VERSION: "v0.88.7"
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'check_version_updates.cjs'));
+ await main();
+ - name: Log runtime features
+ if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }}
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh"
+ - name: Create prompt with built-in context
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions
+ GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
+ GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
+ GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"cli_proxy_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"}]}"
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+ GH_AW_PROMPT_CONTENT_0000: "\n"
+ GH_AW_PROMPT_CONTENT_0001: "\nTools: create_pull_request, missing_tool, missing_data, noop\n"
+ GH_AW_PROMPT_CONTENT_0002: "\n"
+ GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` ā `$GITHUB_WORKSPACE` (cwd) [full history, all branches available as remote-tracking refs]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` ā\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n"
+ GH_AW_PROMPT_CONTENT_0004: "\n"
+ GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/workflows/update-rust-analyzer.md}}\n"
+ with:
+ script: |
+ const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs');
+ await main(core);
+ - name: Interpolate variables and render templates
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
+ GH_AW_ENGINE_ID: "copilot"
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs'));
+ await main();
+ - name: Substitute placeholders
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` ā run `safeoutputs --help` to see available tools'
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+
+ const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs'));
+
+ // Call the substitution function
+ return await substitutePlaceholders({
+ file: process.env.GH_AW_PROMPT,
+ substitutions: {
+ GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A,
+ GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A,
+ GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A,
+ GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE,
+ GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
+ GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
+ GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
+ GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
+ }
+ });
+ - name: Validate prompt placeholders
+ env:
+ GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh"
+ - name: Print prompt
+ env:
+ GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh"
+ - name: Stage prompt files for artifact upload
+ run: |
+ mkdir -p /tmp/gh-aw/aw-prompts
+ cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/
+ - name: Upload activation artifact
+ if: success() || failure()
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: activation
+ include-hidden-files: true
+ path: |
+ /tmp/gh-aw/aw_info.json
+ /tmp/gh-aw/models.json
+ /tmp/gh-aw/aw-prompts/prompt.txt
+ /tmp/gh-aw/aw-prompts/prompt-template.txt
+ /tmp/gh-aw/aw-prompts/prompt-import-tree.json
+ /tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/base
+ /tmp/gh-aw/.github/agents
+ /tmp/gh-aw/.github/skills
+ if-no-files-found: ignore
+ retention-days: 1
+
+ agent:
+ needs: activation
+ if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ copilot-requests: write
+ pull-requests: read
+ timeout-minutes: 180
+ env:
+ DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
+ GH_AW_ASSETS_ALLOWED_EXTS: ""
+ GH_AW_ASSETS_BRANCH: ""
+ GH_AW_ASSETS_MAX_SIZE_KB: 0
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
+ GH_AW_PR_HEAD_BASE_BRANCH: ""
+ GH_AW_PR_HEAD_BASE_PR_NUMBER: ""
+ GH_AW_PR_HEAD_BASE_REF: ""
+ GH_AW_PR_HEAD_BASE_REPO: ""
+ GH_AW_PR_HEAD_BASE_SHA: ""
+ GH_AW_PR_HEAD_REPO: ""
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
+ GH_AW_WORKFLOW_ID_SANITIZED: updaterustanalyzer
+ outputs:
+ agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
+ ai_credits_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.ai_credits_rate_limit_error || 'false' }}
+ aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
+ ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
+ checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
+ effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
+ has_patch: ${{ steps.collect_output.outputs.has_patch }}
+ http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }}
+ inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }}
+ invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }}
+ max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }}
+ mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }}
+ missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }}
+ missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }}
+ model: ${{ needs.activation.outputs.model }}
+ model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }}
+ output: ${{ steps.collect_output.outputs.output }}
+ output_types: ${{ steps.collect_output.outputs.output_types }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }}
+ unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.7
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/update-rust-analyzer.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.80"
+ GH_AW_INFO_AWF_VERSION: "v0.28.14"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Set runtime paths
+ id: set-runtime-paths
+ env:
+ GH_AW_RUNNER_TOOL_CACHE: ${{ runner.tool_cache }}
+ run: |
+ if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then
+ echo "RUNNER_TOOL_CACHE=${GH_AW_RUNNER_TOOL_CACHE}" >> "$GITHUB_ENV"
+ fi
+ {
+ echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl"
+ echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json"
+ echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
+ } >> "$GITHUB_OUTPUT"
+ - name: Mask OTLP telemetry headers
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
+ - name: Check OTLP telemetry configuration
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh"
+ - name: Checkout repository
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ persist-credentials: false
+ fetch-depth: 0
+ - name: Create gh-aw temp directory
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
+ - name: Configure gh CLI for GitHub Enterprise
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh"
+ env:
+ GH_TOKEN: ${{ github.token }}
+ - name: Download activation artifact
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: activation
+ path: /tmp/gh-aw
+ - name: Set up CodeQL
+ uses: ./.github/actions/fetch-codeql
+ - name: Configure Git
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ - continue-on-error: true
+ name: Install cargo-edit
+ run: cargo install cargo-edit@0.13.0 --locked
+ - name: Run rust-analyzer updater script
+ run: "mkdir -p /tmp/gh-aw/agent\nset +e\npython3 rust/scripts/update_rust_analyzer.py \\\n 2>&1 | tee /tmp/gh-aw/agent/rust-analyzer-update.log\nstatus=${PIPESTATUS[0]}\nset -e\n\nprintf '%s\\n' \"$status\" > /tmp/gh-aw/agent/rust-analyzer-update-status.txt\nif grep -Fxq \"No new rust-analyzer version available.\" \\\n /tmp/gh-aw/agent/rust-analyzer-update.log; then\n printf '%s\\n' \"no-update\" > /tmp/gh-aw/agent/rust-analyzer-update-result.txt\nelse\n printf '%s\\n' \"update\" > /tmp/gh-aw/agent/rust-analyzer-update-result.txt\nfi"
+
+ - name: Configure Git credentials
+ env:
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_TOKEN: ${{ github.token }}
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
+ - name: Checkout PR branch
+ id: checkout-pr
+ if: |
+ github.event.pull_request || github.event.issue.pull_request || github.event_name == 'workflow_dispatch' && fromJSON(github.event.inputs.aw_context || '{}').item_type == 'pull_request'
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs'));
+ await main();
+ - name: Install GitHub Copilot CLI
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh"
+ env:
+ GH_HOST: github.com
+ GH_AW_COMPILED_VERSION: v0.88.7
+ - name: Install AWF binary
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.14 --rootless
+ - name: Determine automatic lockdown mode for GitHub MCP Server
+ id: determine-automatic-lockdown
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
+ env:
+ GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
+ GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs'));
+ await determineAutomaticLockdown(github, context, core);
+ - name: Restore agent config folders from base branch
+ if: steps.checkout-pr.outcome == 'success'
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .github"
+ GH_AW_AGENT_FILES: "AGENTS.md"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
+ - name: Restore inline sub-agents from activation artifact
+ env:
+ GH_AW_SUB_AGENT_DIR: ".github/agents"
+ GH_AW_SUB_AGENT_EXT: ".agent.md"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh"
+ - name: Restore inline skills from activation artifact
+ env:
+ GH_AW_SKILL_DIR: ".github/skills"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
+ - name: Download container images
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.14@sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14@sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5 ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.14@sha256:3a379c5e96e29499c815e9dd2a71334d01c326a9b73991c76544fda9cae35c34 ghcr.io/github/gh-aw-firewall/squid:0.28.14@sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5 ghcr.io/github/gh-aw-mcpg:v0.4.18@sha256:85b940556a8faa4e1fdbef124bfd75f2c4ebd855a10b88a1c3b6f3e97f6f1a53 ghcr.io/github/gh-aw-node@sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699
+ - name: Prepare Safe Outputs Directories
+ run: |
+ mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
+ mkdir -p /tmp/gh-aw/safeoutputs
+ mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
+ - name: Generate Safe Outputs Config
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw"
+ GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}"
+ GH_AW_SAFE_OUTPUTS_CONFIG: "{\"create_pull_request\":{\"allowed_files\":[\"Cargo.lock\",\"shared/tree-sitter-extractor/Cargo.toml\",\"shared/yeast/Cargo.toml\",\"shared/yeast-macros/Cargo.toml\",\"shared/yeast-schema/Cargo.toml\",\"ruby/extractor/Cargo.toml\",\"unified/extractor/Cargo.toml\",\"unified/swift-syntax-rs/Cargo.toml\",\"shared/yeast/src/**\",\"shared/yeast-macros/src/**\",\"shared/yeast-schema/src/**\",\"shared/tree-sitter-extractor/src/**\",\"MODULE.bazel\",\"MODULE.bazel.lock\",\"rust-toolchain.toml\",\"rust/**\",\"misc/bazel/3rdparty/**\"],\"branch_prefix\":\"automation/update-rust-analyzer/\",\"draft\":true,\"max\":1,\"max_patch_files\":1000,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"request_review\",\"title_prefix\":\"Rust: \"},\"create_report_incomplete_issue\":{\"title-prefix\":\"[incomplete]\"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}"
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'create_files.cjs'));
+ await main();
+ - name: Generate Safe Outputs Tools
+ env:
+ GH_AW_TOOLS_META_JSON: |
+ {
+ "description_suffixes": {
+ "create_pull_request": " CONSTRAINTS: Maximum 1 pull request(s) can be created. Branch name will be prefixed with \"automation/update-rust-analyzer/\". Title will be prefixed with \"Rust: \". PRs will be created as drafts."
+ },
+ "repo_params": {},
+ "dynamic_tools": []
+ }
+ GH_AW_VALIDATION_JSON: |
+ {
+ "create_pull_request": {
+ "defaultMax": 1,
+ "fields": {
+ "base": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ },
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "branch": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "dependencies": {
+ "type": "array",
+ "itemType": "string",
+ "itemSanitize": true,
+ "itemMaxLength": 256
+ },
+ "draft": {
+ "type": "boolean"
+ },
+ "labels": {
+ "type": "array",
+ "itemType": "string",
+ "itemSanitize": true,
+ "itemMaxLength": 128
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ },
+ "stack_position": {
+ "optionalPositiveInteger": true
+ },
+ "stack_root": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "temporary_id": {
+ "type": "string",
+ "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$"
+ },
+ "title": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ }
+ }
+ },
+ "missing_data": {
+ "defaultMax": 20,
+ "fields": {
+ "alternatives": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "context": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "data_type": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ },
+ "reason": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ }
+ }
+ },
+ "missing_tool": {
+ "defaultMax": 20,
+ "fields": {
+ "alternatives": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 512
+ },
+ "reason": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "tool": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ }
+ }
+ },
+ "noop": {
+ "defaultMax": 1,
+ "fields": {
+ "message": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ }
+ }
+ },
+ "report_incomplete": {
+ "defaultMax": 5,
+ "fields": {
+ "details": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "reason": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 1024
+ }
+ }
+ }
+ }
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs'));
+ await main();
+ - name: Start MCP Gateway
+ id: start-mcp-gateway
+ env:
+ GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST: ${{ vars.GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST || 'true' }}
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
+ GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ set -eo pipefail
+ mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
+ if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then
+ GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json"
+ cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}"
+ export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}"
+ fi
+
+ # Export gateway environment variables for MCP config and gateway script
+ export MCP_GATEWAY_PORT="8080"
+ export MCP_GATEWAY_DOMAIN="awmg-mcpg"
+ export MCP_GATEWAY_HOST_DOMAIN="localhost"
+ MCP_GATEWAY_AGENT_ID=$(openssl rand -base64 45 | tr -d '/+=')
+ echo "::add-mask::${MCP_GATEWAY_AGENT_ID}"
+ export MCP_GATEWAY_AGENT_ID
+ export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
+ mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
+ export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
+ export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro"
+ export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}"
+ export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}"
+ export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}"
+ export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}"
+ export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}"
+ export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}"
+ export DEBUG="*"
+
+ export GH_AW_ENGINE="copilot"
+ MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
+ MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
+ source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh"
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_AGENT_ID -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.18'
+
+ mkdir -p "$HOME/.copilot"
+ GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
+ cat << GH_AW_MCP_CONFIG_da213146dab3586b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ {
+ "mcpServers": {
+ "safeoutputs": {
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}",
+ "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}",
+ "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}",
+ "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}",
+ "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}",
+ "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}",
+ "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}",
+ "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}",
+ "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_SHA": "\${GITHUB_SHA}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
+ },
+ "guard-policies": {
+ "write-sink": {
+ "accept": [
+ "*"
+ ],
+ "sink-visibility": "${GH_AW_SINK_VISIBILITY}"
+ }
+ }
+ }
+ },
+ "gateway": {
+ "port": $MCP_GATEWAY_PORT,
+ "domain": "${MCP_GATEWAY_DOMAIN}",
+ "agentId": "${MCP_GATEWAY_AGENT_ID}",
+ "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}",
+ "startupTimeout": 120,
+ "opentelemetry": {
+ "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}",
+ "traceId": "${GITHUB_AW_OTEL_TRACE_ID}",
+ "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}"
+ }
+ }
+ }
+ GH_AW_MCP_CONFIG_da213146dab3586b_EOF
+ - name: Mount MCP servers as CLIs
+ id: mount-mcp-clis
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_AGENT_ID: ${{ steps.start-mcp-gateway.outputs.gateway-agent-id }}
+ MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io);
+ const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs'));
+ await main();
+ - name: Clean credentials
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
+ - name: Audit pre-agent workspace
+ id: pre_agent_audit
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
+ - name: Start CLI Proxy
+ env:
+ GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_API_URL: ${{ github.api_url }}
+ GH_HOST: ${{ env.GH_HOST }}
+ GITHUB_HOST: ${{ env.GITHUB_HOST }}
+ GITHUB_ENTERPRISE_HOST: ${{ env.GITHUB_ENTERPRISE_HOST }}
+ GITHUB_GRAPHQL_URL: ${{ env.GITHUB_GRAPHQL_URL }}
+ GITHUB_COPILOT_BASE_URL: ${{ env.GITHUB_COPILOT_BASE_URL }}
+ GH_AW_NETWORK_ISOLATION: 'true'
+ CLI_PROXY_POLICY: '{"allow-only":{"repos":"${{ steps.determine-automatic-lockdown.outputs.repos }}","min-integrity":"${{ steps.determine-automatic-lockdown.outputs.min_integrity }}"}}'
+ CLI_PROXY_IMAGE: 'ghcr.io/github/gh-aw-mcpg:v0.4.18'
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/start_cli_proxy.sh"
+ - name: Execute GitHub Copilot CLI
+ id: agentic_execution
+ # Copilot CLI tool arguments (sorted):
+ timeout-minutes: 180
+ run: |
+ set -o pipefail
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
+ trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT
+ mkdir -p "$HOME/.copilot"
+ printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json"
+ export XDG_CONFIG_HOME="$HOME"
+ export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json"
+ GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)"
+ if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then
+ echo "GitHub Copilot CLI executable not found on PATH after installation" >&2
+ exit 127
+ fi
+ GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot"
+ mkdir -p "${RUNNER_TEMP}/gh-aw/bin"
+ if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then
+ cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN"
+ fi
+ chmod 755 "$GH_AW_COPILOT_BIN"
+
+ touch /tmp/gh-aw/agent-step-summary.md
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
+ export GH_AW_NODE_BIN
+ export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
+ (umask 177 && touch /tmp/gh-aw/agent-stdio.log)
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
+ if [[ ! "$GH_AW_MAX_AI_CREDITS" =~ ^[0-9]+$ ]]; then
+ GH_AW_MAX_AI_CREDITS="1000"
+ fi
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.14/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"*.githubusercontent.com\",\"*.pythonhosted.org\",\"anaconda.org\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"bcr.bazel.build\",\"binstar.org\",\"blog.bazel.build\",\"bootstrap.pypa.io\",\"codeload.github.com\",\"conda.anaconda.org\",\"conda.binstar.org\",\"crates.io\",\"crl.geotrust.com\",\"crl.globalsign.com\",\"crl.identrust.com\",\"crl.sectigo.com\",\"crl.thawte.com\",\"crl.usertrust.com\",\"crl.verisign.com\",\"crl3.digicert.com\",\"crl4.digicert.com\",\"crls.ssl.com\",\"docs.github.com\",\"files.pythonhosted.org\",\"github-cloud.githubusercontent.com\",\"github-cloud.s3.amazonaws.com\",\"github.blog\",\"github.com\",\"github.githubassets.com\",\"index.crates.io\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"lfs.github.com\",\"mirror.bazel.build\",\"objects.githubusercontent.com\",\"ocsp.digicert.com\",\"ocsp.geotrust.com\",\"ocsp.globalsign.com\",\"ocsp.identrust.com\",\"ocsp.sectigo.com\",\"ocsp.ssl.com\",\"ocsp.thawte.com\",\"ocsp.usertrust.com\",\"ocsp.verisign.com\",\"packagecloud.io\",\"packages.cloud.google.com\",\"packages.microsoft.com\",\"patch-diff.githubusercontent.com\",\"patchdiff.githubusercontent.com\",\"pip.pypa.io\",\"ppa.launchpad.net\",\"productionresultssa0.blob.core.windows.net\",\"productionresultssa1.blob.core.windows.net\",\"productionresultssa10.blob.core.windows.net\",\"productionresultssa11.blob.core.windows.net\",\"productionresultssa12.blob.core.windows.net\",\"productionresultssa13.blob.core.windows.net\",\"productionresultssa14.blob.core.windows.net\",\"productionresultssa15.blob.core.windows.net\",\"productionresultssa16.blob.core.windows.net\",\"productionresultssa17.blob.core.windows.net\",\"productionresultssa18.blob.core.windows.net\",\"productionresultssa19.blob.core.windows.net\",\"productionresultssa2.blob.core.windows.net\",\"productionresultssa3.blob.core.windows.net\",\"productionresultssa4.blob.core.windows.net\",\"productionresultssa5.blob.core.windows.net\",\"productionresultssa6.blob.core.windows.net\",\"productionresultssa7.blob.core.windows.net\",\"productionresultssa8.blob.core.windows.net\",\"productionresultssa9.blob.core.windows.net\",\"pypi.org\",\"pypi.python.org\",\"raw.githubusercontent.com\",\"releases.bazel.build\",\"repo.anaconda.com\",\"repo.continuum.io\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"sh.rustup.rs\",\"static.crates.io\",\"static.rust-lang.org\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"],\"isolation\":true,\"topologyAttach\":[\"awmg-mcpg\",\"awmg-cli-proxy\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.14,squid=sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5,agent=sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98,api-proxy=sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5,cli-proxy=sha256:3a379c5e96e29499c815e9dd2a71334d01c326a9b73991c76544fda9cae35c34\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
+ GH_AW_DOCKER_HOST=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_CHROOT_BINARIES_SOURCE_PATH="${RUNNER_TEMP}/gh-aw" GH_AW_CHROOT_IDENTITY_HOME="${RUNNER_TEMP}/gh-aw/home" node "${RUNNER_TEMP}/gh-aw/actions/patch_awf_chroot_config.cjs"
+ fi
+ GH_AW_TOOL_CACHE_MOUNT=""
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
+ if [ -d "$GH_AW_TOOL_CACHE" ]; then
+ if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
+ GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
+ fi
+ fi
+ # shellcheck disable=SC1003,SC2016,SC2086
+ GH_AW_AWF_ENGINE_NAME=copilot \
+ GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \
+ GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \
+ GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \
+ bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \
+ awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_AGENT_ID --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull --difc-proxy-host awmg-cli-proxy:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; GH_AW_TOOL_BINS="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')"; GH_AW_TOOL_BINS="${GH_AW_TOOL_BINS%:}"; export PATH="$PATH${GH_AW_TOOL_BINS:+:}$GH_AW_TOOL_BINS"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner ā check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt'
+ env:
+ AWF_REFLECT_ENABLED: 1
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
+ COPILOT_GITHUB_TOKEN: ${{ github.token }}
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'auto' }}
+ GH_AW_LLM_PROVIDER: github
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
+ GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
+ GH_AW_PHASE: agent
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_TIMEOUT_MINUTES: 180
+ GH_AW_VERSION: v0.88.7
+ GH_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || github.token }}
+ GITHUB_API_URL: ${{ github.api_url }}
+ GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_REF_NAME: ${{ github.ref_name }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+ GITHUB_WORKSPACE: ${{ github.workspace }}
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_AUTHOR_NAME: github-actions[bot]
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_COMMITTER_NAME: github-actions[bot]
+ RUNNER_TEMP: ${{ runner.temp }}
+ S2STOKENS: true
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
+ - name: Stop CLI Proxy
+ if: always()
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/stop_cli_proxy.sh"
+ - name: Detect agent errors
+ if: always()
+ id: detect-agent-errors
+ continue-on-error: true
+ env:
+ GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }}
+ GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 180
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs'));
+ await main();
+ - name: Configure Git credentials
+ env:
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_TOKEN: ${{ github.token }}
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
+ - name: Copy Copilot session state files to logs
+ if: always()
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh"
+ - name: Stop MCP Gateway
+ if: always()
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ MCP_GATEWAY_AGENT_ID: ${{ steps.start-mcp-gateway.outputs.gateway-agent-id }}
+ GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID"
+ - name: Redact secrets in logs
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'redact_secrets.cjs'));
+ await main();
+ env:
+ GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
+ SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
+ SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: Append agent step summary
+ if: always()
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh"
+ - name: Copy Safe Outputs
+ if: always()
+ env:
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ run: |
+ mkdir -p /tmp/gh-aw
+ cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
+ - name: Ingest agent output
+ id: collect_output
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.pythonhosted.org,anaconda.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bcr.bazel.build,binstar.org,blog.bazel.build,bootstrap.pypa.io,codeload.github.com,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,docs.github.com,files.pythonhosted.org,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,mirror.bazel.build,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pip.pypa.io,ppa.launchpad.net,productionresultssa0.blob.core.windows.net,productionresultssa1.blob.core.windows.net,productionresultssa10.blob.core.windows.net,productionresultssa11.blob.core.windows.net,productionresultssa12.blob.core.windows.net,productionresultssa13.blob.core.windows.net,productionresultssa14.blob.core.windows.net,productionresultssa15.blob.core.windows.net,productionresultssa16.blob.core.windows.net,productionresultssa17.blob.core.windows.net,productionresultssa18.blob.core.windows.net,productionresultssa19.blob.core.windows.net,productionresultssa2.blob.core.windows.net,productionresultssa3.blob.core.windows.net,productionresultssa4.blob.core.windows.net,productionresultssa5.blob.core.windows.net,productionresultssa6.blob.core.windows.net,productionresultssa7.blob.core.windows.net,productionresultssa8.blob.core.windows.net,productionresultssa9.blob.core.windows.net,pypi.org,pypi.python.org,raw.githubusercontent.com,releases.bazel.build,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sh.rustup.rs,static.crates.io,static.rust-lang.org,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_API_URL: ${{ github.api_url }}
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs'));
+ await main();
+ - name: Parse agent logs for step summary
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
+ GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs'));
+ await main();
+ - name: Parse MCP Gateway logs for step summary
+ if: always()
+ id: parse-mcp-gateway
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs'));
+ await main();
+ - name: Print firewall logs
+ if: always()
+ continue-on-error: true
+ env:
+ AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/print_firewall_logs.sh" --rootless
+ - name: Parse token usage for step summary
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs'));
+ await main();
+ - name: Print AWF reflect summary
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs'));
+ await main();
+ - name: Generate observability summary
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs'));
+ await main(core);
+ - name: Write agent output placeholder if missing
+ if: always()
+ run: |
+ if [ ! -f /tmp/gh-aw/agent_output.json ]; then
+ echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
+ fi
+ # Small dedicated copy of the agent output so safe-output processing
+ # survives a failed or timed-out upload of the larger agent artifact
+ - name: Upload agent output fallback artifact
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: agent-output-fallback
+ path: |
+ /tmp/gh-aw/agent_output.json
+ /tmp/gh-aw/safeoutputs.jsonl
+ if-no-files-found: ignore
+ - name: Upload agent artifacts
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: agent
+ path: |
+ /tmp/gh-aw/aw-prompts/prompt.txt
+ /tmp/gh-aw/sandbox/agent/logs/
+ /tmp/gh-aw/redacted-urls.log
+ /tmp/gh-aw/mcp-logs/
+ /tmp/gh-aw/agent_usage.json
+ /tmp/gh-aw/agent-stdio.log
+ /tmp/gh-aw/pre-agent-audit.txt
+ /tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/otel.jsonl
+ /tmp/gh-aw/otlp-export-errors.jsonl
+ /tmp/gh-aw/safeoutputs.jsonl
+ /tmp/gh-aw/agent_output.json
+ /tmp/gh-aw/aw-*.patch
+ /tmp/gh-aw/aw-*.bundle
+ /tmp/gh-aw/awf-config.json
+ /tmp/gh-aw/sandbox/firewall/logs/
+ /tmp/gh-aw/sandbox/firewall/audit/
+ /tmp/gh-aw/sandbox/firewall/awf-reflect.json
+ if-no-files-found: ignore
+
+ conclusion:
+ needs:
+ - activation
+ - agent
+ - detection
+ - safe_outputs
+ if: >
+ always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
+ needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' ||
+ needs.activation.outputs.daily_ai_credits_exceeded == 'true')
+ runs-on: ubuntu-slim
+ permissions:
+ actions: read
+ contents: write
+ issues: write
+ pull-requests: write
+ concurrency:
+ group: "gh-aw-conclusion-update-rust-analyzer"
+ cancel-in-progress: false
+ queue: max
+ env:
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
+ outputs:
+ incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
+ noop_message: ${{ steps.noop.outputs.noop_message }}
+ tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
+ total_count: ${{ steps.missing_tool.outputs.total_count }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.7
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/update-rust-analyzer.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.80"
+ GH_AW_INFO_AWF_VERSION: "v0.28.14"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Download agent output artifact
+ id: download-agent-output
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ pattern: "{agent,agent-output-fallback}"
+ merge-multiple: true
+ path: /tmp/gh-aw/
+ - name: Setup agent output environment variable
+ id: setup-agent-output-env
+ if: steps.download-agent-output.outcome == 'success'
+ run: |
+ mkdir -p /tmp/gh-aw/
+ find "/tmp/gh-aw/" -type f -print
+ if [ -f "/tmp/gh-aw/agent_output.json" ]; then
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+ fi
+ - name: Download detection artifact
+ id: download-detection-artifact
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: detection
+ path: /tmp/gh-aw/threat-detection/
+ - name: Download Safe Outputs Items Manifest
+ id: download-safe-outputs-manifest
+ if: always()
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ pattern: safe-outputs-items
+ merge-multiple: true
+ path: /tmp/gh-aw/
+ - name: Collect usage artifact files
+ if: always()
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh"
+ - name: Upload usage artifact
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: usage
+ path: |
+ /tmp/gh-aw/usage/aw_info.json
+ /tmp/gh-aw/usage/aw-info.jsonl
+ /tmp/gh-aw/usage/agent_usage.json
+ /tmp/gh-aw/usage/agent_usage.jsonl
+ /tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/evals.jsonl
+ /tmp/gh-aw/usage/graders/grader_manifest.json
+ /tmp/gh-aw/usage/graders/grader_results.json
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
+ /tmp/gh-aw/usage/agent/token_usage.jsonl
+ /tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
+ if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+ with:
+ key: agentic-workflow-usage-updaterustanalyzer-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-updaterustanalyzer-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context);
+ const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs'));
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+ with:
+ key: agentic-workflow-usage-updaterustanalyzer-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ if-no-files-found: ignore
+ retention-days: 7
+ - name: Process no-op messages
+ id: noop
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_NOOP_MAX: "1"
+ GH_AW_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/update-rust-analyzer.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+ GH_AW_NOOP_REPORT_AS_ISSUE: "false"
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
+ GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
+ GH_AW_WORKFLOW_ID: "update-rust-analyzer"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs'));
+ await main();
+ - name: Log detection run
+ id: detection_runs
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/update-rust-analyzer.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
+ GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs'));
+ await main();
+ - name: Record missing tool
+ id: missing_tool
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
+ GH_AW_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/update-rust-analyzer.md"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'missing_tool.cjs'));
+ await main();
+ - name: Record incomplete
+ id: report_incomplete
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
+ GH_AW_REPORT_INCOMPLETE_TITLE_PREFIX: "[incomplete]"
+ GH_AW_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/update-rust-analyzer.md"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs'));
+ await main();
+ - name: Handle agent failure
+ id: handle_agent_failure
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/update-rust-analyzer.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
+ GH_AW_WORKFLOW_ID: "update-rust-analyzer"
+ GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "0"
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
+ GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }}
+ GH_AW_UNKNOWN_MODEL_AI_CREDITS: ${{ needs.agent.outputs.unknown_model_ai_credits || 'false' }}
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
+ GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
+ GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
+ GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
+ GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }}
+ GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }}
+ GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }}
+ GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }}
+ GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }}
+ GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }}
+ GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
+ GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }}
+ GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
+ GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
+ GH_AW_OAUTH_TOKEN_CHECK_FAILED: ${{ needs.activation.outputs.oauth_token_check_failed }}
+ GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
+ GH_AW_DAILY_AI_CREDITS_EXCEEDED: ${{ needs.activation.outputs.daily_ai_credits_exceeded }}
+ GH_AW_DAILY_AI_CREDITS_TOTAL_EFFECTIVE_TOKENS: ${{ needs.activation.outputs.daily_ai_credits_total_effective_tokens }}
+ GH_AW_DAILY_AI_CREDITS_THRESHOLD: ${{ needs.activation.outputs.daily_ai_credits_threshold }}
+ GH_AW_GROUP_REPORTS: "false"
+ GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+ GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
+ GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
+ GH_AW_TIMEOUT_MINUTES: "180"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs'));
+ await main();
+ - name: Report failed jobs
+ id: report_failed_jobs
+ if: always()
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/update-rust-analyzer.md"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_REPORT_FAILED_JOBS: "true"
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs'));
+ await main();
+
+ detection:
+ needs:
+ - activation
+ - agent
+ if: always() && needs.agent.result != 'skipped'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ copilot-requests: write
+ timeout-minutes: 10
+ env:
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
+ outputs:
+ aic: ${{ steps.parse_detection_token_usage.outputs.aic }}
+ detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
+ detection_reason: ${{ steps.detection_conclusion.outputs.reason }}
+ detection_success: ${{ steps.detection_conclusion.outputs.success }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.7
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/update-rust-analyzer.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.80"
+ GH_AW_INFO_AWF_VERSION: "v0.28.14"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Download activation artifact
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: activation
+ path: /tmp/gh-aw
+ - name: Download agent output artifact
+ id: download-agent-output
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ pattern: "{agent,agent-output-fallback}"
+ merge-multiple: true
+ path: /tmp/gh-aw/
+ - name: Setup agent output environment variable
+ id: setup-agent-output-env
+ if: steps.download-agent-output.outcome == 'success'
+ run: |
+ mkdir -p /tmp/gh-aw/
+ find "/tmp/gh-aw/" -type f -print
+ if [ -f "/tmp/gh-aw/agent_output.json" ]; then
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+ fi
+ - name: Checkout repository for patch context
+ if: needs.agent.outputs.has_patch == 'true'
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ persist-credentials: false
+ # --- Threat Detection ---
+ - name: Clean stale firewall files from agent artifact
+ run: |
+ rm -rf /tmp/gh-aw/sandbox/firewall/logs
+ rm -rf /tmp/gh-aw/sandbox/firewall/audit
+ - name: Download container images
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.14@sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14@sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5 ghcr.io/github/gh-aw-firewall/squid:0.28.14@sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5
+ - name: Check if detection needed
+ id: detection_guard
+ if: always()
+ env:
+ OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
+ HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+ run: |
+ if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
+ echo "run_detection=true" >> "$GITHUB_OUTPUT"
+ echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
+ else
+ echo "run_detection=false" >> "$GITHUB_OUTPUT"
+ echo "Detection skipped: no agent outputs or patches to analyze"
+ fi
+ - name: Clear MCP Config for detection
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ run: |
+ rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
+ rm -f "$HOME/.copilot/mcp-config.json"
+ rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
+ - name: Prepare threat detection files
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh"
+ - name: Setup threat detection
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ WORKFLOW_NAME: "Update rust-analyzer"
+ WORKFLOW_DESCRIPTION: "Update the rust-analyzer version used by the Rust extractor and prepare a pull request."
+ HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+ GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
+ GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true"
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs'));
+ await main();
+ - name: Ensure threat-detection directory and log
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ run: |
+ mkdir -p /tmp/gh-aw/threat-detection
+ touch /tmp/gh-aw/threat-detection/detection.log
+ - name: Install AWF binary
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.14 --rootless
+ - name: Setup Node.js
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
+ with:
+ node-version: '24'
+ package-manager-cache: false
+ - name: Install GitHub Copilot CLI
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh"
+ env:
+ GH_HOST: github.com
+ GH_AW_COMPILED_VERSION: v0.88.7
+ - name: Install threat-detect binary
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ continue-on-error: true
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1
+ - name: Execute threat detection with AWF
+ id: detection_agentic_execution
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ continue-on-error: true
+ timeout-minutes: 10
+ env:
+ AWF_REFLECT_ENABLED: 1
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
+ COPILOT_GITHUB_TOKEN: ${{ github.token }}
+ COPILOT_MODEL: detection
+ GH_AW_HARNESS_MAX_RETRIES: 0
+ GH_AW_LLM_PROVIDER: github
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
+ GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
+ GH_AW_PHASE: detection
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_TIMEOUT_MINUTES: 10
+ GH_AW_VERSION: v0.88.7
+ GITHUB_API_URL: ${{ github.api_url }}
+ GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
+ GITHUB_REF_NAME: ${{ github.ref_name }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
+ GITHUB_WORKSPACE: ${{ github.workspace }}
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_AUTHOR_NAME: github-actions[bot]
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
+ GIT_COMMITTER_NAME: github-actions[bot]
+ RUNNER_TEMP: ${{ runner.temp }}
+ S2STOKENS: true
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
+ WORKFLOW_NAME: "Update rust-analyzer"
+ WORKFLOW_DESCRIPTION: "Update the rust-analyzer version used by the Rust extractor and prepare a pull request."
+ HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
+ GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
+ run: |
+ set -o pipefail
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
+ GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)"
+ if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then
+ echo "GitHub Copilot CLI executable not found on PATH after installation" >&2
+ exit 127
+ fi
+ GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot"
+ mkdir -p "${RUNNER_TEMP}/gh-aw/bin"
+ if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then
+ cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN"
+ fi
+ chmod 755 "$GH_AW_COPILOT_BIN"
+
+ (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ if [[ ! "$GH_AW_MAX_AI_CREDITS" =~ ^[0-9]+$ ]]; then
+ GH_AW_MAX_AI_CREDITS="400"
+ fi
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.14/awf-config.schema.json\",\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.14,squid=sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5,agent=sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98,api-proxy=sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5,cli-proxy=sha256:3a379c5e96e29499c815e9dd2a71334d01c326a9b73991c76544fda9cae35c34\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
+ GH_AW_DOCKER_HOST=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ fi
+ GH_AW_TOOL_CACHE_MOUNT=""
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
+ if [ -d "$GH_AW_TOOL_CACHE" ]; then
+ if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
+ GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
+ fi
+ fi
+ # shellcheck disable=SC1003,SC2016,SC2086
+ awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; GH_AW_TOOL_BINS="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')"; GH_AW_TOOL_BINS="${GH_AW_TOOL_BINS%:}"; export PATH="$PATH${GH_AW_TOOL_BINS:+:}$GH_AW_TOOL_BINS"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ - name: Render detection log
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'render_detection_log.cjs'));
+ await main();
+ - name: Copy detection firewall logs
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ continue-on-error: true
+ run: |
+ mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall
+ if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi
+ if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi
+ - name: Upload threat detection artifact
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: detection
+ path: |
+ /tmp/gh-aw/threat-detection/detection_result.json
+ /tmp/gh-aw/threat-detection/sandbox/firewall/logs/
+ /tmp/gh-aw/threat-detection/sandbox/firewall/audit/
+ if-no-files-found: ignore
+ - name: Parse threat detection token usage for step summary
+ id: parse_detection_token_usage
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage
+ with:
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs'));
+ await main();
+ - name: Conclude threat detection
+ id: detection_conclusion
+ if: always()
+ continue-on-error: true
+ env:
+ RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
+ DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }}
+ GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
+ run: |
+ bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json
+
+ safe_outputs:
+ needs:
+ - activation
+ - agent
+ - detection
+ if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
+ runs-on: ubuntu-slim
+ permissions:
+ contents: write
+ issues: write
+ pull-requests: write
+ timeout-minutes: 45
+ env:
+ GH_AW_AGENT_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
+ GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/update-rust-analyzer"
+ GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
+ GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
+ GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }}
+ GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
+ GH_AW_WORKFLOW_EMOJI: "š¦"
+ GH_AW_WORKFLOW_ID: "update-rust-analyzer"
+ GH_AW_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/update-rust-analyzer.md"
+ outputs:
+ code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
+ code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
+ create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
+ create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
+ created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }}
+ created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }}
+ process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }}
+ process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }}
+ process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }}
+ process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }}
+ process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }}
+ process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }}
+ process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }}
+ process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
+ process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }}
+ process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.7
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Update rust-analyzer"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/update-rust-analyzer.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.80"
+ GH_AW_INFO_AWF_VERSION: "v0.28.14"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Mask OTLP telemetry headers
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh"
+ - name: Download agent output artifact
+ id: download-agent-output
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ pattern: "{agent,agent-output-fallback}"
+ merge-multiple: true
+ path: /tmp/gh-aw/
+ - name: Setup agent output environment variable
+ id: setup-agent-output-env
+ if: steps.download-agent-output.outcome == 'success'
+ run: |
+ mkdir -p /tmp/gh-aw/
+ find "/tmp/gh-aw/" -type f -print
+ if [ -f "/tmp/gh-aw/agent_output.json" ]; then
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
+ fi
+ - name: Download patch artifact
+ continue-on-error: true
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: agent
+ path: /tmp/gh-aw/
+ - name: Checkout repository
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ persist-credentials: true
+ fetch-depth: 0
+ token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ - name: Configure Git credentials
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
+ env:
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GIT_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Process Safe Outputs
+ id: process_safe_outputs
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
+ GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,*.pythonhosted.org,anaconda.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bcr.bazel.build,binstar.org,blog.bazel.build,bootstrap.pypa.io,codeload.github.com,conda.anaconda.org,conda.binstar.org,crates.io,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,docs.github.com,files.pythonhosted.org,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,index.crates.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,mirror.bazel.build,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pip.pypa.io,ppa.launchpad.net,productionresultssa0.blob.core.windows.net,productionresultssa1.blob.core.windows.net,productionresultssa10.blob.core.windows.net,productionresultssa11.blob.core.windows.net,productionresultssa12.blob.core.windows.net,productionresultssa13.blob.core.windows.net,productionresultssa14.blob.core.windows.net,productionresultssa15.blob.core.windows.net,productionresultssa16.blob.core.windows.net,productionresultssa17.blob.core.windows.net,productionresultssa18.blob.core.windows.net,productionresultssa19.blob.core.windows.net,productionresultssa2.blob.core.windows.net,productionresultssa3.blob.core.windows.net,productionresultssa4.blob.core.windows.net,productionresultssa5.blob.core.windows.net,productionresultssa6.blob.core.windows.net,productionresultssa7.blob.core.windows.net,productionresultssa8.blob.core.windows.net,productionresultssa9.blob.core.windows.net,pypi.org,pypi.python.org,raw.githubusercontent.com,releases.bazel.build,repo.anaconda.com,repo.continuum.io,s.symcb.com,s.symcd.com,security.ubuntu.com,sh.rustup.rs,static.crates.io,static.rust-lang.org,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
+ GITHUB_SERVER_URL: ${{ github.server_url }}
+ GITHUB_API_URL: ${{ github.api_url }}
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"allowed_files\":[\"Cargo.lock\",\"shared/tree-sitter-extractor/Cargo.toml\",\"shared/yeast/Cargo.toml\",\"shared/yeast-macros/Cargo.toml\",\"shared/yeast-schema/Cargo.toml\",\"ruby/extractor/Cargo.toml\",\"unified/extractor/Cargo.toml\",\"unified/swift-syntax-rs/Cargo.toml\",\"shared/yeast/src/**\",\"shared/yeast-macros/src/**\",\"shared/yeast-schema/src/**\",\"shared/tree-sitter-extractor/src/**\",\"MODULE.bazel\",\"MODULE.bazel.lock\",\"rust-toolchain.toml\",\"rust/**\",\"misc/bazel/3rdparty/**\"],\"branch_prefix\":\"automation/update-rust-analyzer/\",\"draft\":true,\"max\":1,\"max_patch_files\":1000,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"request_review\",\"title_prefix\":\"Rust: \"},\"create_report_incomplete_issue\":{\"title-prefix\":\"[incomplete]\"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}"
+ GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
+ with:
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ script: |
+ const path = require('path');
+ const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
+ const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs'));
+ await main();
+ - name: Upload Safe Outputs Items
+ if: always()
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: safe-outputs-items
+ path: |
+ /tmp/gh-aw/safe-output-items.jsonl
+ /tmp/gh-aw/temporary-id-map.json
+ /tmp/gh-aw/safe-output-errors.json
+ if-no-files-found: ignore
diff --git a/.github/workflows/update-rust-analyzer.md b/.github/workflows/update-rust-analyzer.md
new file mode 100644
index 000000000000..23c6aebb4e44
--- /dev/null
+++ b/.github/workflows/update-rust-analyzer.md
@@ -0,0 +1,129 @@
+---
+name: Update rust-analyzer
+emoji: š¦
+description: Update the rust-analyzer version used by the Rust extractor and prepare a pull request.
+intent: Keep the Rust extractor on the latest compatible rust-analyzer version with a reviewable, validated pull request.
+on:
+ workflow_dispatch:
+ roles: [admin, maintainer, write]
+permissions:
+ contents: read
+ actions: read
+ pull-requests: read
+ copilot-requests: write
+strict: true
+checkout:
+ fetch-depth: 0
+concurrency:
+ group: update-rust-analyzer
+ cancel-in-progress: false
+timeout-minutes: 180
+tools:
+ github:
+ mode: gh-proxy
+ toolsets: [repos, pull_requests, actions]
+ bash: ["*"]
+ edit: true
+network:
+ allowed:
+ - defaults
+ - github
+ - github-actions
+ - rust
+ - bazel
+ - python
+steps:
+ - name: Set up CodeQL
+ uses: ./.github/actions/fetch-codeql
+
+ - name: Configure Git
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+
+ - name: Install cargo-edit
+ continue-on-error: true
+ run: cargo install cargo-edit@0.13.0 --locked
+
+ - name: Run rust-analyzer updater script
+ run: |
+ mkdir -p /tmp/gh-aw/agent
+ set +e
+ python3 rust/scripts/update_rust_analyzer.py \
+ 2>&1 | tee /tmp/gh-aw/agent/rust-analyzer-update.log
+ status=${PIPESTATUS[0]}
+ set -e
+
+ printf '%s\n' "$status" > /tmp/gh-aw/agent/rust-analyzer-update-status.txt
+ if grep -Fxq "No new rust-analyzer version available." \
+ /tmp/gh-aw/agent/rust-analyzer-update.log; then
+ printf '%s\n' "no-update" > /tmp/gh-aw/agent/rust-analyzer-update-result.txt
+ else
+ printf '%s\n' "update" > /tmp/gh-aw/agent/rust-analyzer-update-result.txt
+ fi
+safe-outputs:
+ report-incomplete: {}
+ create-pull-request:
+ title-prefix: "Rust: "
+ branch-prefix: "automation/update-rust-analyzer/"
+ draft: true
+ max-patch-size: 10240
+ max-patch-files: 1000
+ allowed-files:
+ - "Cargo.lock"
+ - "shared/tree-sitter-extractor/Cargo.toml"
+ - "shared/yeast/Cargo.toml"
+ - "shared/yeast-macros/Cargo.toml"
+ - "shared/yeast-schema/Cargo.toml"
+ - "ruby/extractor/Cargo.toml"
+ - "unified/extractor/Cargo.toml"
+ - "unified/swift-syntax-rs/Cargo.toml"
+ # A rust-analyzer update can require a newer Rust toolchain whose Clippy
+ # lints require compatibility fixes in any of the Rust sources.
+ # rust-analyzer dependency updates can also update tree-sitter APIs,
+ # requiring compatibility fixes in the shared extractor implementation.
+ - "shared/yeast/src/**"
+ - "shared/yeast-macros/src/**"
+ - "shared/yeast-schema/src/**"
+ - "shared/tree-sitter-extractor/src/**"
+ - "MODULE.bazel"
+ - "MODULE.bazel.lock"
+ - "rust-toolchain.toml"
+ - "rust/**"
+ - "misc/bazel/3rdparty/**"
+---
+
+# Update rust-analyzer
+
+## Task
+
+The workflow has already run `rust/scripts/update_rust_analyzer.py`. Read:
+
+- `/tmp/gh-aw/agent/rust-analyzer-update.log` for its complete output.
+- `/tmp/gh-aw/agent/rust-analyzer-update-status.txt` for its exit status.
+- `/tmp/gh-aw/agent/rust-analyzer-update-result.txt` for the deterministic result classification.
+
+If the result is `no-update`, call `noop` with the reason
+`No new rust-analyzer version available.` and stop immediately. Do not inspect
+CI, modify files, or create a pull request.
+
+Otherwise, continue the update from the existing working tree and commits:
+
+1. Review the updater log, exit status, commits, and working tree. Do not rerun
+ the updater script or undo changes that it successfully made.
+2. Read `rust/updating-rust-analyzer.md` and all applicable repository
+ instructions, then complete the remaining update steps.
+3. Review the complete diff and commits. Do not include secrets. Do not refer
+ to private repositories, internal issues, or internal pull requests in the
+ public pull request.
+4. Use `create_pull_request` exactly once. Summarize the updater output,
+ changes, and validation. If the update cannot be finished, still create a
+ partial draft pull request when
+ there are useful changes, and clearly list failures, missing work, and the
+ next commands for a maintainer.
+
+The pull request is created after this agent execution, so its newly triggered
+CI cannot be awaited in this run. Compensate with the strongest practical
+local validation and state this limitation accurately in the pull request.
+If the updater did not report `no-update` but no useful patch can be produced,
+call `report_incomplete` with the updater failure and exact blocker.
diff --git a/.github/workflows/yeast-test.yml b/.github/workflows/yeast-test.yml
new file mode 100644
index 000000000000..48e0ca01498f
--- /dev/null
+++ b/.github/workflows/yeast-test.yml
@@ -0,0 +1,32 @@
+name: Test Yeast
+
+on:
+ push:
+ paths:
+ - "shared/yeast/**"
+ - "shared/yeast-macros/**"
+ - "shared/yeast-schema/**"
+ - .github/workflows/yeast-test.yml
+ branches:
+ - main
+ - "rc/*"
+ pull_request:
+ paths:
+ - "shared/yeast/**"
+ - "shared/yeast-macros/**"
+ - "shared/yeast-schema/**"
+ - .github/workflows/yeast-test.yml
+
+env:
+ CARGO_TERM_COLOR: always
+
+permissions:
+ contents: read
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v5
+ - name: Run tests
+ run: cargo test --verbose --package codeql-extractor --package yeast --package yeast-macros --package yeast-schema
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0f2906dab310..1c8d6a8d2c94 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,7 +4,7 @@ default_language_version:
python: python3.12
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v3.2.0
+ rev: v6.0.0
hooks:
- id: trailing-whitespace
exclude: /test([^/]*)/.*$(? 10
- * x = x - 1
- * end
- * end
- * puts x
- * end
- * ```
- *
- * The basic block on line 8 is in the dominance frontier
- * of the basic block starting on line 3 because that block
- * dominates the basic block on line 4, which is a predecessor of
- * `puts x`. Also, the basic block starting on line 3 does not
- * dominate the basic block on line 8.
- */
- predicate inDominanceFrontier(BasicBlock df) {
- this.dominatesPredecessor(df) and
- not this.strictlyDominates(df)
- }
-
- /**
- * Holds if this basic block dominates a predecessor of `df`.
- */
- private predicate dominatesPredecessor(BasicBlock df) { this.dominates(df.getAPredecessor()) }
-
- /**
- * Gets the basic block that immediately dominates this basic block, if any.
- *
- * That is, all paths reaching this basic block from some entry point
- * basic block must go through the result, which is an immediate basic block
- * predecessor of this basic block.
- *
- * Example:
- *
- * ```rb
- * def m b
- * if b
- * return 0
- * end
- * return 1
- * end
- * ```
- *
- * The basic block starting on line 2 is an immediate dominator of
- * the basic block on line 5 (all paths from the entry point of `m`
- * to `return 1` must go through the `if` block, and the `if` block
- * is an immediate predecessor of `return 1`).
- */
- BasicBlock getImmediateDominator() { bbIDominates(result, this) }
-
- /**
- * Holds if this basic block strictly post-dominates basic block `bb`.
- *
- * That is, all paths reaching a normal exit point basic block from basic
- * block `bb` must go through this basic block (which must be different
- * from `bb`).
- *
- * Example:
- *
- * ```rb
- * def m b
- * if b
- * puts "b"
- * end
- * puts "m"
- * end
- * ```
- *
- * The basic block on line 5 strictly post-dominates the basic block on
- * line 3 (all paths to the exit point of `m` from `puts "b"` must go
- * through `puts "m"`).
- */
- predicate strictlyPostDominates(BasicBlock bb) { bbIPostDominates+(this, bb) }
-
- /**
- * Holds if this basic block post-dominates basic block `bb`.
- *
- * That is, all paths reaching a normal exit point basic block from basic
- * block `bb` must go through this basic block.
- *
- * Example:
- *
- * ```rb
- * def m b
- * if b
- * puts "b"
- * end
- * puts "m"
- * end
- * ```
- *
- * The basic block on line 5 post-dominates the basic block on line 3
- * (all paths to the exit point of `m` from `puts "b"` must go through
- * `puts "m"`).
- */
- predicate postDominates(BasicBlock bb) {
- this.strictlyPostDominates(bb) or
- this = bb
- }
-
- /** Holds if this basic block is in a loop in the control flow graph. */
- predicate inLoop() { this.getASuccessor+() = this }
-
- /** Gets a textual representation of this basic block. */
- string toString() { result = this.getFirstNode().toString() }
-
- /** Gets the location of this basic block. */
- Location getLocation() { result = this.getFirstNode().getLocation() }
-}
-
-cached
-private module Cached {
- /** Internal representation of basic blocks. */
- cached
- newtype TBasicBlock = TBasicBlockStart(Node cfn) { startsBB(cfn) }
-
- /** Holds if `cfn` starts a new basic block. */
- private predicate startsBB(Node cfn) {
- not exists(cfn.getAPredecessor()) and exists(cfn.getASuccessor())
- or
- cfn.isJoin()
- or
- cfn.getAPredecessor().isBranch()
- or
- /*
- * In cases such as
- *
- * ```rb
- * if x or y
- * foo
- * else
- * bar
- * ```
- *
- * we have a CFG that looks like
- *
- * x --false--> [false] x or y --false--> bar
- * \ |
- * --true--> y --false--
- * \
- * --true--> [true] x or y --true--> foo
- *
- * and we want to ensure that both `foo` and `bar` start a new basic block,
- * in order to get a `ConditionalBlock` out of the disjunction.
- */
-
- exists(cfn.getAPredecessor(any(BooleanSuccessor s)))
- }
-
- /**
- * Holds if `succ` is a control flow successor of `pred` within
- * the same basic block.
- */
- private predicate intraBBSucc(Node pred, Node succ) {
- succ = pred.getASuccessor() and
- not startsBB(succ)
- }
-
- /**
- * Holds if `cfn` is the `i`th node in basic block `bb`.
- *
- * In other words, `i` is the shortest distance from a node `bbStart`
- * that starts a basic block to `cfn` along the `intraBBSucc` relation.
- */
- cached
- predicate bbIndex(Node bbStart, Node cfn, int i) =
- shortestDistances(startsBB/1, intraBBSucc/2)(bbStart, cfn, i)
-
- /**
- * Holds if the first node of basic block `succ` is a control flow
- * successor of the last node of basic block `pred`.
- */
- private predicate succBB(BasicBlock pred, BasicBlock succ) { succ = pred.getASuccessor() }
-
- /** Holds if `dom` is an immediate dominator of `bb`. */
- cached
- predicate bbIDominates(BasicBlock dom, BasicBlock bb) =
- idominance(entryBB/1, succBB/2)(_, dom, bb)
-
- /** Holds if `pred` is a basic block predecessor of `succ`. */
- private predicate predBB(BasicBlock succ, BasicBlock pred) { succBB(pred, succ) }
-
- /** Holds if `bb` is an exit basic block that represents normal exit. */
- private predicate normalExitBB(BasicBlock bb) { bb.getANode().(AnnotatedExitNode).isNormal() }
-
- /** Holds if `dom` is an immediate post-dominator of `bb`. */
- cached
- predicate bbIPostDominates(BasicBlock dom, BasicBlock bb) =
- idominance(normalExitBB/1, predBB/2)(_, dom, bb)
-
- /**
- * Gets the `i`th predecessor of join block `jb`, with respect to some
- * arbitrary order.
- */
- cached
- JoinBlockPredecessor getJoinBlockPredecessor(JoinBlock jb, int i) {
- none()
- /*
- * result =
- * rank[i + 1](JoinBlockPredecessor jbp |
- * jbp = jb.getAPredecessor()
- * |
- * jbp order by JoinBlockPredecessors::getId(jbp), JoinBlockPredecessors::getSplitString(jbp)
- * )
- */
-
- }
-
- cached
- predicate immediatelyControls(ConditionBlock cb, BasicBlock succ, BooleanSuccessor s) {
- succ = cb.getASuccessor(s) and
- forall(BasicBlock pred | pred = succ.getAPredecessor() and pred != cb | succ.dominates(pred))
- }
-
- cached
- predicate controls(ConditionBlock cb, BasicBlock controlled, BooleanSuccessor s) {
- exists(BasicBlock succ | cb.immediatelyControls(succ, s) | succ.dominates(controlled))
- }
-}
-
-private import Cached
-
-/** Holds if `bb` is an entry basic block. */
-private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof EntryNode }
-
-/**
- * An entry basic block, that is, a basic block whose first node is
- * an entry node.
- */
-class EntryBasicBlock extends BasicBlock {
- EntryBasicBlock() { entryBB(this) }
-}
-
-/**
- * An annotated exit basic block, that is, a basic block whose last node is
- * an annotated exit node.
- */
-class AnnotatedExitBasicBlock extends BasicBlock {
- private boolean normal;
-
- AnnotatedExitBasicBlock() {
- exists(AnnotatedExitNode n |
- n = this.getANode() and
- if n.isNormal() then normal = true else normal = false
- )
- }
-
- /** Holds if this block represent a normal exit. */
- final predicate isNormal() { normal = true }
-}
-
-/**
- * An exit basic block, that is, a basic block whose last node is
- * an exit node.
- */
-class ExitBasicBlock extends BasicBlock {
- ExitBasicBlock() { this.getLastNode() instanceof ExitNode }
-}
-
-/*
- * private module JoinBlockPredecessors {
- * private predicate id(AstNode x, AstNode y) { x = y }
- *
- * private predicate idOf(AstNode x, int y) = equivalenceRelation(id/2)(x, y)
- *
- * int getId(JoinBlockPredecessor jbp) {
- * idOf(Ast::toTreeSitter(jbp.getFirstNode().(AstCfgNode).getAstNode()), result)
- * or
- * idOf(Ast::toTreeSitter(jbp.(EntryBasicBlock).getScope()), result)
- * }
- *
- * string getSplitString(JoinBlockPredecessor jbp) {
- * result = jbp.getFirstNode().(AstCfgNode).getSplitsString()
- * or
- * not exists(jbp.getFirstNode().(AstCfgNode).getSplitsString()) and
- * result = ""
- * }
- * }
- */
-
-/** A basic block with more than one predecessor. */
-class JoinBlock extends BasicBlock {
- JoinBlock() { this.getFirstNode().isJoin() }
-
- /**
- * Gets the `i`th predecessor of this join block, with respect to some
- * arbitrary order.
- */
- JoinBlockPredecessor getJoinBlockPredecessor(int i) { result = getJoinBlockPredecessor(this, i) }
-}
-
-/** A basic block that is an immediate predecessor of a join block. */
-class JoinBlockPredecessor extends BasicBlock {
- JoinBlockPredecessor() { this.getASuccessor() instanceof JoinBlock }
-}
-
-/** A basic block that terminates in a condition, splitting the subsequent control flow. */
-class ConditionBlock extends BasicBlock {
- ConditionBlock() { this.getLastNode().isCondition() }
-
- /**
- * Holds if basic block `succ` is immediately controlled by this basic
- * block with conditional value `s`. That is, `succ` is an immediate
- * successor of this block, and `succ` can only be reached from
- * the callable entry point by going via the `s` edge out of this basic block.
- */
- predicate immediatelyControls(BasicBlock succ, BooleanSuccessor s) {
- immediatelyControls(this, succ, s)
- }
-
- /**
- * Holds if basic block `controlled` is controlled by this basic block with
- * conditional value `s`. That is, `controlled` can only be reached from
- * the callable entry point by going via the `s` edge out of this basic block.
- */
- predicate controls(BasicBlock controlled, BooleanSuccessor s) { controls(this, controlled, s) }
-}
diff --git a/actions/ql/lib/codeql/actions/controlflow/internal/Cfg.qll b/actions/ql/lib/codeql/actions/controlflow/internal/Cfg.qll
index 38ce9e7e03db..f01fdbd0e4a1 100644
--- a/actions/ql/lib/codeql/actions/controlflow/internal/Cfg.qll
+++ b/actions/ql/lib/codeql/actions/controlflow/internal/Cfg.qll
@@ -1,288 +1,418 @@
private import codeql.actions.Ast
-private import codeql.controlflow.Cfg as CfgShared
+private import codeql.controlflow.ControlFlowGraph as CfgShared
private import codeql.Locations
+private import codeql.util.Void
-module Completion {
- import codeql.controlflow.SuccessorType
+private class ActionsAstNode = AstNode;
- private newtype TCompletion =
- TSimpleCompletion() or
- TBooleanCompletion(boolean b) { b in [false, true] } or
- TReturnCompletion()
+module CfgImpl {
+ private predicate isDeclaredEnvExpr(AstNode parent, AstNode child) {
+ exists(Workflow workflow | parent = workflow and child = workflow.getEnv().getAnEnvVarExpr())
+ or
+ exists(Job job | parent = job and child = job.getEnv().getAnEnvVarExpr())
+ or
+ exists(Step step | parent = step and child = step.getEnv().getAnEnvVarExpr())
+ }
- abstract class Completion extends TCompletion {
- abstract string toString();
+ private predicate isCfgChild(AstNode parent, AstNode child) {
+ isDeclaredEnvExpr(parent, child)
+ or
+ exists(CompositeAction action |
+ parent = action and
+ (child = action.getAnInput() or child = action.getOutputs() or child = action.getRuns())
+ )
+ or
+ exists(ReusableWorkflow workflow |
+ parent = workflow and
+ (
+ child = workflow.getAnInput() or
+ child = workflow.getOutputs() or
+ child = workflow.getStrategy() or
+ child = workflow.getAJob()
+ )
+ )
+ or
+ exists(Workflow workflow |
+ parent = workflow and
+ not workflow instanceof ReusableWorkflow and
+ (child = workflow.getStrategy() or child = workflow.getAJob())
+ )
+ or
+ exists(Runs runs | parent = runs and child = runs.getStep(_))
+ or
+ exists(Outputs outputs | parent = outputs and child = outputs.getAnOutputExpr())
+ or
+ exists(Strategy strategy | parent = strategy and child = strategy.getAMatrixVarExpr())
+ or
+ exists(LocalJob job |
+ parent = job and
+ (child = job.getAStep() or child = job.getOutputs() or child = job.getStrategy())
+ )
+ or
+ exists(ExternalJob job |
+ parent = job and
+ (
+ child = job.getArgumentExpr(_) or
+ child = job.getOutputs() or
+ child = job.getStrategy()
+ )
+ )
+ or
+ exists(UsesStep uses | parent = uses and child = uses.getArgumentExpr(_))
+ or
+ exists(Run run |
+ parent = run and
+ (child = run.getAnScriptExpr() or child = run.getScript())
+ )
+ }
- predicate isValidForSpecific(AstNode e) { none() }
+ private AstNode getCfgChild(AstNode parent, int index) {
+ result =
+ rank[index](AstNode child, Location l |
+ isCfgChild(parent, child) and l = child.getLocation()
+ |
+ child
+ order by
+ l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
+ )
+ }
- predicate isValidFor(AstNode e) { this.isValidForSpecific(e) }
+ private module CfgAst implements CfgShared::AstSig {
+ class AstNode = ActionsAstNode;
+
+ AstNode getChild(AstNode node, int index) { result = getCfgChild(node, index) }
+
+ class Callable extends AstNode {
+ Callable() {
+ this instanceof CompositeAction
+ or
+ this instanceof Workflow and
+ not exists(CompositeAction action | action.getLocation() = this.getLocation())
+ }
+ }
+
+ AstNode callableGetBody(Callable callable) { result = callable }
+
+ /**
+ * Gets the unique callable containing `node`.
+ *
+ * An Actions AST node may have multiple parent paths, but they converge on
+ * the same root.
+ */
+ Callable getEnclosingCallable(AstNode node) {
+ result = node
+ or
+ not node instanceof Callable and
+ result = getEnclosingCallable(node.getParentNode())
+ }
- abstract SuccessorType getAMatchingSuccessorType();
- }
+ class Parameter extends AstNode {
+ Parameter() { none() }
- abstract class NormalCompletion extends Completion { }
+ AstNode getPattern() { none() }
- class SimpleCompletion extends NormalCompletion, TSimpleCompletion {
- override string toString() { result = "SimpleCompletion" }
+ Expr getDefaultValue() { none() }
+ }
- override predicate isValidFor(AstNode e) { not any(Completion c).isValidForSpecific(e) }
+ Parameter callableGetParameter(Callable callable, int index) { none() }
- override DirectSuccessor getAMatchingSuccessorType() { any() }
- }
+ class Stmt extends AstNode {
+ Stmt() { none() }
+ }
- class BooleanCompletion extends NormalCompletion, TBooleanCompletion {
- boolean value;
+ class LabeledStmt extends Stmt {
+ LabeledStmt() { none() }
- BooleanCompletion() { this = TBooleanCompletion(value) }
+ Stmt getStmt() { none() }
+ }
- override string toString() { result = "BooleanCompletion(" + value + ")" }
+ class Expr extends AstNode {
+ Expr() { none() }
+ }
- override predicate isValidForSpecific(AstNode e) { none() }
+ class BlockStmt extends Stmt {
+ BlockStmt() { none() }
- override BooleanSuccessor getAMatchingSuccessorType() { result.getValue() = value }
+ Stmt getStmt(int index) { none() }
- final boolean getValue() { result = value }
- }
+ Stmt getLastStmt() { none() }
+ }
- class ReturnCompletion extends Completion, TReturnCompletion {
- override string toString() { result = "ReturnCompletion" }
+ class ExprStmt extends Stmt {
+ ExprStmt() { none() }
- override predicate isValidForSpecific(AstNode e) { none() }
+ Expr getExpr() { none() }
+ }
- override ReturnSuccessor getAMatchingSuccessorType() { any() }
- }
-}
+ class IfStmt extends Stmt {
+ IfStmt() { none() }
-module CfgScope {
- abstract class CfgScope extends AstNode { }
+ Expr getCondition() { none() }
- class WorkflowScope extends CfgScope instanceof Workflow { }
+ Stmt getThen() { none() }
- class CompositeActionScope extends CfgScope instanceof CompositeAction { }
-}
+ Stmt getElse() { none() }
+ }
-private module Implementation implements CfgShared::InputSig {
- import codeql.actions.Ast
- import Completion
- import CfgScope
+ class LoopStmt extends Stmt {
+ LoopStmt() { none() }
- predicate completionIsNormal(Completion c) { not c instanceof ReturnCompletion }
+ Stmt getBody() { none() }
+ }
- // Not using CFG splitting, so the following are just dummy types.
- private newtype TUnit = Unit()
+ class WhileStmt extends LoopStmt {
+ WhileStmt() { none() }
- additional class SplitKindBase = TUnit;
+ Expr getCondition() { none() }
+ }
- additional class Split extends TUnit {
- abstract string toString();
- }
+ class DoStmt extends LoopStmt {
+ DoStmt() { none() }
- predicate completionIsSimple(Completion c) { c instanceof SimpleCompletion }
+ Expr getCondition() { none() }
+ }
- predicate completionIsValidFor(Completion c, AstNode e) { c.isValidFor(e) }
+ class UntilStmt extends LoopStmt {
+ UntilStmt() { none() }
- CfgScope getCfgScope(AstNode e) {
- exists(AstNode p | p = e.getParentNode() |
- result = p
- or
- not p instanceof CfgScope and result = getCfgScope(p)
- )
- }
+ Expr getCondition() { none() }
+ }
- additional int maxSplits() { result = 0 }
+ class ForStmt extends LoopStmt {
+ ForStmt() { none() }
- predicate scopeFirst(CfgScope scope, AstNode e) {
- first(scope.(Workflow), e) or
- first(scope.(CompositeAction), e)
- }
+ AstNode getInit(int index) { none() }
- predicate scopeLast(CfgScope scope, AstNode e, Completion c) {
- last(scope.(Workflow), e, c) or
- last(scope.(CompositeAction), e, c)
- }
+ Expr getCondition() { none() }
- SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
+ AstNode getUpdate(int index) { none() }
+ }
- int idOfAstNode(AstNode node) { none() }
+ class ForEachStmt extends LoopStmt {
+ ForEachStmt() { none() }
- int idOfCfgScope(CfgScope scope) { none() }
-}
+ Expr getVariable() { none() }
-module CfgImpl = CfgShared::Make;
+ Expr getCollection() { none() }
+ }
-private import CfgImpl
-private import Completion
-private import CfgScope
+ class BreakStmt extends Stmt {
+ BreakStmt() { none() }
+ }
-private class CompositeActionTree extends StandardPreOrderTree instanceof CompositeAction {
- override ControlFlowTree getChildNode(int i) {
- result =
- rank[i](AstNode child, Location l |
- (
- child = this.(CompositeAction).getAnInput() or
- child = this.(CompositeAction).getOutputs() or
- child = this.(CompositeAction).getRuns()
- ) and
- l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
- }
-}
+ class ContinueStmt extends Stmt {
+ ContinueStmt() { none() }
+ }
-private class RunsTree extends StandardPreOrderTree instanceof Runs {
- override ControlFlowTree getChildNode(int i) { result = super.getStep(i) }
-}
+ class GotoStmt extends Stmt {
+ GotoStmt() { none() }
+ }
-private class WorkflowTree extends StandardPreOrderTree instanceof Workflow {
- override ControlFlowTree getChildNode(int i) {
- if this instanceof ReusableWorkflow
- then
- result =
- rank[i](AstNode child, Location l |
- (
- child = this.(ReusableWorkflow).getAnInput() or
- child = this.(ReusableWorkflow).getOutputs() or
- child = this.(ReusableWorkflow).getStrategy() or
- child = this.(ReusableWorkflow).getAJob()
- ) and
- l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
- else
- result =
- rank[i](AstNode child, Location l |
- (
- child = super.getStrategy() or
- child = super.getAJob()
- ) and
- l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
- }
-}
+ class ReturnStmt extends Stmt {
+ ReturnStmt() { none() }
-private class OutputsTree extends StandardPreOrderTree instanceof Outputs {
- override ControlFlowTree getChildNode(int i) {
- result =
- rank[i](AstNode child, Location l |
- child = super.getAnOutputExpr() and l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
- }
-}
+ Expr getExpr() { none() }
+ }
-private class StrategyTree extends StandardPreOrderTree instanceof Strategy {
- override ControlFlowTree getChildNode(int i) {
- result =
- rank[i](AstNode child, Location l |
- child = super.getAMatrixVarExpr() and l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
- }
-}
+ class Throw extends AstNode {
+ Throw() { none() }
-private class JobTree extends StandardPreOrderTree instanceof LocalJob {
- override ControlFlowTree getChildNode(int i) {
- result =
- rank[i](AstNode child, Location l |
- (
- child = super.getAStep() or
- child = super.getOutputs() or
- child = super.getStrategy()
- ) and
- l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
- }
-}
+ Expr getExpr() { none() }
+ }
-private class ExternalJobTree extends StandardPreOrderTree instanceof ExternalJob {
- override ControlFlowTree getChildNode(int i) {
- result =
- rank[i](AstNode child, Location l |
- (
- child = super.getArgumentExpr(_) or
- child = super.getInScopeEnvVarExpr(_) or
- child = super.getOutputs() or
- child = super.getStrategy()
- ) and
- l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
- }
-}
+ class TryStmt extends Stmt {
+ TryStmt() { none() }
-private class UsesTree extends StandardPreOrderTree instanceof UsesStep {
- override ControlFlowTree getChildNode(int i) {
- result =
- rank[i](AstNode child, Location l |
- (child = super.getArgumentExpr(_) or child = super.getInScopeEnvVarExpr(_)) and
- l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
+ AstNode getBody(int index) { none() }
+
+ CatchClause getCatch(int index) { none() }
+
+ Stmt getFinally() { none() }
+ }
+
+ class CatchClause extends AstNode {
+ CatchClause() { none() }
+
+ AstNode getPattern() { none() }
+
+ AstNode getVariable() { none() }
+
+ Expr getCondition() { none() }
+
+ Stmt getBody() { none() }
+ }
+
+ class Switch extends AstNode {
+ Switch() { none() }
+
+ Expr getExpr() { none() }
+
+ Case getCase(int index) { none() }
+
+ Stmt getStmt(int index) { none() }
+ }
+
+ class Case extends AstNode {
+ Case() { none() }
+
+ AstNode getPattern(int index) { none() }
+
+ Expr getGuard() { none() }
+
+ AstNode getBody() { none() }
+ }
+
+ class DefaultCase extends Case {
+ DefaultCase() { none() }
+ }
+
+ class ConditionalExpr extends Expr {
+ ConditionalExpr() { none() }
+
+ Expr getCondition() { none() }
+
+ Expr getThen() { none() }
+
+ Expr getElse() { none() }
+ }
+
+ class BinaryExpr extends Expr {
+ BinaryExpr() { none() }
+
+ Expr getLeftOperand() { none() }
+
+ Expr getRightOperand() { none() }
+ }
+
+ class LogicalAndExpr extends BinaryExpr {
+ LogicalAndExpr() { none() }
+ }
+
+ class LogicalOrExpr extends BinaryExpr {
+ LogicalOrExpr() { none() }
+ }
+
+ class NullCoalescingExpr extends BinaryExpr {
+ NullCoalescingExpr() { none() }
+ }
+
+ class UnaryExpr extends Expr {
+ UnaryExpr() { none() }
+
+ Expr getOperand() { none() }
+ }
+
+ class LogicalNotExpr extends UnaryExpr {
+ LogicalNotExpr() { none() }
+ }
+
+ class Assignment extends BinaryExpr {
+ Assignment() { none() }
+ }
+
+ class AssignExpr extends Assignment {
+ AssignExpr() { none() }
+ }
+
+ class CompoundAssignment extends Assignment {
+ CompoundAssignment() { none() }
+ }
+
+ class AssignLogicalAndExpr extends CompoundAssignment {
+ AssignLogicalAndExpr() { none() }
+ }
+
+ class AssignLogicalOrExpr extends CompoundAssignment {
+ AssignLogicalOrExpr() { none() }
+ }
+
+ class AssignNullCoalescingExpr extends CompoundAssignment {
+ AssignNullCoalescingExpr() { none() }
+ }
+
+ class BooleanLiteral extends Expr {
+ BooleanLiteral() { none() }
+
+ boolean getValue() { none() }
+ }
+
+ class PatternMatchExpr extends Expr {
+ PatternMatchExpr() { none() }
+
+ Expr getExpr() { none() }
+
+ AstNode getPattern() { none() }
+ }
}
-}
-private class RunTree extends StandardPreOrderTree instanceof Run {
- override ControlFlowTree getChildNode(int i) {
- result =
- rank[i](AstNode child, Location l |
- (
- child = super.getInScopeEnvVarExpr(_) or
- child = super.getAnScriptExpr() or
- child = super.getScript()
- ) and
- l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
+ private module Cfg0 = CfgShared::Make0;
+
+ private module Input1 implements Cfg0::InputSig1 {
+ predicate cfgCachedStageRef() { CfgCachedStage::ref() }
+
+ class Label = Void;
+
+ class CallableContext = Void;
}
-}
-private class ScalarValueTree extends StandardPreOrderTree instanceof ScalarValue {
- override ControlFlowTree getChildNode(int i) {
- result =
- rank[i](Expression child, Location l |
- child = super.getAChildNode() and
- l = child.getLocation()
- |
- child
- order by
- l.getStartLine(), l.getStartColumn(), l.getEndColumn(), l.getEndLine(), child.toString()
- )
+ private module Cfg1 = Cfg0::Make1;
+
+ private module Input2 implements Cfg1::InputSig2 {
+ predicate beginAbruptCompletion(
+ AstNode ast, PreControlFlowNode node, AbruptCompletion completion, boolean always
+ ) {
+ none()
+ }
+
+ predicate endAbruptCompletion(AstNode ast, PreControlFlowNode node, AbruptCompletion completion) {
+ none()
+ }
+
+ predicate step(PreControlFlowNode predecessor, PreControlFlowNode successor) { none() }
}
-}
-private class UsesLeaf extends LeafTree instanceof Uses { }
+ private module Cfg2 = Cfg1::Make2;
+
+ private import Cfg0
+ private import Cfg1
+ private import Cfg2
+ import Public
+ import ControlFlow
-private class InputTree extends LeafTree instanceof Input { }
+ class CfgScope = CfgAst::Callable;
-private class ScalarValueLeaf extends LeafTree instanceof ScalarValue { }
+ /** A CFG scope for a workflow. */
+ class WorkflowScope extends CfgScope instanceof Workflow { }
+
+ /** A CFG scope for a composite action. */
+ class CompositeActionScope extends CfgScope instanceof CompositeAction { }
-private class ExpressionLeaf extends LeafTree instanceof Expression { }
+ /** A control flow node. */
+ class Node = ControlFlowNode;
+
+ /** The control flow node at the entry point of a scope. */
+ class EntryNode = ControlFlow::EntryNode;
+
+ /** A control flow node indicating normal or exceptional termination of a scope. */
+ class AnnotatedExitNode = ControlFlow::AnnotatedExitNode;
+
+ /** A control flow node indicating normal termination of a scope. */
+ class NormalExitNode = ControlFlow::NormalExitNode;
+
+ /** A control flow node indicating exceptional termination of a scope. */
+ class ExceptionalExitNode = ControlFlow::ExceptionalExitNode;
+
+ /** A control flow node indicating the termination of a scope. */
+ class ExitNode = ControlFlow::ExitNode;
+
+ /**
+ * A node that uniquely represents an AST node.
+ *
+ * Unreachable AST nodes do not have an `AstCfgNode`.
+ */
+ class AstCfgNode extends Node {
+ AstCfgNode() { this.injects(_) }
+
+ AstNode getAstNode() { this.injects(result) }
+ }
+}
diff --git a/actions/ql/lib/codeql/actions/dataflow/FlowSources.qll b/actions/ql/lib/codeql/actions/dataflow/FlowSources.qll
index 18cc4322c81b..8b0a2a33eb55 100644
--- a/actions/ql/lib/codeql/actions/dataflow/FlowSources.qll
+++ b/actions/ql/lib/codeql/actions/dataflow/FlowSources.qll
@@ -52,29 +52,43 @@ class GitHubCtxSource extends RemoteFlowSource {
override string getEventName() { result = event }
}
+bindingset[expression]
+pragma[inline_late]
+private predicate untrustedEventProperty(Expression expression, string kind) {
+ exists(string regexp |
+ untrustedEventPropertiesDataModel(regexp, kind) and
+ kind != "json" and
+ normalizeExpr(expression.getExpression()).regexpMatch("(?i)\\s*" + wrapRegexp(regexp) + ".*")
+ )
+}
+
+bindingset[expression, event]
+pragma[inline_late]
+private predicate expressionContainsEventContext(Expression expression, string event) {
+ exists(string contextPrefix |
+ contextTriggerDataModel(event, contextPrefix) and
+ normalizeExpr(expression.getExpression()).matches("%" + contextPrefix + "%")
+ )
+}
+
class GitHubEventCtxSource extends RemoteFlowSource {
string flag;
string context;
string event;
GitHubEventCtxSource() {
- exists(Expression e, string regexp |
+ exists(Expression e |
this.asExpr() = e and
context = e.getExpression() and
(
// the context is available for the job trigger events
event = e.getATriggerEvent().getName() and
- exists(string context_prefix |
- contextTriggerDataModel(event, context_prefix) and
- normalizeExpr(context).matches("%" + context_prefix + "%")
- )
+ expressionContainsEventContext(e, event)
or
not exists(e.getATriggerEvent()) and
event = "unknown"
) and
- untrustedEventPropertiesDataModel(regexp, flag) and
- not flag = "json" and
- normalizeExpr(context).regexpMatch("(?i)\\s*" + wrapRegexp(regexp) + ".*")
+ untrustedEventProperty(e, flag)
)
}
@@ -177,32 +191,41 @@ class GitHubEventPathSource extends RemoteFlowSource, CommandSource {
override Run getEnclosingRun() { result = run }
}
+bindingset[expression, event]
+pragma[inline_late]
+private predicate jsonSourceForEvent(Expression expression, string event) {
+ exists(string context, string regexp, string contextPrefix |
+ context = expression.getExpression() and
+ untrustedEventPropertiesDataModel(regexp, _) and
+ contextTriggerDataModel(event, contextPrefix) and
+ normalizeExpr(context).matches("%" + contextPrefix + "%") and
+ normalizeExpr(context).regexpMatch("(?i).*" + wrapJsonRegexp(regexp) + ".*")
+ )
+ or
+ exists(string context |
+ context = expression.getExpression() and
+ untrustedEventPropertiesDataModel(_, _) and
+ contextTriggerDataModel(event, _) and
+ normalizeExpr(context).regexpMatch("(?i).*" + wrapJsonRegexp("\\bgithub.event\\b") + ".*")
+ )
+}
+
class GitHubEventJsonSource extends RemoteFlowSource {
string flag;
string event;
GitHubEventJsonSource() {
- exists(Expression e, string context, string regexp |
+ exists(Expression e |
this.asExpr() = e and
- context = e.getExpression() and
- untrustedEventPropertiesDataModel(regexp, _) and
(
// only contexts for the triggering events are considered tainted.
// eg: for `pull_request`, we only consider `github.event.pull_request`
event = e.getEnclosingWorkflow().getATriggerEvent().getName() and
- exists(string context_prefix |
- contextTriggerDataModel(event, context_prefix) and
- normalizeExpr(context).matches("%" + context_prefix + "%")
- ) and
- normalizeExpr(context).regexpMatch("(?i).*" + wrapJsonRegexp(regexp) + ".*")
- or
- // github.event is tainted for all triggers
- event = e.getEnclosingWorkflow().getATriggerEvent().getName() and
- contextTriggerDataModel(e.getEnclosingWorkflow().getATriggerEvent().getName(), _) and
- normalizeExpr(context).regexpMatch("(?i).*" + wrapJsonRegexp("\\bgithub.event\\b") + ".*")
+ jsonSourceForEvent(e, event)
or
not exists(e.getATriggerEvent()) and
- event = "unknown"
+ event = "unknown" and
+ untrustedEventPropertiesDataModel(_, _)
) and
flag = "json"
)
diff --git a/actions/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll b/actions/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll
index cf95292588c3..1576377e0804 100644
--- a/actions/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll
+++ b/actions/ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll
@@ -3,7 +3,6 @@ private import codeql.dataflow.DataFlow
private import codeql.actions.Ast
private import codeql.actions.Cfg as Cfg
private import codeql.Locations
-private import codeql.actions.controlflow.BasicBlocks
private import DataFlowPublic
private import codeql.actions.dataflow.ExternalFlow
private import codeql.actions.dataflow.FlowSteps
@@ -50,7 +49,7 @@ predicate isArgumentNode(ArgumentNode arg, DataFlowCall call, ArgumentPosition p
}
DataFlowCallable nodeGetEnclosingCallable(Node node) {
- node = TExprNode(any(DataFlowExpr e | result = e.getScope()))
+ node = TExprNode(any(DataFlowExpr e | result = e.getEnclosingCallable()))
}
DataFlowType getNodeType(Node node) { any() }
@@ -59,13 +58,16 @@ predicate nodeIsHidden(Node node) { none() }
class DataFlowExpr extends Cfg::Node {
DataFlowExpr() {
- this.getAstNode() instanceof Job or
- this.getAstNode() instanceof Expression or
- this.getAstNode() instanceof Uses or
- this.getAstNode() instanceof Run or
- this.getAstNode() instanceof Outputs or
- this.getAstNode() instanceof Input or
- this.getAstNode() instanceof ScalarValue
+ this.injects(this.getAstNode()) and
+ (
+ this.getAstNode() instanceof Job or
+ this.getAstNode() instanceof Expression or
+ this.getAstNode() instanceof Uses or
+ this.getAstNode() instanceof Run or
+ this.getAstNode() instanceof Outputs or
+ this.getAstNode() instanceof Input or
+ this.getAstNode() instanceof ScalarValue
+ )
}
}
@@ -73,14 +75,17 @@ class DataFlowExpr extends Cfg::Node {
* A call corresponds to a Uses steps where a composite action or a reusable workflow get called
*/
class DataFlowCall instanceof Cfg::Node {
- DataFlowCall() { super.getAstNode() instanceof Uses }
+ DataFlowCall() {
+ this.injects(this.getAstNode()) and
+ super.getAstNode() instanceof Uses
+ }
/** Gets a textual representation of this element. */
string toString() { result = super.toString() }
string getName() { result = super.getAstNode().(Uses).getCallee() }
- DataFlowCallable getEnclosingCallable() { result = super.getScope() }
+ DataFlowCallable getEnclosingCallable() { result = super.getEnclosingCallable() }
/** Gets a best-effort total ordering. */
int totalorder() { none() }
diff --git a/actions/ql/lib/codeql/actions/security/CachePoisoningQuery.qll b/actions/ql/lib/codeql/actions/security/CachePoisoningQuery.qll
index e5c5a3655101..41529c489ff0 100644
--- a/actions/ql/lib/codeql/actions/security/CachePoisoningQuery.qll
+++ b/actions/ql/lib/codeql/actions/security/CachePoisoningQuery.qll
@@ -5,8 +5,8 @@ string defaultBranchTriggerEvent() {
[
"check_run", "check_suite", "delete", "discussion", "discussion_comment", "fork", "gollum",
"issue_comment", "issues", "label", "milestone", "project", "project_card", "project_column",
- "public", "pull_request_comment", "pull_request_target", "repository_dispatch", "schedule",
- "watch", "workflow_run"
+ "public", "pull_request_comment", "pull_request_target", "repository_dispatch",
+ "registry_package", "page_build", "schedule", "watch", "workflow_dispatch", "workflow_run"
]
}
@@ -42,6 +42,27 @@ predicate runsOnDefaultBranch(Event e) {
)
}
+private string defaultBranchCacheWriteEvent() {
+ result =
+ [
+ "push", "workflow_dispatch", "repository_dispatch", "delete", "registry_package",
+ "page_build", "schedule"
+ ]
+}
+
+private predicate eventHasDefaultBranchCacheWriteAccess(Event event) {
+ runsOnDefaultBranch(event) and event.getName() = defaultBranchCacheWriteEvent()
+}
+
+/**
+ * Holds if `job` can write to the cache scope of the default branch for `event`.
+ * Reusable workflow jobs inherit their caller's trigger event.
+ */
+predicate hasDefaultBranchCacheWriteAccess(LocalJob job, Event event) {
+ job.getATriggerEvent() = event and
+ eventHasDefaultBranchCacheWriteAccess(event)
+}
+
abstract class CacheWritingStep extends Step {
abstract string getPath();
}
diff --git a/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll b/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll
index 3d5b8852b850..2afa68244091 100644
--- a/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll
+++ b/actions/ql/lib/codeql/actions/security/CodeInjectionQuery.qll
@@ -29,22 +29,10 @@ Event getRelevantCachePoisoningEventForSink(DataFlow::Node sink) {
exists(LocalJob job |
job = sink.asExpr().getEnclosingJob() and
job.getATriggerEvent() = result and
- // job can be triggered by an external user
- result.isExternallyTriggerable() and
// excluding privileged workflows since they can be exploited in easier circumstances
// which is covered by `actions/code-injection/critical`
not job.isPrivilegedExternallyTriggerable(result) and
- (
- // the workflow runs in the context of the default branch
- runsOnDefaultBranch(result)
- or
- // the workflow caller runs in the context of the default branch
- result.getName() = "workflow_call" and
- exists(ExternalJob caller |
- caller.getCallee() = job.getLocation().getFile().getRelativePath() and
- runsOnDefaultBranch(caller.getATriggerEvent())
- )
- )
+ hasDefaultBranchCacheWriteAccess(job, result)
)
}
diff --git a/actions/ql/lib/codeql/actions/security/ControlChecks.qll b/actions/ql/lib/codeql/actions/security/ControlChecks.qll
index 3f76010bd5a3..733c92559d70 100644
--- a/actions/ql/lib/codeql/actions/security/ControlChecks.qll
+++ b/actions/ql/lib/codeql/actions/security/ControlChecks.qll
@@ -276,7 +276,24 @@ abstract class LabelCheck extends ControlCheck {
}
}
+/**
+ * A deployment environment that may serve as a sanitizer for
+ * various vulnerabilities.
+ *
+ * It is possible to customize which deployment environments apply. The default behavior
+ * of this model is for any environment to be considered a sanitizer.
+ * If values are provided then those names
+ * will be used to define the valid sanitizer set.
+ * To describe the situation where there is no acceptable sanitizer environment
+ * populate the predicate `enabledDeploymentEnvironmentDataModel` to contain a single empty string.
+ */
class EnvironmentCheck extends ControlCheck instanceof Environment {
+ EnvironmentCheck() {
+ if enabledDeploymentEnvironmentDataModel(_)
+ then enabledDeploymentEnvironmentDataModel(this.(Environment).getName())
+ else this instanceof Environment
+ }
+
// Environment checks are not effective against any mutable attacks
// they do actually protect against untrusted code execution (sha)
override predicate protectsCategoryAndEvent(string category, string event) {
@@ -307,17 +324,6 @@ class LabelIfCheck extends LabelCheck instanceof If {
class ActorIfCheck extends ActorCheck instanceof If {
ActorIfCheck() {
- // eg: github.event.pull_request.user.login == 'admin'
- exists(
- normalizeExpr(this.getCondition())
- .regexpFind([
- "\\bgithub\\.event\\.pull_request\\.user\\.login\\b",
- "\\bgithub\\.event\\.head_commit\\.author\\.name\\b",
- "\\bgithub\\.event\\.commits.*\\.author\\.name\\b",
- "\\bgithub\\.event\\.sender\\.login\\b"
- ], _, _)
- )
- or
// eg: github.actor == 'admin'
// eg: github.triggering_actor == 'admin'
exists(
@@ -328,6 +334,51 @@ class ActorIfCheck extends ActorCheck instanceof If {
}
}
+/**
+ * Gets a regular expression matching a condition on an actor field that is
+ * only populated for events whose payload contains the `context_prefix` context.
+ */
+private string eventPayloadActorFieldRegex(string context_prefix) {
+ context_prefix = "github.event.pull_request" and
+ result = "\\bgithub\\.event\\.pull_request\\.user\\.login\\b"
+ or
+ context_prefix = "github.event.head_commit" and
+ result = "\\bgithub\\.event\\.head_commit\\.author\\.name\\b"
+ or
+ context_prefix = "github.event.commits" and
+ result = "\\bgithub\\.event\\.commits.*\\.author\\.name\\b"
+ or
+ context_prefix = "github.event.sender" and
+ result = "\\bgithub\\.event\\.sender\\.login\\b"
+}
+
+/** An If node that checks an actor field from the event payload */
+class EventActorIfCheck extends ActorCheck instanceof If {
+ string context_prefix;
+
+ EventActorIfCheck() {
+ // eg: github.event.pull_request.user.login == 'admin'
+ exists(
+ normalizeExpr(this.getCondition())
+ .regexpFind(eventPayloadActorFieldRegex(context_prefix), _, _)
+ )
+ }
+
+ override predicate protectsCategoryAndEvent(string category, string event) {
+ ActorCheck.super.protectsCategoryAndEvent(category, event) and
+ (
+ // the `sender` object is part of every webhook event payload
+ context_prefix = "github.event.sender"
+ or
+ // other actor fields only restrict events whose payload populates them.
+ // eg: `github.event.pull_request.user.login` cannot restrict the actor
+ // of an `issues` event since `github.event.pull_request` is not
+ // populated there, which makes the condition vacuous
+ contextTriggerDataModel(event, context_prefix)
+ )
+ }
+}
+
class PullRequestTargetRepositoryIfCheck extends RepositoryCheck instanceof If {
PullRequestTargetRepositoryIfCheck() {
// eg: github.event.pull_request.head.repo.full_name == github.repository
@@ -367,16 +418,37 @@ class WorkflowRunRepositoryIfCheck extends RepositoryCheck instanceof If {
}
}
+/**
+ * Gets a regular expression matching a condition on an author association field
+ * that is only populated for events whose payload contains the `context_prefix`
+ * context.
+ */
+private string eventPayloadAssociationFieldRegex(string context_prefix) {
+ context_prefix = "github.event.comment" and
+ result = "\\bgithub\\.event\\.comment\\.author_association\\b"
+ or
+ context_prefix = "github.event.issue" and
+ result = "\\bgithub\\.event\\.issue\\.author_association\\b"
+ or
+ context_prefix = "github.event.pull_request" and
+ result = "\\bgithub\\.event\\.pull_request\\.author_association\\b"
+}
+
class AssociationIfCheck extends AssociationCheck instanceof If {
+ string context_prefix;
+
AssociationIfCheck() {
// eg: contains(fromJson('["MEMBER", "OWNER"]'), github.event.comment.author_association)
- normalizeExpr(this.getCondition())
- .splitAt("\n")
- .regexpMatch([
- ".*\\bgithub\\.event\\.comment\\.author_association\\b.*",
- ".*\\bgithub\\.event\\.issue\\.author_association\\b.*",
- ".*\\bgithub\\.event\\.pull_request\\.author_association\\b.*",
- ])
+ exists(
+ normalizeExpr(this.getCondition())
+ .regexpFind(eventPayloadAssociationFieldRegex(context_prefix), _, _)
+ )
+ }
+
+ override predicate protectsCategoryAndEvent(string category, string event) {
+ AssociationCheck.super.protectsCategoryAndEvent(category, event) and
+ // association fields only restrict events whose payload populates them
+ contextTriggerDataModel(event, context_prefix)
}
}
diff --git a/actions/ql/lib/codeql/actions/security/SelfHostedQuery.qll b/actions/ql/lib/codeql/actions/security/SelfHostedQuery.qll
deleted file mode 100644
index b3f7bdaf24d3..000000000000
--- a/actions/ql/lib/codeql/actions/security/SelfHostedQuery.qll
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * DEPRECATED: Runner labels do not reliably distinguish self-hosted runners from managed runners.
- */
-deprecated module;
-
-import actions
-
-bindingset[runner]
-predicate isGithubHostedRunner(string runner) {
- // The list of github hosted repos:
- // https://github.com/actions/runner-images/blob/main/README.md#available-images
- // https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/write-workflows/choose-where-workflows-run/choose-the-runner-for-a-job#standard-github-hosted-runners-for-public-repositories
- runner.toLowerCase().regexpMatch("^ubuntu-([0-9.]+|latest|slim)(-arm)?$") or
- runner.toLowerCase().regexpMatch("^macos-([0-9]+|latest)(-x?large|-intel)?$") or
- runner.toLowerCase().regexpMatch("^windows-([0-9.]+|latest)(-vs[0-9.]+)?(-arm)?$")
-}
-
-bindingset[runner]
-predicate is3rdPartyHostedRunner(string runner) {
- runner.toLowerCase().regexpMatch("^(buildjet|warp)-[a-z0-9-]+$")
-}
-
-/**
- * This predicate uses data available in the workflow file to identify self-hosted runners.
- * It does not know if the repository is public or private.
- * It is a best-effort approach to identify self-hosted runners.
- */
-predicate staticallyIdentifiedSelfHostedRunner(Job job) {
- exists(string label |
- job.getATriggerEvent().getName() =
- [
- "issue_comment", "pull_request", "pull_request_review", "pull_request_review_comment",
- "pull_request_target", "workflow_run"
- ] and
- label = job.getARunsOnLabel() and
- not isGithubHostedRunner(label) and
- not is3rdPartyHostedRunner(label)
- )
-}
-
-/**
- * This predicate uses data available in the job log files to identify self-hosted runners.
- * It is a best-effort approach to identify self-hosted runners.
- */
-predicate dynamicallyIdentifiedSelfHostedRunner(Job job) {
- exists(string runner_info |
- repositoryDataModel("public", _) and
- workflowDataModel(job.getEnclosingWorkflow().getLocation().getFile().getRelativePath(), _,
- job.getId(), _, _, runner_info) and
- runner_info.indexOf("self-hosted:true") > 0
- )
-}
diff --git a/actions/ql/lib/codeql/actions/test/InlineExpectationsTestQuery.ql b/actions/ql/lib/codeql/actions/test/InlineExpectationsTestQuery.ql
new file mode 100644
index 000000000000..deb797b553e6
--- /dev/null
+++ b/actions/ql/lib/codeql/actions/test/InlineExpectationsTestQuery.ql
@@ -0,0 +1,9 @@
+/**
+ * @kind test-postprocess
+ */
+
+private import actions
+private import codeql.util.test.InlineExpectationsTest as T
+private import codeql.actions.test.internal.InlineExpectationsTestImpl
+import T::TestPostProcessing
+import T::TestPostProcessing::Make
diff --git a/actions/ql/lib/codeql/actions/test/internal/InlineExpectationsTestImpl.qll b/actions/ql/lib/codeql/actions/test/internal/InlineExpectationsTestImpl.qll
new file mode 100644
index 000000000000..f1f275fa136a
--- /dev/null
+++ b/actions/ql/lib/codeql/actions/test/internal/InlineExpectationsTestImpl.qll
@@ -0,0 +1,24 @@
+private import codeql.Locations as L
+private import codeql.actions.ast.internal.Yaml as Yaml
+private import codeql.util.test.InlineExpectationsTest
+
+/** Provides the Actions implementation of inline expectation parsing. */
+module Impl implements InlineExpectationsTestSig {
+ /** A class representing YAML comments that may contain inline expectations. */
+ class ExpectationComment extends Yaml::YamlComment {
+ /** Gets the contents of this comment. */
+ string getContents() { result = this.getText() }
+ }
+
+ class Location = L::Location;
+
+ string getRelativeUrl(Location location) {
+ exists(int startLine, int startColumn, int endLine, int endColumn |
+ location.hasLocationInfo(_, startLine, startColumn, endLine, endColumn)
+ |
+ result =
+ location.getFile().getRelativePath() + ":" + startLine + ":" + startColumn + ":" + endLine +
+ ":" + endColumn
+ )
+ }
+}
diff --git a/actions/ql/lib/ext/config/deployment_environment.yml b/actions/ql/lib/ext/config/deployment_environment.yml
new file mode 100644
index 000000000000..eed2911c2758
--- /dev/null
+++ b/actions/ql/lib/ext/config/deployment_environment.yml
@@ -0,0 +1,5 @@
+extensions:
+ - addsTo:
+ pack: codeql/actions-all
+ extensible: enabledDeploymentEnvironmentDataModel
+ data: []
\ No newline at end of file
diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml
index 5111dd27cc89..3e209144f22c 100644
--- a/actions/ql/lib/qlpack.yml
+++ b/actions/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/actions-all
-version: 0.4.41-dev
+version: 0.7.2-dev
library: true
warnOnImplicitThis: true
dependencies:
diff --git a/actions/ql/src/CHANGELOG.md b/actions/ql/src/CHANGELOG.md
index bc013b962f80..359d69214641 100644
--- a/actions/ql/src/CHANGELOG.md
+++ b/actions/ql/src/CHANGELOG.md
@@ -1,3 +1,51 @@
+## 0.6.39
+
+No user-facing changes.
+
+## 0.6.38
+
+No user-facing changes.
+
+## 0.6.37
+
+No user-facing changes.
+
+## 0.6.36
+
+### Minor Analysis Improvements
+
+* The `actions/unpinned-tag` query no longer reports action references pinned by a structurally valid `.github/workflows/actions.lock` entry for the enclosing workflow.
+* The `actions/unpinned-tag` query no longer reports `$/` self repository references (e.g. `uses: $/path/to/action`), which resolve to the same repository at the running commit and are therefore inherently pinned, just like `./` self workspace (local) references.
+
+## 0.6.35
+
+No user-facing changes.
+
+## 0.6.34
+
+### Minor Analysis Improvements
+
+* The `actions/unpinned-tag` query now detects mutable references to reusable workflows.
+
+## 0.6.33
+
+### Query Metadata Changes
+
+* The name and alert message of the `actions/cache-poisoning/code-injection` query have been reworded for clarity.
+
+### Minor Analysis Improvements
+
+* The `actions/output-clobbering/high` query no longer reports simple `jq` path filters when their output remains JSON-encoded. Raw-output modes, complex filters, and unrecognized options remain reportable.
+* GitHub Actions queries now correctly classify the `schedule` event when determining whether a workflow is externally triggerable.
+* The `actions/envvar-injection/critical` query now requires the untrusted source and privileged context to originate from the same trigger event. The environment variable injection queries also no longer treat pull request head labels as injection-capable because they cannot contain newlines.
+* The `actions/cache-poisoning/code-injection`, `actions/cache-poisoning/direct-cache`, and `actions/cache-poisoning/poisonable-step` queries now account for read-only cache access on low-trust triggers that run in the default branch scope. Results are retained for triggers that GitHub allows to write to that cache scope.
+
+### Bug Fixes
+
+* The `actions/output-clobbering/high` query now provides messages tailored to the affected output channel and includes expanded documentation and recommendations.
+* The `actions/cache-poisoning/poisonable-step` and `actions/untrusted-checkout/critical` queries now start paths at the expressions that control untrusted checkouts and link their alert messages to those expressions.
+* Fixed a performance issue in the `actions/output-clobbering/high` query caused by using unescaped source-code input in a regular expression.
+
## 0.6.32
No user-facing changes.
diff --git a/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.md b/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.md
index f75028a27e61..0ef3199e0fd9 100644
--- a/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.md
+++ b/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.md
@@ -34,48 +34,55 @@ Due to the above design, if something is cached in the context of the default br
## Example
+GitHub gives workflows triggered by low-trust events, such as `issue_comment`,
+`pull_request_target`, and `workflow_run`, read-only access to the default branch cache scope.
+This query therefore reports only workflows whose trigger can write to that scope.
+
### Incorrect Usage
-The following workflow is vulnerable to code injection in a non-privileged job but in the context of the default branch.
+The following workflow interpolates a commit message directly into a script on a push to the
+default branch. A commit message originating from a merged contribution may contain shell syntax,
+which can expose the cache write token and allow the default branch cache to be poisoned.
```yaml
name: Vulnerable Workflow
on:
- issue_comment:
- types: [created]
+ push:
+ branches: [main]
jobs:
- pr-comment:
+ build:
permissions: {}
runs-on: ubuntu-latest
steps:
- run: |
- echo ${{ github.event.comment.body }}
+ echo ${{ github.event.head_commit.message }}
```
### Correct Usage
-The following workflow is not vulnerable to code injections even if it runs in the context of the default branch.
+The following workflow passes the commit message through an environment variable, so the shell
+does not interpret its contents as code.
```yaml
name: Secure Workflow
on:
- issue_comment:
- types: [created]
+ push:
+ branches: [main]
jobs:
- pr-comment:
+ build:
permissions: {}
runs-on: ubuntu-latest
steps:
- env:
- BODY: ${{ github.event.comment.body }}
+ MESSAGE: ${{ github.event.head_commit.message }}
run: |
- echo "$BODY"
+ echo "$MESSAGE"
```
## References
- Adnan Khan's Blog: [The Monsters in Your Build Cache ā GitHub Actions Cache Poisoning](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/).
-- GitHub Docs: [GitHub Actions Caching Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows).
+- GitHub Docs: [Cache access for low-trust workflow triggers](https://docs.github.com/actions/reference/workflows-and-actions/dependency-caching#cache-access-for-low-trust-workflow-triggers).
- Scribe Security Blog: [Cache Poisoning in GitHub Actions](https://scribesecurity.com/blog/github-cache-poisoning/).
diff --git a/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql b/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql
index 8ff02c5ee288..c6d7ea9ccec3 100644
--- a/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql
+++ b/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql
@@ -22,6 +22,7 @@ from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Event
where
CodeInjectionFlow::flowPath(source, sink) and
event = getRelevantCachePoisoningEventForSink(sink.getNode()) and
+ source.getNode().(RemoteFlowSource).getEventName() = event.getName() and
// the checkout is not controlled by an access check
not exists(ControlCheck check |
check.protects(source.getNode().asExpr(), event, "code-injection")
diff --git a/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.md b/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.md
index 849b771a8ff0..a22c41ad3e3a 100644
--- a/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.md
+++ b/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.md
@@ -34,35 +34,39 @@ Due to the above design, if something is cached in the context of the default br
## Example
+GitHub gives workflows triggered by low-trust events, such as `issue_comment`,
+`pull_request_target`, and `workflow_run`, read-only access to the default branch cache scope.
+This query therefore reports only workflows whose trigger can write to that scope.
+
### Incorrect Usage
-The following workflow is caching an attacker-controlled file (`large_file`) in the context of the default branch.
+The following write-capable manually dispatched workflow accepts a revision without validation,
+fetches files from it, and saves those files in the default branch cache. This is unsafe if an
+untrusted integration or automation can influence the dispatch input.
```yaml
name: Vulnerable Workflow
on:
- issue_comment:
- types: [created]
+ workflow_dispatch:
+ inputs:
+ head_sha:
+ required: true
jobs:
- pr-comment:
+ cache:
permissions: read-all
runs-on: ubuntu-latest
steps:
- - uses: xt0rted/pull-request-comment-branch@v2
- id: comment-branch
- - uses: actions/checkout@v3
- with:
- ref: ${{ steps.comment-branch.outputs.head_sha }}
- - name: Set up Python 3.10
- uses: actions/setup-python@v5
- - name: Cache pip dependencies
+ - env:
+ HEAD_SHA: ${{ github.event.inputs.head_sha }}
+ run: |
+ git fetch origin "$HEAD_SHA"
+ git checkout "$HEAD_SHA"
+ - name: Cache fetched files
uses: actions/cache@v4
- id: cache-pip
with:
- path: ~/.cache/pip
- key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
- restore-keys: ${{ runner.os }}-pip-
+ path: .
+ key: dispatched-${{ github.event.inputs.head_sha }}
```
### Correct Usage
@@ -91,36 +95,8 @@ jobs:
restore-keys: ${{ runner.os }}-pip-
```
-Note, that the example above doesn't allow using secrets if the Pull Request originates from a fork. In case secrets are needed, `pull_request_target` with labels as `safe to test` can be used, but the code in Pull Request must be manually reviewed before applying the label.
-
-```yaml
-name: Secure Workflow
-on:
- pull_request_target:
- types: [labeled]
-
-jobs:
- pr-comment:
- if: contains(github.event.pull_request.labels.*.name, 'safe to test')
- permissions: read-all
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- with:
- ref: ${{ github.event.pull_request.head.sha}}
- - name: Set up Python 3.10
- uses: actions/setup-python@v5
- - name: Cache pip dependencies
- uses: actions/cache@v4
- id: cache-pip
- with:
- path: ~/.cache/pip
- key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
- restore-keys: ${{ runner.os }}-pip-
-```
-
## References
- Adnan Khan's Blog: [The Monsters in Your Build Cache ā GitHub Actions Cache Poisoning](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/).
-- GitHub Docs: [GitHub Actions Caching Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows).
+- GitHub Docs: [Cache access for low-trust workflow triggers](https://docs.github.com/actions/reference/workflows-and-actions/dependency-caching#cache-access-for-low-trust-workflow-triggers).
- Scribe Security Blog: [Cache Poisoning in GitHub Actions](https://scribesecurity.com/blog/github-cache-poisoning/).
diff --git a/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql b/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql
index 85a0f53df1dc..b410f92b68a1 100644
--- a/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql
+++ b/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql
@@ -40,17 +40,7 @@ where
job.getATriggerEvent() = event and
// job can be triggered by an external user
event.isExternallyTriggerable() and
- (
- // the workflow runs in the context of the default branch
- runsOnDefaultBranch(event)
- or
- // the workflow's caller runs in the context of the default branch
- event.getName() = "workflow_call" and
- exists(ExternalJob caller |
- caller.getCallee() = job.getLocation().getFile().getRelativePath() and
- runsOnDefaultBranch(caller.getATriggerEvent())
- )
- ) and
+ hasDefaultBranchCacheWriteAccess(job, event) and
// the job writes to the cache
// (No need to follow the checkout/download step since the cache is normally write after the job completes)
job.getAStep() = step and
diff --git a/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.md b/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.md
index fefd6d61a44d..e5fd868609c4 100644
--- a/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.md
+++ b/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.md
@@ -34,25 +34,35 @@ Due to the above design, if something is cached in the context of the default br
## Example
+GitHub gives workflows triggered by low-trust events, such as `issue_comment`,
+`pull_request_target`, and `workflow_run`, read-only access to the default branch cache scope.
+This query therefore reports only workflows whose trigger can write to that scope.
+
### Incorrect Usage
-The following workflow runs untrusted code in a non-privileged job but in the context of the default branch.
+The following write-capable manually dispatched workflow fetches an unvalidated revision and then
+executes code from it. The executed code can use the cache token to poison the default branch cache
+if an untrusted integration or automation can influence the dispatch input.
```yaml
name: Vulnerable Workflow
on:
- pull_request_target:
- branches: [main]
-permissions: {}
+ workflow_dispatch:
+ inputs:
+ head_sha:
+ required: true
jobs:
test:
+ permissions: {}
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- with:
- ref: ${{ github.event.pull_request.head.sha }}
+ - env:
+ HEAD_SHA: ${{ github.event.inputs.head_sha }}
+ run: |
+ git fetch origin "$HEAD_SHA"
+ git checkout "$HEAD_SHA"
- name: Run tests
- run: ./run_tests.sh
+ run: npm install
```
### Correct Usage
@@ -79,5 +89,5 @@ jobs:
## References
- Adnan Khan's Blog: [The Monsters in Your Build Cache ā GitHub Actions Cache Poisoning](https://adnanthekhan.com/2024/05/06/the-monsters-in-your-build-cache-github-actions-cache-poisoning/).
-- GitHub Docs: [GitHub Actions Caching Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows).
+- GitHub Docs: [Cache access for low-trust workflow triggers](https://docs.github.com/actions/reference/workflows-and-actions/dependency-caching#cache-access-for-low-trust-workflow-triggers).
- Scribe Security Blog: [Cache Poisoning in GitHub Actions](https://scribesecurity.com/blog/github-cache-poisoning/).
diff --git a/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql b/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql
index e26f309ce531..35dcb390e131 100644
--- a/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql
+++ b/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql
@@ -50,17 +50,7 @@ where
job.getATriggerEvent() = event and
// job can be triggered by an external user
event.isExternallyTriggerable() and
- (
- // the workflow runs in the context of the default branch
- runsOnDefaultBranch(event)
- or
- // the workflow's caller runs in the context of the default branch
- event.getName() = "workflow_call" and
- exists(ExternalJob caller |
- caller.getCallee() = job.getLocation().getFile().getRelativePath() and
- runsOnDefaultBranch(caller.getATriggerEvent())
- )
- ) and
+ hasDefaultBranchCacheWriteAccess(job, event) and
// the job executes checked-out code
// (The cache specific token can be leaked even for non-privileged workflows)
source.getAFollowingStep() = step and
diff --git a/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.md b/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.md
index 16551e9c89a7..b8c7435adddf 100644
--- a/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.md
+++ b/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.md
@@ -1,10 +1,10 @@
## Overview
-Using a tag for a 3rd party Action that is not pinned to a commit can lead to executing an untrusted Action through a supply chain attack.
+Using a mutable tag or branch for an Action or reusable workflow can lead to executing untrusted code through a supply chain attack.
## Recommendation
-Pinning an action to a full length commit SHA is currently the only way to use a non-immutable action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the action's repository and not a repository fork.
+Pinning an Action or reusable workflow to a full length commit SHA is currently the only way to use a mutable reference as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the referenced repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the intended repository and not a repository fork.
## Example
@@ -14,12 +14,26 @@ Pinning an action to a full length commit SHA is currently the only way to use a
- uses: tj-actions/changed-files@v44
```
+```yaml
+jobs:
+ call-workflow:
+ uses: example/actions/.github/workflows/build.yml@main
+```
+
### Correct Usage
```yaml
- uses: tj-actions/changed-files@c65cd883420fd2eb864698a825fc4162dd94482c # v44
```
+```yaml
+jobs:
+ call-workflow:
+ uses: example/actions/.github/workflows/build.yml@25b062c917b0c75f8b47d8469aff6c94ffd89abb
+```
+
## References
- GitHub Docs: [Using third-party actions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions).
+- GitHub Docs: [Reusing third-party workflows](https://docs.github.com/en/actions/reference/security/secure-use#reusing-third-party-workflows).
+- GitHub Docs: [Workflow syntax for reusable workflow calls](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_iduses).
diff --git a/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.ql b/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.ql
index 530b8e48e0f5..8a1f821d073a 100644
--- a/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.ql
+++ b/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.ql
@@ -1,6 +1,6 @@
/**
- * @name Unpinned tag for a non-immutable Action in workflow or composite action
- * @description Using a tag for a non-immutable Action that is not pinned to a commit can lead to executing an untrusted Action through a supply chain attack.
+ * @name Unpinned tag for a non-immutable Action or reusable workflow
+ * @description Using a mutable reference for a non-immutable Action or reusable workflow can lead to executing untrusted code through a supply chain attack.
* @kind problem
* @security-severity 5.0
* @problem.severity warning
@@ -33,7 +33,13 @@ private predicate isPinnedContainer(string version) {
bindingset[nwo]
private predicate isContainerImage(string nwo) { nwo.regexpMatch("^docker://.+") }
-private predicate getStepContainerName(UsesStep uses, string name) {
+// A `$/` reference is a same-repository (self repository) reference (e.g. `$/path/to/action`),
+// resolved at the commit the calling workflow is running. Like `./` local (self workspace)
+// references, it is inherently pinned and can never be an unpinned-tag finding, so we never flag it.
+bindingset[nwo]
+private predicate isSelfRepository(string nwo) { nwo.matches("$/%") }
+
+private predicate hasUsesContainerName(Uses uses, string name) {
exists(Workflow workflow |
uses.getEnclosingWorkflow() = workflow and
(
@@ -49,14 +55,27 @@ private predicate getStepContainerName(UsesStep uses, string name) {
)
}
-from UsesStep uses, string nwo, string version, string name
+from Uses uses, string nwo, string version, string name, string message
where
uses.getCallee() = nwo and
- getStepContainerName(uses, name) and
+ hasUsesContainerName(uses, name) and
uses.getVersion() = version and
not isTrustedOwner(nwo) and
- not (if isContainerImage(nwo) then isPinnedContainer(version) else isPinnedCommit(version)) and
- not isImmutableAction(uses, nwo)
-select uses.getCalleeNode(),
- "Unpinned 3rd party Action '" + name + "' step $@ uses '" + nwo + "' with ref '" + version +
- "', not a pinned commit hash", uses, uses.toString()
+ not isSelfRepository(nwo) and
+ not any(ActionsLock lock).pins(uses, version) and
+ not (
+ if uses instanceof UsesStep and isContainerImage(nwo)
+ then isPinnedContainer(version)
+ else isPinnedCommit(version)
+ ) and
+ not exists(UsesStep step | uses = step and isImmutableAction(step, nwo)) and
+ if uses instanceof ExternalJob
+ then
+ message =
+ "Job $@ in '" + name + "' uses reusable workflow '" + nwo + "' with ref '" + version +
+ "', not a pinned commit hash"
+ else
+ message =
+ "Unpinned 3rd party Action '" + name + "' step $@ uses '" + nwo + "' with ref '" + version +
+ "', not a pinned commit hash"
+select uses.getCalleeNode(), message, uses, uses.toString()
diff --git a/actions/ql/src/change-notes/2026-07-18-envvar-injection-precision.md b/actions/ql/src/change-notes/2026-07-18-envvar-injection-precision.md
deleted file mode 100644
index c5bc9ba79bf1..000000000000
--- a/actions/ql/src/change-notes/2026-07-18-envvar-injection-precision.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* The `actions/envvar-injection/critical` query now requires the untrusted source and privileged context to originate from the same trigger event. The environment variable injection queries also no longer treat pull request head labels as injection-capable because they cannot contain newlines.
diff --git a/actions/ql/src/change-notes/2026-07-28-checkout-provenance.md b/actions/ql/src/change-notes/2026-07-28-checkout-provenance.md
deleted file mode 100644
index 9a1bb29be1d9..000000000000
--- a/actions/ql/src/change-notes/2026-07-28-checkout-provenance.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: fix
----
-* The `actions/cache-poisoning/poisonable-step` and `actions/untrusted-checkout/critical` queries now start paths at the expressions that control untrusted checkouts and link their alert messages to those expressions.
diff --git a/actions/ql/src/change-notes/2026-07-28-output-clobbering-regex.md b/actions/ql/src/change-notes/2026-07-28-output-clobbering-regex.md
deleted file mode 100644
index d9e84a447c91..000000000000
--- a/actions/ql/src/change-notes/2026-07-28-output-clobbering-regex.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: fix
----
-* Fixed a performance issue in the `actions/output-clobbering/high` query caused by using unescaped source-code input in a regular expression.
diff --git a/actions/ql/src/change-notes/2026-07-28-schedule-event-mapping.md b/actions/ql/src/change-notes/2026-07-28-schedule-event-mapping.md
deleted file mode 100644
index ff949c266d08..000000000000
--- a/actions/ql/src/change-notes/2026-07-28-schedule-event-mapping.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* GitHub Actions queries now correctly classify the `schedule` event when determining whether a workflow is externally triggerable.
diff --git a/actions/ql/src/change-notes/2026-07-29-output-clobbering-jq-precision.md b/actions/ql/src/change-notes/2026-07-29-output-clobbering-jq-precision.md
deleted file mode 100644
index 9fba403a5715..000000000000
--- a/actions/ql/src/change-notes/2026-07-29-output-clobbering-jq-precision.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* The `actions/output-clobbering/high` query no longer reports simple `jq` path filters when their output remains JSON-encoded. Raw-output modes, complex filters, and unrecognized options remain reportable.
diff --git a/actions/ql/src/change-notes/2026-07-29-output-clobbering-messages.md b/actions/ql/src/change-notes/2026-07-29-output-clobbering-messages.md
deleted file mode 100644
index 4abb7a029762..000000000000
--- a/actions/ql/src/change-notes/2026-07-29-output-clobbering-messages.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: fix
----
-* The `actions/output-clobbering/high` query now provides messages tailored to the affected output channel and includes expanded documentation and recommendations.
diff --git a/actions/ql/src/change-notes/2026-07-31-cache-poisoning-code-injection-wording.md b/actions/ql/src/change-notes/2026-07-31-cache-poisoning-code-injection-wording.md
deleted file mode 100644
index 8e2ade04f8b0..000000000000
--- a/actions/ql/src/change-notes/2026-07-31-cache-poisoning-code-injection-wording.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: queryMetadata
----
-* The name and alert message of the `actions/cache-poisoning/code-injection` query have been reworded for clarity.
\ No newline at end of file
diff --git a/actions/ql/src/change-notes/released/0.6.33.md b/actions/ql/src/change-notes/released/0.6.33.md
new file mode 100644
index 000000000000..86351b4c9158
--- /dev/null
+++ b/actions/ql/src/change-notes/released/0.6.33.md
@@ -0,0 +1,18 @@
+## 0.6.33
+
+### Query Metadata Changes
+
+* The name and alert message of the `actions/cache-poisoning/code-injection` query have been reworded for clarity.
+
+### Minor Analysis Improvements
+
+* The `actions/output-clobbering/high` query no longer reports simple `jq` path filters when their output remains JSON-encoded. Raw-output modes, complex filters, and unrecognized options remain reportable.
+* GitHub Actions queries now correctly classify the `schedule` event when determining whether a workflow is externally triggerable.
+* The `actions/envvar-injection/critical` query now requires the untrusted source and privileged context to originate from the same trigger event. The environment variable injection queries also no longer treat pull request head labels as injection-capable because they cannot contain newlines.
+* The `actions/cache-poisoning/code-injection`, `actions/cache-poisoning/direct-cache`, and `actions/cache-poisoning/poisonable-step` queries now account for read-only cache access on low-trust triggers that run in the default branch scope. Results are retained for triggers that GitHub allows to write to that cache scope.
+
+### Bug Fixes
+
+* The `actions/output-clobbering/high` query now provides messages tailored to the affected output channel and includes expanded documentation and recommendations.
+* The `actions/cache-poisoning/poisonable-step` and `actions/untrusted-checkout/critical` queries now start paths at the expressions that control untrusted checkouts and link their alert messages to those expressions.
+* Fixed a performance issue in the `actions/output-clobbering/high` query caused by using unescaped source-code input in a regular expression.
diff --git a/actions/ql/src/change-notes/released/0.6.34.md b/actions/ql/src/change-notes/released/0.6.34.md
new file mode 100644
index 000000000000..cfb871641149
--- /dev/null
+++ b/actions/ql/src/change-notes/released/0.6.34.md
@@ -0,0 +1,5 @@
+## 0.6.34
+
+### Minor Analysis Improvements
+
+* The `actions/unpinned-tag` query now detects mutable references to reusable workflows.
diff --git a/actions/ql/src/change-notes/released/0.6.35.md b/actions/ql/src/change-notes/released/0.6.35.md
new file mode 100644
index 000000000000..aa17e650d404
--- /dev/null
+++ b/actions/ql/src/change-notes/released/0.6.35.md
@@ -0,0 +1,3 @@
+## 0.6.35
+
+No user-facing changes.
diff --git a/actions/ql/src/change-notes/released/0.6.36.md b/actions/ql/src/change-notes/released/0.6.36.md
new file mode 100644
index 000000000000..1dce71ce8b9d
--- /dev/null
+++ b/actions/ql/src/change-notes/released/0.6.36.md
@@ -0,0 +1,6 @@
+## 0.6.36
+
+### Minor Analysis Improvements
+
+* The `actions/unpinned-tag` query no longer reports action references pinned by a structurally valid `.github/workflows/actions.lock` entry for the enclosing workflow.
+* The `actions/unpinned-tag` query no longer reports `$/` self repository references (e.g. `uses: $/path/to/action`), which resolve to the same repository at the running commit and are therefore inherently pinned, just like `./` self workspace (local) references.
diff --git a/actions/ql/src/change-notes/released/0.6.37.md b/actions/ql/src/change-notes/released/0.6.37.md
new file mode 100644
index 000000000000..1740f508517b
--- /dev/null
+++ b/actions/ql/src/change-notes/released/0.6.37.md
@@ -0,0 +1,3 @@
+## 0.6.37
+
+No user-facing changes.
diff --git a/actions/ql/src/change-notes/released/0.6.38.md b/actions/ql/src/change-notes/released/0.6.38.md
new file mode 100644
index 000000000000..2e9de7e7bd69
--- /dev/null
+++ b/actions/ql/src/change-notes/released/0.6.38.md
@@ -0,0 +1,3 @@
+## 0.6.38
+
+No user-facing changes.
diff --git a/actions/ql/src/change-notes/released/0.6.39.md b/actions/ql/src/change-notes/released/0.6.39.md
new file mode 100644
index 000000000000..8b72c9e25164
--- /dev/null
+++ b/actions/ql/src/change-notes/released/0.6.39.md
@@ -0,0 +1,3 @@
+## 0.6.39
+
+No user-facing changes.
diff --git a/actions/ql/src/codeql-pack.release.yml b/actions/ql/src/codeql-pack.release.yml
index 6c5978280b02..8bb51432d803 100644
--- a/actions/ql/src/codeql-pack.release.yml
+++ b/actions/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 0.6.32
+lastReleaseVersion: 0.6.39
diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml
index 6d2a221c1b4a..fd909c917439 100644
--- a/actions/ql/src/qlpack.yml
+++ b/actions/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/actions-queries
-version: 0.6.33-dev
+version: 0.6.40-dev
library: false
warnOnImplicitThis: true
groups: [actions, queries]
diff --git a/actions/ql/test/library-tests/actions-lock/.github/workflows/actions.lock b/actions/ql/test/library-tests/actions-lock/.github/workflows/actions.lock
new file mode 100644
index 000000000000..bb91aa093d86
--- /dev/null
+++ b/actions/ql/test/library-tests/actions-lock/.github/workflows/actions.lock
@@ -0,0 +1,19 @@
+# This file is machine-generated by `gh actions-lock`.
+# Do not edit by hand; run `gh actions-lock` to update.
+# Docs: https://gh.io/actions-lockfile
+version: 'v0.0.2'
+workflows:
+ '.github/workflows/test.yml':
+ - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1'
+ - 'github/codeql-action@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28'
+dependencies:
+ 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1':
+ ref: '3d3c42e5aac5ba805825da76410c181273ba90b1'
+ commit: 'sha1-3d3c42e5aac5ba805825da76410c181273ba90b1'
+ owner_id: 44036562
+ repo_id: 197814629
+ 'github/codeql-action@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28':
+ ref: 'v4.37.8'
+ commit: 'sha1-db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28'
+ owner_id: 9919
+ repo_id: 259445878
diff --git a/actions/ql/test/library-tests/actions-lock/.github/workflows/test.yml b/actions/ql/test/library-tests/actions-lock/.github/workflows/test.yml
new file mode 100644
index 000000000000..79afdcdf7006
--- /dev/null
+++ b/actions/ql/test/library-tests/actions-lock/.github/workflows/test.yml
@@ -0,0 +1,6 @@
+on: push
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo test
diff --git a/actions/ql/test/library-tests/actions-lock/options b/actions/ql/test/library-tests/actions-lock/options
new file mode 100644
index 000000000000..af54d6532407
--- /dev/null
+++ b/actions/ql/test/library-tests/actions-lock/options
@@ -0,0 +1 @@
+semmle-extractor-options: --file-type YAML .github/workflows/actions.lock
diff --git a/actions/ql/test/library-tests/actions-lock/test.expected b/actions/ql/test/library-tests/actions-lock/test.expected
new file mode 100644
index 000000000000..bd9b029ccd89
--- /dev/null
+++ b/actions/ql/test/library-tests/actions-lock/test.expected
@@ -0,0 +1 @@
+| .github/workflows/actions.lock:0:0:0:0 | .github/workflows/actions.lock |
diff --git a/actions/ql/test/library-tests/actions-lock/test.ql b/actions/ql/test/library-tests/actions-lock/test.ql
new file mode 100644
index 000000000000..03451f476fcd
--- /dev/null
+++ b/actions/ql/test/library-tests/actions-lock/test.ql
@@ -0,0 +1,4 @@
+import codeql.actions.Lock
+
+from ActionsLock lock
+select lock.getFile()
diff --git a/actions/ql/test/library-tests/basic/.github/workflows/controlcheck.yml b/actions/ql/test/library-tests/basic/.github/workflows/controlcheck.yml
new file mode 100644
index 000000000000..bd8ba15784b4
--- /dev/null
+++ b/actions/ql/test/library-tests/basic/.github/workflows/controlcheck.yml
@@ -0,0 +1,16 @@
+on:
+ pull_request_target:
+ types: [Created]
+jobs:
+ test1:
+ environment: EnvironmentInRepo
+ runs-on: ubuntu-latest
+ steps:
+ - name: Test 1
+ run: echo "test1"
+ test2:
+ environment: EnvironmentNotInRepo
+ runs-on: ubuntu-latest
+ steps:
+ - name: Test 2
+ run: echo "test2"
\ No newline at end of file
diff --git a/actions/ql/test/library-tests/basic/commands.expected b/actions/ql/test/library-tests/basic/commands.expected
index 82ea1739b28a..adbcdb5a40a7 100644
--- a/actions/ql/test/library-tests/basic/commands.expected
+++ b/actions/ql/test/library-tests/basic/commands.expected
@@ -16,6 +16,8 @@
| .github/workflows/commands.yml:28:9:31:2 | Run Step | wc -l |
| .github/workflows/commands.yml:34:9:37:6 | Run Step | command1 |
| .github/workflows/commands.yml:34:9:37:6 | Run Step | command2 |
+| .github/workflows/controlcheck.yml:9:9:11:2 | Run Step | echo "test1" |
+| .github/workflows/controlcheck.yml:15:9:16:25 | Run Step | echo "test2" |
| .github/workflows/expression_nodes.yml:7:9:8:6 | Run Step | LINE 1echo '${{ github.event.comment.body }}' |
| .github/workflows/expression_nodes.yml:8:9:10:6 | Run Step | LINE 1 echo '${{ github.event.comment.body }}' |
| .github/workflows/expression_nodes.yml:10:9:13:6 | Run Step | LINE 1 echo '${{ github.event.comment.body }}' |
diff --git a/actions/ql/test/library-tests/basic/controlchecktest.expected b/actions/ql/test/library-tests/basic/controlchecktest.expected
new file mode 100644
index 000000000000..ac2f7ac38aa1
--- /dev/null
+++ b/actions/ql/test/library-tests/basic/controlchecktest.expected
@@ -0,0 +1 @@
+| .github/workflows/controlcheck.yml:6:18:6:34 | EnvironmentInRepo |
diff --git a/actions/ql/test/library-tests/basic/controlchecktest.ext.yml b/actions/ql/test/library-tests/basic/controlchecktest.ext.yml
new file mode 100644
index 000000000000..96ded8ff2b2c
--- /dev/null
+++ b/actions/ql/test/library-tests/basic/controlchecktest.ext.yml
@@ -0,0 +1,8 @@
+extensions:
+ - addsTo:
+ pack: codeql/actions-all
+ extensible: enabledDeploymentEnvironmentDataModel
+ data:
+ # assumed to exist in a repo where controlcheck.yml exists
+ # realistically would need to be manually/externally provided
+ - ["EnvironmentInRepo"]
\ No newline at end of file
diff --git a/actions/ql/test/library-tests/basic/controlchecktest.ql b/actions/ql/test/library-tests/basic/controlchecktest.ql
new file mode 100644
index 000000000000..1daba58fe749
--- /dev/null
+++ b/actions/ql/test/library-tests/basic/controlchecktest.ql
@@ -0,0 +1,5 @@
+import actions
+import codeql.actions.security.ControlChecks
+
+from ControlCheck c
+select c
diff --git a/actions/ql/test/library-tests/basic/test.expected b/actions/ql/test/library-tests/basic/test.expected
index 4de3336aba7b..d29f21b8360a 100644
--- a/actions/ql/test/library-tests/basic/test.expected
+++ b/actions/ql/test/library-tests/basic/test.expected
@@ -1,5 +1,6 @@
files
| .github/workflows/commands.yml:0:0:0:0 | .github/workflows/commands.yml |
+| .github/workflows/controlcheck.yml:0:0:0:0 | .github/workflows/controlcheck.yml |
| .github/workflows/expression_nodes.yml:0:0:0:0 | .github/workflows/expression_nodes.yml |
| .github/workflows/many_strings.yml:0:0:0:0 | .github/workflows/many_strings.yml |
| .github/workflows/multiline2.yml:0:0:0:0 | .github/workflows/multiline2.yml |
@@ -7,8 +8,10 @@ files
| .github/workflows/poisonable_steps.yml:0:0:0:0 | .github/workflows/poisonable_steps.yml |
| .github/workflows/shell.yml:0:0:0:0 | .github/workflows/shell.yml |
| .github/workflows/test.yml:0:0:0:0 | .github/workflows/test.yml |
+| controlchecktest.ext.yml:0:0:0:0 | controlchecktest.ext.yml |
workflows
| .github/workflows/commands.yml:1:1:39:30 | on: push |
+| .github/workflows/controlcheck.yml:1:1:16:25 | on: |
| .github/workflows/expression_nodes.yml:1:1:21:47 | on: issue_comment |
| .github/workflows/many_strings.yml:1:1:18:1211 | on: |
| .github/workflows/multiline2.yml:1:1:89:35 | on: |
@@ -21,6 +24,8 @@ compositeActions
jobs
| .github/workflows/commands.yml:9:5:31:2 | Job: local_commands |
| .github/workflows/commands.yml:32:5:39:30 | Job: local_commands2 |
+| .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
| .github/workflows/expression_nodes.yml:5:5:21:47 | Job: echo-chamber |
| .github/workflows/many_strings.yml:9:5:18:1211 | Job: Test |
| .github/workflows/multiline2.yml:9:5:89:35 | Job: Test |
@@ -35,6 +40,8 @@ jobs
localJobs
| .github/workflows/commands.yml:9:5:31:2 | Job: local_commands |
| .github/workflows/commands.yml:32:5:39:30 | Job: local_commands2 |
+| .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
| .github/workflows/expression_nodes.yml:5:5:21:47 | Job: echo-chamber |
| .github/workflows/many_strings.yml:9:5:18:1211 | Job: Test |
| .github/workflows/multiline2.yml:9:5:89:35 | Job: Test |
@@ -57,6 +64,8 @@ steps
| .github/workflows/commands.yml:28:9:31:2 | Run Step |
| .github/workflows/commands.yml:34:9:37:6 | Run Step |
| .github/workflows/commands.yml:37:9:39:30 | Run Step |
+| .github/workflows/controlcheck.yml:9:9:11:2 | Run Step |
+| .github/workflows/controlcheck.yml:15:9:16:25 | Run Step |
| .github/workflows/expression_nodes.yml:7:9:8:6 | Run Step |
| .github/workflows/expression_nodes.yml:8:9:10:6 | Run Step |
| .github/workflows/expression_nodes.yml:10:9:13:6 | Run Step |
@@ -180,6 +189,10 @@ runStepChildren
| .github/workflows/commands.yml:34:9:37:6 | Run Step | .github/workflows/commands.yml:35:14:36:30 | command1 ; command2\n |
| .github/workflows/commands.yml:37:9:39:30 | Run Step | .github/workflows/commands.yml:37:16:37:19 | pwsh |
| .github/workflows/commands.yml:37:9:39:30 | Run Step | .github/workflows/commands.yml:38:14:39:30 | command3 \| command4\n |
+| .github/workflows/controlcheck.yml:9:9:11:2 | Run Step | .github/workflows/controlcheck.yml:9:15:9:20 | Test 1 |
+| .github/workflows/controlcheck.yml:9:9:11:2 | Run Step | .github/workflows/controlcheck.yml:10:14:10:25 | echo "test1" |
+| .github/workflows/controlcheck.yml:15:9:16:25 | Run Step | .github/workflows/controlcheck.yml:15:15:15:20 | Test 2 |
+| .github/workflows/controlcheck.yml:15:9:16:25 | Run Step | .github/workflows/controlcheck.yml:16:14:16:25 | echo "test2" |
| .github/workflows/expression_nodes.yml:7:9:8:6 | Run Step | .github/workflows/expression_nodes.yml:7:14:7:58 | LINE 1echo '${{ github.event.comment.body }}' |
| .github/workflows/expression_nodes.yml:8:9:10:6 | Run Step | .github/workflows/expression_nodes.yml:8:14:9:57 | LINE 1 echo '${{ github.event.comment.body }}'\n |
| .github/workflows/expression_nodes.yml:10:9:13:6 | Run Step | .github/workflows/expression_nodes.yml:10:14:12:53 | LINE 1 echo '${{ github.event.comment.body }}'\nLINE 2 echo '${{github.event.issue.body}}'\n |
@@ -347,6 +360,43 @@ parentNodes
| .github/workflows/commands.yml:38:14:39:30 | command3 \| command4\n | .github/workflows/commands.yml:1:1:39:30 | on: push |
| .github/workflows/commands.yml:38:14:39:30 | command3 \| command4\n | .github/workflows/commands.yml:32:5:39:30 | Job: local_commands2 |
| .github/workflows/commands.yml:38:14:39:30 | command3 \| command4\n | .github/workflows/commands.yml:37:9:39:30 | Run Step |
+| .github/workflows/controlcheck.yml:2:3:2:21 | pull_request_target | .github/workflows/controlcheck.yml:2:3:3:21 | pull_request_target: |
+| .github/workflows/controlcheck.yml:2:3:3:21 | pull_request_target: | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:3:13:3:19 | Created | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:3:13:3:19 | Created | .github/workflows/controlcheck.yml:2:3:2:21 | pull_request_target |
+| .github/workflows/controlcheck.yml:3:13:3:19 | Created | .github/workflows/controlcheck.yml:2:3:3:21 | pull_request_target: |
+| .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:6:18:6:34 | EnvironmentInRepo | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:6:18:6:34 | EnvironmentInRepo | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:6:18:6:34 | EnvironmentInRepo | .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:6:18:6:34 | EnvironmentInRepo | .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:6:18:6:34 | EnvironmentInRepo | .github/workflows/controlcheck.yml:6:18:6:34 | EnvironmentInRepo |
+| .github/workflows/controlcheck.yml:6:18:6:34 | EnvironmentInRepo | .github/workflows/controlcheck.yml:6:18:6:34 | EnvironmentInRepo |
+| .github/workflows/controlcheck.yml:7:14:7:26 | ubuntu-latest | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:7:14:7:26 | ubuntu-latest | .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:9:9:11:2 | Run Step | .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:9:15:9:20 | Test 1 | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:9:15:9:20 | Test 1 | .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:9:15:9:20 | Test 1 | .github/workflows/controlcheck.yml:9:9:11:2 | Run Step |
+| .github/workflows/controlcheck.yml:10:14:10:25 | echo "test1" | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:10:14:10:25 | echo "test1" | .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:10:14:10:25 | echo "test1" | .github/workflows/controlcheck.yml:9:9:11:2 | Run Step |
+| .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:12:18:12:37 | EnvironmentNotInRepo | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:12:18:12:37 | EnvironmentNotInRepo | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:12:18:12:37 | EnvironmentNotInRepo | .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
+| .github/workflows/controlcheck.yml:12:18:12:37 | EnvironmentNotInRepo | .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
+| .github/workflows/controlcheck.yml:12:18:12:37 | EnvironmentNotInRepo | .github/workflows/controlcheck.yml:12:18:12:37 | EnvironmentNotInRepo |
+| .github/workflows/controlcheck.yml:12:18:12:37 | EnvironmentNotInRepo | .github/workflows/controlcheck.yml:12:18:12:37 | EnvironmentNotInRepo |
+| .github/workflows/controlcheck.yml:13:14:13:26 | ubuntu-latest | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:13:14:13:26 | ubuntu-latest | .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
+| .github/workflows/controlcheck.yml:15:9:16:25 | Run Step | .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
+| .github/workflows/controlcheck.yml:15:15:15:20 | Test 2 | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:15:15:15:20 | Test 2 | .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
+| .github/workflows/controlcheck.yml:15:15:15:20 | Test 2 | .github/workflows/controlcheck.yml:15:9:16:25 | Run Step |
+| .github/workflows/controlcheck.yml:16:14:16:25 | echo "test2" | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:16:14:16:25 | echo "test2" | .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
+| .github/workflows/controlcheck.yml:16:14:16:25 | echo "test2" | .github/workflows/controlcheck.yml:15:9:16:25 | Run Step |
| .github/workflows/expression_nodes.yml:1:5:1:17 | issue_comment | .github/workflows/expression_nodes.yml:1:1:21:47 | on: issue_comment |
| .github/workflows/expression_nodes.yml:1:5:1:17 | issue_comment | .github/workflows/expression_nodes.yml:1:1:21:47 | on: issue_comment |
| .github/workflows/expression_nodes.yml:1:5:1:17 | issue_comment | .github/workflows/expression_nodes.yml:1:5:1:17 | issue_comment |
@@ -881,244 +931,368 @@ parentNodes
| .github/workflows/test.yml:40:14:40:52 | echo ${{needs.job1.outputs.job_output}} | .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
| .github/workflows/test.yml:40:20:40:53 | needs.job1.outputs.job_output | .github/workflows/test.yml:40:14:40:52 | echo ${{needs.job1.outputs.job_output}} |
cfgNodes
-| .github/workflows/commands.yml:1:1:39:30 | enter on: push |
-| .github/workflows/commands.yml:1:1:39:30 | exit on: push |
-| .github/workflows/commands.yml:1:1:39:30 | exit on: push (normal) |
+| .github/workflows/commands.yml:1:1:39:30 | After on: push |
+| .github/workflows/commands.yml:1:1:39:30 | Entry |
+| .github/workflows/commands.yml:1:1:39:30 | Exit |
+| .github/workflows/commands.yml:1:1:39:30 | Normal Exit |
| .github/workflows/commands.yml:1:1:39:30 | on: push |
+| .github/workflows/commands.yml:9:5:31:2 | After Job: local_commands |
| .github/workflows/commands.yml:9:5:31:2 | Job: local_commands |
+| .github/workflows/commands.yml:15:9:18:6 | After Run Step |
| .github/workflows/commands.yml:15:9:18:6 | Run Step |
| .github/workflows/commands.yml:16:14:17:30 | command1 ; command2\n |
+| .github/workflows/commands.yml:18:9:20:6 | After Run Step |
| .github/workflows/commands.yml:18:9:20:6 | Run Step |
| .github/workflows/commands.yml:18:14:19:30 | command3 \| command4\n |
+| .github/workflows/commands.yml:20:9:22:6 | After Run Step |
| .github/workflows/commands.yml:20:9:22:6 | Run Step |
| .github/workflows/commands.yml:20:14:21:33 | command5 "$(command6)"\n |
+| .github/workflows/commands.yml:22:9:24:6 | After Run Step |
| .github/workflows/commands.yml:22:9:24:6 | Run Step |
| .github/workflows/commands.yml:22:14:23:31 | command7 && command8\n |
+| .github/workflows/commands.yml:24:9:26:6 | After Run Step |
| .github/workflows/commands.yml:24:9:26:6 | Run Step |
| .github/workflows/commands.yml:24:14:25:32 | command9 \|\| command10\n |
+| .github/workflows/commands.yml:26:9:28:6 | After Run Step |
| .github/workflows/commands.yml:26:9:28:6 | Run Step |
| .github/workflows/commands.yml:26:14:27:34 | command11 "`command12`"\n |
+| .github/workflows/commands.yml:28:9:31:2 | After Run Step |
| .github/workflows/commands.yml:28:9:31:2 | Run Step |
| .github/workflows/commands.yml:28:14:29:50 | command13 "`command14` $(date \| wc -l)"\n |
+| .github/workflows/commands.yml:32:5:39:30 | After Job: local_commands2 |
| .github/workflows/commands.yml:32:5:39:30 | Job: local_commands2 |
+| .github/workflows/commands.yml:34:9:37:6 | After Run Step |
| .github/workflows/commands.yml:34:9:37:6 | Run Step |
| .github/workflows/commands.yml:35:14:36:30 | command1 ; command2\n |
+| .github/workflows/commands.yml:37:9:39:30 | After Run Step |
| .github/workflows/commands.yml:37:9:39:30 | Run Step |
| .github/workflows/commands.yml:38:14:39:30 | command3 \| command4\n |
-| .github/workflows/expression_nodes.yml:1:1:21:47 | enter on: issue_comment |
-| .github/workflows/expression_nodes.yml:1:1:21:47 | exit on: issue_comment |
-| .github/workflows/expression_nodes.yml:1:1:21:47 | exit on: issue_comment (normal) |
+| .github/workflows/controlcheck.yml:1:1:16:25 | After on: |
+| .github/workflows/controlcheck.yml:1:1:16:25 | Entry |
+| .github/workflows/controlcheck.yml:1:1:16:25 | Exit |
+| .github/workflows/controlcheck.yml:1:1:16:25 | Normal Exit |
+| .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/controlcheck.yml:6:5:11:2 | After Job: test1 |
+| .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:9:9:11:2 | After Run Step |
+| .github/workflows/controlcheck.yml:9:9:11:2 | Run Step |
+| .github/workflows/controlcheck.yml:10:14:10:25 | echo "test1" |
+| .github/workflows/controlcheck.yml:12:5:16:25 | After Job: test2 |
+| .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
+| .github/workflows/controlcheck.yml:15:9:16:25 | After Run Step |
+| .github/workflows/controlcheck.yml:15:9:16:25 | Run Step |
+| .github/workflows/controlcheck.yml:16:14:16:25 | echo "test2" |
+| .github/workflows/expression_nodes.yml:1:1:21:47 | After on: issue_comment |
+| .github/workflows/expression_nodes.yml:1:1:21:47 | Entry |
+| .github/workflows/expression_nodes.yml:1:1:21:47 | Exit |
+| .github/workflows/expression_nodes.yml:1:1:21:47 | Normal Exit |
| .github/workflows/expression_nodes.yml:1:1:21:47 | on: issue_comment |
+| .github/workflows/expression_nodes.yml:5:5:21:47 | After Job: echo-chamber |
| .github/workflows/expression_nodes.yml:5:5:21:47 | Job: echo-chamber |
+| .github/workflows/expression_nodes.yml:7:9:8:6 | After Run Step |
| .github/workflows/expression_nodes.yml:7:9:8:6 | Run Step |
| .github/workflows/expression_nodes.yml:7:14:7:58 | LINE 1echo '${{ github.event.comment.body }}' |
| .github/workflows/expression_nodes.yml:7:27:7:58 | github.event.comment.body |
+| .github/workflows/expression_nodes.yml:8:9:10:6 | After Run Step |
| .github/workflows/expression_nodes.yml:8:9:10:6 | Run Step |
| .github/workflows/expression_nodes.yml:8:14:9:57 | LINE 1 echo '${{ github.event.comment.body }}'\n |
| .github/workflows/expression_nodes.yml:9:25:9:56 | github.event.comment.body |
+| .github/workflows/expression_nodes.yml:10:9:13:6 | After Run Step |
| .github/workflows/expression_nodes.yml:10:9:13:6 | Run Step |
| .github/workflows/expression_nodes.yml:10:14:12:53 | LINE 1 echo '${{ github.event.comment.body }}'\nLINE 2 echo '${{github.event.issue.body}}'\n |
| .github/workflows/expression_nodes.yml:11:25:11:56 | github.event.comment.body |
| .github/workflows/expression_nodes.yml:12:24:12:51 | github.event.issue.body |
+| .github/workflows/expression_nodes.yml:13:9:16:6 | After Run Step |
| .github/workflows/expression_nodes.yml:13:9:16:6 | Run Step |
| .github/workflows/expression_nodes.yml:13:14:15:46 | LINE 1 echo '${{ github.event.comment.body }}' echo '${{github.event.issue.body}}'\n |
| .github/workflows/expression_nodes.yml:14:9:15:46 | github.event.comment.body |
| .github/workflows/expression_nodes.yml:14:9:15:46 | github.event.issue.body |
+| .github/workflows/expression_nodes.yml:16:9:20:6 | After Run Step |
| .github/workflows/expression_nodes.yml:16:9:20:6 | Run Step |
| .github/workflows/expression_nodes.yml:16:14:19:57 | LINE 1 echo '${{ github.event.comment.body }}'\nLINE 2 echo '${{github.event.issue.body}}'\nLINE 3 echo '${{ github.event.comment.body }}'\n |
| .github/workflows/expression_nodes.yml:17:25:17:56 | github.event.comment.body |
| .github/workflows/expression_nodes.yml:18:24:18:51 | github.event.issue.body |
| .github/workflows/expression_nodes.yml:19:24:19:55 | github.event.comment.body |
+| .github/workflows/expression_nodes.yml:20:9:21:47 | After Run Step |
| .github/workflows/expression_nodes.yml:20:9:21:47 | Run Step |
| .github/workflows/expression_nodes.yml:20:14:21:46 | LINE 1 echo '${{ github.event.comment.body }}' echo '${{github.event.issue.body}}' |
| .github/workflows/expression_nodes.yml:20:14:21:46 | github.event.comment.body |
| .github/workflows/expression_nodes.yml:20:14:21:46 | github.event.issue.body |
-| .github/workflows/many_strings.yml:1:1:18:1211 | enter on: |
-| .github/workflows/many_strings.yml:1:1:18:1211 | exit on: |
-| .github/workflows/many_strings.yml:1:1:18:1211 | exit on: (normal) |
+| .github/workflows/many_strings.yml:1:1:18:1211 | After on: |
+| .github/workflows/many_strings.yml:1:1:18:1211 | Entry |
+| .github/workflows/many_strings.yml:1:1:18:1211 | Exit |
+| .github/workflows/many_strings.yml:1:1:18:1211 | Normal Exit |
| .github/workflows/many_strings.yml:1:1:18:1211 | on: |
+| .github/workflows/many_strings.yml:9:5:18:1211 | After Job: Test |
| .github/workflows/many_strings.yml:9:5:18:1211 | Job: Test |
+| .github/workflows/many_strings.yml:11:9:18:1211 | After Run Step |
| .github/workflows/many_strings.yml:11:9:18:1211 | Run Step |
| .github/workflows/many_strings.yml:11:14:18:1211 | # Avoid choking on large chunks of data containing quotes\necho '["string1", "string2", "string3", "string4", "string5", "string6", "string7", "string8", "string9", "string10", "string11", "string12", "string13", "string14", "string15", "string16", "string17", "string18", "string19", "string20", "string21", "string22", "string23", "string24", "string25", "string26", "string27", "string28", "string29", "string30", "string31", "string32", "string33", "string34", "string35", "string36", "string37", "string38", "string39", "string40", "string41", "string42", "string43", "string44", "string45", "string46", "string47", "string48", "string49", "string50", "string51", "string52", "string53", "string54", "string55", "string56", "string57", "string58", "string59", "string60", "string61", "string62", "string63", "string64", "string65", "string66", "string67", "string68", "string69", "string70", "string71", "string72", "string73", "string74", "string75", "string76", "string77", "string78", "string79", "string80", "string81", "string82", "string83", "string84", "string85", "string86", "string87", "string88", "string89", "string90", "string91", "string92", "string93", "string94", "string95", "string96", "string97", "string98", "string99", "string100"]'\necho "['string1', 'string2', 'string3', 'string4', 'string5', 'string6', 'string7', 'string8', 'string9', 'string10', 'string11', 'string12', 'string13', 'string14', 'string15', 'string16', 'string17', 'string18', 'string19', 'string20', 'string21', 'string22', 'string23', 'string24', 'string25', 'string26', 'string27', 'string28', 'string29', 'string30', 'string31', 'string32', 'string33', 'string34', 'string35', 'string36', 'string37', 'string38', 'string39', 'string40', 'string41', 'string42', 'string43', 'string44', 'string45', 'string46', 'string47', 'string48', 'string49', 'string50', 'string51', 'string52', 'string53', 'string54', 'string55', 'string56', 'string57', 'string58', 'string59', 'string60', 'string61', 'string62', 'string63', 'string64', 'string65', 'string66', 'string67', 'string68', 'string69', 'string70', 'string71', 'string72', 'string73', 'string74', 'string75', 'string76', 'string77', 'string78', 'string79', 'string80', 'string81', 'string82', 'string83', 'string84', 'string85', 'string86', 'string87', 'string88', 'string89', 'string90', 'string91', 'string92', 'string93', 'string94', 'string95', 'string96', 'string97', 'string98', 'string99', 'string100']"\n\n# Same as above but where each line has an unbalanced internal quote near the end\necho '["string1", "string2", "string3", "string4", "string5", "string6", "string7", "string8", "string9", "string10", "string11", "string12", "string13", "string14", "string15", "string16", "string17", "string18", "string19", "string20", "string21", "string22", "string23", "string24", "string25", "string26", "string27", "string28", "string29", "string30", "string31", "string32", "string33", "string34", "string35", "string36", "string37", "string38", "string39", "string40", "string41", "string42", "string43", "string44", "string45", "string46", "string47", "string48", "string49", "string50", "string51", "string52", "string53", "string54", "string55", "string56", "string57", "string58", "string59", "string60", "string61", "string62", "string63", "string64", "string65", "string66", "string67", "string68", "string69", "string70", "string71", "string72", "string73", "string74", "string75", "string76", "string77", "string78", "string79", "string80", "string81", "string82", "string83", "string84", "string85", "string86", "string87", "string88", "string89", "string90", "string91", "string92", "string93", "string94", "string95", "string96", "string97", "string98", "string99", "string100"]"'\necho "['string1', 'string2', 'string3', 'string4', 'string5', 'string6', 'string7', 'string8', 'string9', 'string10', 'string11', 'string12', 'string13', 'string14', 'string15', 'string16', 'string17', 'string18', 'string19', 'string20', 'string21', 'string22', 'string23', 'string24', 'string25', 'string26', 'string27', 'string28', 'string29', 'string30', 'string31', 'string32', 'string33', 'string34', 'string35', 'string36', 'string37', 'string38', 'string39', 'string40', 'string41', 'string42', 'string43', 'string44', 'string45', 'string46', 'string47', 'string48', 'string49', 'string50', 'string51', 'string52', 'string53', 'string54', 'string55', 'string56', 'string57', 'string58', 'string59', 'string60', 'string61', 'string62', 'string63', 'string64', 'string65', 'string66', 'string67', 'string68', 'string69', 'string70', 'string71', 'string72', 'string73', 'string74', 'string75', 'string76', 'string77', 'string78', 'string79', 'string80', 'string81', 'string82', 'string83', 'string84', 'string85', 'string86', 'string87', 'string88', 'string89', 'string90', 'string91', 'string92', 'string93', 'string94', 'string95', 'string96', 'string97', 'string98', 'string99', 'string100']'"\n |
-| .github/workflows/multiline2.yml:1:1:89:35 | enter on: |
-| .github/workflows/multiline2.yml:1:1:89:35 | exit on: |
-| .github/workflows/multiline2.yml:1:1:89:35 | exit on: (normal) |
+| .github/workflows/multiline2.yml:1:1:89:35 | After on: |
+| .github/workflows/multiline2.yml:1:1:89:35 | Entry |
+| .github/workflows/multiline2.yml:1:1:89:35 | Exit |
+| .github/workflows/multiline2.yml:1:1:89:35 | Normal Exit |
| .github/workflows/multiline2.yml:1:1:89:35 | on: |
+| .github/workflows/multiline2.yml:9:5:89:35 | After Job: Test |
| .github/workflows/multiline2.yml:9:5:89:35 | Job: Test |
+| .github/workflows/multiline2.yml:11:9:15:6 | After Run Step |
| .github/workflows/multiline2.yml:11:9:15:6 | Run Step |
| .github/workflows/multiline2.yml:11:14:14:54 | echo "changelog< event.json\n ${{ toJson(github.event) }}\nEOF\n |
| .github/workflows/multiline2.yml:32:13:32:39 | toJson(github.event) |
+| .github/workflows/multiline2.yml:34:9:40:6 | After Run Step |
| .github/workflows/multiline2.yml:34:9:40:6 | Run Step |
| .github/workflows/multiline2.yml:35:14:39:14 | cat \| tee -a $GITHUB_ENV << EOL\n${ISSUE_BODY}\nFOO\nEOL\n |
+| .github/workflows/multiline2.yml:40:9:46:6 | After Run Step |
| .github/workflows/multiline2.yml:40:9:46:6 | Run Step |
| .github/workflows/multiline2.yml:41:14:45:14 | cat > issue.txt << EOL\n${ISSUE_BODY}\nFOO\nEOL\n |
+| .github/workflows/multiline2.yml:46:9:52:6 | After Run Step |
| .github/workflows/multiline2.yml:46:9:52:6 | Run Step |
| .github/workflows/multiline2.yml:47:14:51:14 | cat << EOL \| tee -a $GITHUB_ENV\n${ISSUE_BODY}\nFOO\nEOL\n |
+| .github/workflows/multiline2.yml:52:9:58:6 | After Run Step |
| .github/workflows/multiline2.yml:52:9:58:6 | Run Step |
| .github/workflows/multiline2.yml:53:14:57:14 | cat < file.txt\nHello\nWorld\nEOF\n |
+| .github/workflows/multiline2.yml:58:9:63:6 | After Run Step |
| .github/workflows/multiline2.yml:58:9:63:6 | Run Step |
| .github/workflows/multiline2.yml:59:14:62:14 | cat <<-EOF \| tee -a "$GITHUB_ENV"\necho "FOO=$TITLE"\nEOF\n |
+| .github/workflows/multiline2.yml:63:9:66:6 | After Run Step |
| .github/workflows/multiline2.yml:63:9:66:6 | Run Step |
| .github/workflows/multiline2.yml:64:14:65:142 | echo REPO_NAME=$(cat issue.txt \| sed 's/\\\\r/\\\\n/g' \| grep -ioE '\\\\s*[a-z0-9_-]+/[a-z0-9_-]+\\\\s*$' \| tr -d ' ') \| tee -a $GITHUB_ENV\n |
+| .github/workflows/multiline2.yml:66:9:71:6 | After Run Step |
| .github/workflows/multiline2.yml:66:9:71:6 | Run Step |
| .github/workflows/multiline2.yml:67:14:70:42 | echo "PR_TITLE<> $GITHUB_OUTPUT\necho -e "$FILTERED_CHANGELOG" >> $GITHUB_OUTPUT\necho "CHANGELOGEOF" >> $GITHUB_OUTPUT\n |
+| .github/workflows/multiline.yml:15:9:20:6 | After Run Step |
| .github/workflows/multiline.yml:15:9:20:6 | Run Step |
| .github/workflows/multiline.yml:15:14:19:40 | EOF=$(dd if=/dev/urandom bs=15 count=1 status=none \| base64)\necho "status<<$EOF" >> $GITHUB_OUTPUT\necho "$(cat status.output.json)" >> $GITHUB_OUTPUT\necho "$EOF" >> $GITHUB_OUTPUT\n |
+| .github/workflows/multiline.yml:20:9:24:6 | After Run Step |
| .github/workflows/multiline.yml:20:9:24:6 | Run Step |
| .github/workflows/multiline.yml:20:14:23:40 | echo "response<<$EOF" >> $GITHUB_OUTPUT\necho $output >> $GITHUB_OUTPUT\necho "$EOF" >> $GITHUB_OUTPUT\n |
+| .github/workflows/multiline.yml:24:9:30:6 | After Run Step |
| .github/workflows/multiline.yml:24:9:30:6 | Run Step |
| .github/workflows/multiline.yml:24:14:29:29 | {\n echo 'JSON_RESPONSE<> "$GITHUB_ENV"\n |
+| .github/workflows/multiline.yml:30:9:34:6 | After Run Step |
| .github/workflows/multiline.yml:30:9:34:6 | Run Step |
| .github/workflows/multiline.yml:30:14:33:14 | cat <<-"EOF" > event.json\n ${{ toJson(github.event) }}\nEOF\n |
| .github/workflows/multiline.yml:32:13:32:39 | toJson(github.event) |
+| .github/workflows/multiline.yml:34:9:40:6 | After Run Step |
| .github/workflows/multiline.yml:34:9:40:6 | Run Step |
| .github/workflows/multiline.yml:35:14:39:14 | cat >> $GITHUB_ENV << EOL\n${ISSUE_BODY}\nFOO\nEOL\n |
+| .github/workflows/multiline.yml:40:9:46:6 | After Run Step |
| .github/workflows/multiline.yml:40:9:46:6 | Run Step |
| .github/workflows/multiline.yml:41:14:45:14 | cat > issue.txt << EOL\n${ISSUE_BODY}\nFOO\nEOL\n |
+| .github/workflows/multiline.yml:46:9:52:6 | After Run Step |
| .github/workflows/multiline.yml:46:9:52:6 | Run Step |
| .github/workflows/multiline.yml:47:14:51:14 | cat << EOL >> $GITHUB_ENV\n${ISSUE_BODY}\nFOO\nEOL\n |
+| .github/workflows/multiline.yml:52:9:58:6 | After Run Step |
| .github/workflows/multiline.yml:52:9:58:6 | Run Step |
| .github/workflows/multiline.yml:53:14:57:14 | cat < file.txt\nHello\nWorld\nEOF\n |
+| .github/workflows/multiline.yml:58:9:63:6 | After Run Step |
| .github/workflows/multiline.yml:58:9:63:6 | Run Step |
| .github/workflows/multiline.yml:59:14:62:14 | cat <<-EOF >> "$GITHUB_ENV"\necho "FOO=$TITLE"\nEOF\n |
+| .github/workflows/multiline.yml:63:9:66:6 | After Run Step |
| .github/workflows/multiline.yml:63:9:66:6 | Run Step |
| .github/workflows/multiline.yml:64:14:65:136 | echo REPO_NAME=$(cat issue.txt \| sed 's/\\\\r/\\\\n/g' \| grep -ioE '\\\\s*[a-z0-9_-]+/[a-z0-9_-]+\\\\s*$' \| tr -d ' ') >> $GITHUB_ENV\n |
+| .github/workflows/multiline.yml:66:9:71:6 | After Run Step |
| .github/workflows/multiline.yml:66:9:71:6 | Run Step |
| .github/workflows/multiline.yml:67:14:70:36 | echo "PR_TITLE<> $GITHUB_ENV\necho "$TITLE" >> $GITHUB_ENV\necho "EOF" >> $GITHUB_ENV\n |
+| .github/workflows/multiline.yml:71:9:78:6 | After Run Step |
| .github/workflows/multiline.yml:71:9:78:6 | Run Step |
| .github/workflows/multiline.yml:72:14:77:29 | {\n echo 'JSON_RESPONSE<> "$GITHUB_ENV"\n |
+| .github/workflows/multiline.yml:78:9:85:6 | After Run Step |
| .github/workflows/multiline.yml:78:9:85:6 | Run Step |
| .github/workflows/multiline.yml:79:14:84:29 | {\n echo 'JSON_RESPONSE<> "$GITHUB_ENV"\n |
+| .github/workflows/multiline.yml:85:9:89:29 | After Run Step |
| .github/workflows/multiline.yml:85:9:89:29 | Run Step |
| .github/workflows/multiline.yml:86:14:89:29 | {\n echo 'JSON_RESPONSE<> "$GITHUB_ENV"\n |
-| .github/workflows/poisonable_steps.yml:1:1:46:111 | enter on: push |
-| .github/workflows/poisonable_steps.yml:1:1:46:111 | exit on: push |
-| .github/workflows/poisonable_steps.yml:1:1:46:111 | exit on: push (normal) |
+| .github/workflows/poisonable_steps.yml:1:1:46:111 | After on: push |
+| .github/workflows/poisonable_steps.yml:1:1:46:111 | Entry |
+| .github/workflows/poisonable_steps.yml:1:1:46:111 | Exit |
+| .github/workflows/poisonable_steps.yml:1:1:46:111 | Normal Exit |
| .github/workflows/poisonable_steps.yml:1:1:46:111 | on: push |
+| .github/workflows/poisonable_steps.yml:5:5:46:111 | After Job: local_commands |
| .github/workflows/poisonable_steps.yml:5:5:46:111 | Job: local_commands |
+| .github/workflows/poisonable_steps.yml:7:9:8:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:7:9:8:6 | Run Step |
| .github/workflows/poisonable_steps.yml:7:14:7:30 | venv/bin/activate |
+| .github/workflows/poisonable_steps.yml:8:9:13:6 | After Uses Step |
| .github/workflows/poisonable_steps.yml:8:9:13:6 | Uses Step |
| .github/workflows/poisonable_steps.yml:11:53:11:75 | github.workspace |
+| .github/workflows/poisonable_steps.yml:13:9:14:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:13:9:14:6 | Run Step |
| .github/workflows/poisonable_steps.yml:13:14:13:32 | . venv/bin/activate |
+| .github/workflows/poisonable_steps.yml:14:9:15:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:14:9:15:6 | Run Step |
| .github/workflows/poisonable_steps.yml:14:14:14:42 | echo foo; . venv/bin/activate |
+| .github/workflows/poisonable_steps.yml:15:9:16:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:15:9:16:6 | Run Step |
| .github/workflows/poisonable_steps.yml:15:14:15:41 | echo foo;. venv/bin/activate |
+| .github/workflows/poisonable_steps.yml:16:9:17:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:16:9:17:6 | Run Step |
| .github/workflows/poisonable_steps.yml:16:14:16:42 | echo foo \|. venv/bin/activate |
+| .github/workflows/poisonable_steps.yml:17:9:18:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:17:9:18:6 | Run Step |
| .github/workflows/poisonable_steps.yml:17:14:17:32 | ./venv/bin/activate |
+| .github/workflows/poisonable_steps.yml:18:9:19:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:18:9:19:6 | Run Step |
| .github/workflows/poisonable_steps.yml:18:14:18:36 | sh venv/bin/activate.sh |
+| .github/workflows/poisonable_steps.yml:19:9:20:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:19:9:20:6 | Run Step |
| .github/workflows/poisonable_steps.yml:19:14:19:44 | echo $(sh venv/bin/activate.sh) |
+| .github/workflows/poisonable_steps.yml:20:9:21:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:20:9:21:6 | Run Step |
| .github/workflows/poisonable_steps.yml:20:14:20:56 | echo foo; sh venv/bin/activate.sh; echo bar |
+| .github/workflows/poisonable_steps.yml:21:9:22:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:21:9:22:6 | Run Step |
| .github/workflows/poisonable_steps.yml:21:14:21:56 | echo foo \| sh venv/bin/activate.sh > output |
+| .github/workflows/poisonable_steps.yml:22:9:23:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:22:9:23:6 | Run Step |
| .github/workflows/poisonable_steps.yml:22:14:22:40 | python venv/bin/activate.py |
+| .github/workflows/poisonable_steps.yml:23:9:24:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:23:9:24:6 | Run Step |
| .github/workflows/poisonable_steps.yml:23:14:23:50 | echo foo; python venv/bin/activate.py |
+| .github/workflows/poisonable_steps.yml:24:9:25:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:24:9:25:6 | Run Step |
| .github/workflows/poisonable_steps.yml:24:14:24:29 | pnpm run test:ct |
+| .github/workflows/poisonable_steps.yml:25:9:26:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:25:9:26:6 | Run Step |
| .github/workflows/poisonable_steps.yml:25:14:25:73 | pip install nbformat && python scripts/generate_notebooks.py |
+| .github/workflows/poisonable_steps.yml:26:9:27:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:26:9:27:6 | Run Step |
| .github/workflows/poisonable_steps.yml:26:14:26:78 | python scripts/generate_theme.py --outfile js/storybook/theme.css |
+| .github/workflows/poisonable_steps.yml:27:9:28:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:27:9:28:6 | Run Step |
| .github/workflows/poisonable_steps.yml:27:14:27:76 | ruby scripts/generate_theme.rb --outfile js/storybook/theme.css |
+| .github/workflows/poisonable_steps.yml:28:9:29:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:28:9:29:6 | Run Step |
| .github/workflows/poisonable_steps.yml:28:14:28:92 | bundle run exec ruby scripts/generate_theme.rb --outfile js/storybook/theme.css |
+| .github/workflows/poisonable_steps.yml:29:9:30:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:29:9:30:6 | Run Step |
| .github/workflows/poisonable_steps.yml:29:14:29:42 | xvfb-run ./mvnw clean package |
+| .github/workflows/poisonable_steps.yml:30:9:31:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:30:9:31:6 | Run Step |
| .github/workflows/poisonable_steps.yml:30:14:30:46 | echo "foo" && npm i && echo "bar" |
+| .github/workflows/poisonable_steps.yml:31:9:32:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:31:9:32:6 | Run Step |
| .github/workflows/poisonable_steps.yml:31:14:31:44 | echo "foo" \| npm i \| echo "bar" |
+| .github/workflows/poisonable_steps.yml:32:9:33:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:32:9:33:6 | Run Step |
| .github/workflows/poisonable_steps.yml:32:14:32:44 | echo "foo" \| npm i \| echo "bar" |
+| .github/workflows/poisonable_steps.yml:33:9:34:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:33:9:34:6 | Run Step |
| .github/workflows/poisonable_steps.yml:33:14:33:35 | echo "foo `npm i` bar" |
+| .github/workflows/poisonable_steps.yml:34:9:35:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:34:9:35:6 | Run Step |
| .github/workflows/poisonable_steps.yml:34:14:34:52 | dotnet test foo/Tests.csproj -c Release |
+| .github/workflows/poisonable_steps.yml:35:9:36:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:35:9:36:6 | Run Step |
| .github/workflows/poisonable_steps.yml:35:14:35:26 | go run foo.go |
+| .github/workflows/poisonable_steps.yml:36:9:37:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:36:9:37:6 | Run Step |
| .github/workflows/poisonable_steps.yml:36:14:36:86 | sed -i "s\|git_branch = .*\|git_branch = \\"$GITHUB_HEAD_REF\\"\|" config.json |
+| .github/workflows/poisonable_steps.yml:37:9:38:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:37:9:38:6 | Run Step |
| .github/workflows/poisonable_steps.yml:37:14:37:51 | sed -f ./config.sed file.txt > foo.txt |
+| .github/workflows/poisonable_steps.yml:38:9:39:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:38:9:39:6 | Run Step |
| .github/workflows/poisonable_steps.yml:38:14:38:45 | sed -f config file.txt > foo.txt |
+| .github/workflows/poisonable_steps.yml:39:9:40:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:39:9:40:6 | Run Step |
| .github/workflows/poisonable_steps.yml:39:14:39:55 | echo "foo" \| awk -f ./config.awk > foo.txt |
+| .github/workflows/poisonable_steps.yml:40:9:41:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:40:9:41:6 | Run Step |
| .github/workflows/poisonable_steps.yml:40:14:40:73 | gcloud builds submit --quiet --substitutions="COMMIT_SHA=foo |
+| .github/workflows/poisonable_steps.yml:41:9:42:6 | After Run Step |
| .github/workflows/poisonable_steps.yml:41:9:42:6 | Run Step |
| .github/workflows/poisonable_steps.yml:41:14:41:22 | ./foo/cmd |
+| .github/workflows/poisonable_steps.yml:42:9:46:111 | After Run Step |
| .github/workflows/poisonable_steps.yml:42:9:46:111 | Run Step |
| .github/workflows/poisonable_steps.yml:42:14:46:111 | sed -e 's##TITLE#' \\\n -e 's##${{ env.sot_repo }}#' \\\n -e 's##${TITLE}#' \\\n .github/workflows/common-copybara.bara.sky.template > .github/workflows/common-copybara.bara.sky\n |
| .github/workflows/poisonable_steps.yml:44:32:44:50 | env.sot_repo |
-| .github/workflows/shell.yml:1:1:22:32 | enter on: push |
-| .github/workflows/shell.yml:1:1:22:32 | exit on: push |
-| .github/workflows/shell.yml:1:1:22:32 | exit on: push (normal) |
+| .github/workflows/shell.yml:1:1:22:32 | After on: push |
+| .github/workflows/shell.yml:1:1:22:32 | Entry |
+| .github/workflows/shell.yml:1:1:22:32 | Exit |
+| .github/workflows/shell.yml:1:1:22:32 | Normal Exit |
| .github/workflows/shell.yml:1:1:22:32 | on: push |
+| .github/workflows/shell.yml:5:5:9:2 | After Job: job1 |
| .github/workflows/shell.yml:5:5:9:2 | Job: job1 |
+| .github/workflows/shell.yml:7:9:9:2 | After Run Step |
| .github/workflows/shell.yml:7:9:9:2 | Run Step |
| .github/workflows/shell.yml:8:14:8:31 | Write-Output "foo" |
+| .github/workflows/shell.yml:10:5:14:2 | After Job: job2 |
| .github/workflows/shell.yml:10:5:14:2 | Job: job2 |
+| .github/workflows/shell.yml:12:9:14:2 | After Run Step |
| .github/workflows/shell.yml:12:9:14:2 | Run Step |
| .github/workflows/shell.yml:12:14:12:23 | echo "foo" |
+| .github/workflows/shell.yml:15:5:19:2 | After Job: job3 |
| .github/workflows/shell.yml:15:5:19:2 | Job: job3 |
+| .github/workflows/shell.yml:17:9:19:2 | After Run Step |
| .github/workflows/shell.yml:17:9:19:2 | Run Step |
| .github/workflows/shell.yml:18:14:18:23 | echo "foo" |
+| .github/workflows/shell.yml:20:5:22:32 | After Job: job4 |
| .github/workflows/shell.yml:20:5:22:32 | Job: job4 |
+| .github/workflows/shell.yml:22:9:22:32 | After Run Step |
| .github/workflows/shell.yml:22:9:22:32 | Run Step |
| .github/workflows/shell.yml:22:14:22:31 | Write-Output "foo" |
-| .github/workflows/test.yml:1:1:40:53 | enter on: push |
-| .github/workflows/test.yml:1:1:40:53 | exit on: push |
-| .github/workflows/test.yml:1:1:40:53 | exit on: push (normal) |
+| .github/workflows/test.yml:1:1:40:53 | After on: push |
+| .github/workflows/test.yml:1:1:40:53 | Entry |
+| .github/workflows/test.yml:1:1:40:53 | Exit |
+| .github/workflows/test.yml:1:1:40:53 | Normal Exit |
| .github/workflows/test.yml:1:1:40:53 | on: push |
+| .github/workflows/test.yml:5:5:31:2 | After Job: job1 |
| .github/workflows/test.yml:5:5:31:2 | Job: job1 |
+| .github/workflows/test.yml:8:7:10:4 | After Job outputs node |
| .github/workflows/test.yml:8:7:10:4 | Job outputs node |
| .github/workflows/test.yml:8:20:8:50 | steps.step.outputs.value |
| .github/workflows/test.yml:11:9:15:6 | Uses Step |
| .github/workflows/test.yml:15:9:19:6 | Uses Step: source |
+| .github/workflows/test.yml:19:9:26:6 | After Uses Step: step |
| .github/workflows/test.yml:19:9:26:6 | Uses Step: step |
| .github/workflows/test.yml:23:20:23:64 | steps.source.outputs.all_changed_files |
+| .github/workflows/test.yml:26:9:28:6 | After Run Step: simplesink1 |
| .github/workflows/test.yml:26:9:28:6 | Run Step: simplesink1 |
| .github/workflows/test.yml:27:14:27:63 | echo ${{ steps.source.outputs.all_changed_files }} |
| .github/workflows/test.yml:27:20:27:64 | steps.source.outputs.all_changed_files |
+| .github/workflows/test.yml:28:9:31:2 | After Run Step: simplesink2 |
| .github/workflows/test.yml:28:9:31:2 | Run Step: simplesink2 |
| .github/workflows/test.yml:29:14:29:54 | ${{ github.event.pull_request.head.ref }} |
| .github/workflows/test.yml:29:15:29:55 | github.event.pull_request.head.ref |
+| .github/workflows/test.yml:32:5:40:53 | After Job: job2 |
| .github/workflows/test.yml:32:5:40:53 | Job: job2 |
+| .github/workflows/test.yml:39:9:40:53 | After Run Step: sink |
| .github/workflows/test.yml:39:9:40:53 | Run Step: sink |
| .github/workflows/test.yml:40:14:40:52 | echo ${{needs.job1.outputs.job_output}} |
| .github/workflows/test.yml:40:20:40:53 | needs.job1.outputs.job_output |
+cfgCycles
dfNodes
| .github/workflows/commands.yml:9:5:31:2 | Job: local_commands |
| .github/workflows/commands.yml:15:9:18:6 | Run Step |
@@ -1140,6 +1314,12 @@ dfNodes
| .github/workflows/commands.yml:35:14:36:30 | command1 ; command2\n |
| .github/workflows/commands.yml:37:9:39:30 | Run Step |
| .github/workflows/commands.yml:38:14:39:30 | command3 \| command4\n |
+| .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 |
+| .github/workflows/controlcheck.yml:9:9:11:2 | Run Step |
+| .github/workflows/controlcheck.yml:10:14:10:25 | echo "test1" |
+| .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 |
+| .github/workflows/controlcheck.yml:15:9:16:25 | Run Step |
+| .github/workflows/controlcheck.yml:16:14:16:25 | echo "test2" |
| .github/workflows/expression_nodes.yml:5:5:21:47 | Job: echo-chamber |
| .github/workflows/expression_nodes.yml:7:9:8:6 | Run Step |
| .github/workflows/expression_nodes.yml:7:14:7:58 | LINE 1echo '${{ github.event.comment.body }}' |
@@ -1353,6 +1533,12 @@ nodeLocations
| .github/workflows/commands.yml:35:14:36:30 | command1 ; command2\n | .github/workflows/commands.yml:35:14:36:30 | .github/workflows/commands.yml@35:14:36:30 |
| .github/workflows/commands.yml:37:9:39:30 | Run Step | .github/workflows/commands.yml:37:9:39:30 | .github/workflows/commands.yml@37:9:39:30 |
| .github/workflows/commands.yml:38:14:39:30 | command3 \| command4\n | .github/workflows/commands.yml:38:14:39:30 | .github/workflows/commands.yml@38:14:39:30 |
+| .github/workflows/controlcheck.yml:6:5:11:2 | Job: test1 | .github/workflows/controlcheck.yml:6:5:11:2 | .github/workflows/controlcheck.yml@6:5:11:2 |
+| .github/workflows/controlcheck.yml:9:9:11:2 | Run Step | .github/workflows/controlcheck.yml:9:9:11:2 | .github/workflows/controlcheck.yml@9:9:11:2 |
+| .github/workflows/controlcheck.yml:10:14:10:25 | echo "test1" | .github/workflows/controlcheck.yml:10:14:10:25 | .github/workflows/controlcheck.yml@10:14:10:25 |
+| .github/workflows/controlcheck.yml:12:5:16:25 | Job: test2 | .github/workflows/controlcheck.yml:12:5:16:25 | .github/workflows/controlcheck.yml@12:5:16:25 |
+| .github/workflows/controlcheck.yml:15:9:16:25 | Run Step | .github/workflows/controlcheck.yml:15:9:16:25 | .github/workflows/controlcheck.yml@15:9:16:25 |
+| .github/workflows/controlcheck.yml:16:14:16:25 | echo "test2" | .github/workflows/controlcheck.yml:16:14:16:25 | .github/workflows/controlcheck.yml@16:14:16:25 |
| .github/workflows/expression_nodes.yml:5:5:21:47 | Job: echo-chamber | .github/workflows/expression_nodes.yml:5:5:21:47 | .github/workflows/expression_nodes.yml@5:5:21:47 |
| .github/workflows/expression_nodes.yml:7:9:8:6 | Run Step | .github/workflows/expression_nodes.yml:7:9:8:6 | .github/workflows/expression_nodes.yml@7:9:8:6 |
| .github/workflows/expression_nodes.yml:7:14:7:58 | LINE 1echo '${{ github.event.comment.body }}' | .github/workflows/expression_nodes.yml:7:14:7:58 | .github/workflows/expression_nodes.yml@7:14:7:58 |
@@ -1541,6 +1727,7 @@ nodeLocations
| .github/workflows/test.yml:40:20:40:53 | needs.job1.outputs.job_output | .github/workflows/test.yml:40:20:40:53 | .github/workflows/test.yml@40:20:40:53 |
scopes
| .github/workflows/commands.yml:1:1:39:30 | on: push |
+| .github/workflows/controlcheck.yml:1:1:16:25 | on: |
| .github/workflows/expression_nodes.yml:1:1:21:47 | on: issue_comment |
| .github/workflows/many_strings.yml:1:1:18:1211 | on: |
| .github/workflows/multiline2.yml:1:1:89:35 | on: |
@@ -1548,6 +1735,47 @@ scopes
| .github/workflows/poisonable_steps.yml:1:1:46:111 | on: push |
| .github/workflows/shell.yml:1:1:22:32 | on: push |
| .github/workflows/test.yml:1:1:40:53 | on: push |
+workflowScopes
+| .github/workflows/commands.yml:1:1:39:30 | on: push |
+| .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/expression_nodes.yml:1:1:21:47 | on: issue_comment |
+| .github/workflows/many_strings.yml:1:1:18:1211 | on: |
+| .github/workflows/multiline2.yml:1:1:89:35 | on: |
+| .github/workflows/multiline.yml:1:1:89:29 | on: |
+| .github/workflows/poisonable_steps.yml:1:1:46:111 | on: push |
+| .github/workflows/shell.yml:1:1:22:32 | on: push |
+| .github/workflows/test.yml:1:1:40:53 | on: push |
+compositeActionScopes
+workflowCfgNodes
+| .github/workflows/commands.yml:1:1:39:30 | on: push |
+| .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/expression_nodes.yml:1:1:21:47 | on: issue_comment |
+| .github/workflows/many_strings.yml:1:1:18:1211 | on: |
+| .github/workflows/multiline2.yml:1:1:89:35 | on: |
+| .github/workflows/multiline.yml:1:1:89:29 | on: |
+| .github/workflows/poisonable_steps.yml:1:1:46:111 | on: push |
+| .github/workflows/shell.yml:1:1:22:32 | on: push |
+| .github/workflows/test.yml:1:1:40:53 | on: push |
+entryScopes
+| .github/workflows/commands.yml:1:1:39:30 | Entry | .github/workflows/commands.yml:1:1:39:30 | on: push |
+| .github/workflows/controlcheck.yml:1:1:16:25 | Entry | .github/workflows/controlcheck.yml:1:1:16:25 | on: |
+| .github/workflows/expression_nodes.yml:1:1:21:47 | Entry | .github/workflows/expression_nodes.yml:1:1:21:47 | on: issue_comment |
+| .github/workflows/many_strings.yml:1:1:18:1211 | Entry | .github/workflows/many_strings.yml:1:1:18:1211 | on: |
+| .github/workflows/multiline2.yml:1:1:89:35 | Entry | .github/workflows/multiline2.yml:1:1:89:35 | on: |
+| .github/workflows/multiline.yml:1:1:89:29 | Entry | .github/workflows/multiline.yml:1:1:89:29 | on: |
+| .github/workflows/poisonable_steps.yml:1:1:46:111 | Entry | .github/workflows/poisonable_steps.yml:1:1:46:111 | on: push |
+| .github/workflows/shell.yml:1:1:22:32 | Entry | .github/workflows/shell.yml:1:1:22:32 | on: push |
+| .github/workflows/test.yml:1:1:40:53 | Entry | .github/workflows/test.yml:1:1:40:53 | on: push |
+normalExitNodes
+| .github/workflows/commands.yml:1:1:39:30 | Normal Exit |
+| .github/workflows/controlcheck.yml:1:1:16:25 | Normal Exit |
+| .github/workflows/expression_nodes.yml:1:1:21:47 | Normal Exit |
+| .github/workflows/many_strings.yml:1:1:18:1211 | Normal Exit |
+| .github/workflows/multiline2.yml:1:1:89:35 | Normal Exit |
+| .github/workflows/multiline.yml:1:1:89:29 | Normal Exit |
+| .github/workflows/poisonable_steps.yml:1:1:46:111 | Normal Exit |
+| .github/workflows/shell.yml:1:1:22:32 | Normal Exit |
+| .github/workflows/test.yml:1:1:40:53 | Normal Exit |
sources
| AvraamMavridis/files-changed-action | * | output.CHANGED_FILES | filename | manual |
| AvraamMavridis/files-changed-action | * | output.CHANGED_FILES_EXTENSIONS | filename | manual |
diff --git a/actions/ql/test/library-tests/basic/test.ql b/actions/ql/test/library-tests/basic/test.ql
index e4c1d9e443d0..fe44a0f4dcf5 100644
--- a/actions/ql/test/library-tests/basic/test.ql
+++ b/actions/ql/test/library-tests/basic/test.ql
@@ -37,6 +37,8 @@ query predicate parentNodes(AstNode child, AstNode parent) { child.getParentNode
query predicate cfgNodes(Cfg::Node n) { any() }
+query predicate cfgCycles(Cfg::Node n) { n.getASuccessor+() = n }
+
query predicate dfNodes(DataFlow::Node e) { any() }
query predicate argumentNodes(DataFlow::ArgumentNode e) { any() }
@@ -47,6 +49,21 @@ query predicate nodeLocations(DataFlow::Node n, Location l) { n.getLocation() =
query predicate scopes(Cfg::CfgScope c) { any() }
+query predicate workflowScopes(Cfg::WorkflowScope c) { any() }
+
+query predicate compositeActionScopes(Cfg::CompositeActionScope c) { any() }
+
+query predicate workflowCfgNodes(Cfg::AstCfgNode node) {
+ node.getAstNode() instanceof Workflow and
+ node.getEnclosingCallable() = node.getAstNode()
+}
+
+query predicate entryScopes(Cfg::EntryNode entry, Cfg::CfgScope scope) {
+ scope = entry.getEnclosingCallable()
+}
+
+query predicate normalExitNodes(Cfg::AnnotatedExitNode exit) { exit instanceof Cfg::NormalExitNode }
+
query predicate sources(string action, string version, string output, string kind, string provenance) {
actionsSourceModel(action, version, output, kind, provenance)
}
diff --git a/actions/ql/test/library-tests/cfg-callable/action.yml b/actions/ql/test/library-tests/cfg-callable/action.yml
new file mode 100644
index 000000000000..81aa1df95a00
--- /dev/null
+++ b/actions/ql/test/library-tests/cfg-callable/action.yml
@@ -0,0 +1,12 @@
+name: Ambiguous root
+
+runs:
+ using: composite
+ steps:
+ - run: echo "${{ github.actor }}"
+
+jobs:
+ unexpected:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo "This must not make action.yml a workflow"
diff --git a/actions/ql/test/library-tests/cfg-callable/test.expected b/actions/ql/test/library-tests/cfg-callable/test.expected
new file mode 100644
index 000000000000..17687b33ef7d
--- /dev/null
+++ b/actions/ql/test/library-tests/cfg-callable/test.expected
@@ -0,0 +1,4 @@
+roots
+| 1 | 1 |
+cfgScopes
+| action.yml:1:1:12:61 | name: Ambiguous root | composite action |
diff --git a/actions/ql/test/library-tests/cfg-callable/test.ql b/actions/ql/test/library-tests/cfg-callable/test.ql
new file mode 100644
index 000000000000..5b66c1c4d314
--- /dev/null
+++ b/actions/ql/test/library-tests/cfg-callable/test.ql
@@ -0,0 +1,18 @@
+import codeql.actions.Ast
+import codeql.actions.Cfg as Cfg
+
+query predicate roots(int workflows, int compositeActions) {
+ workflows =
+ strictcount(Workflow workflow | workflow.getLocation().getFile().getBaseName() = "action.yml") and
+ compositeActions =
+ strictcount(CompositeAction action | action.getLocation().getFile().getBaseName() = "action.yml")
+}
+
+query predicate cfgScopes(Cfg::CfgScope scope, string kind) {
+ scope.getLocation().getFile().getBaseName() = "action.yml" and
+ (
+ scope instanceof Cfg::WorkflowScope and kind = "workflow"
+ or
+ scope instanceof Cfg::CompositeActionScope and kind = "composite action"
+ )
+}
diff --git a/actions/ql/test/library-tests/cfg-environment/.github/workflows/test.yml b/actions/ql/test/library-tests/cfg-environment/.github/workflows/test.yml
new file mode 100644
index 000000000000..1bd23112154a
--- /dev/null
+++ b/actions/ql/test/library-tests/cfg-environment/.github/workflows/test.yml
@@ -0,0 +1,21 @@
+on: issues
+
+env:
+ GLOBAL_VALUE: ${{ github.event.issue.title }}
+
+jobs:
+ local:
+ runs-on: ubuntu-latest
+ env:
+ JOB_VALUE: ${{ github.event.issue.body }}
+ steps:
+ - uses: actions/checkout@v4
+ - run: echo "$GLOBAL_VALUE $JOB_VALUE"
+ - run: echo "$GLOBAL_VALUE $JOB_VALUE $STEP_VALUE"
+ env:
+ STEP_VALUE: ${{ github.actor }}
+
+ external:
+ uses: octo/example/.github/workflows/reusable.yml@main
+ with:
+ value: ${{ github.event.issue.number }}
diff --git a/actions/ql/test/library-tests/cfg-environment/test.expected b/actions/ql/test/library-tests/cfg-environment/test.expected
new file mode 100644
index 000000000000..21d55030e278
--- /dev/null
+++ b/actions/ql/test/library-tests/cfg-environment/test.expected
@@ -0,0 +1,5 @@
+envCfgNodes
+| .github/workflows/test.yml:4:18:4:48 | github.event.issue.title |
+| .github/workflows/test.yml:10:19:10:48 | github.event.issue.body |
+| .github/workflows/test.yml:16:24:16:42 | github.actor |
+cfgCycles
diff --git a/actions/ql/test/library-tests/cfg-environment/test.ql b/actions/ql/test/library-tests/cfg-environment/test.ql
new file mode 100644
index 000000000000..b4a94fa80bc6
--- /dev/null
+++ b/actions/ql/test/library-tests/cfg-environment/test.ql
@@ -0,0 +1,9 @@
+import codeql.actions.Ast
+import codeql.actions.Cfg as Cfg
+
+query predicate envCfgNodes(Expression expression) {
+ expression = any(Env env).getAnEnvVarExpr() and
+ exists(Cfg::AstCfgNode node | node.getAstNode() = expression)
+}
+
+query predicate cfgCycles(Cfg::Node node) { node.getASuccessor+() = node }
diff --git a/actions/ql/test/library-tests/reusable-workflow-callers/.github/workflows/caller.yml b/actions/ql/test/library-tests/reusable-workflow-callers/.github/workflows/caller.yml
new file mode 100644
index 000000000000..12f3016f5d07
--- /dev/null
+++ b/actions/ql/test/library-tests/reusable-workflow-callers/.github/workflows/caller.yml
@@ -0,0 +1,5 @@
+on: workflow_dispatch
+
+jobs:
+ call-reusable:
+ uses: ./.github/workflows/reusable.yml
\ No newline at end of file
diff --git a/actions/ql/test/library-tests/reusable-workflow-callers/.github/workflows/reusable.yml b/actions/ql/test/library-tests/reusable-workflow-callers/.github/workflows/reusable.yml
new file mode 100644
index 000000000000..f27aeb584fbd
--- /dev/null
+++ b/actions/ql/test/library-tests/reusable-workflow-callers/.github/workflows/reusable.yml
@@ -0,0 +1,7 @@
+on: workflow_call
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo build
\ No newline at end of file
diff --git a/actions/ql/test/library-tests/reusable-workflow-callers/test.expected b/actions/ql/test/library-tests/reusable-workflow-callers/test.expected
new file mode 100644
index 000000000000..4d2bad7a2bf1
--- /dev/null
+++ b/actions/ql/test/library-tests/reusable-workflow-callers/test.expected
@@ -0,0 +1 @@
+| .github/workflows/reusable.yml:1:1:7:23 | on: workflow_call | .github/workflows/caller.yml:5:5:5:42 | Job: call-reusable | .github/workflows/reusable.yml:5:5:7:23 | Job: build | workflow_dispatch |
diff --git a/actions/ql/test/library-tests/reusable-workflow-callers/test.ql b/actions/ql/test/library-tests/reusable-workflow-callers/test.ql
new file mode 100644
index 000000000000..544db1647332
--- /dev/null
+++ b/actions/ql/test/library-tests/reusable-workflow-callers/test.ql
@@ -0,0 +1,9 @@
+import actions
+
+from ReusableWorkflow workflow, ExternalJob caller, LocalJob job, Event event
+where
+ workflow.getACaller() = caller and
+ job.getEnclosingWorkflow() = workflow and
+ caller.getATriggerEvent() = event and
+ job.getATriggerEvent() = event
+select workflow, caller, job, event.getName()
diff --git a/rust/ql/test/library-tests/dataflow/sources/net/CONSISTENCY/PathResolutionConsistency.expected b/actions/ql/test/query-tests/Security/CWE-078/CONSISTENCY/CfgConsistency.expected
similarity index 100%
rename from rust/ql/test/library-tests/dataflow/sources/net/CONSISTENCY/PathResolutionConsistency.expected
rename to actions/ql/test/query-tests/Security/CWE-078/CONSISTENCY/CfgConsistency.expected
diff --git a/actions/ql/test/query-tests/Security/CWE-088/CONSISTENCY/CfgConsistency.expected b/actions/ql/test/query-tests/Security/CWE-088/CONSISTENCY/CfgConsistency.expected
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/actor_check_valid_event.yml b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/actor_check_valid_event.yml
new file mode 100644
index 000000000000..cd139700f078
--- /dev/null
+++ b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/actor_check_valid_event.yml
@@ -0,0 +1,12 @@
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ # The `if:` condition checks an actor field that is populated for
+ # `pull_request_target` events, so the injectable step is protected.
+ valid-actor-check:
+ runs-on: ubuntu-latest
+ if: github.event.pull_request.user.login == 'trusted-user'
+ steps:
+ - run: echo '${{ github.event.pull_request.title }}'
diff --git a/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/actor_check_wrong_event.yml b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/actor_check_wrong_event.yml
new file mode 100644
index 000000000000..982956b3d953
--- /dev/null
+++ b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/actor_check_wrong_event.yml
@@ -0,0 +1,46 @@
+on:
+ issues:
+ types: [opened]
+
+jobs:
+ # The `if:` condition compares an actor field that is never populated for
+ # `issues` events, so it is always true and does not protect the injectable step.
+ vacuous-actor-check:
+ runs-on: ubuntu-latest
+ if: github.event.pull_request.user.login != 'some-bot[bot]'
+ steps:
+ - run: echo '${{ github.event.issue.title }}'
+
+ # The `if:` condition checks an actor context that is populated for every
+ # event, so the injectable step is protected.
+ valid-actor-check:
+ runs-on: ubuntu-latest
+ if: github.actor == 'trusted-user'
+ steps:
+ - run: echo '${{ github.event.issue.title }}'
+
+ # The `sender` object is part of every webhook event payload, so this
+ # check is effective and the injectable step is protected.
+ valid-sender-check:
+ runs-on: ubuntu-latest
+ if: github.event.sender.login == 'trusted-user'
+ steps:
+ - run: echo '${{ github.event.issue.title }}'
+
+ # `github.event.head_commit` is only populated for `push` events, so this
+ # condition is always true for `issues` events and does not protect the
+ # injectable step.
+ vacuous-head-commit-check:
+ runs-on: ubuntu-latest
+ if: github.event.head_commit.author.name != 'some-bot'
+ steps:
+ - run: echo '${{ github.event.issue.title }}'
+
+ # `github.event.commits` is only populated for `push` events, so this
+ # condition is always true for `issues` events and does not protect the
+ # injectable step.
+ vacuous-commits-check:
+ runs-on: ubuntu-latest
+ if: github.event.commits[0].author.name != 'some-bot'
+ steps:
+ - run: echo '${{ github.event.issue.title }}'
diff --git a/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/association_check_wrong_event.yml b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/association_check_wrong_event.yml
new file mode 100644
index 000000000000..b1cef25955dd
--- /dev/null
+++ b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/association_check_wrong_event.yml
@@ -0,0 +1,21 @@
+on:
+ issues:
+ types: [opened]
+
+jobs:
+ # The `if:` condition compares an association field that is never populated
+ # for `issues` events, so it is always true and does not protect the
+ # injectable step.
+ vacuous-association-check:
+ runs-on: ubuntu-latest
+ if: github.event.pull_request.author_association != 'NONE'
+ steps:
+ - run: echo '${{ github.event.issue.title }}'
+
+ # `github.event.issue` is populated for `issues` events, so this check is
+ # effective and the injectable step is protected.
+ valid-association-check:
+ runs-on: ubuntu-latest
+ if: github.event.issue.author_association == 'MEMBER'
+ steps:
+ - run: echo '${{ github.event.issue.title }}'
diff --git a/actions/ql/test/query-tests/Security/CWE-094/CONSISTENCY/CfgConsistency.expected b/actions/ql/test/query-tests/Security/CWE-094/CONSISTENCY/CfgConsistency.expected
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected
index 02f7f68c05f4..e32155dffe93 100644
--- a/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected
+++ b/actions/ql/test/query-tests/Security/CWE-094/CodeInjectionCritical.expected
@@ -270,6 +270,12 @@ nodes
| .github/actions/external/ultralytics/actions/action.yaml:66:3:66:6 | input body | semmle.label | input body |
| .github/actions/external/ultralytics/actions/action.yaml:96:16:96:33 | inputs.body | semmle.label | inputs.body |
| .github/actions/external/ultralytics/actions/action.yaml:223:25:223:60 | github.head_ref \|\| github.ref | semmle.label | github.head_ref \|\| github.ref |
+| .github/workflows/actor_check_valid_event.yml:12:21:12:58 | github.event.pull_request.title | semmle.label | github.event.pull_request.title |
+| .github/workflows/actor_check_wrong_event.yml:12:21:12:51 | github.event.issue.title | semmle.label | github.event.issue.title |
+| .github/workflows/actor_check_wrong_event.yml:20:21:20:51 | github.event.issue.title | semmle.label | github.event.issue.title |
+| .github/workflows/actor_check_wrong_event.yml:28:21:28:51 | github.event.issue.title | semmle.label | github.event.issue.title |
+| .github/workflows/actor_check_wrong_event.yml:37:21:37:51 | github.event.issue.title | semmle.label | github.event.issue.title |
+| .github/workflows/actor_check_wrong_event.yml:46:21:46:51 | github.event.issue.title | semmle.label | github.event.issue.title |
| .github/workflows/argus_case_study.yml:15:9:24:6 | Uses Step: remove_quotations [replaced] | semmle.label | Uses Step: remove_quotations [replaced] |
| .github/workflows/argus_case_study.yml:17:25:17:53 | github.event.issue.title | semmle.label | github.event.issue.title |
| .github/workflows/argus_case_study.yml:22:20:22:39 | env.ISSUE_TITLE | semmle.label | env.ISSUE_TITLE |
@@ -306,6 +312,8 @@ nodes
| .github/workflows/artifactpoisoning8.yml:17:9:21:6 | Run Step: artifact [id] | semmle.label | Run Step: artifact [id] |
| .github/workflows/artifactpoisoning8.yml:19:14:19:58 | echo "::set-output name=id::$(
diff --git a/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/exprs.ql b/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/exprs.ql
new file mode 100644
index 000000000000..3af03b1d60b2
--- /dev/null
+++ b/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/exprs.ql
@@ -0,0 +1,17 @@
+class Expr extends @expr {
+ string toString() { none() }
+}
+
+class Location extends @location_default {
+ string toString() { none() }
+}
+
+predicate isExprWithNewBuiltin(Expr expr) {
+ exists(int kind | exprs(expr, kind, _) | 397 <= kind and kind <= 403)
+}
+
+from Expr expr, int kind, int kind_new, Location location
+where
+ exprs(expr, kind, location) and
+ if isExprWithNewBuiltin(expr) then kind_new = 1 else kind_new = kind
+select expr, kind_new, location
diff --git a/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/old.dbscheme b/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/old.dbscheme
new file mode 100644
index 000000000000..293904928d85
--- /dev/null
+++ b/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/old.dbscheme
@@ -0,0 +1,2602 @@
+
+/*- Compilations -*/
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- Diagnostic messages -*/
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+/*- C++ dbscheme -*/
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+/**
+ * Gives the TRAP filename that `trap` is associated with.
+ * For debugging only.
+ */
+trap_filename(
+ int trap: @trap,
+ string filename: string ref
+);
+
+/**
+ * Gives the tag name for `tag`.
+ * For debugging only.
+ */
+tag_name(
+ int tag: @tag,
+ string name: string ref
+);
+
+@trap_or_tag = @tag | @trap;
+
+/**
+ * Gives the name for the source file.
+ */
+source_file_name(
+ int sf: @source_file,
+ string name: string ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that `source_file`
+ * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the
+ * TRAP file corresponding to `foo.c`, something it transitively
+ * includes, or a template instantiation it transitively uses.
+ */
+source_file_uses_trap(
+ int source_file: @source_file ref,
+ int trap_file: @trap ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that the TRAP file
+ * `trap_file` uses tag `tag`.
+ */
+trap_uses_tag(
+ int trap_file: @trap ref,
+ int tag: @tag ref
+);
+
+/**
+ * Holds if there is a definition of `element` in TRAP file or tag `t`.
+ */
+in_trap_or_tag(
+ int element: @element ref,
+ int t: @trap_or_tag ref
+);
+
+pch_uses(
+ int pch: @pch ref,
+ int compilation: @compilation ref,
+ int id: @file ref
+)
+
+#keyset[pch, compilation]
+pch_creations(
+ int pch: @pch,
+ int compilation: @compilation ref,
+ int from: @file ref
+)
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location_default ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+case @function.kind of
+ 0 = @unknown_function
+| 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+builtin_functions(
+ int id: @function ref
+)
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+// ... 40 _Decimal32
+// ... 41 _Decimal64
+// ... 42 _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+| 63 = @scalable_vector_count // __SVCount_t
+| 64 = @complex_fp16 // _Complex __fp16
+| 65 = @complex_std_bfloat16 // _Complex __bf16
+| 66 = @complex_std_float16 // _Complex std::float16_t
+| 67 = @bit_precise_int // _BitInt(N)
+| 68 = @unsigned_bit_precise_int // unsigned _BitInt(N)
+| 69 = @signed_bit_precise_int // signed _BitInt(N)
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+bit_precise_int_types(
+ unique int id: @builtintype ref,
+ int bit_width: int ref
+)
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+| 11 = @scalable_vector // Arm SVE
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(
+ unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+tupleelements(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+case @type_operator.kind of
+ 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+case @usertype.kind of
+ 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+class_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+)
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location_default ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+function_template_generated_from(
+ unique int template: @function ref,
+ int from: @function ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+variable_template_generated_from(
+ unique int template: @variable ref,
+ int from: @variable ref
+);
+
+is_alias_template(unique int id: @usertype ref);
+alias_instantiation(
+ unique int to: @usertype ref,
+ int from: @usertype ref
+);
+alias_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+alias_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+alias_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+namespaceattributes(
+ int namespace_id: @namespace ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype
+ | @decltype
+ | @derivedtype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_default ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+| 394 = @isinvocable
+| 395 = @isnothrowinvocable
+| 396 = @isbitwisecloneable
+| 397 = @isvirtualbaseof
+| 398 = @isimplicitlifetime
+| 399 = @ltsynthesizesfromspaceship
+| 400 = @gtsynthesizesfromspaceship
+| 401 = @lesynthesizesfromspaceship
+| 402 = @gesynthesizesfromspaceship
+| 403 = @isstructural
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ | @isinvocable
+ | @isnothrowinvocable
+ | @isbitwisecloneable
+ | @isvirtualbaseof
+ | @isimplicitlifetime
+ | @ltsynthesizesfromspaceship
+ | @gtsynthesizesfromspaceship
+ | @lesynthesizesfromspaceship
+ | @gesynthesizesfromspaceship
+ | @isstructural
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+param_ref_to_this(
+ int expr: @param_ref ref
+)
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 17 = @ppd_embed
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+embeds(
+ unique int id: @ppd_embed ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- Database metadata -*/
+
+/**
+ * The CLI will automatically emit applicable tuples for this table,
+ * such as `databaseMetadata("isOverlay", "true")` when building an
+ * overlay database.
+ */
+databaseMetadata(
+ string metadataKey: string ref,
+ string value: string ref
+);
+
+/*- Overlay support -*/
+
+/**
+ * The CLI will automatically emit tuples for each new/modified/deleted file
+ * when building an overlay database.
+ */
+overlayChangedFiles(
+ string path: string ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/semmlecode.cpp.dbscheme b/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..6aec212e408f
--- /dev/null
+++ b/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/semmlecode.cpp.dbscheme
@@ -0,0 +1,2588 @@
+
+/*- Compilations -*/
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- Diagnostic messages -*/
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+/*- C++ dbscheme -*/
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+/**
+ * Gives the TRAP filename that `trap` is associated with.
+ * For debugging only.
+ */
+trap_filename(
+ int trap: @trap,
+ string filename: string ref
+);
+
+/**
+ * Gives the tag name for `tag`.
+ * For debugging only.
+ */
+tag_name(
+ int tag: @tag,
+ string name: string ref
+);
+
+@trap_or_tag = @tag | @trap;
+
+/**
+ * Gives the name for the source file.
+ */
+source_file_name(
+ int sf: @source_file,
+ string name: string ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that `source_file`
+ * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the
+ * TRAP file corresponding to `foo.c`, something it transitively
+ * includes, or a template instantiation it transitively uses.
+ */
+source_file_uses_trap(
+ int source_file: @source_file ref,
+ int trap_file: @trap ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that the TRAP file
+ * `trap_file` uses tag `tag`.
+ */
+trap_uses_tag(
+ int trap_file: @trap ref,
+ int tag: @tag ref
+);
+
+/**
+ * Holds if there is a definition of `element` in TRAP file or tag `t`.
+ */
+in_trap_or_tag(
+ int element: @element ref,
+ int t: @trap_or_tag ref
+);
+
+pch_uses(
+ int pch: @pch ref,
+ int compilation: @compilation ref,
+ int id: @file ref
+)
+
+#keyset[pch, compilation]
+pch_creations(
+ int pch: @pch,
+ int compilation: @compilation ref,
+ int from: @file ref
+)
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location_default ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+case @function.kind of
+ 0 = @unknown_function
+| 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+builtin_functions(
+ int id: @function ref
+)
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+// ... 40 _Decimal32
+// ... 41 _Decimal64
+// ... 42 _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+| 63 = @scalable_vector_count // __SVCount_t
+| 64 = @complex_fp16 // _Complex __fp16
+| 65 = @complex_std_bfloat16 // _Complex __bf16
+| 66 = @complex_std_float16 // _Complex std::float16_t
+| 67 = @bit_precise_int // _BitInt(N)
+| 68 = @unsigned_bit_precise_int // unsigned _BitInt(N)
+| 69 = @signed_bit_precise_int // signed _BitInt(N)
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+bit_precise_int_types(
+ unique int id: @builtintype ref,
+ int bit_width: int ref
+)
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+| 11 = @scalable_vector // Arm SVE
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(
+ unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+tupleelements(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+case @type_operator.kind of
+ 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+case @usertype.kind of
+ 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+class_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+)
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location_default ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+function_template_generated_from(
+ unique int template: @function ref,
+ int from: @function ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+variable_template_generated_from(
+ unique int template: @variable ref,
+ int from: @variable ref
+);
+
+is_alias_template(unique int id: @usertype ref);
+alias_instantiation(
+ unique int to: @usertype ref,
+ int from: @usertype ref
+);
+alias_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+alias_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+alias_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+namespaceattributes(
+ int namespace_id: @namespace ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype
+ | @decltype
+ | @derivedtype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_default ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+| 394 = @isinvocable
+| 395 = @isnothrowinvocable
+| 396 = @isbitwisecloneable
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ | @isinvocable
+ | @isnothrowinvocable
+ | @isbitwisecloneable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+param_ref_to_this(
+ int expr: @param_ref ref
+)
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 17 = @ppd_embed
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+embeds(
+ unique int id: @ppd_embed ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- Database metadata -*/
+
+/**
+ * The CLI will automatically emit applicable tuples for this table,
+ * such as `databaseMetadata("isOverlay", "true")` when building an
+ * overlay database.
+ */
+databaseMetadata(
+ string metadataKey: string ref,
+ string value: string ref
+);
+
+/*- Overlay support -*/
+
+/**
+ * The CLI will automatically emit tuples for each new/modified/deleted file
+ * when building an overlay database.
+ */
+overlayChangedFiles(
+ string path: string ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/upgrade.properties b/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/upgrade.properties
new file mode 100644
index 000000000000..d697a16a42fd
--- /dev/null
+++ b/cpp/downgrades/293904928d857b61a44dc0ff34c89c9eccb8a90a/upgrade.properties
@@ -0,0 +1,3 @@
+description: Add new builtin operations
+compatibility: partial
+exprs.rel: run exprs.qlo
diff --git a/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/builtintypes.ql b/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/builtintypes.ql
new file mode 100644
index 000000000000..2ad09def291c
--- /dev/null
+++ b/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/builtintypes.ql
@@ -0,0 +1,9 @@
+class BuiltInType extends @builtintype {
+ string toString() { none() }
+}
+
+from BuiltInType type, string name, int kind, int kind_new, int size, int sign, int alignment
+where
+ builtintypes(type, name, kind, size, sign, alignment) and
+ if kind in [67, 68, 69] then kind_new = 1 else kind_new = kind
+select type, name, kind_new, size, sign, alignment
diff --git a/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/old.dbscheme b/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/old.dbscheme
new file mode 100644
index 000000000000..6aec212e408f
--- /dev/null
+++ b/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/old.dbscheme
@@ -0,0 +1,2588 @@
+
+/*- Compilations -*/
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- Diagnostic messages -*/
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+/*- C++ dbscheme -*/
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+/**
+ * Gives the TRAP filename that `trap` is associated with.
+ * For debugging only.
+ */
+trap_filename(
+ int trap: @trap,
+ string filename: string ref
+);
+
+/**
+ * Gives the tag name for `tag`.
+ * For debugging only.
+ */
+tag_name(
+ int tag: @tag,
+ string name: string ref
+);
+
+@trap_or_tag = @tag | @trap;
+
+/**
+ * Gives the name for the source file.
+ */
+source_file_name(
+ int sf: @source_file,
+ string name: string ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that `source_file`
+ * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the
+ * TRAP file corresponding to `foo.c`, something it transitively
+ * includes, or a template instantiation it transitively uses.
+ */
+source_file_uses_trap(
+ int source_file: @source_file ref,
+ int trap_file: @trap ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that the TRAP file
+ * `trap_file` uses tag `tag`.
+ */
+trap_uses_tag(
+ int trap_file: @trap ref,
+ int tag: @tag ref
+);
+
+/**
+ * Holds if there is a definition of `element` in TRAP file or tag `t`.
+ */
+in_trap_or_tag(
+ int element: @element ref,
+ int t: @trap_or_tag ref
+);
+
+pch_uses(
+ int pch: @pch ref,
+ int compilation: @compilation ref,
+ int id: @file ref
+)
+
+#keyset[pch, compilation]
+pch_creations(
+ int pch: @pch,
+ int compilation: @compilation ref,
+ int from: @file ref
+)
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location_default ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+case @function.kind of
+ 0 = @unknown_function
+| 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+builtin_functions(
+ int id: @function ref
+)
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+// ... 40 _Decimal32
+// ... 41 _Decimal64
+// ... 42 _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+| 63 = @scalable_vector_count // __SVCount_t
+| 64 = @complex_fp16 // _Complex __fp16
+| 65 = @complex_std_bfloat16 // _Complex __bf16
+| 66 = @complex_std_float16 // _Complex std::float16_t
+| 67 = @bit_precise_int // _BitInt(N)
+| 68 = @unsigned_bit_precise_int // unsigned _BitInt(N)
+| 69 = @signed_bit_precise_int // signed _BitInt(N)
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+bit_precise_int_types(
+ unique int id: @builtintype ref,
+ int bit_width: int ref
+)
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+| 11 = @scalable_vector // Arm SVE
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(
+ unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+tupleelements(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+case @type_operator.kind of
+ 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+case @usertype.kind of
+ 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+class_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+)
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location_default ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+function_template_generated_from(
+ unique int template: @function ref,
+ int from: @function ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+variable_template_generated_from(
+ unique int template: @variable ref,
+ int from: @variable ref
+);
+
+is_alias_template(unique int id: @usertype ref);
+alias_instantiation(
+ unique int to: @usertype ref,
+ int from: @usertype ref
+);
+alias_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+alias_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+alias_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+namespaceattributes(
+ int namespace_id: @namespace ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype
+ | @decltype
+ | @derivedtype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_default ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+| 394 = @isinvocable
+| 395 = @isnothrowinvocable
+| 396 = @isbitwisecloneable
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ | @isinvocable
+ | @isnothrowinvocable
+ | @isbitwisecloneable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+param_ref_to_this(
+ int expr: @param_ref ref
+)
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 17 = @ppd_embed
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+embeds(
+ unique int id: @ppd_embed ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- Database metadata -*/
+
+/**
+ * The CLI will automatically emit applicable tuples for this table,
+ * such as `databaseMetadata("isOverlay", "true")` when building an
+ * overlay database.
+ */
+databaseMetadata(
+ string metadataKey: string ref,
+ string value: string ref
+);
+
+/*- Overlay support -*/
+
+/**
+ * The CLI will automatically emit tuples for each new/modified/deleted file
+ * when building an overlay database.
+ */
+overlayChangedFiles(
+ string path: string ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/semmlecode.cpp.dbscheme b/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..0853f43dc8c0
--- /dev/null
+++ b/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/semmlecode.cpp.dbscheme
@@ -0,0 +1,2578 @@
+
+/*- Compilations -*/
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- Diagnostic messages -*/
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+/*- C++ dbscheme -*/
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+/**
+ * Gives the TRAP filename that `trap` is associated with.
+ * For debugging only.
+ */
+trap_filename(
+ int trap: @trap,
+ string filename: string ref
+);
+
+/**
+ * Gives the tag name for `tag`.
+ * For debugging only.
+ */
+tag_name(
+ int tag: @tag,
+ string name: string ref
+);
+
+@trap_or_tag = @tag | @trap;
+
+/**
+ * Gives the name for the source file.
+ */
+source_file_name(
+ int sf: @source_file,
+ string name: string ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that `source_file`
+ * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the
+ * TRAP file corresponding to `foo.c`, something it transitively
+ * includes, or a template instantiation it transitively uses.
+ */
+source_file_uses_trap(
+ int source_file: @source_file ref,
+ int trap_file: @trap ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that the TRAP file
+ * `trap_file` uses tag `tag`.
+ */
+trap_uses_tag(
+ int trap_file: @trap ref,
+ int tag: @tag ref
+);
+
+/**
+ * Holds if there is a definition of `element` in TRAP file or tag `t`.
+ */
+in_trap_or_tag(
+ int element: @element ref,
+ int t: @trap_or_tag ref
+);
+
+pch_uses(
+ int pch: @pch ref,
+ int compilation: @compilation ref,
+ int id: @file ref
+)
+
+#keyset[pch, compilation]
+pch_creations(
+ int pch: @pch,
+ int compilation: @compilation ref,
+ int from: @file ref
+)
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location_default ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+case @function.kind of
+ 0 = @unknown_function
+| 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+builtin_functions(
+ int id: @function ref
+)
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+// ... 40 _Decimal32
+// ... 41 _Decimal64
+// ... 42 _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+| 63 = @scalable_vector_count // __SVCount_t
+| 64 = @complex_fp16 // _Complex __fp16
+| 65 = @complex_std_bfloat16 // _Complex __bf16
+| 66 = @complex_std_float16 // _Complex std::float16_t
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+| 11 = @scalable_vector // Arm SVE
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+tupleelements(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+case @type_operator.kind of
+ 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+case @usertype.kind of
+ 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+class_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+)
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location_default ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+function_template_generated_from(
+ unique int template: @function ref,
+ int from: @function ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+variable_template_generated_from(
+ unique int template: @variable ref,
+ int from: @variable ref
+);
+
+is_alias_template(unique int id: @usertype ref);
+alias_instantiation(
+ unique int to: @usertype ref,
+ int from: @usertype ref
+);
+alias_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+alias_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+alias_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+namespaceattributes(
+ int namespace_id: @namespace ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype
+ | @decltype
+ | @derivedtype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_default ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+| 394 = @isinvocable
+| 395 = @isnothrowinvocable
+| 396 = @isbitwisecloneable
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ | @isinvocable
+ | @isnothrowinvocable
+ | @isbitwisecloneable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+param_ref_to_this(
+ int expr: @param_ref ref
+)
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 17 = @ppd_embed
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+embeds(
+ unique int id: @ppd_embed ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- Database metadata -*/
+
+/**
+ * The CLI will automatically emit applicable tuples for this table,
+ * such as `databaseMetadata("isOverlay", "true")` when building an
+ * overlay database.
+ */
+databaseMetadata(
+ string metadataKey: string ref,
+ string value: string ref
+);
+
+/*- Overlay support -*/
+
+/**
+ * The CLI will automatically emit tuples for each new/modified/deleted file
+ * when building an overlay database.
+ */
+overlayChangedFiles(
+ string path: string ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/upgrade.properties b/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/upgrade.properties
new file mode 100644
index 000000000000..f387b03144f0
--- /dev/null
+++ b/cpp/downgrades/6aec212e408fad907b19368a3376a4d9837783d2/upgrade.properties
@@ -0,0 +1,4 @@
+description: Support C23 _BitInt
+compatibility: full
+bit_precise_int_types.rel: delete
+builtintypes.rel: run builtintypes.qlo
diff --git a/cpp/ql/integration-tests/query-suite/cpp-code-quality-extended.qls.expected b/cpp/ql/integration-tests/query-suite/cpp-code-quality-extended.qls.expected
index 8b137891791f..207617d4ac06 100644
--- a/cpp/ql/integration-tests/query-suite/cpp-code-quality-extended.qls.expected
+++ b/cpp/ql/integration-tests/query-suite/cpp-code-quality-extended.qls.expected
@@ -1 +1,45 @@
-
+ql/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql
+ql/cpp/ql/src/Best Practices/ComplexCondition.ql
+ql/cpp/ql/src/Best Practices/Exceptions/AccidentalRethrow.ql
+ql/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.ql
+ql/cpp/ql/src/Best Practices/Exceptions/LeakyCatch.ql
+ql/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.ql
+ql/cpp/ql/src/Best Practices/GuardedFree.ql
+ql/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.ql
+ql/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql
+ql/cpp/ql/src/Best Practices/Likely Errors/Slicing.ql
+ql/cpp/ql/src/Best Practices/RuleOfTwo.ql
+ql/cpp/ql/src/Best Practices/UseOfGoto.ql
+ql/cpp/ql/src/Critical/LargeParameter.ql
+ql/cpp/ql/src/Critical/NewArrayDeleteMismatch.ql
+ql/cpp/ql/src/Critical/NewDeleteArrayMismatch.ql
+ql/cpp/ql/src/Documentation/FixmeComments.ql
+ql/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/BitwiseSignCheck.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/FloatComparison.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/UnsignedGEZero.ql
+ql/cpp/ql/src/Likely Bugs/ContinueInFalseLoop.ql
+ql/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.ql
+ql/cpp/ql/src/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql
+ql/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/DubiousNullCheck.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql
+ql/cpp/ql/src/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString.ql
+ql/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.ql
+ql/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructorInBaseClass.ql
+ql/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.ql
+ql/cpp/ql/src/Likely Bugs/ReturnConstTypeMember.ql
+ql/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql
+ql/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
+ql/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql
+ql/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql
+ql/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
+ql/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql
diff --git a/cpp/ql/integration-tests/query-suite/cpp-code-quality.qls.expected b/cpp/ql/integration-tests/query-suite/cpp-code-quality.qls.expected
index 8b137891791f..207617d4ac06 100644
--- a/cpp/ql/integration-tests/query-suite/cpp-code-quality.qls.expected
+++ b/cpp/ql/integration-tests/query-suite/cpp-code-quality.qls.expected
@@ -1 +1,45 @@
-
+ql/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql
+ql/cpp/ql/src/Best Practices/ComplexCondition.ql
+ql/cpp/ql/src/Best Practices/Exceptions/AccidentalRethrow.ql
+ql/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.ql
+ql/cpp/ql/src/Best Practices/Exceptions/LeakyCatch.ql
+ql/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.ql
+ql/cpp/ql/src/Best Practices/GuardedFree.ql
+ql/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.ql
+ql/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql
+ql/cpp/ql/src/Best Practices/Likely Errors/Slicing.ql
+ql/cpp/ql/src/Best Practices/RuleOfTwo.ql
+ql/cpp/ql/src/Best Practices/UseOfGoto.ql
+ql/cpp/ql/src/Critical/LargeParameter.ql
+ql/cpp/ql/src/Critical/NewArrayDeleteMismatch.ql
+ql/cpp/ql/src/Critical/NewDeleteArrayMismatch.ql
+ql/cpp/ql/src/Documentation/FixmeComments.ql
+ql/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/BitwiseSignCheck.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/FloatComparison.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
+ql/cpp/ql/src/Likely Bugs/Arithmetic/UnsignedGEZero.ql
+ql/cpp/ql/src/Likely Bugs/ContinueInFalseLoop.ql
+ql/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.ql
+ql/cpp/ql/src/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql
+ql/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/DubiousNullCheck.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql
+ql/cpp/ql/src/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString.ql
+ql/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.ql
+ql/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructorInBaseClass.ql
+ql/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.ql
+ql/cpp/ql/src/Likely Bugs/ReturnConstTypeMember.ql
+ql/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql
+ql/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
+ql/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql
+ql/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql
+ql/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
+ql/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.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 cb4e5f7b305a..17ebac8ee50c 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
@@ -65,6 +65,7 @@ ql/cpp/ql/src/Likely Bugs/InconsistentCheckReturnNull.ql
ql/cpp/ql/src/Likely Bugs/Leap Year/Adding365DaysPerYear.ql
ql/cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql
ql/cpp/ql/src/Likely Bugs/Leap Year/UncheckedReturnValueForTimeFunctions.ql
+ql/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.ql
ql/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql
ql/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql
ql/cpp/ql/src/Likely Bugs/Likely Typos/DubiousNullCheck.ql
diff --git a/cpp/ql/integration-tests/query-suite/not_included_in_qls.expected b/cpp/ql/integration-tests/query-suite/not_included_in_qls.expected
index 20ffa7c40c0d..70affad11648 100644
--- a/cpp/ql/integration-tests/query-suite/not_included_in_qls.expected
+++ b/cpp/ql/integration-tests/query-suite/not_included_in_qls.expected
@@ -242,6 +242,7 @@ ql/cpp/ql/src/experimental/Security/CWE/CWE-078/WordexpTainted.ql
ql/cpp/ql/src/experimental/Security/CWE/CWE-1041/FindWrapperFunctions.ql
ql/cpp/ql/src/experimental/Security/CWE/CWE-1126/DeclarationOfVariableWithUnnecessarilyWideScope.ql
ql/cpp/ql/src/experimental/Security/CWE/CWE-120/MemoryUnsafeFunctionScan.ql
+ql/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpy.ql
ql/cpp/ql/src/experimental/Security/CWE/CWE-1240/CustomCryptographicPrimitive.ql
ql/cpp/ql/src/experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql
ql/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql
diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md
index f5f7d195fa61..512af6062bf3 100644
--- a/cpp/ql/lib/CHANGELOG.md
+++ b/cpp/ql/lib/CHANGELOG.md
@@ -1,3 +1,61 @@
+## 12.4.0
+
+### New Features
+
+* Added support for the `__builtin_lt_synthesizes_from_spaceship`, `__builtin_gt_synthesizes_from_spaceship`, `__builtin_le_synthesizes_from_spaceship`, `__builtin_ge_synthesizes_from_spaceship`, `__builtin_is_implicit_lifetime`, `__builtin_is_structural`, and `__builtin_is_virtual_base_of` builtin operations.
+* Added a new predicate `getBitWidth` to the `Type` class, which yields the bit-width of the type.
+
+## 12.3.0
+
+### New Features
+
+* Added support for C23 bit-precise integers (`_BitInt(N)`).
+
+### Minor Analysis Improvements
+
+* Added flow summaries for the BlazingMQ `BloombergLP::bmqa::Message` and `MessageProperties` classes and their iterators.
+
+## 12.2.0
+
+### New Features
+
+* Added a C++ regular-expression parser for the ECMAScript grammar used by `std::regex`.
+
+### Minor Analysis Improvements
+
+* Added SQL-injection sink models for the Comdb2 C API functions `cdb2_run_statement` and `cdb2_run_statement_typed`.
+* Added flow summaries for the BDE codecs `BloombergLP::balber::BerDecoder`/`BerEncoder`, `BloombergLP::baljsn::Decoder`/`Encoder` and `BloombergLP::balxml::Decoder`/`Encoder`.
+* Added taint flow summaries for the BDE `bslx` byte-stream deserializers `BloombergLP::bslx::ByteInStream`, `BloombergLP::bslx::GenericInStream`, and `BloombergLP::bslx::InStreamFunctions::bdexStreamIn`.
+
+## 12.1.1
+
+### Minor Analysis Improvements
+
+* Added taint flow models for the `boost::asio::ip::basic_resolver::resolve` function.
+* Added flow summaries for the BDE `BloombergLP::bdlbb::Blob` segmented byte buffer.
+* Added flow summaries for the Protocol Buffers `google::protobuf::MessageLite` C++ API.
+
+## 12.1.0
+
+### New Features
+
+* Sources and sinks defined using models-as-data now support access paths with fields. For example, the path `ReturnValue.Field[S::f]` makes the field `S::f` a flow source when it is returned by a call.
+
+### Minor Analysis Improvements
+
+* Added the PostgreSQL libpq (asynchronous) query-execution functions `PQexec`, `PQexecParams`, `PQprepare`, `PQsendQuery`, `PQsendQueryParams`, `PQsendPrepare` as `sql-injection` sinks.
+* Initializers of compiler-generated variables are now recognized as compiler-generated. A new predicate `isCompilerGenerated` on `Initializer` has been added to reflect this.
+
+## 12.0.3
+
+No user-facing changes.
+
+## 12.0.2
+
+### Minor Analysis Improvements
+
+* Added flow source models for `RegQueryValue` and related functions from the `winreg.h` Windows header.
+
## 12.0.1
No user-facing changes.
diff --git a/cpp/ql/lib/change-notes/2026-07-28-winreg-sources.md b/cpp/ql/lib/change-notes/2026-07-28-winreg-sources.md
deleted file mode 100644
index 9a70926b9984..000000000000
--- a/cpp/ql/lib/change-notes/2026-07-28-winreg-sources.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-category: minorAnalysis
----
-* Added flow source models for `RegQueryValue` and related functions from the `winreg.h` Windows header.
\ No newline at end of file
diff --git a/cpp/ql/lib/change-notes/released/12.0.2.md b/cpp/ql/lib/change-notes/released/12.0.2.md
new file mode 100644
index 000000000000..cecfb536211f
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/12.0.2.md
@@ -0,0 +1,5 @@
+## 12.0.2
+
+### Minor Analysis Improvements
+
+* Added flow source models for `RegQueryValue` and related functions from the `winreg.h` Windows header.
diff --git a/cpp/ql/lib/change-notes/released/12.0.3.md b/cpp/ql/lib/change-notes/released/12.0.3.md
new file mode 100644
index 000000000000..b86eecea8b6d
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/12.0.3.md
@@ -0,0 +1,3 @@
+## 12.0.3
+
+No user-facing changes.
diff --git a/cpp/ql/lib/change-notes/released/12.1.0.md b/cpp/ql/lib/change-notes/released/12.1.0.md
new file mode 100644
index 000000000000..a56939e92a70
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/12.1.0.md
@@ -0,0 +1,10 @@
+## 12.1.0
+
+### New Features
+
+* Sources and sinks defined using models-as-data now support access paths with fields. For example, the path `ReturnValue.Field[S::f]` makes the field `S::f` a flow source when it is returned by a call.
+
+### Minor Analysis Improvements
+
+* Added the PostgreSQL libpq (asynchronous) query-execution functions `PQexec`, `PQexecParams`, `PQprepare`, `PQsendQuery`, `PQsendQueryParams`, `PQsendPrepare` as `sql-injection` sinks.
+* Initializers of compiler-generated variables are now recognized as compiler-generated. A new predicate `isCompilerGenerated` on `Initializer` has been added to reflect this.
diff --git a/cpp/ql/lib/change-notes/released/12.1.1.md b/cpp/ql/lib/change-notes/released/12.1.1.md
new file mode 100644
index 000000000000..9f0cb4c5ad36
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/12.1.1.md
@@ -0,0 +1,7 @@
+## 12.1.1
+
+### Minor Analysis Improvements
+
+* Added taint flow models for the `boost::asio::ip::basic_resolver::resolve` function.
+* Added flow summaries for the BDE `BloombergLP::bdlbb::Blob` segmented byte buffer.
+* Added flow summaries for the Protocol Buffers `google::protobuf::MessageLite` C++ API.
diff --git a/cpp/ql/lib/change-notes/released/12.2.0.md b/cpp/ql/lib/change-notes/released/12.2.0.md
new file mode 100644
index 000000000000..63340c0ee4a4
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/12.2.0.md
@@ -0,0 +1,11 @@
+## 12.2.0
+
+### New Features
+
+* Added a C++ regular-expression parser for the ECMAScript grammar used by `std::regex`.
+
+### Minor Analysis Improvements
+
+* Added SQL-injection sink models for the Comdb2 C API functions `cdb2_run_statement` and `cdb2_run_statement_typed`.
+* Added flow summaries for the BDE codecs `BloombergLP::balber::BerDecoder`/`BerEncoder`, `BloombergLP::baljsn::Decoder`/`Encoder` and `BloombergLP::balxml::Decoder`/`Encoder`.
+* Added taint flow summaries for the BDE `bslx` byte-stream deserializers `BloombergLP::bslx::ByteInStream`, `BloombergLP::bslx::GenericInStream`, and `BloombergLP::bslx::InStreamFunctions::bdexStreamIn`.
diff --git a/cpp/ql/lib/change-notes/released/12.3.0.md b/cpp/ql/lib/change-notes/released/12.3.0.md
new file mode 100644
index 000000000000..d2527bb761f2
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/12.3.0.md
@@ -0,0 +1,9 @@
+## 12.3.0
+
+### New Features
+
+* Added support for C23 bit-precise integers (`_BitInt(N)`).
+
+### Minor Analysis Improvements
+
+* Added flow summaries for the BlazingMQ `BloombergLP::bmqa::Message` and `MessageProperties` classes and their iterators.
diff --git a/cpp/ql/lib/change-notes/released/12.4.0.md b/cpp/ql/lib/change-notes/released/12.4.0.md
new file mode 100644
index 000000000000..6467dc2b9381
--- /dev/null
+++ b/cpp/ql/lib/change-notes/released/12.4.0.md
@@ -0,0 +1,6 @@
+## 12.4.0
+
+### New Features
+
+* Added support for the `__builtin_lt_synthesizes_from_spaceship`, `__builtin_gt_synthesizes_from_spaceship`, `__builtin_le_synthesizes_from_spaceship`, `__builtin_ge_synthesizes_from_spaceship`, `__builtin_is_implicit_lifetime`, `__builtin_is_structural`, and `__builtin_is_virtual_base_of` builtin operations.
+* Added a new predicate `getBitWidth` to the `Type` class, which yields the bit-width of the type.
diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml
index 95ce69d8d492..6514beb79b03 100644
--- a/cpp/ql/lib/codeql-pack.release.yml
+++ b/cpp/ql/lib/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 12.0.1
+lastReleaseVersion: 12.4.0
diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/ConstantShiftExprRange.qll b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/ConstantShiftExprRange.qll
index 3f300d7aa8d6..0f7e1ce5ed40 100644
--- a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/ConstantShiftExprRange.qll
+++ b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/ConstantShiftExprRange.qll
@@ -21,7 +21,7 @@ bindingset[val]
private predicate isValidShiftExprShift(float val, Expr l) {
val >= 0 and
// We use getFullyConverted because the spec says to use the *promoted* left operand
- val < (l.getFullyConverted().getUnderlyingType().getSize() * 8)
+ val < l.getFullyConverted().getUnderlyingType().getBitWidth()
}
bindingset[val, shift, max_val]
diff --git a/cpp/ql/lib/ext/Boost.Asio.model.yml b/cpp/ql/lib/ext/Boost.Asio.model.yml
index f6ba957d2596..eb6728af4124 100644
--- a/cpp/ql/lib/ext/Boost.Asio.model.yml
+++ b/cpp/ql/lib/ext/Boost.Asio.model.yml
@@ -23,3 +23,19 @@ extensions:
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
- ["boost::asio", "", False, "buffer", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const string &,const string &)", "", "Argument[*0..1]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const string &,const string &,error_code &)", "", "Argument[*0..1]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const string &,const string &,flags)", "", "Argument[*0..1]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const string &,const string &,flags,error_code &)", "", "Argument[*0..1]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(string_view,string_view)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(string_view,string_view,error_code &)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(string_view,string_view,flags)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(string_view,string_view,flags,error_code &)", "", "Argument[0..1]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const InternetProtocol &,const string &,const string &)", "", "Argument[*1..2]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const InternetProtocol &,const string &,const string &,error_code &)", "", "Argument[*1..2]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const InternetProtocol &,const string &,const string &,flags)", "", "Argument[*1..2]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const InternetProtocol &,const string &,const string &,flags,error_code &)", "", "Argument[*1..2]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const InternetProtocol &,string_view,string_view)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const InternetProtocol &,string_view,string_view,error_code &)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const InternetProtocol &,string_view,string_view,flags)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"]
+ - ["boost::asio::ip", "basic_resolver", False, "resolve", "(const InternetProtocol &,string_view,string_view,flags,error_code &)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"]
\ No newline at end of file
diff --git a/cpp/ql/lib/ext/Comdb2.model.yml b/cpp/ql/lib/ext/Comdb2.model.yml
new file mode 100644
index 000000000000..7edcab128ce2
--- /dev/null
+++ b/cpp/ql/lib/ext/Comdb2.model.yml
@@ -0,0 +1,11 @@
+# Partial model of the Comdb2 C API.
+# https://bloomberg.github.io/comdb2/c_api.html
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: sinkModel
+ data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
+ # Both functions interpret the second argument as SQL. The typed variant
+ # specifies result-column types; bound parameter values are passed separately.
+ - ["", "", False, "cdb2_run_statement", "", "", "Argument[*1]", "sql-injection", "manual"]
+ - ["", "", False, "cdb2_run_statement_typed", "", "", "Argument[*1]", "sql-injection", "manual"]
diff --git a/cpp/ql/lib/ext/Postgres.model.yml b/cpp/ql/lib/ext/Postgres.model.yml
new file mode 100644
index 000000000000..5c977ebc5756
--- /dev/null
+++ b/cpp/ql/lib/ext/Postgres.model.yml
@@ -0,0 +1,16 @@
+# partial model of the PostgreSQL libpq C API
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: sinkModel
+ data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
+ # The `*Params`/`*Prepare` functions interpret their command/query text as SQL,
+ # so injection into that text is a sink even though the parameter values are
+ # passed separately. The `*Prepared` functions take a prepared-statement name
+ # rather than SQL text and are therefore not modeled here.
+ - ["", "", False, "PQexec", "", "", "Argument[*1]", "sql-injection", "manual"]
+ - ["", "", False, "PQexecParams", "", "", "Argument[*1]", "sql-injection", "manual"]
+ - ["", "", False, "PQprepare", "", "", "Argument[*2]", "sql-injection", "manual"]
+ - ["", "", False, "PQsendQuery", "", "", "Argument[*1]", "sql-injection", "manual"]
+ - ["", "", False, "PQsendQueryParams", "", "", "Argument[*1]", "sql-injection", "manual"]
+ - ["", "", False, "PQsendPrepare", "", "", "Argument[*2]", "sql-injection", "manual"]
diff --git a/cpp/ql/lib/ext/Protobuf.model.yml b/cpp/ql/lib/ext/Protobuf.model.yml
new file mode 100644
index 000000000000..02bbad0b1282
--- /dev/null
+++ b/cpp/ql/lib/ext/Protobuf.model.yml
@@ -0,0 +1,59 @@
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: summaryModel
+ data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
+ # File-descriptor variants (`{Parse,Serialize}*FromFileDescriptor`) are intentionally omitted:
+ # the descriptor is an `int`, not a data buffer, so there is no buffer argument to model.
+
+ # Deserialization
+ - ["google::protobuf", "MessageLite", True, "ParseFromString", "(string_view)", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParseFromString", "(const Cord &)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParsePartialFromString", "(string_view)", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParsePartialFromString", "(const Cord &)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergeFromString", "(string_view)", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergeFromString", "(const Cord &)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergePartialFromString", "(string_view)", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergePartialFromString", "(const Cord &)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParseFromArray", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParsePartialFromArray", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParseFromCord", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParsePartialFromCord", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergeFromCord", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergePartialFromCord", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParseFromIstream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParsePartialFromIstream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParseFromZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParsePartialFromZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParseFromBoundedZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParsePartialFromBoundedZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergeFromBoundedZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergePartialFromBoundedZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParseFromCodedStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "ParsePartialFromCodedStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergeFromCodedStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "MergePartialFromCodedStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+
+ # Serialization
+ - ["google::protobuf", "MessageLite", True, "SerializeToString", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializePartialToString", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "AppendToString", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "AppendPartialToString", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializeToArray", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializePartialToArray", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializeToCord", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializePartialToCord", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "AppendToCord", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "AppendPartialToCord", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializeToOstream", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializePartialToOstream", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializeToZeroCopyStream", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializePartialToZeroCopyStream", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializeToCodedStream", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializePartialToCodedStream", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+
+ # Serialization returning bytes
+ - ["google::protobuf", "MessageLite", True, "SerializeAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializePartialAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializeAsCord", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
+ - ["google::protobuf", "MessageLite", True, "SerializePartialAsCord", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
diff --git a/cpp/ql/lib/ext/balber.model.yml b/cpp/ql/lib/ext/balber.model.yml
new file mode 100644
index 000000000000..5cbc6fa71a27
--- /dev/null
+++ b/cpp/ql/lib/ext/balber.model.yml
@@ -0,0 +1,13 @@
+# Model of the BDE balber BER codec (BloombergLP::balber).
+# All overloads take the stream at argument 0 and the object at argument 1 and return int.
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: summaryModel
+ data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
+ # Decoding: stream -> object
+ - ["BloombergLP::balber", "BerDecoder", true, "decode", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ - ["BloombergLP::balber", "BerDecoder", true, "decodeAny", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ # Encoding: object -> stream
+ - ["BloombergLP::balber", "BerEncoder", true, "encode", "", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::balber", "BerEncoder", true, "encodeAny", "", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
diff --git a/cpp/ql/lib/ext/baljsn.model.yml b/cpp/ql/lib/ext/baljsn.model.yml
new file mode 100644
index 000000000000..b85463dbbb2e
--- /dev/null
+++ b/cpp/ql/lib/ext/baljsn.model.yml
@@ -0,0 +1,14 @@
+# Model of the BDE baljsn JSON codec (BloombergLP::baljsn).
+# All overloads, including those taking DecoderOptions/EncoderOptions, take the stream at
+# argument 0 and the object at argument 1 and return int.
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: summaryModel
+ data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
+ # Decoding: stream -> object
+ - ["BloombergLP::baljsn", "Decoder", true, "decode", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ - ["BloombergLP::baljsn", "Decoder", true, "decodeAny", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ # Encoding: object -> stream
+ - ["BloombergLP::baljsn", "Encoder", true, "encode", "", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::baljsn", "Encoder", true, "encodeAny", "", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
diff --git a/cpp/ql/lib/ext/balxml.model.yml b/cpp/ql/lib/ext/balxml.model.yml
new file mode 100644
index 000000000000..ec563089d794
--- /dev/null
+++ b/cpp/ql/lib/ext/balxml.model.yml
@@ -0,0 +1,32 @@
+# Model of the BDE balxml XML codec (BloombergLP::balxml).
+# Rows name their overload where the overloads differ in argument layout. Not modelled:
+# decode(const char *filename, TYPE *), the two-step open() + decode(TYPE *) form, and the
+# Formatter overloads.
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: summaryModel
+ data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
+ # Decoding: stream -> object; the istream overloads also return the stream
+ - ["BloombergLP::balxml", "Decoder", true, "decode", "(istream &,TYPE *,const char *)", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Decoder", true, "decode", "(istream &,TYPE *,const char *)", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Decoder", true, "decode", "(streambuf *,TYPE *,const char *)", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Decoder", true, "decode", "(const char *,size_t,TYPE *,const char *)", "", "Argument[*0]", "Argument[*2]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Decoder", true, "decodeAny", "(istream &,TYPE *,const char *)", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Decoder", true, "decodeAny", "(istream &,TYPE *,const char *)", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Decoder", true, "decodeAny", "(streambuf *,TYPE *,const char *)", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Decoder", true, "decodeAny", "(istream &,AnyRef *,const char *)", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Decoder", true, "decodeAny", "(istream &,AnyRef *,const char *)", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Decoder", true, "decodeAny", "(streambuf *,AnyRef *,const char *)", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ # Encoding: object -> stream; the ostream overloads also return the stream
+ - ["BloombergLP::balxml", "Encoder", true, "encode", "(streambuf *,const TYPE &)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encode", "(ostream &,const TYPE &)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encode", "(ostream &,const TYPE &)", "", "Argument[*0..1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encodeToStream", "", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encodeAny", "(streambuf *,const TYPE &)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encodeAny", "(ostream &,const TYPE &)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encodeAny", "(ostream &,const TYPE &)", "", "Argument[*0..1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encodeAnyToStream", "", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encodeAny", "(streambuf *,const AnyConstRef &)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encodeAny", "(ostream &,const AnyConstRef &)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::balxml", "Encoder", true, "encodeAny", "(ostream &,const AnyConstRef &)", "", "Argument[*0..1]", "ReturnValue[*]", "taint", "manual"]
diff --git a/cpp/ql/lib/ext/bdlbb.model.yml b/cpp/ql/lib/ext/bdlbb.model.yml
new file mode 100644
index 000000000000..e5c50207c464
--- /dev/null
+++ b/cpp/ql/lib/ext/bdlbb.model.yml
@@ -0,0 +1,18 @@
+# Model of the BDE bdlbb::Blob segmented byte buffer (BloombergLP::bdlbb).
+# Lets taint reach a blob's payload bytes, e.g. a message body filled by bmqa::Message::getData.
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: summaryModel
+ data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
+ # Accessor chain
+ - ["BloombergLP::bdlbb", "Blob", true, "buffer", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bdlbb", "BlobBuffer", true, "data", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bdlbb", "BlobBuffer", true, "buffer", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ # BlobUtil read-out
+ - ["BloombergLP::bdlbb", "BlobUtil", true, "copy", "(char *,const Blob &,int,int)", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bdlbb", "BlobUtil", true, "getContiguousRangeOrCopy", "", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bdlbb", "BlobUtil", true, "getContiguousRangeOrCopy", "", "", "Argument[*1]", "ReturnValue[*]", "taint", "manual"]
+ # BlobUtil write-in
+ - ["BloombergLP::bdlbb", "BlobUtil", true, "copy", "(Blob *,int,const char *,int)", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bdlbb", "BlobUtil", true, "copy", "(Blob *,int,const Blob &,int,int)", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
diff --git a/cpp/ql/lib/ext/bmqa.model.yml b/cpp/ql/lib/ext/bmqa.model.yml
new file mode 100644
index 000000000000..d5bfbf675e18
--- /dev/null
+++ b/cpp/ql/lib/ext/bmqa.model.yml
@@ -0,0 +1,51 @@
+# Model of the BlazingMQ client API (BloombergLP::bmqa). Scalar property getters are not modelled.
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: summaryModel
+ data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
+ # Message payload
+ - ["BloombergLP::bmqa", "Message", true, "getData", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "setData", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "setData", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "setData", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "setDataRef", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "setDataRef", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "setDataRef", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "clone", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
+ # Message properties
+ - ["BloombergLP::bmqa", "Message", true, "loadProperties", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "setPropertiesRef", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "setPropertiesRef", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "Message", true, "setPropertiesRef", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "MessageProperties", "(const MessageProperties &,Allocator *)", "", "Argument[*0]", "Argument[-1]", "value", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "operator=", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "operator=", "", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "getPropertyAsString", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "getPropertyAsBinary", "", "", "Argument[-1]", "ReturnValue[*].Element", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "getPropertyAsStringOr", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "getPropertyAsStringOr", "", "", "Argument[*1]", "ReturnValue[*]", "value", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "getPropertyAsBinaryOr", "", "", "Argument[-1]", "ReturnValue[*].Element", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "getPropertyAsBinaryOr", "", "", "Argument[*1].Element[@]", "ReturnValue[*].Element[@]", "value", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "setPropertyAsString", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "setPropertyAsBinary", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"]
+ # Property names are stored and exposed by MessagePropertiesIterator::name
+ - ["BloombergLP::bmqa", "MessageProperties", true, "setPropertyAsBool", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "setPropertyAsChar", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "setPropertyAsShort", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "setPropertyAsInt32", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "setPropertyAsInt64", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "setPropertyAsString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "setPropertyAsBinary", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "streamIn", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageProperties", true, "streamOut", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ # Property iteration
+ - ["BloombergLP::bmqa", "MessagePropertiesIterator", true, "MessagePropertiesIterator", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessagePropertiesIterator", true, "operator=", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"]
+ - ["BloombergLP::bmqa", "MessagePropertiesIterator", true, "operator=", "", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"]
+ - ["BloombergLP::bmqa", "MessagePropertiesIterator", true, "name", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessagePropertiesIterator", true, "getAsString", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessagePropertiesIterator", true, "getAsBinary", "", "", "Argument[-1]", "ReturnValue[*].Element", "taint", "manual"]
+ # Event -> iterator -> message
+ - ["BloombergLP::bmqa", "MessageEvent", true, "messageIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
+ - ["BloombergLP::bmqa", "MessageIterator", true, "message", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
diff --git a/cpp/ql/lib/ext/bslx.model.yml b/cpp/ql/lib/ext/bslx.model.yml
new file mode 100644
index 000000000000..11732ff5e4b2
--- /dev/null
+++ b/cpp/ql/lib/ext/bslx.model.yml
@@ -0,0 +1,140 @@
+# Model of the BDE `bslx` byte-stream deserializers (BloombergLP::bslx).
+extensions:
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: summaryModel
+ data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
+ # bslx::ByteInStream
+ - ["BloombergLP::bslx", "ByteInStream", true, "ByteInStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ # Input-taking resets replace the buffer; reset() only rewinds it.
+ - ["BloombergLP::bslx", "ByteInStream", true, "reset", "(const char *,size_t)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "reset", "(const StringRef &)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ # bslx::ByteInStream getters.
+ # Scalar getters (getLength, getVersion, getInt*, getUint*, getFloat*) are not modeled,
+ # as we are generally not interested in tainted scalar values.
+ - ["BloombergLP::bslx", "ByteInStream", true, "getString", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt8", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint8", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt16", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint16", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt24", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint24", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt32", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint32", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt40", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint40", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt48", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint48", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt56", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint56", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt64", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint64", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayFloat32", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayFloat64", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ # bslx::ByteInStream fluent interface
+ - ["BloombergLP::bslx", "ByteInStream", true, "getLength", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getVersion", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getInt8", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getUint8", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getInt16", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getUint16", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getInt24", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getUint24", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getInt32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getUint32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getInt40", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getUint40", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getInt48", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getUint48", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getInt56", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getUint56", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getInt64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getUint64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getFloat32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getFloat64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getString", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt8", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint8", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt16", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint16", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt24", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint24", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt40", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint40", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt48", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint48", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt56", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint56", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayInt64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayUint64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayFloat32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "ByteInStream", true, "getArrayFloat64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ # bslx::GenericInStream
+ - ["BloombergLP::bslx", "GenericInStream", true, "GenericInStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
+ # bslx::GenericInStream getters.
+ # Scalar getters (getLength, getVersion, getInt*, getUint*, getFloat*) are not modeled,
+ # as we are generally not interested in tainted scalar values.
+ - ["BloombergLP::bslx", "GenericInStream", true, "getString", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt8", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint8", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt16", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint16", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt24", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint24", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt32", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint32", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt40", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint40", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt48", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint48", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt56", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint56", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt64", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint64", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayFloat32", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayFloat64", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
+ # bslx::GenericInStream fluent interface
+ - ["BloombergLP::bslx", "GenericInStream", true, "getLength", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getVersion", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getInt8", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getUint8", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getInt16", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getUint16", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getInt24", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getUint24", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getInt32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getUint32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getInt40", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getUint40", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getInt48", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getUint48", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getInt56", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getUint56", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getInt64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getUint64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getFloat32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getFloat64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getString", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt8", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint8", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt16", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint16", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt24", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint24", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt40", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint40", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt48", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint48", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt56", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint56", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayInt64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayUint64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayFloat32", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["BloombergLP::bslx", "GenericInStream", true, "getArrayFloat64", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ # bslx::InStreamFunctions::bdexStreamIn
+ - ["BloombergLP::bslx::InStreamFunctions", "", false, "bdexStreamIn", "", "", "Argument[*0]", "Argument[*1]", "taint", "manual"]
+ - ["BloombergLP::bslx::InStreamFunctions", "", false, "bdexStreamIn", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"]
diff --git a/cpp/ql/lib/ext/empty.model.yml b/cpp/ql/lib/ext/empty.model.yml
index e5202b5ad73c..9c2921cfef1b 100644
--- a/cpp/ql/lib/ext/empty.model.yml
+++ b/cpp/ql/lib/ext/empty.model.yml
@@ -21,3 +21,7 @@ extensions:
pack: codeql/cpp-all
extensible: summaryModel
data: []
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: forwardsModel
+ data: []
\ No newline at end of file
diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml
index 2932987ec152..9d3f8acde278 100644
--- a/cpp/ql/lib/qlpack.yml
+++ b/cpp/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-all
-version: 12.0.2-dev
+version: 12.4.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
@@ -10,6 +10,7 @@ dependencies:
codeql/mad: ${workspace}
codeql/quantum: ${workspace}
codeql/rangeanalysis: ${workspace}
+ codeql/regex: ${workspace}
codeql/ssa: ${workspace}
codeql/typeflow: ${workspace}
codeql/tutorial: ${workspace}
diff --git a/cpp/ql/lib/semmle/code/cpp/Enum.qll b/cpp/ql/lib/semmle/code/cpp/Enum.qll
index 38263dacf7ac..6b30d7921157 100644
--- a/cpp/ql/lib/semmle/code/cpp/Enum.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Enum.qll
@@ -55,6 +55,12 @@ class Enum extends UserType, IntegralOrEnumType {
not exists(UserType.super.getSize()) and result = 4
}
+ override int getBitWidth() {
+ result = UserType.super.getBitWidth()
+ or
+ not exists(UserType.super.getBitWidth()) and result = 32
+ }
+
/** See `Type.isDeeplyConst` and `Type.isDeeplyConstBelow`. Internal. */
override predicate isDeeplyConstBelow() { any() } // No subparts
diff --git a/cpp/ql/lib/semmle/code/cpp/Initializer.qll b/cpp/ql/lib/semmle/code/cpp/Initializer.qll
index 5748ab505e7c..6f03ec84116b 100644
--- a/cpp/ql/lib/semmle/code/cpp/Initializer.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Initializer.qll
@@ -54,4 +54,15 @@ class Initializer extends ControlFlowNode, @initialiser {
/** Holds if the initializer used the C++ braced initializer notation. */
predicate isBraced() { braced_initialisers(underlyingElement(this)) }
+
+ /** Holds if this initializer is generated by the compiler. */
+ predicate isCompilerGenerated() {
+ exists(Variable v |
+ v = this.getDeclaration() and
+ // We require the variable to be an orphan to not mark the initializer
+ // from a desugared ranged for loop as compiler generated.
+ orphaned_variables(unresolveElement(v), _) and
+ v.isCompilerGenerated()
+ )
+ }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/Type.qll b/cpp/ql/lib/semmle/code/cpp/Type.qll
index 4069b58134be..78367dbf7be4 100644
--- a/cpp/ql/lib/semmle/code/cpp/Type.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Type.qll
@@ -123,6 +123,16 @@ class Type extends Locatable, @type {
usertypesize(underlyingElement(this), result, _)
}
+ /**
+ * Gets the bit width of this type.
+ */
+ int getBitWidth() {
+ not bit_precise_int_types(underlyingElement(this), _) and
+ result = this.getSize() * 8
+ or
+ bit_precise_int_types(underlyingElement(this), result)
+ }
+
/**
* Gets the alignment of this type in bytes.
*/
@@ -398,6 +408,8 @@ private predicate isIntegralType(@builtintype type, int kind) {
kind = 44
or
kind = 51
+ or
+ 67 <= kind and kind <= 69
)
}
@@ -484,6 +496,12 @@ private predicate integralTypeMapping(int original, int canonical, int unsigned,
original = 44 and canonical = 44 and unsigned = -1 and signed = -1 // char32_t
or
original = 51 and canonical = 51 and unsigned = -1 and signed = -1 // char8_t
+ or
+ original = 67 and canonical = 67 and unsigned = 68 and signed = 69 // _BitInt(N)
+ or
+ original = 68 and canonical = 68 and unsigned = 68 and signed = 69 // unsigned _BitInt(N)
+ or
+ original = 69 and canonical = 67 and unsigned = 68 and signed = 69 // signed _BitInt(N)
}
/**
@@ -517,7 +535,8 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
builtintypes(underlyingElement(this), _, 13, _, _, _) or
builtintypes(underlyingElement(this), _, 16, _, _, _) or
builtintypes(underlyingElement(this), _, 19, _, _, _) or
- builtintypes(underlyingElement(this), _, 37, _, _, _)
+ builtintypes(underlyingElement(this), _, 37, _, _, _) or
+ builtintypes(underlyingElement(this), _, 69, _, _, _)
}
/** Holds if this integral type is explicitly unsigned. */
@@ -527,7 +546,8 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
builtintypes(underlyingElement(this), _, 12, _, _, _) or
builtintypes(underlyingElement(this), _, 15, _, _, _) or
builtintypes(underlyingElement(this), _, 18, _, _, _) or
- builtintypes(underlyingElement(this), _, 36, _, _, _)
+ builtintypes(underlyingElement(this), _, 36, _, _, _) or
+ builtintypes(underlyingElement(this), _, 68, _, _, _)
}
/** Holds if this integral type is implicitly signed. */
@@ -537,7 +557,8 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
builtintypes(underlyingElement(this), _, 11, _, -1, _) or
builtintypes(underlyingElement(this), _, 14, _, -1, _) or
builtintypes(underlyingElement(this), _, 17, _, -1, _) or
- builtintypes(underlyingElement(this), _, 35, _, -1, _)
+ builtintypes(underlyingElement(this), _, 35, _, -1, _) or
+ builtintypes(underlyingElement(this), _, 67, _, -1, _)
}
/**
@@ -547,7 +568,14 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
IntegralType getUnsigned() {
exists(int unsignedKind |
integralTypeMapping(kind, _, unsignedKind, _) and
- builtintypes(unresolveElement(result), _, unsignedKind, _, _, _)
+ builtintypes(unresolveElement(result), _, unsignedKind, _, _, _) and
+ (
+ not kind in [67, 68, 69]
+ or
+ exists(int bitWidth | bit_precise_int_types(underlyingElement(this), bitWidth) |
+ bit_precise_int_types(unresolveElement(result), bitWidth)
+ )
+ )
)
}
@@ -562,7 +590,14 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
IntegralType getCanonicalArithmeticType() {
exists(int canonicalKind |
integralTypeMapping(kind, canonicalKind, _, _) and
- builtintypes(unresolveElement(result), _, canonicalKind, _, _, _)
+ builtintypes(unresolveElement(result), _, canonicalKind, _, _, _) and
+ (
+ not kind in [67, 68, 69]
+ or
+ exists(int bitWidth | bit_precise_int_types(underlyingElement(this), bitWidth) |
+ bit_precise_int_types(unresolveElement(result), bitWidth)
+ )
+ )
)
}
}
@@ -1045,6 +1080,15 @@ class Char32Type extends IntegralType {
override string getAPrimaryQlClass() { result = "Char32Type" }
}
+/**
+ * A C23 bit-precise integer type `_BitInt(N)`.
+ */
+class BitPreciseIntType extends IntegralType {
+ BitPreciseIntType() { builtintypes(underlyingElement(this), _, [67, 68, 69], _, _, _) }
+
+ override string getAPrimaryQlClass() { result = "BitPreciseIntType" }
+}
+
/**
* The (primitive) type of the C++11 `nullptr` constant. It is a
* distinct type, denoted by `decltype(nullptr)`, that is not itself a pointer
@@ -1145,6 +1189,8 @@ class Decltype extends Type, NameQualifyingElement {
override int getSize() { result = this.getBaseType().getSize() }
+ override int getBitWidth() { result = this.getBaseType().getBitWidth() }
+
override int getAlignment() { result = this.getBaseType().getAlignment() }
override int getPointerIndirectionLevel() {
@@ -1205,6 +1251,8 @@ class TypeofType extends Type {
override int getSize() { result = this.getBaseType().getSize() }
+ override int getBitWidth() { result = this.getBaseType().getBitWidth() }
+
override int getAlignment() { result = this.getBaseType().getAlignment() }
override int getPointerIndirectionLevel() {
@@ -1350,6 +1398,8 @@ class IntrinsicTransformedType extends Type {
override int getSize() { result = this.getBaseType().getSize() }
+ override int getBitWidth() { result = this.getBaseType().getBitWidth() }
+
override int getAlignment() { result = this.getBaseType().getAlignment() }
override int getPointerIndirectionLevel() {
@@ -1475,6 +1525,8 @@ class SpecifiedType extends DerivedType {
override int getSize() { result = this.getBaseType().getSize() }
+ override int getBitWidth() { result = this.getBaseType().getBitWidth() }
+
override int getAlignment() { result = this.getBaseType().getAlignment() }
override int getPointerIndirectionLevel() {
@@ -1550,6 +1602,8 @@ class ArrayType extends DerivedType {
*/
override int getSize() { result = this.getByteSize() }
+ override int getBitWidth() { result = this.getByteSize() * 8 }
+
override string explain() {
if exists(this.getArraySize())
then
diff --git a/cpp/ql/lib/semmle/code/cpp/TypedefType.qll b/cpp/ql/lib/semmle/code/cpp/TypedefType.qll
index 69eb8f881d29..70aa933d6a2d 100644
--- a/cpp/ql/lib/semmle/code/cpp/TypedefType.qll
+++ b/cpp/ql/lib/semmle/code/cpp/TypedefType.qll
@@ -26,6 +26,8 @@ class TypedefType extends UserType {
override int getSize() { result = this.getBaseType().getSize() }
+ override int getBitWidth() { result = this.getBaseType().getBitWidth() }
+
override int getAlignment() { result = this.getBaseType().getAlignment() }
override int getPointerIndirectionLevel() {
diff --git a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
index 624465761c2c..dfda2f4796c5 100644
--- a/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
+++ b/cpp/ql/lib/semmle/code/cpp/commons/Printf.qll
@@ -1193,7 +1193,7 @@ class FormatLiteral extends Literal instanceof StringLiteral {
// Subtract one in the exponent because one bit is for the sign.
// Add 1 to account for the possible sign in the output.
typeBasedBound =
- 1 + lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8 - 1)) and
+ 1 + lengthInBase10(2.pow(this.getIntegralDisplayType(n).getBitWidth() - 1)) and
// The second case uses range analysis to deduce a length that's shorter than the length
// of the number -2^31.
exists(Expr arg, float lower, float upper |
@@ -1227,7 +1227,7 @@ class FormatLiteral extends Literal instanceof StringLiteral {
// e.g. 2^32 - 1 = "4294967295"
exists(float typeBasedBound, float valueBasedBound |
// The first case handles length sub-specifiers
- typeBasedBound = lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8) - 1) and
+ typeBasedBound = lengthInBase10(2.pow(this.getIntegralDisplayType(n).getBitWidth()) - 1) and
// The second case uses range analysis to deduce a length that's shorter than
// the length of the number 2^31 - 1.
exists(Expr arg, float lower, float upper |
@@ -1239,7 +1239,7 @@ class FormatLiteral extends Literal instanceof StringLiteral {
lengthInBase10(max(float cand |
// If lower can be negative we use `(unsigned)-1` as the candidate value.
lower < 0 and
- cand = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
+ cand = 2.pow(any(IntType t | t.isUnsigned()).getBitWidth())
or
cand = upper
)) and
@@ -1275,7 +1275,7 @@ class FormatLiteral extends Literal instanceof StringLiteral {
lengthInBase16(max(float cand |
// If lower can be negative we use `(unsigned)-1` as the candidate value.
lower < 0 and
- cand = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
+ cand = 2.pow(any(IntType t | t.isUnsigned()).getBitWidth())
or
cand = upper
)) and
@@ -1304,12 +1304,12 @@ class FormatLiteral extends Literal instanceof StringLiteral {
exists(int sizeBits, int baseLen |
sizeBits =
min(int bits |
- bits = this.getIntegralDisplayType(n).getSize() * 8
+ bits = this.getIntegralDisplayType(n).getBitWidth()
or
exists(IntegralType t |
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
|
- t.isUnsigned() and bits = t.getSize() * 8
+ t.isUnsigned() and bits = t.getBitWidth()
)
) and
baseLen = (sizeBits / 3.0).ceil() and
diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll
index 84e96fa9c468..5329fb92a5a4 100644
--- a/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll
+++ b/cpp/ql/lib/semmle/code/cpp/controlflow/internal/ConstantExprs.qll
@@ -344,12 +344,12 @@ private int convertIntToType(int val, IntegralType t) {
then if val = 0 then result = 0 else result = 1
else
if t.isUnsigned()
- then val >= 0 and val.bitShiftRight(t.getSize() * 8) = 0 and result = val
+ then val >= 0 and val.bitShiftRight(t.getBitWidth()) = 0 and result = val
else
- if val >= 0 and val.bitShiftRight(t.getSize() * 8 - 1) = 0
+ if val >= 0 and val.bitShiftRight(t.getBitWidth() - 1) = 0
then result = val
else (
- (-(val + 1)).bitShiftRight(t.getSize() * 8 - 1) = 0 and result = val
+ (-(val + 1)).bitShiftRight(t.getBitWidth() - 1) = 0 and result = val
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll
index 29da7f7204c0..ee894f95648f 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll
@@ -15,6 +15,8 @@
* `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
* - BarrierGuards:
* `namespace; type; subtypes; name; signature; ext; input; acceptingValue; kind; provenance`
+ * - Forwards:
+ * `namespace; type; subtypes; name; signature; ext; start; constructor; output; provenance`
*
* The interpretation of a row is similar to API-graphs with a left-to-right
* reading.
@@ -108,12 +110,23 @@
* - "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.
+ *
+ * The "Forwards" relation allows modeling of function that perform C++11-style "perfect
+ * forwarding" where a function receives a number of arguments and forwards those arguments
+ * to a constructor of another type. For example, the row:
+ * `"std"; "vector"; "True"; "emplace"; ""; ""; "1"; T; Argument[-1].Element; manual`
+ * says that `std::vector::emplace(arg0, arg1, ..., argn)` forwards arguments
+ * `arg1, ..., argn` to a constructor for `T`, and the result of `T(arg1, ..., argn)`
+ * flows to `Argument[-1].Element` (see information about the semantics of the `output`
+ * column further above).
*/
import cpp
private import new.DataFlow
private import semmle.code.cpp.controlflow.IRGuards
+private import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes as Nodes
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as Private
+private import semmle.code.cpp.ir.dataflow.internal.SsaImpl as SsaImpl
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import internal.FlowSummaryImpl
private import internal.FlowSummaryImpl::Public
@@ -159,6 +172,20 @@ predicate summaryModel(
)
}
+/**
+ * Holds if a forward model exists for the given parameters.
+ */
+predicate forwardsModel(
+ string namespace, string type, boolean subtypes, string name, string signature, string ext,
+ string start, string constructor, string output, string provenance, string model
+) {
+ exists(QlBuiltins::ExtensionId madId |
+ Extensions::forwardsModel(namespace, type, subtypes, name, signature, ext, start, constructor,
+ output, provenance, madId) and
+ model = "MaD:" + madId.toString()
+ )
+}
+
/** Provides a query predicate to check the data for validation errors. */
module ModelValidation {
private string getInvalidModelInput() {
@@ -185,6 +212,8 @@ module ModelValidation {
sourceModel(_, _, _, _, _, _, output, _, _, _) and pred = "source"
or
summaryModel(_, _, _, _, _, _, _, output, _, _, _) and pred = "summary"
+ or
+ forwardsModel(_, _, _, _, _, _, _, _, output, _, _) and pred = "forwards"
|
invalidSpecComponent(output, part) and
not part = "" and
@@ -258,7 +287,8 @@ private predicate elementSpec(
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
barrierModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
barrierGuardModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or
- summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _)
+ summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or
+ forwardsModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _)
}
/**
@@ -595,6 +625,14 @@ private string getAtIndex(string s, int i) {
not (s = "" and i = 0)
}
+/** Gets the number of comma-separated arguments in `s`. */
+bindingset[s]
+private int getNumberOfArguments(string s) {
+ s = "" and result = 0
+ or
+ s != "" and result = count(s.indexOf(",")) + 1
+}
+
/**
* Normalizes `partiallyNormalizedSignature` by replacing the `remaining`
* number of template arguments in `partiallyNormalizedSignature` with their
@@ -604,7 +642,7 @@ private string getSignatureWithoutClassTemplateNames(
string partiallyNormalizedSignature, string typeArgs, string nameArgs, int remaining
) {
elementSpecWithArguments0(_, _, _, partiallyNormalizedSignature, typeArgs, nameArgs) and
- remaining = count(partiallyNormalizedSignature.indexOf(",")) + 1 and
+ remaining = getNumberOfArguments(typeArgs) and
result = partiallyNormalizedSignature
or
exists(string mid |
@@ -618,7 +656,7 @@ private string getSignatureWithoutClassTemplateNames(
)
or
// Make sure `remaining` is properly bound
- remaining = [0 .. count(partiallyNormalizedSignature.indexOf(",")) + 1] and
+ remaining = [0 .. getNumberOfArguments(typeArgs)] and
not exists(getAtIndex(typeArgs, remaining)) and
result = mid
)
@@ -635,7 +673,7 @@ pragma[nomagic]
private string getSignatureWithoutFunctionTemplateNames(
string partiallyNormalizedSignature, string typeArgs, string nameArgs, int remaining
) {
- remaining = count(partiallyNormalizedSignature.indexOf(",")) + 1 and
+ remaining = getNumberOfArguments(nameArgs) and
result =
getSignatureWithoutClassTemplateNames(partiallyNormalizedSignature, typeArgs, nameArgs, 0)
or
@@ -650,7 +688,7 @@ private string getSignatureWithoutFunctionTemplateNames(
)
or
// Make sure `remaining` is properly bound
- remaining = [0 .. count(partiallyNormalizedSignature.indexOf(",")) + 1] and
+ remaining = [0 .. getNumberOfArguments(nameArgs)] and
not exists(getAtIndex(nameArgs, remaining)) and
result = mid
)
@@ -952,9 +990,7 @@ private module Cached {
*/
cached
predicate sourceNode(DataFlow::Node node, string kind, string model) {
- exists(SourceSinkInterpretationInput::InterpretNode n |
- isSourceNode(n, kind, model) and n.asNode() = node
- )
+ node.(Nodes::FlowSummaryNode).isSource(kind, model)
}
/**
@@ -963,9 +999,7 @@ private module Cached {
*/
cached
predicate sinkNode(DataFlow::Node node, string kind, string model) {
- exists(SourceSinkInterpretationInput::InterpretNode n |
- isSinkNode(n, kind, model) and n.asNode() = node
- )
+ node.(Nodes::FlowSummaryNode).isSink(kind, model)
}
private newtype TKindModelPair =
@@ -1049,6 +1083,538 @@ private module Cached {
import Cached
+/** Gets the constructor type selected by `constructorType` in a forwarding model. */
+private Type getForwardedConstructorType(
+ Function forwarder, string namespace, string type, boolean subtypes, string name,
+ string signature, string ext, string constructorType
+) {
+ forwardsModel(namespace, type, subtypes, name, signature, ext, _, constructorType, _, _, _) and
+ forwarder = interpretElement(namespace, type, subtypes, name, signature, ext) and
+ (
+ exists(string typeArguments, int index |
+ parseAngles(type, _, typeArguments, "") and
+ constructorType = getAtIndex(typeArguments, index) and
+ result = forwarder.getDeclaringType().getTemplateArgument(index)
+ )
+ or
+ exists(string nameArguments, int index |
+ parseAngles(name, _, nameArguments, "") and
+ constructorType = getAtIndex(nameArguments, index) and
+ result = forwarder.getTemplateArgument(index)
+ )
+ or
+ exists(TypedefType member |
+ member = forwarder.getDeclaringType().getAMember() and
+ member.hasName(constructorType) and
+ result = member.getUnderlyingType()
+ )
+ )
+}
+
+/** Interprets a forwarding model, retaining its constructed type, output, and provenance. */
+private predicate interpretForwardsModelType(
+ Function forwarder, Type constructedType, int start, string output, string provenance,
+ string model
+) {
+ exists(
+ string namespace, string type, boolean subtypes, string name, string signature, string ext,
+ string startString, string constructorType
+ |
+ forwardsModel(namespace, type, subtypes, name, signature, ext, startString, constructorType,
+ output, provenance, model) and
+ forwarder = interpretElement(namespace, type, subtypes, name, signature, ext) and
+ start = startString.toInt()
+ |
+ // Either the row specifies forwarding to a type given by the type or
+ // function template, in which case we need to resolve that from the type
+ // or function name.
+ constructedType =
+ getForwardedConstructorType(forwarder, namespace, type, subtypes, name, signature, ext,
+ constructorType).getUnspecifiedType()
+ or
+ // Or the row specifies forwarding to a specific type.
+ not exists(
+ getForwardedConstructorType(forwarder, namespace, type, subtypes, name, signature, ext,
+ constructorType)
+ ) and
+ classHasQualifiedName(constructedType, namespace, constructorType)
+ )
+}
+
+/**
+ * Holds if `forwarder` may forward its arguments starting at `start` to a
+ * constructor of `c`. The actual constructor being forwarded to depends on the
+ * types of arguments from `start` at calls to `forwarder`.
+ */
+private predicate interpretForwardsModel(
+ Function forwarder, Class c, int start, string output, string provenance, string model
+) {
+ interpretForwardsModelType(forwarder, c, start, output, provenance, model)
+}
+
+/**
+ * Holds if `forwarder` forwards its arguments starting at `start` to a
+ * constructor of `c`.
+ */
+predicate forwards(Function forwarder, Class c, int start) {
+ interpretForwardsModel(forwarder, c, start, _, _, _)
+}
+
+private int referenceIndirection(Type unspecified) {
+ if unspecified instanceof ReferenceType then result = 1 else result = 0
+}
+
+/** Gets `unspecified`, but with its outermost reference removed, if any. */
+private Type stripReference(Type unspecified) {
+ result = unspecified.(ReferenceType).getBaseType().getUnspecifiedType()
+ or
+ not unspecified instanceof ReferenceType and
+ result = unspecified
+}
+
+/**
+ * Encapsulates predicates used to compute which constructor a perfect
+ * forwarding function targets.
+ */
+module ConstructorForwarding {
+ private import codeql.util.Boolean
+
+ private class ConvertingConstructor extends Constructor {
+ Type fromType;
+
+ ConvertingConstructor() {
+ not this.isFromUninstantiatedTemplate(_) and
+ not this.isExplicit() and
+ not this.isDeleted() and
+ not this instanceof CopyConstructor and
+ not this instanceof MoveConstructor and
+ fromType = this.getParameter(0).getUnderlyingType() and
+ forall(int index | index > 0 and exists(this.getParameter(index)) |
+ this.getParameter(index).hasInitializer()
+ )
+ }
+
+ Type getUnderlyingFromType() { result = fromType }
+ }
+
+ private Type getForwardedArgumentType(Function forwarder, int start, int i) {
+ forwards(forwarder, _, start) and
+ i = [0 .. forwarder.getNumberOfParameters() - start - 1] and
+ result = forwarder.getParameter(start + i).getUnderlyingType()
+ }
+
+ private Type getConstructorParameterType(Cpp::Constructor constructor, int i) {
+ forwards(_, constructor.getDeclaringType(), _) and
+ result = constructor.getParameter(i).getUnderlyingType()
+ }
+
+ private newtype ValueCategory =
+ LValue() or
+ XValue() or
+ PRValue()
+
+ bindingset[t1, t2]
+ pragma[inline_late]
+ private predicate preservesQualifiers(Type t1, Type t2) {
+ (t1.isConst() implies t2.isConst()) and
+ (t1.isVolatile() implies t2.isVolatile())
+ }
+
+ private predicate baseTypeCompatible(Type arg, Type param) {
+ param.stripTopLevelSpecifiers() = arg.stripTopLevelSpecifiers().(Class).getABaseClass+() and
+ preservesQualifiers(arg, param)
+ }
+
+ private predicate voidType(Type t) { t.stripTopLevelSpecifiers() instanceof VoidType }
+
+ private predicate routineType(Type t) { t.stripTopLevelSpecifiers() instanceof RoutineType }
+
+ private predicate pointerConversion(Cpp::PointerType arg, Cpp::PointerType param) {
+ exists(Type argBase, Type paramBase |
+ argBase = arg.getBaseType() and
+ paramBase = param.getBaseType()
+ |
+ baseTypeCompatible(argBase, paramBase)
+ or
+ voidType(paramBase) and
+ not routineType(argBase) and
+ preservesQualifiers(argBase, paramBase)
+ )
+ }
+
+ private predicate nullPointerConversion(Type t) {
+ t instanceof Cpp::PointerType or t instanceof FunctionPointerType
+ }
+
+ private predicate booleanConversion(Type t) {
+ t instanceof Cpp::PointerType
+ or
+ t instanceof FunctionPointerType
+ or
+ t instanceof Cpp::ArrayType
+ or
+ t instanceof RoutineType
+ }
+
+ private predicate referenceAcceptsCategory(Cpp::ReferenceType t, ValueCategory category) {
+ if t instanceof Cpp::LValueReferenceType
+ then
+ category = LValue()
+ or
+ exists(Type base |
+ base = t.getBaseType() and
+ base.isConst() and
+ not base.isVolatile()
+ )
+ else category != LValue()
+ }
+
+ /**
+ * Tracks the ordering of standard conversions. All phases allow parameter matching
+ * and, if none has been used, a user-defined conversion that resets to `Initial()`.
+ */
+ private newtype Phase =
+ // Allows array/function decay, a value or base-class conversion, or pointer qualification.
+ Initial() or
+ // Allows a value or base-class conversion or pointer qualification, but no further decay.
+ AfterTransformation() or
+ // Allows only pointer qualification among the remaining conversion steps.
+ AfterValueConversion() or
+ // Allows no further conversion steps.
+ AfterQualification()
+
+ private predicate isUnderlyingType(Type type) { type = type.getUnderlyingType() }
+
+ private newtype TTypeState =
+ MkTypeState(Type type, ValueCategory category, Boolean conversionUsed, Phase phase) {
+ not type instanceof Cpp::ReferenceType and
+ not type instanceof FunctionReferenceType and
+ isUnderlyingType(type)
+ }
+
+ private ValueCategory getCategoryForRef(Cpp::ReferenceType reference) {
+ reference instanceof Cpp::LValueReferenceType and result = LValue()
+ or
+ reference instanceof Cpp::RValueReferenceType and result = XValue()
+ }
+
+ private Type getValueType(Type t, ValueCategory category) {
+ result = t.(FunctionReferenceType).getBaseType().getUnderlyingType() and
+ category = LValue()
+ or
+ result = t.(Cpp::ReferenceType).getBaseType().getUnderlyingType() and
+ category = getCategoryForRef(t)
+ or
+ not t instanceof FunctionReferenceType and
+ not t instanceof Cpp::ReferenceType and
+ result = t and
+ category = PRValue()
+ }
+
+ bindingset[arg, param]
+ pragma[inline_late]
+ private predicate qualificationCompatible(Type arg, Type param) {
+ arg.stripTopLevelSpecifiers() = param.stripTopLevelSpecifiers() and
+ preservesQualifiers(arg, param)
+ }
+
+ private class TypeState extends TTypeState {
+ Type getType() { this = MkTypeState(result, _, _, _) }
+
+ ValueCategory getCategory() { this = MkTypeState(_, result, _, _) }
+
+ Phase getPhase() { this = MkTypeState(_, _, _, result) }
+
+ /** Holds if this state's phase permits a value or base-class conversion. */
+ predicate canConvertValue() {
+ this.getPhase() = Initial() or this.getPhase() = AfterTransformation()
+ }
+
+ predicate hasNotUsedConversion() { this = MkTypeState(_, _, false, _) }
+
+ string toString() { result = this.getType().toString() }
+
+ predicate isSource(Type argType) {
+ argType = getForwardedArgumentType(_, _, _) and
+ exists(ValueCategory category |
+ this = MkTypeState(getValueType(argType, category), category, false, Initial())
+ )
+ }
+
+ predicate matchesParameter(Type paramType) {
+ exists(Type base | base = paramType.(Cpp::ReferenceType).getBaseType() |
+ qualificationCompatible(this.getType(), base) and
+ referenceAcceptsCategory(paramType, this.getCategory())
+ )
+ or
+ not paramType instanceof Cpp::ReferenceType and
+ this.getType().stripTopLevelSpecifiers() = paramType.stripTopLevelSpecifiers()
+ }
+
+ predicate isSink(Type paramType, Cpp::Constructor constructor) {
+ paramType = getConstructorParameterType(constructor, _) and
+ this.matchesParameter(paramType)
+ }
+ }
+
+ private Cpp::PointerType pointerType(Type base) {
+ result.getBaseType() = base.getUnderlyingType()
+ }
+
+ private predicate arrayToPointerStep(TypeState argState, TypeState paramState) {
+ exists(Cpp::ArrayType array, boolean conversionUsed |
+ argState = MkTypeState(array, _, conversionUsed, Initial()) and
+ paramState =
+ MkTypeState(pointerType(array.getBaseType()), PRValue(), conversionUsed,
+ AfterTransformation())
+ )
+ }
+
+ private predicate functionToPointerStep(TypeState argState, TypeState paramState) {
+ exists(RoutineType routine, FunctionPointerType pointer, boolean conversionUsed |
+ argState = MkTypeState(routine, _, conversionUsed, Initial()) and
+ routine = pointer.getBaseType().getUnderlyingType() and
+ paramState = MkTypeState(pointer, PRValue(), conversionUsed, AfterTransformation())
+ )
+ }
+
+ private predicate arithmeticConversion(Type t) {
+ t instanceof ArithmeticType
+ or
+ t instanceof Enum and not t instanceof ScopedEnum
+ }
+
+ private predicate hasNoTopLevelSpecifiers(Type type) { type = type.stripTopLevelSpecifiers() }
+
+ private predicate valueConversionStep(TypeState argState, TypeState paramState) {
+ exists(Type argType, Type paramType, boolean conversionUsed |
+ argState = MkTypeState(_, _, conversionUsed, _) and
+ argState.canConvertValue() and
+ argType = argState.getType().stripTopLevelSpecifiers() and
+ hasNoTopLevelSpecifiers(paramType) and
+ argType != paramType and
+ paramState = MkTypeState(paramType, PRValue(), conversionUsed, AfterValueConversion())
+ |
+ paramType instanceof ArithmeticType and
+ arithmeticConversion(argType)
+ or
+ pointerConversion(argType, paramType)
+ or
+ argType instanceof NullPointerType and
+ nullPointerConversion(paramType)
+ or
+ booleanConversion(argType) and
+ paramType instanceof BoolType
+ )
+ }
+
+ private newtype PtrKind =
+ NormalPtrKind() or
+ FunPtrKind()
+
+ private Type pointerBase(Type pointer, PtrKind k) {
+ result = pointer.(Cpp::PointerType).getBaseType() and
+ k = NormalPtrKind()
+ or
+ result = pointer.(FunctionPointerType).getBaseType() and
+ k = FunPtrKind()
+ }
+
+ private predicate pointerQualificationStep(TypeState argState, TypeState paramState) {
+ exists(Type argType, Type paramType, boolean conversionUsed, PtrKind k |
+ argState = MkTypeState(_, _, conversionUsed, _) and
+ argState.getPhase() != AfterQualification() and
+ argType = argState.getType().stripTopLevelSpecifiers() and
+ hasNoTopLevelSpecifiers(paramType) and
+ argType != paramType and
+ qualificationCompatible(pointerBase(argType, k), pointerBase(paramType, k)) and
+ paramState = MkTypeState(paramType, PRValue(), conversionUsed, AfterQualification())
+ )
+ }
+
+ private predicate baseClassStep(TypeState argState, TypeState paramState) {
+ exists(Type arg, Type param, ValueCategory category, boolean conversionUsed |
+ argState = MkTypeState(arg, category, conversionUsed, _) and
+ argState.canConvertValue() and
+ baseTypeCompatible(arg, param) and
+ paramState = MkTypeState(param, category, conversionUsed, AfterValueConversion())
+ )
+ }
+
+ private predicate convertingConstructorStep(TypeState argState, TypeState paramState) {
+ exists(ConvertingConstructor constructor |
+ argState.hasNotUsedConversion() and
+ argState.matchesParameter(constructor.getUnderlyingFromType()) and
+ paramState = MkTypeState(constructor.getDeclaringType(), PRValue(), true, Initial())
+ )
+ }
+
+ private predicate conversionOperatorStep(TypeState argState, TypeState paramState) {
+ exists(ConversionOperator conversion, ValueCategory category |
+ not conversion.isFromUninstantiatedTemplate(_) and
+ not conversion.isExplicit() and
+ not conversion.isDeleted() and
+ argState.hasNotUsedConversion() and
+ conversion.getSourceType() =
+ argState.getType().stripTopLevelSpecifiers().(Class).getABaseClass*() and
+ paramState =
+ MkTypeState(getValueType(conversion.getDestType().getUnderlyingType(), category), category,
+ true, Initial())
+ )
+ }
+
+ private predicate step(TypeState argState, TypeState paramState) {
+ arrayToPointerStep(argState, paramState)
+ or
+ functionToPointerStep(argState, paramState)
+ or
+ valueConversionStep(argState, paramState)
+ or
+ pointerQualificationStep(argState, paramState)
+ or
+ baseClassStep(argState, paramState)
+ or
+ convertingConstructorStep(argState, paramState)
+ or
+ conversionOperatorStep(argState, paramState)
+ }
+
+ private predicate typeFwd(TypeState state) {
+ state.isSource(_)
+ or
+ exists(TypeState previous |
+ typeFwd(previous) and
+ step(previous, state)
+ )
+ }
+
+ private predicate typeRev(TypeState state, Cpp::Constructor constructor) {
+ typeFwd(state) and
+ (
+ state.isSink(_, constructor)
+ or
+ exists(TypeState next |
+ typeRev(next, constructor) and
+ step(state, next)
+ )
+ )
+ }
+
+ private predicate prunedStep(TypeState argState, TypeState paramState) {
+ exists(Cpp::Constructor constructor |
+ typeRev(argState, constructor) and
+ typeRev(paramState, constructor) and
+ step(argState, paramState)
+ )
+ }
+
+ private predicate compatible(Function forwarder, int start, int i, Cpp::Constructor constructor) {
+ exists(TypeState argState, TypeState paramState |
+ argState.isSource(getForwardedArgumentType(forwarder, start, i)) and
+ paramState.isSink(getConstructorParameterType(constructor, i), constructor) and
+ prunedStep*(argState, paramState)
+ )
+ }
+
+ /**
+ * Gets the `Constructor` that should be invoked with arguments `0 .. n`
+ * when `forwarder` is called with arguments `start + 0 .. start + n`.
+ */
+ Cpp::Constructor getForwardingConstructor(Function forwarder, int start) {
+ exists(int numberOfForwardedArguments |
+ numberOfForwardedArguments <= result.getNumberOfParameters()
+ or
+ result.isVarargs()
+ |
+ forwards(forwarder, result.getDeclaringType(), start) and
+ forwarder.getNumberOfParameters() = start + numberOfForwardedArguments and
+ forex(int i | i = [0 .. result.getNumberOfParameters() - 1] |
+ // If we are still processing the forwarded arguments then we need to
+ // check that the argument types match the parameter types.
+ // Functions that perform perfect forwarding are always written as:
+ // ```
+ // template void emplace(Args&&... args) { ... }
+ // ```
+ // and so all the arguments will be reference typed (lvalue or rvalued).
+ // However, the constructor may not specify all the arguments by
+ // reference.
+ i < numberOfForwardedArguments and
+ compatible(forwarder, start, i, result)
+ or
+ // If the constructor has a default argument and we have processed all
+ // the forwarded arguments then we don't need to check the types.
+ i >= numberOfForwardedArguments and result.getParameter(i).hasInitializer()
+ )
+ )
+ }
+
+ /** Holds if `call` is a call that forwards arguments to a constructor call. */
+ predicate isForwarderConstructorArgumentNodeImpl(CallInstruction call) {
+ exists(getForwardingConstructor(call.getStaticCallTarget(), _))
+ }
+}
+
+/**
+ * In order to support flow summaries for functions that perform "perfect
+ * forwarding" we interpret a call such as:
+ * ```cpp
+ * struct Foo { Foo(int) };
+ * std::vector v;
+ * v.emplace_back(42);
+ * ```
+ * as:
+ * ```cpp
+ * v.emplace_back(42, &Foo);
+ * ```
+ * and add two summaries:
+ * (1) One flow from `42` to the first argument of a call to `Foo`
+ * (2) One flow from the return value of `Foo` to the `this` argument of the call
+ * to `emplace_back` (with a sequence of output `Content`s).
+ *
+ * These two summaries are automatically generated when a forwarding model
+ * for `emplace_back` exists.
+ */
+private predicate interpretForwardingSummary(
+ Function forwarder, string input, string output, string provenance, string model
+) {
+ exists(Class c, int start, string constructorOutput |
+ interpretForwardsModel(forwarder, c, start, constructorOutput, provenance, model)
+ |
+ // Generate the (1) summary
+ exists(int index, Parameter arg, Parameter p, int indirection, Cpp::Constructor constructor |
+ arg = forwarder.getParameter(start + index) and
+ constructor = ConstructorForwarding::getForwardingConstructor(forwarder, start) and
+ constructor.getDeclaringType() = c and
+ p = constructor.getParameter(index) and
+ indirection = [0 .. SsaImpl::getMaxIndirectionsForPRType(p.getUnspecifiedType())] and
+ input =
+ "Argument[" + repeatStars(indirection + referenceIndirection(arg.getUnspecifiedType())) +
+ (start + index) + "]" and
+ output =
+ "Argument[forward].Parameter[" +
+ repeatStars(indirection + referenceIndirection(p.getUnspecifiedType())) + index + "]"
+ )
+ or
+ // Generate the (2) summary
+ input = "Argument[forward].Parameter[-1]" and
+ output = constructorOutput
+ )
+ or
+ // Scalar types have no constructor to synthesize. In this case, directly
+ // preserve the value of the single forwarded argument at the modeled output.
+ exists(Type constructedType, int start, Parameter p, int indirection |
+ interpretForwardsModelType(forwarder, constructedType, start, output, provenance, model) and
+ not constructedType instanceof Class and
+ forwarder.getNumberOfParameters() = start + 1 and
+ p = forwarder.getParameter(start) and
+ stripReference(p.getUnspecifiedType()) = constructedType and
+ indirection = [0 .. SsaImpl::getMaxIndirectionsForPRType(constructedType)] and
+ input =
+ "Argument[" + repeatStars(indirection + referenceIndirection(p.getUnspecifiedType())) + start +
+ "]"
+ )
+}
+
/**
* Holds if `node` is specified as a source with the given kind in a MaD flow
* model.
@@ -1077,6 +1643,9 @@ private predicate interpretSummary(
model) and
f = interpretElement(namespace, type, subtypes, name, signature, ext)
)
+ or
+ interpretForwardingSummary(f, input, output, provenance, model) and
+ kind = "value"
}
// adapter class for converting Mad summaries to `SummarizedCallable`s
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 22c74c2aa714..e05c1bb2b810 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll
@@ -51,6 +51,14 @@ extensible predicate neutralModel(
string namespace, string type, string name, string signature, string kind, string provenance
);
+/**
+ * Holds if a constructor forwarding model exists for the given parameters.
+ */
+extensible predicate forwardsModel(
+ string namespace, string type, boolean subtypes, string name, string signature, string ext,
+ string start, string constructor, string output, string provenance, QlBuiltins::ExtensionId madId
+);
+
module Extensions implements SharedMaD::ExtensionsSig {
import ExternalFlowExtensions
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 66b33b1ed522..6c613308d5f4 100644
--- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll
@@ -17,10 +17,6 @@ module Input implements InputSig {
class SummarizedCallableBase = Function;
- class SourceBase = Void;
-
- class SinkBase = Void;
-
class FlowSummaryCallBase = CallInstruction;
predicate callableFromSource(SummarizedCallableBase c) { exists(c.getBlock()) }
@@ -115,6 +111,9 @@ module Input implements InputSig {
pos = -1 and result = TIndirectionPosition(pos, indirection + 1)
)
)
+ or
+ argString = "forward" and
+ result = TForwardPosition()
}
bindingset[token]
@@ -132,11 +131,216 @@ module Input implements InputSig {
private import Make as Impl
-private module StepsInput implements Impl::Private::StepsInputSig {
- Impl::Private::SummaryNode getSummaryNode(Node n) {
- result = n.(FlowSummaryNode).getSummaryNode()
+private class ConversionCall extends Call {
+ ConversionCall() { this.getTarget() instanceof ConversionOperator }
+}
+
+private module Input2 implements Impl::Private::InputSig2 {
+ private import codeql.util.Void
+
+ pragma[nomagic]
+ private predicate hasFunctionAndIndirectionIndex(
+ Function f, int indirectionIndex, Ssa::ExplicitDefinition def
+ ) {
+ def.getFunction() = f and
+ def.getSourceVariable().getIRVariable() instanceof IRReturnVariable and
+ def.getIndirectionIndex() = indirectionIndex
+ }
+
+ /** Holds if `def` defines `e` as a returned value with return kind `rk`. */
+ bindingset[rk, e]
+ private predicate isReturnExpr(Function f, ReturnKind rk, Expr e) {
+ exists(Ssa::ExplicitDefinition def |
+ hasFunctionAndIndirectionIndex(f, rk.getIndirectionIndex(), def) and
+ e =
+ def.getAssignedInstruction()
+ .(StoreInstruction)
+ .getSourceValue()
+ .getUnconvertedResultExpression()
+ )
+ }
+
+ private MemberFunction getFunctionFromType(Expr e) {
+ result.getClassAndName("operator()").getADerivedClass*() = e.getUnspecifiedType()
+ }
+
+ private Function getFunctionFromExpr(Expr e) {
+ result = e.(FunctionAccess).getTarget()
+ or
+ result = e.(ConversionCall).getQualifier().(LambdaExpression).getLambdaFunction()
+ }
+
+ private predicate isRelevantUltimateDefinition(Ssa::DirectExplicitDefinition def, Function f) {
+ f =
+ getFunctionFromExpr(def.getAssignedInstruction()
+ .(StoreInstruction)
+ .getSourceValue()
+ .getUnconvertedResultExpression())
+ }
+
+ private module GetAnUltimateDefinitionInput implements Ssa::GetAnUltimateDefinitionSig {
+ predicate isRelevantUltimateDefinition(Ssa::Definition def) {
+ isRelevantUltimateDefinition(def, _)
+ }
+ }
+
+ private predicate hasAnUltimateFunctionAccessDefinition(Ssa::Definition def, Function f) {
+ exists(Ssa::Definition ultimate |
+ ultimate =
+ Ssa::GetAnUltimateDefinition::getAnUltimateDefinition(def) and
+ isRelevantUltimateDefinition(ultimate, f)
+ )
}
+ class SourceSinkReportingElement extends Element {
+ SourceSinkReportingElement() { this instanceof Expr or this instanceof Parameter }
+
+ DataFlowCallable getEnclosingCallable() {
+ result.asSourceCallable() =
+ [this.(Expr).getEnclosingFunction(), this.(Parameter).getFunction()]
+ }
+
+ /** Gets the function invoked when this element is used as a callback. */
+ private Function getCallable() {
+ // The expression is a struct which implements `operator()`.
+ result = getFunctionFromType(this)
+ or
+ // The expression is a function pointer
+ result = getFunctionFromExpr(this)
+ or
+ // The expression is an SSA read of an assignment of a callable
+ exists(Ssa::Definition def |
+ def.getAUse().getDef().getUnconvertedResultExpression() = this and
+ hasAnUltimateFunctionAccessDefinition(def, result)
+ )
+ }
+
+ SourceSinkReportingElement getASuccessor(Impl::Private::SummaryComponent sc) {
+ exists(Function f | f = this.getCallable() |
+ exists(ParameterPosition pos | sc = Impl::Private::SummaryComponent::parameter(pos) |
+ result = pos.getParameter(f)
+ )
+ or
+ exists(ReturnKind rk |
+ sc = Impl::Private::SummaryComponent::return(rk) and
+ isReturnExpr(f, rk, result)
+ )
+ )
+ }
+ }
+
+ bindingset[source, sc]
+ SourceSinkReportingElement getASourceReportingElement(
+ Input::SummarizedCallableBase source, Impl::Private::SummaryComponent sc
+ ) {
+ exists(Call call | call.getTarget() = source |
+ sc = Impl::Private::SummaryComponent::return(_) and
+ result = call
+ or
+ exists(ArgumentPosition pos |
+ sc = Impl::Private::SummaryComponent::argument(pos) and
+ result = pos.getArgument(call)
+ )
+ )
+ or
+ exists(ParameterPosition pos |
+ sc = Impl::Private::SummaryComponent::parameter(pos) and
+ result = pos.getParameter(source)
+ )
+ }
+
+ pragma[nomagic]
+ private IndirectReturnOutNode getIndirectReturn(CallInstruction call, NormalReturnKind rk) {
+ result.getCallInstruction() = call and
+ pragma[only_bind_out](result.getIndirectionIndex()) =
+ pragma[only_bind_out](rk.getIndirectionIndex())
+ }
+
+ pragma[nomagic]
+ private predicate hasKindAndEnclosingFunction(Function f, ReturnKind rk, ReturnNode r) {
+ r.getEnclosingCallable().asSourceCallable() = f and
+ pragma[only_bind_into](r).getKind() = rk
+ }
+
+ pragma[nomagic]
+ private predicate hasParameterAndIndirectionIndex(
+ Parameter p, int indirectionIndex, ParameterNode n
+ ) {
+ n.getParameter() = p and
+ n.getIndirectionIndex() = indirectionIndex
+ }
+
+ bindingset[e, sc]
+ Node getSourceDataFlowNode(SourceSinkReportingElement e, Impl::Private::SummaryComponent sc) {
+ exists(DataFlowCall call |
+ exists(ArgumentPosition pos |
+ sc = Impl::Private::SummaryComponent::argument(pos) and
+ pos.getArgument(call.asCallInstruction().getUnconvertedResultExpression()) = e
+ |
+ pos.getIndirectionIndex() = 0 and
+ result.(PostUpdateNode).getPreUpdateNode().asExpr() = e
+ or
+ result.(PostUpdateNode).getPreUpdateNode().asIndirectExpr(pos.getIndirectionIndex()) = e
+ )
+ or
+ exists(ReturnKind rk |
+ sc = Impl::Private::SummaryComponent::return(rk) and
+ // When `e` is a call the node becomes an `OutNode`.
+ e = call.asCallInstruction().getUnconvertedResultExpression()
+ |
+ rk.getIndirectionIndex() = 0 and
+ simpleOutNode(result, call.asCallInstruction())
+ or
+ result = getIndirectReturn(call.asCallInstruction(), rk)
+ )
+ )
+ or
+ exists(ParameterPosition pos |
+ sc = Impl::Private::SummaryComponent::parameter(pos) and
+ hasParameterAndIndirectionIndex(e, pos.getIndirectionIndex(), result)
+ )
+ or
+ exists(Function f, ReturnKind rk |
+ sc = Impl::Private::SummaryComponent::return(rk) and
+ // When `e` is the returned expression from a function the node is
+ // the `ReturnNode`.
+ isReturnExpr(f, rk, e) and
+ hasKindAndEnclosingFunction(f, rk, result)
+ )
+ }
+
+ bindingset[sink, sc]
+ SourceSinkReportingElement getASinkReportingElement(
+ Input::SummarizedCallableBase sink, Impl::Private::SummaryComponent sc
+ ) {
+ exists(Call call, ArgumentPosition pos |
+ call.getTarget() = sink and
+ sc = Impl::Private::SummaryComponent::argument(pos) and
+ result = pos.getArgument(call)
+ )
+ }
+
+ bindingset[e, sc]
+ Node getSinkDataFlowNode(SourceSinkReportingElement e, Impl::Private::SummaryComponent sc) {
+ exists(ArgumentPosition pos, CallInstruction call |
+ sc = Impl::Private::SummaryComponent::argument(pos) and
+ pos.getArgument(call.getUnconvertedResultExpression()) = e and
+ result.(ArgumentNode).sourceArgumentOf(call, pos)
+ )
+ or
+ exists(Function f, ReturnKind rk |
+ sc = Impl::Private::SummaryComponent::return(rk) and
+ isReturnExpr(f, rk, e) and
+ hasKindAndEnclosingFunction(f, rk, result)
+ )
+ }
+}
+
+private import Impl::Private::Make2 as Impl2
+
+private module StepsInput implements Impl2::StepsInputSig {
+ Impl2::SummaryNode getSummaryNode(Node n) { result = n.(FlowSummaryNode).getSummaryNode() }
+
DataFlowCall getACall(Public::SummarizedCallable sc) {
result.getStaticCallTarget().getUnderlyingCallable() = sc
}
@@ -148,12 +352,6 @@ private module StepsInput implements Impl::Private::StepsInputSig {
pragma[only_bind_out](out.getIndirectionIndex())
)
}
-
- DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() }
-
- Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() }
-
- Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}
module SourceSinkInterpretationInput implements
@@ -270,8 +468,9 @@ module SourceSinkInterpretationInput implements
module Private {
import Impl::Private
+ import Impl2
- module Steps = Impl::Private::Steps;
+ module Steps = Impl2::Steps;
module External {
import Impl::Private::External
@@ -310,3 +509,45 @@ module Private {
}
module Public = Impl::Public;
+
+private class SourceModelFunction extends Public::SourceElement instanceof Function {
+ private string namespace;
+ private string type;
+ private boolean subtypes;
+ private string name;
+ private string signature;
+ private string ext;
+
+ SourceModelFunction() {
+ sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) and
+ this = interpretElement(namespace, type, subtypes, name, signature, ext)
+ }
+
+ override predicate isSource(
+ string output, string kind, Public::Provenance provenance, boolean isExact, string model
+ ) {
+ sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) and
+ isExact = true
+ }
+}
+
+private class SinkModelFunction extends Public::SinkElement instanceof Function {
+ private string namespace;
+ private string type;
+ private boolean subtypes;
+ private string name;
+ private string signature;
+ private string ext;
+
+ SinkModelFunction() {
+ sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) and
+ this = interpretElement(namespace, type, subtypes, name, signature, ext)
+ }
+
+ override predicate isSink(
+ string input, string kind, Public::Provenance provenance, boolean isExact, string model
+ ) {
+ sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance, model) and
+ isExact = true
+ }
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll
index 2246a887b9c1..be7636fdadee 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll
@@ -353,6 +353,21 @@ class BuiltInOperationIsBaseOf extends BuiltInOperation, @isbaseofexpr {
override string getAPrimaryQlClass() { result = "BuiltInOperationIsBaseOf" }
}
+/**
+ * A C++ `__builtin_is_virtual_base_of` built-in operation (used by some implementations of the
+ * `` header).
+ *
+ * Returns `true` if the first type is a virtual base class of the second type.
+ * ```
+ * bool v = __builtin_is_virtual_base_of(MyType, OtherType);
+ * ```
+ */
+class BuiltInOperationIsVirtualBaseOf extends BuiltInOperation, @isvirtualbaseof {
+ override string toString() { result = "__builtin_is_virtual_base_of" }
+
+ override string getAPrimaryQlClass() { result = "BuiltInOperationIsVirtualBaseOf" }
+}
+
/**
* A C++ `__is_class` built-in operation (used by some implementations of the
* `` header).
@@ -1999,3 +2014,105 @@ class BuiltInOperationIsNothrowInvocable extends BuiltInOperation, @isnothrowinv
override string getAPrimaryQlClass() { result = "BuiltInOperationIsNothrowInvocable" }
}
+
+/**
+ * A C++ `__builtin_is_implicit_lifetime` built-in operation (used by some implementations
+ * of the `` header).
+ *
+ * Returns `true` if a type `_Tp` is an implicit lifetime type.
+ *
+ * ```
+ * template
+ * constexpr bool is_implicit_lifetime = __builtin_is_implicit_lifetime(_Tp);
+ * ```
+ */
+class BuiltInOperationIsImplicitLifetime extends BuiltInOperation, @isimplicitlifetime {
+ override string toString() { result = "__builtin_is_implicit_lifetime" }
+
+ override string getAPrimaryQlClass() { result = "BuiltInOperationIsImplicitLifetime" }
+}
+
+/**
+ * A C++ `__builtin_is_structural` built-in operation (used by some implementations
+ * of the `` header).
+ *
+ * Returns `true` if a type `_Tp` is structural type.
+ *
+ * ```
+ * template
+ * constexpr bool is_structural = __builtin_is_structural(_Tp);
+ * ```
+ */
+class BuiltInOperationIsStructural extends BuiltInOperation, @isstructural {
+ override string toString() { result = "__builtin_is_structural" }
+
+ override string getAPrimaryQlClass() { result = "BuiltInOperationIsStructural" }
+}
+
+/**
+ * A C++ `__builtin_lt_synthesizes_from_spaceship` built-in operation (used by some container
+ * implementations).
+ *
+ * Returns `true` if the `<` operator is synthesized from the spaceship operator `<=>`.
+ *
+ * ```
+ * bool v = __builtin_lt_synthesizes_from_spaceship(MyType, OtherType);
+ */
+class BuiltInOperationLtSynthesizesFromSpaceship extends BuiltInOperation,
+ @ltsynthesizesfromspaceship
+{
+ override string toString() { result = "__builtin_lt_synthesizes_from_spaceship" }
+
+ override string getAPrimaryQlClass() { result = "BuiltInOperationLtSynthesizesFromSpaceship" }
+}
+
+/**
+ * A C++ `__builtin_gt_synthesizes_from_spaceship` built-in operation (used by some container
+ * implementations).
+ *
+ * Returns `true` if the `>` operator is synthesized from the spaceship operator `<=>`.
+ *
+ * ```
+ * bool v = __builtin_gt_synthesizes_from_spaceship(MyType, OtherType);
+ */
+class BuiltInOperationGtSynthesizesFromSpaceship extends BuiltInOperation,
+ @gtsynthesizesfromspaceship
+{
+ override string toString() { result = "__builtin_gt_synthesizes_from_spaceship" }
+
+ override string getAPrimaryQlClass() { result = "BuiltInOperationGtSynthesizesFromSpaceship" }
+}
+
+/**
+ * A C++ `__builtin_le_synthesizes_from_spaceship` built-in operation (used by some container
+ * implementations).
+ *
+ * Returns `true` if the `<=` operator is synthesized from the spaceship operator `<=>`.
+ *
+ * ```
+ * bool v = __builtin_le_synthesizes_from_spaceship(MyType, OtherType);
+ */
+class BuiltInOperationLeSynthesizesFromSpaceship extends BuiltInOperation,
+ @lesynthesizesfromspaceship
+{
+ override string toString() { result = "__builtin_le_synthesizes_from_spaceship" }
+
+ override string getAPrimaryQlClass() { result = "BuiltInOperationLeSynthesizesFromSpaceship" }
+}
+
+/**
+ * A C++ `__builtin_ge_synthesizes_from_spaceship` built-in operation (used by some container
+ * implementations).
+ *
+ * Returns `true` if the `>=` operator is synthesized from the spaceship operator `<=>`.
+ *
+ * ```
+ * bool v = __builtin_ge_synthesizes_from_spaceship(MyType, OtherType);
+ */
+class BuiltInOperationGeSynthesizesFromSpaceship extends BuiltInOperation,
+ @gesynthesizesfromspaceship
+{
+ override string toString() { result = "__builtin_ge_synthesizes_from_spaceship" }
+
+ override string getAPrimaryQlClass() { result = "BuiltInOperationGeSynthesizesFromSpaceship" }
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll
index 851d987b1fd6..82824445ccf2 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll
@@ -108,7 +108,8 @@ class Expr extends StmtParent, @expr {
/** Holds if this is an auxiliary expression generated by the compiler. */
predicate isCompilerGenerated() {
compgenerated(underlyingElement(this)) or
- this.getParent().(ConstructorFieldInit).isCompilerGenerated()
+ this.getParent().(ConstructorFieldInit).isCompilerGenerated() or
+ this.getParent().(Initializer).isCompilerGenerated()
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll
index 31e2b5135b42..7238ea2a35ed 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll
@@ -133,6 +133,19 @@ class StringLiteral extends TextLiteral {
override string getAPrimaryQlClass() { result = "StringLiteral" }
}
+/**
+ * A C++ raw string literal. For example:
+ * ```
+ * const char *s1 = R"(abcdef)";
+ * const wchar_t *s2 = LR"x(123456)x";
+ * ```
+ */
+class RawStringLiteral extends StringLiteral {
+ RawStringLiteral() { this.getValueText().regexpMatch("[^\"]*R\".*\\(.*") }
+
+ override string getAPrimaryQlClass() { result = "RawStringLiteral" }
+}
+
/**
* An octal literal. For example:
* ```
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 bce936552768..03a565ef946d 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
@@ -131,6 +131,15 @@ private predicate qualifierSourceImpl(RelevantNode n, Class c) {
)
}
+pragma[nomagic]
+private predicate hasKindAndEnclosingCallable(
+ DataFlowPrivate::DataFlowCallable callable, DataFlowPrivate::ReturnKind kind,
+ DataFlowPrivate::ReturnNode return
+) {
+ return.getEnclosingCallable() = callable and
+ return.getKind() = kind
+}
+
private module TrackVirtualDispatch {
/**
* Gets a possible runtime target of `c` using both static call-target
@@ -197,11 +206,21 @@ private module TrackVirtualDispatch {
)
}
+ pragma[nomagic]
+ private predicate hasDispatchWithKind(
+ DataFlowPrivate::DataFlowCallable callable, DataFlowPrivate::ReturnKind kind,
+ LocalSourceNode n2
+ ) {
+ exists(DataFlowPrivate::DataFlowCall call |
+ n2 = DataFlowPrivate::getAnOutNode(call, kind) and
+ callable = dispatch(call)
+ )
+ }
+
predicate returnStep(Node n1, LocalSourceNode n2) {
- exists(DataFlowPrivate::DataFlowCallable callable, DataFlowPrivate::DataFlowCall call |
- n1.(DataFlowPrivate::ReturnNode).getEnclosingCallable() = callable and
- callable = dispatch(call) and
- n2 = DataFlowPrivate::getAnOutNode(call, n1.(DataFlowPrivate::ReturnNode).getKind())
+ exists(DataFlowPrivate::DataFlowCallable callable, DataFlowPrivate::ReturnKind kind |
+ hasKindAndEnclosingCallable(callable, kind, n1) and
+ hasDispatchWithKind(callable, kind, n2)
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll
index 6b0de326d114..3b900320882b 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll
@@ -6,6 +6,8 @@
private import cpp
private import DataFlowImplSpecific
private import TaintTrackingImplSpecific
+private import DataFlowNodes as Nodes
+private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
private import codeql.dataflow.internal.DataFlowImplConsistency
private module Input implements InputSig {
@@ -14,6 +16,12 @@ private module Input implements InputSig {
// complex to model here.
any()
}
+
+ predicate postWithInFlowExclude(CppDataFlow::Node n) {
+ n instanceof Nodes::FlowSummaryNode
+ or
+ FlowSummaryImpl::Private::Steps::summaryLocalStep(_, n, _, _)
+ }
}
module Consistency = MakeConsistency;
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 abcff398420c..9dbf7f8e73c5 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
@@ -3,6 +3,7 @@ private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
+private import semmle.code.cpp.dataflow.ExternalFlow as External
private import DataFlowPrivate
private import DataFlowUtil
private import ModelUtil
@@ -144,7 +145,7 @@ private module Cached {
TNonUnionContent(CanonicalField f, int indirectionIndex) {
// the indirection index for field content starts at 1 (because `TNonUnionContent` is thought of as
// the address of the field, `FieldAddress` in the IR).
- indirectionIndex = [1 .. max(SsaImpl::getMaxIndirectionsForType(f.getAnUnspecifiedType()))] and
+ indirectionIndex = [1 .. max(SsaImpl::getMaxIndirectionsForGLType(f.getAnUnspecifiedType()))] and
// Reads and writes of union fields are tracked using `UnionContent`.
not f.getDeclaringType() instanceof Union
} or
@@ -156,7 +157,7 @@ private module Cached {
// field can be read by any read of the union's fields. Again, the indirection index
// is 1-based (because 0 is considered the address).
indirectionIndex =
- [1 .. max(SsaImpl::getMaxIndirectionsForType(getAFieldWithSize(u, bytes)
+ [1 .. max(SsaImpl::getMaxIndirectionsForGLType(getAFieldWithSize(u, bytes)
.getAnUnspecifiedType())
)]
)
@@ -184,13 +185,16 @@ private module Cached {
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
TGlobalLikeVariableNode(GlobalLikeVariable var, int indirectionIndex) {
indirectionIndex =
- [getMinIndirectionsForType(var.getUnspecifiedType()) .. SsaImpl::getMaxIndirectionsForType(var.getUnspecifiedType())]
+ [getMinIndirectionsForType(var.getUnspecifiedType()) .. SsaImpl::getMaxIndirectionsForGLType(var.getUnspecifiedType())]
} or
TPostUpdateNodeImpl(Operand operand, int indirectionIndex) {
isPostUpdateNodeImpl(operand, indirectionIndex)
} or
TSsaSynthNode(SsaImpl::SynthNode n) or
TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or
+ TForwarderConstructorArgumentNode(CallInstruction call) {
+ External::ConstructorForwarding::isForwarderConstructorArgumentNodeImpl(call)
+ } or
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
SsaImpl::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
} or
@@ -209,10 +213,7 @@ private module Cached {
TBodyLessParameterNodeImpl(Parameter p, int indirectionIndex) {
// Rule out parameters of catch blocks.
not exists(p.getCatchBlock()) and
- // We subtract one because `getMaxIndirectionsForType` returns the maximum
- // indirection for a glvalue of a given type, and this doesn't apply to
- // parameters.
- indirectionIndex = [0 .. SsaImpl::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and
+ indirectionIndex = [0 .. SsaImpl::getMaxIndirectionsForPRType(p.getUnspecifiedType())] and
not any(InitializeParameterInstruction init).getParameter() = p
} or
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn)
@@ -1535,12 +1536,49 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
}
override DataFlowCallable getEnclosingCallable() {
- result = FlowSummaryImpl::Private::getEnclosingCallable(this.getSummaryNode())
+ result = this.getSummaryNode().getEnclosingCallable()
}
- override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }
+ override Location getLocationImpl() { result = this.getSummaryNode().getLocation() }
override string toStringImpl() { result = this.getSummaryNode().toString() }
+
+ /** Gets the source element that this node belongs to, if any. */
+ FlowSummaryImpl::Public::SourceElement getSourceElement() {
+ result = this.getSummaryNode().getSourceElement()
+ }
+
+ /** Gets the sink element that this node belongs to, if any. */
+ FlowSummaryImpl::Public::SinkElement getSinkElement() {
+ result = this.getSummaryNode().getSinkElement()
+ }
+
+ /** Holds if this node is a source node of kind `kind`. */
+ predicate isSource(string kind, string model) {
+ this.getSummaryNode().(FlowSummaryImpl::Private::SourceOutputNode).isEntry(kind, model)
+ }
+
+ /** Holds if this node is a sink node of kind `kind`. */
+ predicate isSink(string kind, string model) {
+ this.getSummaryNode().(FlowSummaryImpl::Private::SinkInputNode).isExit(kind, model)
+ }
+}
+
+private class SourceOutputNode extends FlowSummaryImpl::Private::SourceOutputNode {
+ final override string toString() {
+ exists(Call call |
+ this.isOutArgument(call) and
+ result = call.getTarget() + " output argument"
+ )
+ or
+ not this.isOutArgument(_) and
+ result = super.toString()
+ }
+
+ private predicate isOutArgument(Call call) {
+ call.getTarget() = this.getSourceElement() and
+ [call.getAnArgument(), call.getQualifier()] = this.getSourceSinkReportingElement()
+ }
}
/**
@@ -1655,13 +1693,13 @@ abstract private class AbstractParameterNode extends Node {
* Holds if this node represents an implicit `this` parameter, if it exists.
*/
predicate isThis() { none() } // overridden by subclasses
-}
-abstract private class AbstractIndirectParameterNode extends AbstractParameterNode {
/** Gets the indirection index of this parameter node. */
- abstract int getIndirectionIndex();
+ int getIndirectionIndex() { none() }
}
+abstract private class AbstractIndirectParameterNode extends AbstractParameterNode { }
+
pragma[noinline]
private predicate indirectParameterNodeHasArgumentIndexAndIndex(
IndirectInstructionParameterNode node, int argumentIndex, int indirectionIndex
@@ -1725,7 +1763,9 @@ private class IndirectInstructionParameterNode extends AbstractIndirectParameter
final override int getIndirectionIndex() { this.hasInstructionAndIndirectionIndex(init, result) }
}
-abstract private class AbstractDirectParameterNode extends AbstractParameterNode { }
+abstract private class AbstractDirectParameterNode extends AbstractParameterNode {
+ override int getIndirectionIndex() { result = 0 }
+}
/**
* A non-indirect parameter node that is represented as an `Instruction`.
@@ -1796,6 +1836,8 @@ private class DirectBodyLessParameterNode extends AbstractExplicitParameterNode,
}
override Parameter getParameter() { result = p }
+
+ final override int getIndirectionIndex() { result = 0 }
}
private class IndirectBodyLessParameterNode extends AbstractIndirectParameterNode,
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 cdcbaa438d3a..492e2ca1c022 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
@@ -119,8 +119,48 @@ private module Cached {
)
or
// models-as-data summarized flow
- FlowSummaryImpl::Private::Steps::summaryJumpStep(n1.(FlowSummaryNode).getSummaryNode(),
- n2.(FlowSummaryNode).getSummaryNode())
+ FlowSummaryImpl::Private::Steps::summaryJumpStep(n1, n2)
+ }
+
+ bindingset[store]
+ pragma[inline_late]
+ private predicate nodeHasInstructionLate(Node node, StoreInstruction store, int indirectionIndex) {
+ nodeHasInstruction(node, store, indirectionIndex)
+ }
+
+ pragma[nomagic]
+ private predicate storeStepSource(
+ Operand fieldAddress, int contentIndirectionIndex, Node node, boolean certain
+ ) {
+ exists(int indirectionIndex, int numberOfLoads, StoreInstruction store |
+ nodeHasInstructionLate(node, store, indirectionIndex) and
+ numberOfLoadsFromOperand(fieldAddress, store.getDestinationAddressOperand(), numberOfLoads,
+ certain) and
+ contentIndirectionIndex = 1 + indirectionIndex + numberOfLoads
+ )
+ }
+
+ pragma[nomagic]
+ private predicate hasFieldAddressAndField(Field f, PostFieldUpdateNode pfu, Operand fieldAddress) {
+ pfu.getIndirectionIndex() = 1 and
+ pfu.getUpdatedField() = f and
+ pfu.getFieldAddress() = fieldAddress
+ }
+
+ pragma[nomagic]
+ private predicate hasFieldAndIndirectionIndex(Field f, int indirectionIndex, FieldContent fc) {
+ fc.getAField() = f and
+ fc.getIndirectionIndex() = indirectionIndex
+ }
+
+ pragma[nomagic]
+ private predicate storeStepTarget(
+ Operand address, int indirectionIndex, PostFieldUpdateNode pfu, FieldContent fc
+ ) {
+ exists(Field f |
+ hasFieldAddressAndField(f, pfu, address) and
+ hasFieldAndIndirectionIndex(f, indirectionIndex, fc)
+ )
}
/**
@@ -133,19 +173,9 @@ private module Cached {
*/
cached
predicate storeStepImpl(Node node1, Content c, Node node2, boolean certain) {
- exists(
- PostFieldUpdateNode postFieldUpdate, int indirectionIndex1, int numberOfLoads,
- StoreInstruction store, FieldContent fc
- |
- postFieldUpdate = node2 and
- fc = c and
- nodeHasInstruction(node1, pragma[only_bind_into](store),
- pragma[only_bind_into](indirectionIndex1)) and
- postFieldUpdate.getIndirectionIndex() = 1 and
- numberOfLoadsFromOperand(postFieldUpdate.getFieldAddress(),
- store.getDestinationAddressOperand(), numberOfLoads, certain) and
- fc.getAField() = postFieldUpdate.getUpdatedField() and
- getIndirectionIndexLate(fc) = 1 + indirectionIndex1 + numberOfLoads
+ exists(Operand fieldAddress, int indirectionIndex |
+ storeStepSource(fieldAddress, indirectionIndex, node1, certain) and
+ storeStepTarget(fieldAddress, indirectionIndex, node2, c)
)
or
// models-as-data summarized flow
@@ -509,11 +539,31 @@ predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos)
* on parameters are also included.
*/
abstract class ArgumentNode extends Node {
+ /**
+ * Holds if this argument occurs at the given position in the given call,
+ * and this call is represented in the source code.
+ * The instance argument is considered to have index `-1`.
+ */
+ predicate sourceArgumentOf(CallInstruction call, ArgumentPosition pos) { none() }
+
+ /**
+ * Holds if this argument occurs at the given position in the given call,
+ * and this call is part of a summary.
+ * The instance argument is considered to have index `-1`.
+ */
+ predicate summaryArgumentOf(FlowSummaryImpl::Public::SummarizedCallable call, ArgumentPosition pos) {
+ none()
+ }
+
/**
* Holds if this argument occurs at the given position in the given call.
* The instance argument is considered to have index `-1`.
*/
- abstract predicate argumentOf(DataFlowCall call, ArgumentPosition pos);
+ final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
+ this.sourceArgumentOf(call.asCallInstruction(), pos)
+ or
+ this.summaryArgumentOf(call.asSummaryCall(), pos)
+ }
/** Gets the call in which this node is an argument. */
DataFlowCall getCall() { this.argumentOf(result, _) }
@@ -528,21 +578,77 @@ private class PrimaryArgumentNode extends ArgumentNode, OperandNode {
PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) }
- override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
+ override predicate sourceArgumentOf(CallInstruction call, ArgumentPosition pos) {
op = call.getArgumentOperand(pos.(DirectPosition).getArgumentIndex())
}
}
private class SideEffectArgumentNode extends ArgumentNode, SideEffectOperandNode {
- override predicate argumentOf(DataFlowCall dfCall, ArgumentPosition pos) {
+ override predicate sourceArgumentOf(CallInstruction c, ArgumentPosition pos) {
exists(int indirectionIndex |
pos = TIndirectionPosition(argumentIndex, pragma[only_bind_into](indirectionIndex)) and
- this.getCallInstruction() = dfCall.asCallInstruction() and
+ this.getCallInstruction() = c and
super.hasAddressOperandAndIndirectionIndex(arg, pragma[only_bind_into](indirectionIndex))
)
}
}
+/**
+ * In order to implement a MaD summary for a flow such as:
+ * ```
+ * struct Foo {
+ * int x;
+ * Foo(int x) { // (2)
+ * this->x = x;
+ * }
+ * }
+ *
+ * std::vector v;
+ * int x = source();
+ * v.emplace_back(x); // (1)
+ * sink(v.back());
+ * ```
+ * we model it as if the code was:
+ * ```
+ * v.__emplace_back(x, &Foo)
+ * ```
+ * (never mind that this is not real C++ since you cannot take the address of a
+ * constructor.)
+ * where `__emplace_back` invokes `Foo` with the `x` argument and returns the
+ * result.
+ *
+ * This class serves as the argument node for `&Foo`.
+ */
+private class ForwarderConstructorArgumentNode extends ArgumentNode,
+ TForwarderConstructorArgumentNode
+{
+ private CallInstruction call;
+
+ ForwarderConstructorArgumentNode() { this = TForwarderConstructorArgumentNode(call) }
+
+ override predicate sourceArgumentOf(CallInstruction c, ArgumentPosition pos) {
+ c = call and pos = TForwardPosition()
+ }
+
+ /**
+ * Gets a constructor which may be targeted by this forwarding call.
+ */
+ Cpp::Constructor getAConstructor() {
+ result =
+ External::ConstructorForwarding::getForwardingConstructor(call.getStaticCallTarget(), _)
+ }
+
+ override DataFlowCallable getEnclosingCallable() {
+ result.asSourceCallable() = this.getFunction()
+ }
+
+ override Declaration getFunction() { result = call.getEnclosingFunction() }
+
+ override Location getLocationImpl() { result = call.getLocation() }
+
+ override string toStringImpl() { result = "forwarder for " + call.toString() }
+}
+
/**
* An argument node that is part of a summary. These only occur when the
* summary contains a synthesized call.
@@ -555,8 +661,10 @@ class SummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
FlowSummaryImpl::Private::summaryArgumentNode(call_.getReceiver(), this.getSummaryNode(), pos_)
}
- override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
- call = call_ and
+ override predicate summaryArgumentOf(
+ FlowSummaryImpl::Public::SummarizedCallable call, ArgumentPosition pos
+ ) {
+ call = call_.asSummaryCall() and
pos = pos_
}
}
@@ -570,8 +678,8 @@ private class FlowSummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
this.getSummaryNode() = FlowSummaryImpl::Private::summaryArgumentNode(callInstruction, rk)
}
- override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
- call.asCallInstruction() = callInstruction and
+ override predicate sourceArgumentOf(CallInstruction call, ArgumentPosition pos) {
+ call = callInstruction and
pos = TFlowSummaryPosition(rk)
}
}
@@ -594,6 +702,38 @@ abstract class Position extends TPosition {
/** Gets the indirection index of this position. */
abstract int getIndirectionIndex();
+
+ /**
+ * Gets the parameter of `f` associated with this position, if any.
+ *
+ * Since a `Position` is defined by both an argument index and an
+ * indirection multiple `Position`s can be associated with the
+ * same `Parameter`.
+ */
+ Parameter getParameter(Function f) {
+ result.getFunction() = f and
+ this.getArgumentIndex() = result.getIndex()
+ }
+
+ /**
+ * Gets the argument (or qualifier) of `call` associated with this position, if any.
+ *
+ * Since a `Position` is defined by both an argument index and an
+ * indirection multiple `Position`s can be associated with the
+ * same argument/qualifier.
+ */
+ Expr getArgument(Cpp::Call call) {
+ result = call.getArgument(this.getArgumentIndex())
+ or
+ this.getArgumentIndex() = -1 and
+ result = call.getQualifier()
+ }
+
+ /**
+ * Holds if this position is the synthetic argument for an address of a
+ * constructor used for functions which perform "perfect forwarding".
+ */
+ predicate isForward() { none() }
}
class DirectPosition extends Position, TDirectPosition {
@@ -643,6 +783,16 @@ class FlowSummaryPosition extends Position, TFlowSummaryPosition {
final override int getIndirectionIndex() { result = rk.getIndirectionIndex() }
}
+class ForwardPosition extends Position, TForwardPosition {
+ final override predicate isForward() { any() }
+
+ override int getArgumentIndex() { none() }
+
+ final override int getIndirectionIndex() { result = 0 }
+
+ override string toString() { result = "forward" }
+}
+
newtype TPosition =
TDirectPosition(int argumentIndex) {
exists(any(CallInstruction c).getArgument(argumentIndex))
@@ -659,9 +809,10 @@ newtype TPosition =
// the function.
exists(Cpp::Function f, Cpp::Parameter p |
p = f.getParameter(argumentIndex) and
- indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1]
+ indirectionIndex = [1 .. Ssa::getMaxIndirectionsForPRType(p.getUnspecifiedType())]
)
} or
+ TForwardPosition() or
TFlowSummaryPosition(ReturnKind rk) { FlowSummaryImpl::Private::relevantFlowSummaryPosition(rk) }
private newtype TReturnKind =
@@ -677,7 +828,7 @@ private newtype TReturnKind =
[0 .. max(Cpp::Function f |
not exists(f.getBlock())
|
- Ssa::getMaxIndirectionsForType(f.getUnspecifiedType()) - 1 // -1 because a returned value is a prvalue not a glvalue
+ Ssa::getMaxIndirectionsForPRType(f.getUnspecifiedType())
)]
} or
TIndirectReturnKind(int argumentIndex, int indirectionIndex) {
@@ -692,7 +843,7 @@ private newtype TReturnKind =
[0 .. max(Cpp::Function f |
not exists(f.getBlock())
|
- Ssa::getMaxIndirectionsForType(f.getParameter(argumentIndex).getUnspecifiedType()) - 1 // -1 because an argument is a prvalue not a glvalue
+ Ssa::getMaxIndirectionsForPRType(f.getParameter(argumentIndex).getUnspecifiedType())
)]
}
@@ -1180,6 +1331,19 @@ private predicate summarizedCallableIsManual(SummarizedCallable sc) {
sc.asSummarizedCallable().hasManualModel()
}
+private DataFlowCallable getTarget(Declaration target) {
+ // Don't use the source callable if there is a manual model for the target.
+ not exists(SummarizedCallable sc |
+ sc.asSummarizedCallable() = target and
+ summarizedCallableIsManual(sc)
+ ) and
+ result.asSourceCallable() = target
+ or
+ // When there is no function body, or when we have a manual model, dispatch to the summary.
+ (not target.hasDefinition() or summarizedCallableIsManual(result)) and
+ result.asSummarizedCallable() = target
+}
+
/**
* A function call relevant for data flow. This includes calls from source
* code and calls inside library callables with a flow summary.
@@ -1190,6 +1354,11 @@ class DataFlowCall extends TDataFlowCall {
*/
CallInstruction asCallInstruction() { none() }
+ /**
+ * Gets the underlying summarized call, if any.
+ */
+ FlowSummaryImpl::Public::SummarizedCallable asSummaryCall() { none() }
+
/**
* Gets the operand the specifies the target function of the call.
*/
@@ -1210,20 +1379,7 @@ class DataFlowCall extends TDataFlowCall {
* whether is it manual or generated.
*/
final DataFlowCallable getStaticCallTarget() {
- 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 |
- sc.asSummarizedCallable() = target and
- summarizedCallableIsManual(sc)
- ) and
- result.asSourceCallable() = target
- or
- // When there is no function body, or when we have a manual model then
- // we dispatch to the summary.
- (not target.hasDefinition() or summarizedCallableIsManual(result)) and
- result.asSummarizedCallable() = target
- )
+ result = getTarget(this.getStaticCallSourceTarget())
}
/**
@@ -1307,6 +1463,8 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
*/
FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver }
+ final override FlowSummaryImpl::Public::SummarizedCallable asSummaryCall() { result = c }
+
// no implementation for `getCallTargetOperand()`, `getStaticCallTarget()`
// or `getArgumentOperand(int index)`. This is because the flow summary
// library is responsible for finding the call target, and there are no
@@ -1408,6 +1566,8 @@ predicate nodeIsHidden(Node n) {
n instanceof SsaSynthNode
or
n.(FlowSummaryNode).getSummaryNode().isHidden()
+ or
+ n instanceof ForwarderConstructorArgumentNode
}
predicate neverSkipInPathGraph(Node n) {
@@ -1489,6 +1649,9 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
kind.isFunctionPointer() and
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable()
or
+ kind.isFunctionPointer() and
+ c = getTarget(creation.(ForwarderConstructorArgumentNode).getAConstructor())
+ or
kind.isFunctor() and
exists(OperatorCall operator | operator = c.asSourceCallable() |
isFunctorCreationWithoutConstructor(creation, operator)
@@ -1923,13 +2086,23 @@ module IteratorFlow {
}
/**
- * Gets an ultimate definition of `def`.
- *
- * Note: Unlike `def.getAnUltimateDefinition()` this predicate also
- * traverses back through iterator increment and decrement operations.
+ * Holds if `write` is an instruction that writes to address `address`
*/
- private Ssa::Definition getAnUltimateDefinition(Ssa::Definition def) {
- result = def.getAnUltimateDefinition()
+ private predicate isIteratorWrite(Instruction write, Operand address) {
+ exists(Ssa::DefImpl writeDef, IRBlock bb, int i |
+ writeDef.hasIndexInBlock(_, bb, i) and
+ bb.getInstruction(i) = write and
+ address = writeDef.getAddressOperand()
+ )
+ }
+
+ private module GetAnUltimateDefinitionInput implements Ssa::GetAnUltimateDefinitionSig {
+ predicate isRelevantUltimateDefinition(Ssa::Definition def) { fwd(_, def) }
+ }
+
+ private Ssa::Definition getAnUltimateDefinitionStep(Ssa::Definition def) {
+ result =
+ Ssa::GetAnUltimateDefinition::getAnUltimateDefinition(def)
or
exists(IRBlock bb, int i, IteratorCrementCall crementCall, Ssa::SourceVariable sv |
crementCall = def.getValue().asInstruction().(StoreInstruction).getSourceValue() and
@@ -1939,14 +2112,28 @@ module IteratorFlow {
)
}
- /**
- * Holds if `write` is an instruction that writes to address `address`
- */
- private predicate isIteratorWrite(Instruction write, Operand address) {
- exists(Ssa::DefImpl writeDef, IRBlock bb, int i |
- writeDef.hasIndexInBlock(_, bb, i) and
- bb.getInstruction(i) = write and
- address = writeDef.getAddressOperand()
+ private predicate isSource(GetsIteratorCall beginCall, Ssa::Definition def) {
+ exists(StoreInstruction beginStore |
+ beginStore = def.getValue().asInstruction() and
+ operandForFullyConvertedCall(beginStore.getSourceValueOperand(), beginCall)
+ )
+ }
+
+ private predicate isSink(Instruction writeToDeref, Ssa::Definition def) {
+ exists(IteratorPointerDereferenceCall starCall, Operand address, IRBlock bbStar, int iStar |
+ isIteratorWrite(writeToDeref, address) and
+ operandForFullyConvertedCall(address, starCall) and
+ bbStar.getInstruction(iStar) = starCall and
+ Ssa::ssaDefReachesRead(_, def, bbStar, iStar)
+ )
+ }
+
+ private predicate fwd(GetsIteratorCall beginCall, Ssa::Definition def) {
+ isSource(beginCall, def)
+ or
+ exists(Ssa::Definition def0 |
+ fwd(beginCall, def0) and
+ def0 = getAnUltimateDefinitionStep(def)
)
}
@@ -1962,17 +2149,9 @@ module IteratorFlow {
private predicate isIteratorStoreInstruction(
GetsIteratorCall beginCall, Instruction writeToDeref
) {
- exists(
- StoreInstruction beginStore, IRBlock bbStar, int iStar, Ssa::Definition def,
- IteratorPointerDereferenceCall starCall, Ssa::Definition ultimate, Operand address
- |
- isIteratorWrite(writeToDeref, address) and
- operandForFullyConvertedCall(address, starCall) and
- bbStar.getInstruction(iStar) = starCall and
- Ssa::ssaDefReachesRead(_, def, bbStar, iStar) and
- ultimate = getAnUltimateDefinition*(def) and
- beginStore = ultimate.getValue().asInstruction() and
- operandForFullyConvertedCall(beginStore.getSourceValueOperand(), beginCall)
+ exists(Ssa::Definition def |
+ fwd(beginCall, def) and
+ isSink(writeToDeref, def)
)
}
@@ -2113,7 +2292,10 @@ module IteratorFlow {
predicate localFlowStep(Node nodeFrom, Node nodeTo) {
exists(SourceVariable v |
nodeFrom != nodeTo and
- DataFlowIntegrationImpl::localFlowStep(v, fromDfNode(nodeFrom, v), fromDfNode(nodeTo, v), _)
+ // Skip use-use steps. These are already accounted for by regular SSA
+ // flow including proper handling of `modeledFlowBarrier`.
+ DataFlowIntegrationImpl::localFlowStep(v, fromDfNode(nodeFrom, v), fromDfNode(nodeTo, v),
+ false)
)
}
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
index 2e3274c82c7c..17c3438f098a 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
@@ -158,8 +158,7 @@ private module Cached {
model = ""
or
// models-as-data summarized flow
- FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
- nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
+ FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true, model)
}
private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo) {
@@ -1019,4 +1018,6 @@ module Ssa {
class IndirectExplicitDefinition = SsaImpl::IndirectExplicitDefinition;
class PhiNode = SsaImpl::PhiNode;
+
+ import SsaImpl::Public
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll
index 432261dfe278..8f17c3c9a136 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll
@@ -1243,14 +1243,6 @@ private module IntWithParam {
}
module BarrierGuardWithIntParam::guardChecksNodeSig/5 guardChecksNode> {
- private predicate ssaDefReachesCertainUse(Definition def, UseImpl use) {
- exists(SourceVariable v, IRBlock bb, int i |
- use.hasIndexInBlock(bb, i, v) and
- variableRead(bb, i, v, true) and
- ssaDefReachesRead(v, def, bb, i)
- )
- }
-
private predicate guardChecksInstr(
IRGuards::Guards_v1::Guard g, IRGuards::GuardsInput::Expr instr, IRGuards::GuardValue gv,
ParamIntPair::TPair pair
@@ -1279,24 +1271,9 @@ module BarrierGuardWithIntParam::guardChecksNodeSig/
}
Node getABarrierNode(int indirectionIndex, P p) {
- // Only get the SynthNodes from the shared implementation, as the ExprNodes cannot
- // be matched on SourceVariable.
- result.(SsaSynthNode).getSynthNode() =
+ fromDfNode(result) =
DataFlowIntegrationImpl::BarrierGuardDefWithState::MkPair, guardChecksWithWrappers/4>::getABarrierNode(ParamIntPair::MkPair(p,
indirectionIndex))
- or
- // Calculate the guarded UseImpls corresponding to ExprNodes directly.
- exists(
- DataFlowIntegrationInput::Guard g, IRGuards::GuardValue branch, Definition def, IRBlock bb
- |
- exists(UseImpl use |
- guardChecksWithWrappers(g, def, branch, ParamIntPair
::MkPair(p, indirectionIndex)) and
- ssaDefReachesCertainUse(def, use) and
- use.getBlock() = bb and
- DataFlowIntegrationInput::guardControlsBlock(g, bb, branch) and
- result = use.getNode()
- )
- )
}
}
@@ -1313,13 +1290,12 @@ module BarrierGuard::guardChecksNodeSig/4 guardChecksNo
}
}
-bindingset[result, v]
-pragma[inline_late]
-private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
+pragma[nomagic]
+private DataFlowIntegrationImpl::Node fromDfNode(Node n) {
result = n.(SsaSynthNode).getSynthNode()
or
- exists(UseImpl use, IRBlock bb, int i |
- result.(DataFlowIntegrationImpl::ExprNode).getExpr().hasCfgNode(bb, i) and
+ exists(UseImpl use, IRBlock bb, int i, SourceVariable v |
+ result.(DataFlowIntegrationImpl::ReadNode).readsAt(bb, i, v) and
use.hasIndexInBlock(bb, i, v) and
use.isCertain() and
use.getNode() = n
@@ -1329,10 +1305,8 @@ private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
}
private predicate ssaFlowImpl(Node nodeFrom, Node nodeTo) {
- exists(SourceVariable v |
- nodeFrom != nodeTo and
- DataFlowIntegrationImpl::localFlowStep(v, fromDfNode(nodeFrom, v), fromDfNode(nodeTo, v), _)
- )
+ nodeFrom != nodeTo and
+ DataFlowIntegrationImpl::localFlowStep(_, fromDfNode(nodeFrom), fromDfNode(nodeTo), _)
}
/** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */
@@ -1405,14 +1379,96 @@ private class PhiCycle extends PhiCycleEquivalence::EquivalenceClass {
}
}
-/** An static single assignment (SSA) definition. */
-class Definition extends SsaImpl::Definition {
- private Definition getAPhiInputOrPriorDefinition() {
- result = this.(PhiNode).getAnInput()
- or
- uncertainWriteDefinitionInput(this, result)
+private Definition getAPhiInputOrPriorDefinition(Definition def) {
+ result = def.(PhiNode).getAnInput()
+ or
+ uncertainWriteDefinitionInput(def, result)
+}
+
+module Public {
+ /**
+ * A module signature to define relevant ultimate definitions for an
+ * optimized version of `Definition.getAnUltimateDefinition`.
+ */
+ signature module GetAnUltimateDefinitionSig {
+ /**
+ * Holds if `def` is a relevant definition. This defines the set
+ * of `Definition`s which may be returned by
+ * `GetAnUltimateDefinition::getAnUltimateDefinition`.
+ */
+ predicate isRelevantUltimateDefinition(Definition def);
}
+ /**
+ * A module which constructs an optimized version of
+ * ```
+ * Definition.getAnUltimateDefinition
+ * ```
+ * by restricting the set of possible ultimate definitions.
+ *
+ * Use this module by defining a module `M` which implements
+ * `GetAnUltimateDefinitionSig` and then call:
+ * ```
+ * GetAnUltimateDefinition::getAnUltimateDefinition
+ * ```
+ */
+ module GetAnUltimateDefinition {
+ private import Sig
+
+ private predicate relevantUltimateDefinition(Definition def) {
+ isRelevantUltimateDefinition(def) and
+ not def instanceof PhiNode
+ }
+
+ /**
+ * The `getAnUltimateDefinition` predicate uses an optimized step relation
+ * which is pruned to only those uncertain steps which lead back to a
+ * definition which satisfies `relevantUltimateDefinition`. This predicate
+ * computes the subset of `Definition`s which can lead back to definitions
+ * which satisfy `relevantUltimateDefinition`.
+ */
+ private predicate fwd(Definition def) {
+ // Base case: This definition is a relevant definition
+ relevantUltimateDefinition(def)
+ or
+ exists(Definition def0 |
+ // Recursive case: `def0` is a relevant definition, and
+ // `def` is an uncertain step which takes us back to `def0`.
+ fwd(def0) and
+ def0 = getAPhiInputOrPriorDefinition(def)
+ )
+ }
+
+ /**
+ * Holds if `def1 = getAPhiInputOrPriorDefinition(def2)`, and
+ * both `def1` and `def2` are part of a sequence of uncertain
+ * steps which lead back to a `Definition` which
+ * satisfies `relevantUltimateDefinition`.
+ */
+ private predicate step(Definition def1, Definition def2) {
+ fwd(def1) and
+ fwd(def2) and
+ def1 = getAPhiInputOrPriorDefinition(def2)
+ }
+
+ /**
+ * Gets a definition that ultimately defines this SSA definition and is
+ * not itself a phi node.
+ *
+ * This predicate is restricted to ultimate definitions which
+ * satisfy `isRelevantUltimateDefinition`.
+ */
+ Definition getAnUltimateDefinition(Definition def) {
+ step*(result, def) and
+ relevantUltimateDefinition(result)
+ }
+ }
+}
+
+import Public
+
+/** A static single assignment (SSA) definition. */
+class Definition extends SsaImpl::Definition {
/**
* Holds if this SSA definition is live at the end of basic block `bb`.
* That is, this definition reaches the end of basic block `bb`, at which
@@ -1424,9 +1480,13 @@ class Definition extends SsaImpl::Definition {
/**
* Gets a definition that ultimately defines this SSA definition and is
* not itself a phi node.
+ *
+ * Note: A more efficient implementation of this predicate exists. See the
+ * `GetAnUltimateDefinition` module for a description of how to access
+ * the more efficient implementation.
*/
final Definition getAnUltimateDefinition() {
- result = this.getAPhiInputOrPriorDefinition*() and
+ result = getAPhiInputOrPriorDefinition*(this) and
not result instanceof PhiNode
}
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 31931189003c..2fdac4649fd7 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
@@ -40,10 +40,21 @@ CppType getLanguageType(Operand operand) { result = getResultLanguageType(operan
* - If `type = MyStruct`, the result is 1
* - If `type = char*`, the result is 2
*/
-int getMaxIndirectionsForType(Type type) {
+int getMaxIndirectionsForGLType(Type type) {
result = countIndirectionsForCppType(getTypeForGLValue(type))
}
+/**
+ * Gets the maximum number of indirections a prvalue of type `type` can have.
+ * For example:
+ * - If `type = int`, the result is 0
+ * - If `type = MyStruct`, the result is 0
+ * - If `type = char*`, the result is 1
+ */
+int getMaxIndirectionsForPRType(Type type) {
+ result = countIndirectionsForCppType(getTypeForPRValue(type))
+}
+
private class PointerOrArrayOrReferenceType extends Cpp::DerivedType {
PointerOrArrayOrReferenceType() {
this instanceof Cpp::PointerType
@@ -206,6 +217,16 @@ private module IteratorIndirections {
)
}
+ // A by-value crement result loads the iterator, rather than aliasing its address.
+ override predicate isAdditionalDereference(Instruction deref, Operand address) {
+ exists(CallInstruction call |
+ deref = call and
+ call.getStaticCallTarget() instanceof Iterator::IteratorCrementMemberOperator and
+ not call.getResultType() instanceof Cpp::ReferenceType and
+ address = call.getThisArgumentOperand()
+ )
+ }
+
override predicate isAdditionalConversionFlow(Operand opFrom, Instruction instrTo) {
// This is a bit annoying: Consider the following snippet:
// ```
@@ -244,11 +265,11 @@ private module IteratorIndirections {
store.getDestinationAddress() = var
)
or
- // A call to `operator++` or `operator--` is the iterator equivalent version of a
- // pointer arithmetic instruction.
+ // A reference-returning `operator++` or `operator--` preserves the iterator's address.
exists(CallInstruction call |
instrTo = call and
call.getStaticCallTarget() instanceof Iterator::IteratorCrementMemberOperator and
+ call.getResultType() instanceof Cpp::ReferenceType and
opFrom = call.getThisArgumentOperand()
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll
index e4e0adf5897b..84c0a92ec8e6 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll
@@ -67,8 +67,7 @@ private module Cached {
model = ""
or
// models-as-data summarized flow
- FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
- nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
+ FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false, model)
or
// object->field conflation for content that is a `TaintInheritingContent`.
exists(DataFlow::ContentSet f |
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 b7dcd4d8f754..5205e8d3f0ba 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
@@ -1706,6 +1706,13 @@ class CallInstruction extends Instruction {
result.getIndex() = index
}
+ /**
+ * Gets a positional argument operand, if any.
+ */
+ final PositionalArgumentOperand getAPositionalArgumentOperand() {
+ result = this.getPositionalArgumentOperand(_)
+ }
+
/**
* Gets the argument at the specified index.
*/
@@ -1714,6 +1721,11 @@ class CallInstruction extends Instruction {
result = this.getPositionalArgumentOperand(index).getDef()
}
+ /**
+ * Gets a positional argument, if any.
+ */
+ final Instruction getAPositionalArgument() { result = this.getPositionalArgument(_) }
+
/**
* Gets the argument operand at the specified index, or `this` if `index` is `-1`.
*/
@@ -1735,6 +1747,13 @@ class CallInstruction extends Instruction {
*/
final int getNumberOfArguments() { result = count(this.getAnArgumentOperand()) }
+ /**
+ * Gets the number of positional arguments of the call.
+ */
+ final int getNumberOfPositionalArguments() {
+ result = count(this.getAPositionalArgumentOperand())
+ }
+
/**
* Holds if the result is a side effect for the argument at the specified index, or `this` if
* `index` is `-1`.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll
index 41e1a4c3082d..7871ddb16189 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/PrintIR.qll
@@ -396,9 +396,7 @@ private int maxColumnWidth() {
}
private string getPaddingString(int n) {
- n = 0 and result = ""
- or
- n > 0 and n <= maxColumnWidth() and result = getPaddingString(n - 1) + " "
+ n = [0 .. maxColumnWidth()] and result = concat(int i | i in [1 .. n] | " ")
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll
index 522cd393081e..59ee08973e1a 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll
@@ -295,6 +295,11 @@ abstract class MemoryLocation0 extends TMemoryLocation {
*/
abstract class VirtualVariable extends MemoryLocation0 { }
+pragma[nomagic]
+private VirtualVariable getAllocationMemoryLocation(Allocation alloc) {
+ result.getAnAllocation() = alloc
+}
+
abstract class AllocationMemoryLocation extends MemoryLocation0 {
Allocation var;
boolean isMayAccess;
@@ -313,7 +318,7 @@ abstract class AllocationMemoryLocation extends MemoryLocation0 {
result = getGroupedMemoryLocation(var, false, false).getVirtualVariable()
or
not exists(getGroupedMemoryLocation(var, false, false)) and
- result.(AllocationMemoryLocation).getAnAllocation() = var
+ result = getAllocationMemoryLocation(var)
)
}
@@ -815,6 +820,7 @@ private predicate isRelatableMemoryLocation(VariableMemoryLocation vml) {
vml.getStartBitOffset() != Ints::unknown()
}
+pragma[no_dynamic_join_order]
private predicate isCoveredOffset(Allocation var, int offsetRank, VariableMemoryLocation vml) {
exists(int startRank, int endRank, VirtualVariable vvar |
vml.getStartBitOffset() = rank[startRank](IntValue offset_ | isRelevantOffset(vvar, offset_)) and
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 b7dcd4d8f754..5205e8d3f0ba 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
@@ -1706,6 +1706,13 @@ class CallInstruction extends Instruction {
result.getIndex() = index
}
+ /**
+ * Gets a positional argument operand, if any.
+ */
+ final PositionalArgumentOperand getAPositionalArgumentOperand() {
+ result = this.getPositionalArgumentOperand(_)
+ }
+
/**
* Gets the argument at the specified index.
*/
@@ -1714,6 +1721,11 @@ class CallInstruction extends Instruction {
result = this.getPositionalArgumentOperand(index).getDef()
}
+ /**
+ * Gets a positional argument, if any.
+ */
+ final Instruction getAPositionalArgument() { result = this.getPositionalArgument(_) }
+
/**
* Gets the argument operand at the specified index, or `this` if `index` is `-1`.
*/
@@ -1735,6 +1747,13 @@ class CallInstruction extends Instruction {
*/
final int getNumberOfArguments() { result = count(this.getAnArgumentOperand()) }
+ /**
+ * Gets the number of positional arguments of the call.
+ */
+ final int getNumberOfPositionalArguments() {
+ result = count(this.getAPositionalArgumentOperand())
+ }
+
/**
* Holds if the result is a side effect for the argument at the specified index, or `this` if
* `index` is `-1`.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll
index 41e1a4c3082d..7871ddb16189 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/PrintIR.qll
@@ -396,9 +396,7 @@ private int maxColumnWidth() {
}
private string getPaddingString(int n) {
- n = 0 and result = ""
- or
- n > 0 and n <= maxColumnWidth() and result = getPaddingString(n - 1) + " "
+ n = [0 .. maxColumnWidth()] and result = concat(int i | i in [1 .. n] | " ")
}
/**
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 58456476f6a2..8103f64a5144 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
@@ -303,7 +303,7 @@ private predicate isInConditionalEvaluation(Expr e) {
isInConditionalEvaluation(getRealParent(e))
}
-private predicate isConditionalTemporaryDestructorCall(DestructorCall dc) {
+predicate isConditionalTemporaryDestructorCall(DestructorCall dc) {
exists(TemporaryObjectExpr temp |
temp = dc.getQualifier().(ReuseExpr).getReusedExpr() and
isInConditionalEvaluation(temp)
@@ -430,14 +430,18 @@ private predicate mustTransformToGLValue(Expr expr) {
}
/**
- * Holds if `expr` has an lvalue-to-rvalue conversion that should be ignored
- * when generating IR. This occurs for conversion from an lvalue of function type
- * to an rvalue of function pointer type. The conversion is represented in the
- * AST as an lvalue-to-rvalue conversion, but the IR represents both a function
+ * Holds if `expr` has an explicit or implicit load that should be ignored
+ * when generating IR. For example, this occurs for conversion from an lvalue of
+ * function type to an rvalue of function pointer type. The conversion is represented
+ * in the AST as an lvalue-to-rvalue conversion, but the IR represents both a function
* lvalue and a function pointer prvalue the same.
*/
predicate ignoreLoad(Expr expr) {
- expr.hasLValueToRValueConversion() and
+ (
+ expr.hasLValueToRValueConversion()
+ or
+ isPRValueFieldAccessWithImplicitLoad(expr)
+ ) and
(
expr instanceof ThisExpr
or
@@ -517,8 +521,11 @@ predicate hasTranslatedLoad(Expr expr) {
predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
not ignoreExpr(expr) and
mustTransformToGLValue(expr) and
- // If it's a load, we'll just ignore the load in `ignoreLoad()`.
- not expr.hasLValueToRValueConversion()
+ // If it's an explicit or implicit field load, reuse the existing address by
+ // ignoring the load in `ignoreLoad` instead of materializing another
+ // temporary.
+ not expr.hasLValueToRValueConversion() and
+ not isPRValueFieldAccessWithImplicitLoad(expr)
}
Opcode comparisonOpcode(ComparisonOperation expr) {
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 9a437b905381..5605e4857f7b 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
@@ -107,7 +107,12 @@ abstract class TranslatedExpr extends TranslatedElement {
}
final private TranslatedExpr getImplicitDestructorCall(int index) {
- result.getExpr() = expr.getImplicitDestructorCall(index)
+ result.getExpr() =
+ rank[index + 1](DestructorCall dc, int i |
+ dc = expr.getImplicitDestructorCall(i) and not isConditionalTemporaryDestructorCall(dc)
+ |
+ dc order by i
+ )
}
final override predicate hasAnImplicitDestructorCall() {
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 10c033131225..c24cb98d2bd9 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
@@ -618,6 +618,11 @@ class TranslatedExplicitFieldInitialization extends TranslatedNonDefaultFieldIni
override int getPosition() { result = position }
}
+pragma[nomagic]
+private Instruction getCallInstruction(TranslatedDefaultFieldInitialization tdfi) {
+ result = tdfi.getInstruction(CallTag())
+}
+
/**
* The IR translation of the initialization of a field from an element of an initializer
* list where default initialization is used.
@@ -642,7 +647,7 @@ class TranslatedDefaultFieldInitialization extends TranslatedFieldInitialization
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
tag = CallTargetTag() and
- result = this.getInstruction(CallTag())
+ result = getCallInstruction(this)
or
tag = CallTag() and
result = this.getSideEffects().getFirstInstruction(kind)
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll
index 7dfebc56fe18..9ffa132c7eab 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll
@@ -297,11 +297,20 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
abstract TranslatedElement getChildInternal(int id);
+ DestructorCall getImplicitDestructorCall(int index) {
+ result =
+ rank[index + 1](DestructorCall dc, int i |
+ dc = stmt.getImplicitDestructorCall(i) and not isConditionalTemporaryDestructorCall(dc)
+ |
+ dc order by i
+ )
+ }
+
final override TranslatedElement getChild(int id) {
result = this.getChildInternal(id)
or
exists(int destructorIndex |
- result.(TranslatedExpr).getExpr() = stmt.getImplicitDestructorCall(destructorIndex) and
+ result.(TranslatedExpr).getExpr() = this.getImplicitDestructorCall(destructorIndex) and
id = this.getFirstDestructorCallIndex() + destructorIndex
)
}
@@ -313,7 +322,7 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
}
final override predicate hasAnImplicitDestructorCall() {
- exists(stmt.getAnImplicitDestructorCall())
+ exists(this.getImplicitDestructorCall(_))
}
final override string toString() { result = stmt.toString() }
@@ -1227,7 +1236,7 @@ class TranslatedWhileStmt extends TranslatedLoop {
id = 1 and result = this.getBody()
or
exists(int n |
- result.getAst() = stmt.getImplicitDestructorCall(n) and
+ result.getAst() = this.getImplicitDestructorCall(n) and
id = 2 + n
)
}
@@ -1289,7 +1298,7 @@ class TranslatedForStmt extends TranslatedLoop {
id = 3 and result = this.getBody()
or
exists(int n |
- result.getAst() = stmt.getImplicitDestructorCall(n) and
+ result.getAst() = this.getImplicitDestructorCall(n) and
id = 4 + n
)
}
@@ -1492,13 +1501,13 @@ class TranslatedJumpStmt extends TranslatedStmt {
}
private TranslatedCall getTranslatedImplicitDestructorCall(int id) {
- result.getExpr() = stmt.getImplicitDestructorCall(id)
+ result.getExpr() = this.getImplicitDestructorCall(id)
}
override TranslatedElement getLastChild() {
result =
this.getTranslatedImplicitDestructorCall(max(int id |
- exists(stmt.getImplicitDestructorCall(id))
+ exists(this.getImplicitDestructorCall(id))
))
}
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 b7dcd4d8f754..5205e8d3f0ba 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
@@ -1706,6 +1706,13 @@ class CallInstruction extends Instruction {
result.getIndex() = index
}
+ /**
+ * Gets a positional argument operand, if any.
+ */
+ final PositionalArgumentOperand getAPositionalArgumentOperand() {
+ result = this.getPositionalArgumentOperand(_)
+ }
+
/**
* Gets the argument at the specified index.
*/
@@ -1714,6 +1721,11 @@ class CallInstruction extends Instruction {
result = this.getPositionalArgumentOperand(index).getDef()
}
+ /**
+ * Gets a positional argument, if any.
+ */
+ final Instruction getAPositionalArgument() { result = this.getPositionalArgument(_) }
+
/**
* Gets the argument operand at the specified index, or `this` if `index` is `-1`.
*/
@@ -1735,6 +1747,13 @@ class CallInstruction extends Instruction {
*/
final int getNumberOfArguments() { result = count(this.getAnArgumentOperand()) }
+ /**
+ * Gets the number of positional arguments of the call.
+ */
+ final int getNumberOfPositionalArguments() {
+ result = count(this.getAPositionalArgumentOperand())
+ }
+
/**
* Holds if the result is a side effect for the argument at the specified index, or `this` if
* `index` is `-1`.
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll
index 41e1a4c3082d..7871ddb16189 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/PrintIR.qll
@@ -396,9 +396,7 @@ private int maxColumnWidth() {
}
private string getPaddingString(int n) {
- n = 0 and result = ""
- or
- n > 0 and n <= maxColumnWidth() and result = getPaddingString(n - 1) + " "
+ n = [0 .. maxColumnWidth()] and result = concat(int i | i in [1 .. n] | " ")
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeAnalysisUtils.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeAnalysisUtils.qll
index 03dbc56dc99c..3b316f5bce5c 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeAnalysisUtils.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/RangeAnalysisUtils.qll
@@ -406,7 +406,7 @@ predicate cmpWithLinearBound(
*/
private predicate typeBounds0(ArithmeticType t, float lb, float ub) {
exists(IntegralType integralType, float limit |
- integralType = t and limit = 2.pow(8 * integralType.getSize())
+ integralType = t and limit = 2.pow(integralType.getBitWidth())
|
if integralType instanceof BoolType
then lb = 0 and ub = 1
@@ -438,7 +438,7 @@ private IntegralType getUnderlyingTypeForEnum(Enum e) {
not e.hasExplicitUnderlyingType() and
result.isSigned() and
exists(IntType intType |
- if max(e.getAnEnumConstant().getValue().toFloat()) >= 2.pow(8 * intType.getSize() - 1)
+ if max(e.getAnEnumConstant().getValue().toFloat()) >= 2.pow(intType.getBitWidth() - 1)
then result instanceof LongType
else result = intType
)
diff --git a/cpp/ql/lib/semmle/code/cpp/regex/RegexTreeView.qll b/cpp/ql/lib/semmle/code/cpp/regex/RegexTreeView.qll
new file mode 100644
index 000000000000..4d7176c14b75
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/regex/RegexTreeView.qll
@@ -0,0 +1,1254 @@
+/**
+ * Provides a class hierarchy corresponding to a parse tree of C++ regular expressions.
+ */
+
+private import internal.ParseRegExp
+private import codeql.util.Numbers
+private import semmle.code.cpp.exprs.Literal
+private import codeql.regex.RegexTreeView
+// exporting as RegexTreeView, and in the top-level scope.
+import Impl as RegexTreeView
+import Impl
+
+/** Gets the parse tree resulting from parsing `re`, if such has been constructed. */
+RegExpTerm getParsedRegExp(StringLiteral re) { result.getRegExp() = re and result.isRootTerm() }
+
+/**
+ * An element containing a regular expression term, that is, either
+ * a string literal (parsed as a regular expression)
+ * or another regular expression term.
+ *
+ * For sequences and alternations, we require at least one child.
+ * Otherwise, we wish to represent the term differently.
+ * This avoids multiple representations of the same term.
+ */
+private newtype TRegExpParent =
+ /** A string literal used as a regular expression */
+ TRegExpLiteral(RegExp re) or
+ /** A quantified term */
+ TRegExpQuantifier(RegExp re, int start, int end) { re.qualifiedItem(start, end, _, _) } or
+ /** A sequence term */
+ TRegExpSequence(RegExp re, int start, int end) { re.sequence(start, end) } or
+ /** An alternation term */
+ TRegExpAlt(RegExp re, int start, int end) { re.alternation(start, end) } or
+ /** A character class term */
+ TRegExpCharacterClass(RegExp re, int start, int end) { re.charSet(start, end) } or
+ /** A character range term */
+ TRegExpCharacterRange(RegExp re, int start, int end) { re.charRange(_, start, _, _, end) } or
+ /** A group term */
+ TRegExpGroup(RegExp re, int start, int end) { re.group(start, end) } or
+ /** A special character */
+ TRegExpSpecialChar(RegExp re, int start, int end) { re.specialCharacter(start, end, _) } or
+ /** A normal character */
+ TRegExpNormalChars(RegExp re, int start, int end) {
+ re.normalCharacterSequence(start, end)
+ or
+ re.escapedCharacter(start, end) and
+ not re.specialCharacter(start, end, _)
+ } or
+ /** A back reference */
+ TRegExpBackRef(RegExp re, int start, int end) { re.backreference(start, end) } or
+ /** A named character property */
+ TRegExpNamedCharacterProperty(RegExp re, int start, int end) {
+ re.namedCharacterProperty(start, end, _, _)
+ }
+
+/** An implementation that satisfies the RegexTreeView signature. */
+private module Impl implements RegexTreeViewSig {
+ /**
+ * An element containing a regular expression term, that is, either
+ * a string literal (parsed as a regular expression)
+ * or another regular expression term.
+ */
+ class RegExpParent extends TRegExpParent {
+ /** Gets a textual representation of this element. */
+ string toString() { result = "RegExpParent" }
+
+ /** Gets the `i`th child term. */
+ RegExpTerm getChild(int i) { none() }
+
+ /** Gets a child term . */
+ final RegExpTerm getAChild() { result = this.getChild(_) }
+
+ /** Gets the number of child terms. */
+ int getNumChild() { result = count(this.getAChild()) }
+
+ /** Gets the last child term of this element. */
+ RegExpTerm getLastChild() { result = this.getChild(this.getNumChild() - 1) }
+
+ /**
+ * Gets the name of a primary CodeQL class to which this regular
+ * expression term belongs.
+ */
+ string getAPrimaryQlClass() { result = "RegExpParent" }
+
+ /**
+ * Gets a comma-separated list of the names of the primary CodeQL classes to
+ * which this regular expression term belongs.
+ */
+ final string getPrimaryQlClasses() { result = concat(this.getAPrimaryQlClass(), ",") }
+ }
+
+ /** A string literal used as a regular expression */
+ class RegExpLiteral extends TRegExpLiteral, RegExpParent {
+ RegExp re;
+
+ RegExpLiteral() { this = TRegExpLiteral(re) }
+
+ override RegExpTerm getChild(int i) {
+ i = 0 and result.getRegExp() = re and result.isRootTerm()
+ }
+
+ /** Holds if dot, `.`, matches all characters, including newlines. */
+ predicate isDotAll() { re.isDotAll() }
+
+ /** Holds if this regex matching is case-insensitive for this regex. */
+ predicate isIgnoreCase() { re.isIgnoreCase() }
+
+ /** Get a string representing all modes for this regex. */
+ string getFlags() { result = re.getFlags() }
+
+ /** Gets the primary QL class for this regex. */
+ override string getAPrimaryQlClass() { result = "RegExpLiteral" }
+ }
+
+ /**
+ * A regular expression term, that is, a syntactic part of a regular expression.
+ */
+ class RegExpTerm extends RegExpParent {
+ RegExp re;
+ int start;
+ int end;
+
+ RegExpTerm() {
+ this = TRegExpAlt(re, start, end)
+ or
+ this = TRegExpBackRef(re, start, end)
+ or
+ this = TRegExpCharacterClass(re, start, end)
+ or
+ this = TRegExpCharacterRange(re, start, end)
+ or
+ this = TRegExpNormalChars(re, start, end)
+ or
+ this = TRegExpGroup(re, start, end)
+ or
+ this = TRegExpQuantifier(re, start, end)
+ or
+ this = TRegExpSequence(re, start, end) and
+ exists(seqChild(re, start, end, 1)) // if a sequence does not have more than one element, it should be treated as that element instead.
+ or
+ this = TRegExpSpecialChar(re, start, end)
+ or
+ this = TRegExpNamedCharacterProperty(re, start, end)
+ }
+
+ /**
+ * Gets the outermost term of this regular expression.
+ */
+ RegExpTerm getRootTerm() {
+ this.isRootTerm() and result = this
+ or
+ result = this.getParent().(RegExpTerm).getRootTerm()
+ }
+
+ /**
+ * Holds if this term is part of a string literal
+ * that is interpreted as a regular expression.
+ */
+ predicate isUsedAsRegExp() { any() }
+
+ /**
+ * Holds if this is the root term of a regular expression.
+ */
+ predicate isRootTerm() { start = 0 and end = re.getText().length() }
+
+ override RegExpTerm getChild(int i) {
+ result = this.(RegExpAlt).getChild(i)
+ or
+ result = this.(RegExpBackRef).getChild(i)
+ or
+ result = this.(RegExpCharacterClass).getChild(i)
+ or
+ result = this.(RegExpCharacterRange).getChild(i)
+ or
+ result = this.(RegExpNormalChars).getChild(i)
+ or
+ result = this.(RegExpGroup).getChild(i)
+ or
+ result = this.(RegExpQuantifier).getChild(i)
+ or
+ result = this.(RegExpSequence).getChild(i)
+ or
+ result = this.(RegExpSpecialChar).getChild(i)
+ or
+ result = this.(RegExpNamedCharacterProperty).getChild(i)
+ }
+
+ /**
+ * Gets the parent term of this regular expression term, or the
+ * regular expression literal if this is the root term.
+ */
+ RegExpParent getParent() { result.getAChild() = this }
+
+ /** Gets the associated `RegExp`. */
+ RegExp getRegExp() { result = re }
+
+ /** Gets the offset at which this term starts. */
+ int getStart() { result = start }
+
+ /** Gets the offset at which this term ends. */
+ int getEnd() { result = end }
+
+ override string toString() { result = re.getText().substring(start, end) }
+
+ /**
+ * Gets the location of the surrounding regex, as locations inside the regex do not exist.
+ * To get location information corresponding to the term inside the regex,
+ * use `hasLocationInfo`.
+ */
+ Location getLocation() { result = re.getLocation() }
+
+ /**
+ * Gets the number of source characters from the start of the string literal
+ * to the first content character (i.e., past the opening delimiter).
+ */
+ private int regexpContentOffset() {
+ exists(string vt | vt = re.getValueText() |
+ // Find the '(' that opens the raw content.
+ re instanceof RawStringLiteral and
+ result = 1 + min(int i | vt.charAt(i) = "(")
+ or
+ // Find the opening '"'.
+ not re instanceof RawStringLiteral and
+ result = 1 + min(int i | vt.charAt(i) = "\"")
+ or
+ // No opening '"'.
+ not re instanceof RawStringLiteral and
+ not vt.charAt(_) = "\"" and
+ result = 0
+ )
+ }
+
+ /**
+ * Holds if this term is found at the specified location offsets.
+ *
+ * Note: these locations may not be accurate when the regex was not defined as a raw string
+ * and contains `\`-escaped characters, or when macros were used to define the regex.
+ */
+ predicate hasLocationInfo(
+ string filepath, int startline, int startcolumn, int endline, int endcolumn
+ ) {
+ exists(int re_start, int offset |
+ re.getLocation().hasLocationInfo(filepath, startline, re_start, endline, _) and
+ offset = this.regexpContentOffset() and
+ startcolumn = re_start + offset + start and
+ endcolumn = re_start + offset + end - 1
+ )
+ }
+
+ /** Gets the file in which this term is found. */
+ File getFile() { result = this.getLocation().getFile() }
+
+ /** Gets the raw source text of this term. */
+ string getRawValue() { result = this.toString() }
+
+ /** Gets the string literal in which this term is found. */
+ RegExpLiteral getLiteral() { result = TRegExpLiteral(re) }
+
+ /** Gets the regular expression term that is matched (textually) before this one, if any. */
+ RegExpTerm getPredecessor() {
+ exists(RegExpTerm parent | parent = this.getParent() |
+ result = parent.(RegExpSequence).previousElement(this)
+ or
+ not exists(parent.(RegExpSequence).previousElement(this)) and
+ not parent instanceof RegExpSubPattern and
+ result = parent.getPredecessor()
+ )
+ }
+
+ /** Gets the regular expression term that is matched (textually) after this one, if any. */
+ RegExpTerm getSuccessor() {
+ exists(RegExpTerm parent | parent = this.getParent() |
+ result = parent.(RegExpSequence).nextElement(this)
+ or
+ not exists(parent.(RegExpSequence).nextElement(this)) and
+ not parent instanceof RegExpSubPattern and
+ result = parent.getSuccessor()
+ )
+ }
+
+ /**
+ * Gets the single string this regular-expression term matches.
+ *
+ * This predicate is only defined for (sequences/groups of) constant regular
+ * expressions. In particular, terms involving zero-width assertions like `^`
+ * or `\b` are not considered to have a constant value.
+ *
+ * Note that this predicate does not take flags of the enclosing
+ * regular-expression literal into account.
+ */
+ string getConstantValue() { none() }
+
+ /**
+ * Gets a string that is matched by this regular-expression term.
+ */
+ string getAMatchedString() { result = this.getConstantValue() }
+
+ /** Gets the primary QL class for this term. */
+ override string getAPrimaryQlClass() { result = "RegExpTerm" }
+
+ /** Holds if this regular expression term can match the empty string. */
+ predicate isNullable() { none() }
+ }
+
+ /**
+ * A quantified regular expression term.
+ *
+ * Example:
+ *
+ * ```
+ * ((ECMA|Java)[sS]cript)*
+ * ```
+ */
+ class RegExpQuantifier extends RegExpTerm, TRegExpQuantifier {
+ int part_end;
+ boolean may_repeat_forever;
+
+ RegExpQuantifier() {
+ this = TRegExpQuantifier(re, start, end) and
+ re.qualifiedPart(start, part_end, end, _, may_repeat_forever)
+ }
+
+ override RegExpTerm getChild(int i) {
+ i = 0 and
+ result.getRegExp() = re and
+ result.getStart() = start and
+ result.getEnd() = part_end
+ }
+
+ /** Holds if this term may match an unlimited number of times. */
+ predicate mayRepeatForever() { may_repeat_forever = true }
+
+ /** Gets the qualifier for this term. That is e.g "?" for "a?". */
+ string getQualifier() { result = re.getText().substring(part_end, end) }
+
+ override string getAPrimaryQlClass() { result = "RegExpQuantifier" }
+ }
+
+ /**
+ * A regular expression term that permits unlimited repetitions.
+ */
+ class InfiniteRepetitionQuantifier extends RegExpQuantifier {
+ InfiniteRepetitionQuantifier() { this.mayRepeatForever() }
+
+ override string getAPrimaryQlClass() { result = "InfiniteRepetitionQuantifier" }
+ }
+
+ /**
+ * A star-quantified term.
+ *
+ * Example:
+ *
+ * ```
+ * \w*
+ * ```
+ */
+ class RegExpStar extends InfiniteRepetitionQuantifier {
+ RegExpStar() { this.getQualifier().charAt(0) = "*" }
+
+ override string getAPrimaryQlClass() { result = "RegExpStar" }
+
+ override predicate isNullable() { any() }
+ }
+
+ /**
+ * A plus-quantified term.
+ *
+ * Example:
+ *
+ * ```
+ * \w+
+ * ```
+ */
+ class RegExpPlus extends InfiniteRepetitionQuantifier {
+ RegExpPlus() { this.getQualifier().charAt(0) = "+" }
+
+ override string getAPrimaryQlClass() { result = "RegExpPlus" }
+
+ override predicate isNullable() { this.getAChild().isNullable() }
+ }
+
+ /**
+ * An optional term.
+ *
+ * Example:
+ *
+ * ```
+ * ;?
+ * ```
+ */
+ class RegExpOpt extends RegExpQuantifier {
+ RegExpOpt() { this.getQualifier().charAt(0) = "?" }
+
+ override string getAPrimaryQlClass() { result = "RegExpOpt" }
+
+ override predicate isNullable() { any() }
+ }
+
+ /**
+ * A range-quantified term
+ *
+ * Examples:
+ *
+ * ```
+ * \w{2,4}
+ * \w{2,}
+ * \w{2}
+ * ```
+ */
+ class RegExpRange extends RegExpQuantifier {
+ string upper;
+ string lower;
+
+ RegExpRange() { re.multiples(part_end, end, lower, upper) }
+
+ override string getAPrimaryQlClass() { result = "RegExpRange" }
+
+ /** Gets the string defining the upper bound of this range, if any. */
+ string getUpper() { result = upper }
+
+ /** Gets the string defining the lower bound of this range, if any. */
+ string getLower() { result = lower }
+
+ /**
+ * Gets the upper bound of the range, if any.
+ *
+ * If there is no upper bound, any number of repetitions is allowed.
+ * For a term of the form `r{lo}`, both the lower and the upper bound
+ * are `lo`.
+ */
+ int getUpperBound() { result = this.getUpper().toInt() }
+
+ /** Gets the lower bound of the range. */
+ int getLowerBound() { result = this.getLower().toInt() }
+
+ override predicate isNullable() { this.getAChild().isNullable() or this.getLowerBound() = 0 }
+ }
+
+ /**
+ * A sequence term.
+ *
+ * Example:
+ *
+ * ```
+ * (ECMA|Java)Script
+ * ```
+ *
+ * This is a sequence with the elements `(ECMA|Java)` and `Script`.
+ */
+ class RegExpSequence extends RegExpTerm, TRegExpSequence {
+ RegExpSequence() {
+ this = TRegExpSequence(re, start, end) and
+ exists(seqChild(re, start, end, 1)) // if a sequence does not have more than one element, it should be treated as that element instead.
+ }
+
+ override RegExpTerm getChild(int i) { result = seqChild(re, start, end, i) }
+
+ /** Gets the element preceding `element` in this sequence. */
+ RegExpTerm previousElement(RegExpTerm element) { element = this.nextElement(result) }
+
+ /** Gets the element following `element` in this sequence. */
+ RegExpTerm nextElement(RegExpTerm element) {
+ exists(int i |
+ element = this.getChild(i) and
+ result = this.getChild(i + 1)
+ )
+ }
+
+ override string getConstantValue() { result = this.getConstantValue(0) }
+
+ /**
+ * Gets the single string matched by the `i`th child and all following
+ * children of this sequence, if any.
+ */
+ private string getConstantValue(int i) {
+ i = this.getNumChild() and
+ result = ""
+ or
+ result = this.getChild(i).getConstantValue() + this.getConstantValue(i + 1)
+ }
+
+ override string getAPrimaryQlClass() { result = "RegExpSequence" }
+
+ override predicate isNullable() {
+ forall(RegExpTerm child | child = this.getAChild() | child.isNullable())
+ }
+ }
+
+ pragma[nomagic]
+ private int seqChildEnd(RegExp re, int start, int end, int i) {
+ result = seqChild(re, start, end, i).getEnd()
+ }
+
+ // moved out so we can use it in the charpred
+ private RegExpTerm seqChild(RegExp re, int start, int end, int i) {
+ re.sequence(start, end) and
+ (
+ i = 0 and
+ result.getRegExp() = re and
+ result.getStart() = start and
+ exists(int itemEnd |
+ re.item(start, itemEnd) and
+ result.getEnd() = itemEnd
+ )
+ or
+ i > 0 and
+ result.getRegExp() = re and
+ exists(int itemStart | itemStart = seqChildEnd(re, start, end, i - 1) |
+ result.getStart() = itemStart and
+ re.item(itemStart, result.getEnd())
+ )
+ )
+ }
+
+ /**
+ * An alternative term, that is, a term of the form `a|b`.
+ *
+ * Example:
+ *
+ * ```
+ * ECMA|Java
+ * ```
+ */
+ class RegExpAlt extends RegExpTerm, TRegExpAlt {
+ RegExpAlt() { this = TRegExpAlt(re, start, end) }
+
+ override RegExpTerm getChild(int i) {
+ i = 0 and
+ result.getRegExp() = re and
+ result.getStart() = start and
+ exists(int part_end |
+ re.alternationOption(start, end, start, part_end) and
+ result.getEnd() = part_end
+ )
+ or
+ i > 0 and
+ result.getRegExp() = re and
+ exists(int part_start |
+ part_start = this.getChild(i - 1).getEnd() + 1 // allow for the |
+ |
+ result.getStart() = part_start and
+ re.alternationOption(start, end, part_start, result.getEnd())
+ )
+ }
+
+ /** Gets an alternative of this term. */
+ RegExpTerm getAlternative() { result = this.getAChild() }
+
+ override string getAMatchedString() { result = this.getAlternative().getAMatchedString() }
+
+ override string getAPrimaryQlClass() { result = "RegExpAlt" }
+
+ override predicate isNullable() { this.getAChild().isNullable() }
+ }
+
+ /**
+ * A character escape in a regular expression.
+ *
+ * Example:
+ *
+ * ```
+ * \.
+ * ```
+ */
+ class RegExpCharEscape = RegExpEscape;
+
+ /**
+ * An escaped regular expression term, that is, a regular expression
+ * term starting with a backslash, which is not a backreference.
+ *
+ * Example:
+ *
+ * ```
+ * \.
+ * \w
+ * ```
+ */
+ class RegExpEscape extends RegExpNormalChars {
+ RegExpEscape() { re.escapedCharacter(start, end) }
+
+ /**
+ * Gets the name of the escaped; for example, `w` for `\w`.
+ * TODO: Handle named escapes.
+ */
+ override string getValue() {
+ this.isIdentityEscape() and
+ result = this.getUnescaped()
+ or
+ this.getUnescaped() = "n" and result = "\n"
+ or
+ this.getUnescaped() = "r" and result = "\r"
+ or
+ this.getUnescaped() = "t" and result = "\t"
+ or
+ this.getUnescaped() = "f" and result = 12.toUnicode()
+ or
+ this.getUnescaped() = "v" and result = 11.toUnicode()
+ or
+ this.getUnescaped() = "0" and result = 0.toUnicode()
+ or
+ this.isUnicode() and
+ result = this.getUnicode()
+ or
+ this.isHex() and
+ result = this.getHex()
+ or
+ this.isControl() and
+ result = this.getControl()
+ }
+
+ /** Holds if this terms name is given by the part following the escape character. */
+ predicate isIdentityEscape() {
+ not this.getUnescaped() in ["n", "r", "t", "f", "v", "0"] and
+ not this.isUnicode() and
+ not this.isHex() and
+ not this.isControl()
+ }
+
+ override string getAPrimaryQlClass() { result = "RegExpEscape" }
+
+ /** Gets the part of the term following the escape character. That is e.g. "w" if the term is "\w". */
+ string getUnescaped() { result = this.getText().suffix(1) }
+
+ /**
+ * Gets the text for this escape. That is e.g. "\w".
+ */
+ private string getText() { result = re.getText().substring(start, end) }
+
+ /**
+ * Holds if this is a unicode escape.
+ */
+ private predicate isUnicode() { this.getText().matches("\\u%") }
+
+ /**
+ * Gets the unicode char for this escape.
+ * E.g. for `\u0061` this returns "a".
+ */
+ private string getUnicode() {
+ this.isUnicode() and
+ result = parseHexInt(this.getText().suffix(2)).toUnicode()
+ }
+
+ /**
+ * Holds if this is a hex escape.
+ */
+ private predicate isHex() { this.getText().matches("\\x%") }
+
+ /**
+ * Gets the unicode char for this escape.
+ * E.g. for `\x61` this returns "a".
+ */
+ private string getHex() {
+ this.isHex() and
+ result = parseHexInt(this.getText().suffix(2)).toUnicode()
+ }
+
+ /**
+ * Holds if this is a `\cX` escape.
+ */
+ private predicate isControl() { this.getText().matches("\\c%") }
+
+ /**
+ * Gets the unicode char for this escape.
+ * E.g. for `\cA` this returns `0x01`.
+ */
+ private string getControl() {
+ this.isControl() and
+ exists(string letter | letter = this.getText().suffix(2).toUpperCase() |
+ result = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf(letter) + 1).toUnicode()
+ )
+ }
+ }
+
+ /**
+ * A word boundary, that is, a regular expression term of the form `\b`.
+ */
+ class RegExpWordBoundary extends RegExpSpecialChar {
+ RegExpWordBoundary() { this.getChar() = "\\b" }
+
+ override predicate isNullable() { none() }
+ }
+
+ /**
+ * A non-word boundary, that is, a regular expression term of the form `\B`.
+ */
+ class RegExpNonWordBoundary extends RegExpSpecialChar {
+ RegExpNonWordBoundary() { this.getChar() = "\\B" }
+
+ override string getAPrimaryQlClass() { result = "RegExpNonWordBoundary" }
+ }
+
+ /**
+ * A character class escape in a regular expression.
+ * That is, an escaped character that denotes multiple characters.
+ *
+ * Examples:
+ *
+ * ```
+ * \w
+ * \S
+ * ```
+ */
+ class RegExpCharacterClassEscape extends RegExpEscape {
+ RegExpCharacterClassEscape() { this.getValue() in ["d", "D", "s", "S", "w", "W"] }
+
+ override RegExpTerm getChild(int i) { none() }
+
+ override string getAPrimaryQlClass() { result = "RegExpCharacterClassEscape" }
+
+ override predicate isNullable() { none() }
+ }
+
+ /**
+ * A character class in a regular expression.
+ *
+ * Examples:
+ *
+ * ```cpp
+ * "[a-fA-F0-9]"
+ * "[^abc]"
+ * ```
+ */
+ class RegExpCharacterClass extends RegExpTerm, TRegExpCharacterClass {
+ RegExpCharacterClass() { this = TRegExpCharacterClass(re, start, end) }
+
+ /** Holds if this character class is inverted, matching the opposite of its content. */
+ predicate isInverted() { re.getChar(start + 1) = "^" }
+
+ /** Holds if this character class can match anything. */
+ predicate isUniversalClass() {
+ // [^]
+ this.isInverted() and not exists(this.getAChild())
+ or
+ // [\w\W] and similar
+ not this.isInverted() and
+ exists(string cce1, string cce2 |
+ cce1 = this.getAChild().(RegExpCharacterClassEscape).getValue() and
+ cce2 = this.getAChild().(RegExpCharacterClassEscape).getValue()
+ |
+ cce1 != cce2 and cce1.toLowerCase() = cce2.toLowerCase()
+ )
+ }
+
+ override RegExpTerm getChild(int i) {
+ i = 0 and
+ result.getRegExp() = re and
+ exists(int itemStart, int itemEnd |
+ result.getStart() = itemStart and
+ re.charSetStart(start, itemStart) and
+ re.charSetChild(start, itemStart, itemEnd) and
+ result.getEnd() = itemEnd
+ )
+ or
+ i > 0 and
+ result.getRegExp() = re and
+ exists(int itemStart | itemStart = this.getChild(i - 1).getEnd() |
+ result.getStart() = itemStart and
+ re.charSetChild(start, itemStart, result.getEnd())
+ )
+ }
+
+ override string getAMatchedString() {
+ not this.isInverted() and result = this.getAChild().getAMatchedString()
+ }
+
+ override string getAPrimaryQlClass() { result = "RegExpCharacterClass" }
+
+ override predicate isNullable() { none() }
+ }
+
+ /**
+ * A character range in a character class in a regular expression.
+ *
+ * Example:
+ *
+ * ```
+ * a-z
+ * ```
+ */
+ class RegExpCharacterRange extends RegExpTerm, TRegExpCharacterRange {
+ int lower_end;
+ int upper_start;
+
+ RegExpCharacterRange() {
+ this = TRegExpCharacterRange(re, start, end) and
+ re.charRange(_, start, lower_end, upper_start, end)
+ }
+
+ /** Holds if this range goes from `lo` to `hi`, in effect is `lo-hi`. */
+ predicate isRange(string lo, string hi) {
+ lo = re.getText().substring(start, lower_end) and
+ hi = re.getText().substring(upper_start, end)
+ }
+
+ override RegExpTerm getChild(int i) {
+ i = 0 and
+ result.getRegExp() = re and
+ result.getStart() = start and
+ result.getEnd() = lower_end
+ or
+ i = 1 and
+ result.getRegExp() = re and
+ result.getStart() = upper_start and
+ result.getEnd() = end
+ }
+
+ override string getAPrimaryQlClass() { result = "RegExpCharacterRange" }
+
+ override predicate isNullable() { none() }
+ }
+
+ /**
+ * A normal-character term in a regular expression, that is, a sequence
+ * of characters without special meaning or a single escaped character.
+ *
+ * Examples:
+ * ```
+ * abc
+ * \t
+ * ```
+ */
+ additional class RegExpNormalChars extends RegExpTerm, TRegExpNormalChars {
+ RegExpNormalChars() { this = TRegExpNormalChars(re, start, end) }
+
+ /**
+ * Holds if this constant consists of a valid Unicode character (as opposed
+ * to a surrogate code point that does not correspond to a character by itself.)
+ */
+ predicate isCharacter() { any() }
+
+ /** Gets the string representation of this term. */
+ string getValue() { result = re.getText().substring(start, end) }
+
+ override RegExpTerm getChild(int i) { none() }
+
+ override string getAPrimaryQlClass() { result = "RegExpNormalChars" }
+ }
+
+ /**
+ * A constant regular expression term, that is, a regular expression
+ * term matching a single string. Currently, this will always be a single character.
+ *
+ * Example:
+ *
+ * ```
+ * a
+ * ```
+ */
+ class RegExpConstant extends RegExpTerm {
+ string value;
+
+ RegExpConstant() {
+ this = TRegExpNormalChars(re, start, end) and
+ not this instanceof RegExpCharacterClassEscape and
+ // exclude chars in qualifiers
+ // TODO: push this into regex library
+ not exists(int qstart, int qend | re.qualifiedPart(_, qstart, qend, _, _) |
+ qstart <= start and end <= qend
+ ) and
+ value = this.(RegExpNormalChars).getValue()
+ or
+ this = TRegExpSpecialChar(re, start, end) and
+ re.inCharSet(start) and
+ value = this.(RegExpSpecialChar).getChar()
+ }
+
+ /**
+ * Holds if this constant represents a valid Unicode character (as opposed
+ * to a surrogate code point that does not correspond to a character by itself.)
+ */
+ predicate isCharacter() { any() }
+
+ /** Gets the string matched by this constant term. */
+ string getValue() { result = value }
+
+ override RegExpTerm getChild(int i) { none() }
+
+ override string getConstantValue() { result = this.getValue() }
+
+ override string getAPrimaryQlClass() { result = "RegExpConstant" }
+
+ override predicate isNullable() { none() }
+ }
+
+ /**
+ * A grouped regular expression.
+ *
+ * Examples:
+ *
+ * ```
+ * (ECMA|Java)
+ * (?:ECMA|Java)
+ * (?['"])
+ * ```
+ */
+ class RegExpGroup extends RegExpTerm, TRegExpGroup {
+ RegExpGroup() { this = TRegExpGroup(re, start, end) }
+
+ /**
+ * Gets the index of this capture group within the enclosing regular
+ * expression literal.
+ *
+ * For example, in the regular expression `/((a?).)(?:b)/`, the
+ * group `((a?).)` has index 1, the group `(a?)` nested inside it
+ * has index 2, and the group `(?:b)` has no index, since it is
+ * not a capture group.
+ */
+ int getNumber() { result = re.getGroupNumber(start, end) }
+
+ /** Holds if this is a capture group. */
+ predicate isCapture() { exists(this.getNumber()) }
+
+ override RegExpTerm getChild(int i) {
+ result.getRegExp() = re and
+ i = 0 and
+ re.groupContents(start, end, result.getStart(), result.getEnd())
+ }
+
+ override string getConstantValue() { result = this.getAChild().getConstantValue() }
+
+ override string getAMatchedString() { result = this.getAChild().getAMatchedString() }
+
+ override string getAPrimaryQlClass() { result = "RegExpGroup" }
+
+ override predicate isNullable() { this.getAChild().isNullable() }
+ }
+
+ /**
+ * A special character in a regular expression.
+ *
+ * Examples:
+ * ```
+ * ^
+ * $
+ * .
+ * ```
+ */
+ additional class RegExpSpecialChar extends RegExpTerm, TRegExpSpecialChar {
+ string char;
+
+ RegExpSpecialChar() {
+ this = TRegExpSpecialChar(re, start, end) and
+ re.specialCharacter(start, end, char)
+ }
+
+ /**
+ * Holds if this constant represents a valid Unicode character (as opposed
+ * to a surrogate code point that does not correspond to a character by itself.)
+ */
+ predicate isCharacter() { any() }
+
+ /** Gets the char for this term. */
+ string getChar() { result = char }
+
+ override RegExpTerm getChild(int i) { none() }
+
+ override string getAPrimaryQlClass() { result = "RegExpSpecialChar" }
+ }
+
+ /**
+ * A dot regular expression.
+ *
+ * Example:
+ *
+ * ```
+ * .
+ * ```
+ */
+ class RegExpDot extends RegExpSpecialChar {
+ RegExpDot() { this.getChar() = "." }
+
+ override string getAPrimaryQlClass() { result = "RegExpDot" }
+
+ override predicate isNullable() { none() }
+ }
+
+ /**
+ * A term that matches a specific position between characters in the string.
+ *
+ * Example:
+ *
+ * ```
+ * ^
+ * ```
+ */
+ class RegExpAnchor extends RegExpSpecialChar {
+ RegExpAnchor() { this.getChar() = ["^", "$"] }
+
+ override string getAPrimaryQlClass() { result = "RegExpAnchor" }
+ }
+
+ /**
+ * A dollar assertion `$` matching the end of a line.
+ *
+ * Example:
+ *
+ * ```
+ * $
+ * ```
+ */
+ class RegExpDollar extends RegExpAnchor {
+ RegExpDollar() { this.getChar() = "$" }
+
+ override string getAPrimaryQlClass() { result = "RegExpDollar" }
+
+ override predicate isNullable() { any() }
+ }
+
+ /**
+ * A caret assertion `^` matching the beginning of a line.
+ *
+ * Example:
+ *
+ * ```
+ * ^
+ * ```
+ */
+ class RegExpCaret extends RegExpAnchor {
+ RegExpCaret() { this.getChar() = "^" }
+
+ override string getAPrimaryQlClass() { result = "RegExpCaret" }
+
+ override predicate isNullable() { any() }
+ }
+
+ /**
+ * A zero-width match, that is, either an empty group or an assertion.
+ *
+ * Examples:
+ * ```
+ * ()
+ * (?=\w)
+ * ```
+ */
+ additional class RegExpZeroWidthMatch extends RegExpGroup {
+ RegExpZeroWidthMatch() { re.zeroWidthMatch(start, end) }
+
+ override RegExpTerm getChild(int i) { none() }
+
+ override string getAPrimaryQlClass() { result = "RegExpZeroWidthMatch" }
+
+ override predicate isNullable() { any() }
+ }
+
+ /**
+ * A zero-width lookahead assertion.
+ *
+ * Examples:
+ *
+ * ```
+ * (?=\w)
+ * (?!\n)
+ * ```
+ */
+ class RegExpSubPattern extends RegExpZeroWidthMatch {
+ RegExpSubPattern() { not re.emptyGroup(start, end) }
+
+ /** Gets the lookahead term. */
+ RegExpTerm getOperand() {
+ exists(int in_start, int in_end | re.groupContents(start, end, in_start, in_end) |
+ result.getRegExp() = re and
+ result.getStart() = in_start and
+ result.getEnd() = in_end
+ )
+ }
+
+ override predicate isNullable() { any() }
+ }
+
+ /**
+ * A zero-width lookahead assertion.
+ *
+ * Examples:
+ *
+ * ```
+ * (?=\w)
+ * (?!\n)
+ * ```
+ */
+ abstract class RegExpLookahead extends RegExpSubPattern { }
+
+ /**
+ * A positive-lookahead assertion.
+ *
+ * Examples:
+ *
+ * ```
+ * (?=\w)
+ * ```
+ */
+ class RegExpPositiveLookahead extends RegExpLookahead {
+ RegExpPositiveLookahead() { re.positiveLookaheadAssertionGroup(start, end) }
+
+ override string getAPrimaryQlClass() { result = "RegExpPositiveLookahead" }
+
+ override predicate isNullable() { any() }
+ }
+
+ /**
+ * A negative-lookahead assertion.
+ *
+ * Examples:
+ *
+ * ```
+ * (?!\n)
+ * ```
+ */
+ additional class RegExpNegativeLookahead extends RegExpLookahead {
+ RegExpNegativeLookahead() { re.negativeLookaheadAssertionGroup(start, end) }
+
+ override string getAPrimaryQlClass() { result = "RegExpNegativeLookahead" }
+ }
+
+ abstract class RegExpLookbehind extends RegExpSubPattern { }
+
+ abstract class RegExpPositiveLookbehind extends RegExpLookbehind { }
+
+ /**
+ * A back reference, that is, a term of the form `\i` in a regular
+ * expression.
+ *
+ * Examples:
+ *
+ * ```
+ * \1
+ * ```
+ */
+ class RegExpBackRef extends RegExpTerm, TRegExpBackRef {
+ RegExpBackRef() { this = TRegExpBackRef(re, start, end) }
+
+ /**
+ * Gets the number of the capture group this back reference refers to, if any.
+ */
+ int getNumber() { result = re.getBackRefNumber(start, end) }
+
+ /** Gets the capture group this back reference refers to. */
+ RegExpGroup getGroup() {
+ result.getLiteral() = this.getLiteral() and
+ result.getNumber() = this.getNumber()
+ }
+
+ override RegExpTerm getChild(int i) { none() }
+
+ override string getAPrimaryQlClass() { result = "RegExpBackRef" }
+
+ override predicate isNullable() { this.getGroup().isNullable() }
+ }
+
+ /**
+ * A named character property. For example, the POSIX bracket expression
+ * `[:digit:]`.
+ */
+ additional class RegExpNamedCharacterProperty extends RegExpTerm, TRegExpNamedCharacterProperty {
+ RegExpNamedCharacterProperty() { this = TRegExpNamedCharacterProperty(re, start, end) }
+
+ override RegExpTerm getChild(int i) { none() }
+
+ override string getAPrimaryQlClass() { result = "RegExpNamedCharacterProperty" }
+
+ /**
+ * Gets the property name. For example, in `[:digit:]`, the result is
+ * `"digit"`.
+ */
+ string getName() { result = re.getCharacterPropertyName(start, end) }
+
+ /**
+ * Gets the property symbol. For example, in `[:digit:]`, the result is
+ * `":"`.
+ */
+ string getSymbol() { result = re.getCharacterPropertySymbol(start, end) }
+ }
+
+ /**
+ * A named POSIX character class. For example, `[:digit:]`.
+ */
+ additional class RegExpNamedCharacterClass extends RegExpNamedCharacterProperty {
+ RegExpNamedCharacterClass() { ":" = re.getCharacterPropertySymbol(start, end) }
+ }
+
+ /**
+ * A named POSIX collating element. For example, `[.tilde.]`.
+ */
+ additional class RegExpNamedCollatingElement extends RegExpNamedCharacterProperty {
+ RegExpNamedCollatingElement() { "." = re.getCharacterPropertySymbol(start, end) }
+ }
+
+ /**
+ * A POSIX character equivalence class. For example, `[=a=]`.
+ */
+ additional class RegExpCharacterEquivalenceClass extends RegExpNamedCharacterProperty {
+ RegExpCharacterEquivalenceClass() { "=" = re.getCharacterPropertySymbol(start, end) }
+ }
+
+ class Top = RegExpParent;
+
+ /**
+ * Holds if `term` is an escape class representing e.g. `\d`.
+ * `clazz` is which character class it represents, e.g. "d" for `\d`.
+ */
+ predicate isEscapeClass(RegExpTerm term, string clazz) {
+ exists(RegExpCharacterClassEscape escape | term = escape | escape.getValue() = clazz)
+ or
+ // TODO: expand to cover more properties
+ exists(RegExpNamedCharacterClass escape | term = escape |
+ escape.getName().toLowerCase() = "digit" and
+ clazz = "d"
+ or
+ escape.getName().toLowerCase() = "space" and
+ clazz = "s"
+ or
+ escape.getName().toLowerCase() = "word" and
+ clazz = "w"
+ )
+ }
+
+ /**
+ * Holds if the regular expression should not be considered.
+ */
+ predicate isExcluded(RegExpParent parent) { none() }
+
+ /**
+ * Holds if `term` is a possessive quantifier.
+ * Not currently implemented, but is used by the shared library.
+ */
+ predicate isPossessive(RegExpQuantifier term) { none() }
+
+ /**
+ * Holds if the regex that `term` is part of is used in a way that ignores any leading prefix of the input it's matched against.
+ * Not yet implemented for C++.
+ */
+ predicate matchesAnyPrefix(RegExpTerm term) { any() }
+
+ /**
+ * Holds if the regex that `term` is part of is used in a way that ignores any trailing suffix of the input it's matched against.
+ * Not yet implemented for C++.
+ */
+ predicate matchesAnySuffix(RegExpTerm term) { any() }
+
+ /**
+ * Holds if `root` has the `i` flag for case-insensitive matching.
+ */
+ predicate isIgnoreCase(RegExpTerm root) {
+ root.isRootTerm() and
+ root.getLiteral().isIgnoreCase()
+ }
+
+ /**
+ * Holds if `root` has the `s` flag for dot-all matching.
+ */
+ predicate isDotAll(RegExpTerm root) {
+ root.isRootTerm() and
+ root.getLiteral().isDotAll()
+ }
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll b/cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll
new file mode 100644
index 000000000000..c90826d95c8c
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/regex/internal/ParseRegExp.qll
@@ -0,0 +1,871 @@
+/**
+ * Library for parsing C++ regular expressions.
+ *
+ * N.B. does not yet handle stripping whitespace and comments in regexes with
+ * the `x` (free-spacing) flag.
+ */
+
+private import semmle.code.cpp.exprs.Literal
+
+/**
+ * A C++ string literal containing a regular expression term, that is, either
+ * a regular expression literal, or a string literal used in a context where
+ * it is parsed as a regular expression.
+ */
+abstract class RegExp extends StringLiteral {
+ /**
+ * Holds if this `RegExp` has the `s` flag for dot-all matching.
+ */
+ predicate isDotAll() { none() }
+
+ /**
+ * Holds if this `RegExp` has the `i` flag for case-insensitive matching.
+ */
+ predicate isIgnoreCase() { none() }
+
+ /**
+ * Gets the flags for this `RegExp`, or the empty string if it has no flags.
+ */
+ string getFlags() { result = "" }
+
+ /**
+ * Helper predicate for `charSetStart(int start, int end)`.
+ *
+ * In order to identify left brackets ('[') which actually start a character class,
+ * we perform a left to right scan of the string.
+ *
+ * To avoid negative recursion we return a boolean. See `escaping`,
+ * the helper for `escapingChar`, for a clean use of this pattern.
+ *
+ * result is true for those start chars that actually mark a start of a char set.
+ */
+ boolean charSetStart(int pos) {
+ exists(int index |
+ // is opening bracket
+ this.charSetDelimiter(index, pos) = true and
+ (
+ // if this is the first bracket, `pos` starts a char set
+ index = 1 and result = true
+ or
+ // if the previous char set delimiter was not a closing bracket, `pos` does
+ // not start a char set. This is needed to handle cases such as `[[]` (a
+ // char set that matches the `[` char)
+ index > 1 and
+ not this.charSetDelimiter(index - 1, _) = false and
+ result = false
+ or
+ // special handling of cases such as `[][]` (the character-set of the characters `]` and `[`).
+ exists(int prevClosingBracketPos |
+ // previous bracket is a closing bracket
+ this.charSetDelimiter(index - 1, prevClosingBracketPos) = false and
+ if
+ // check if the character that comes before the previous closing bracket
+ // is an opening bracket (taking `^` into account)
+ // check if the character that comes before the previous closing bracket
+ // is an opening bracket (taking `^` into account)
+ exists(int posBeforePrevClosingBracket |
+ if this.getChar(prevClosingBracketPos - 1) = "^"
+ then posBeforePrevClosingBracket = prevClosingBracketPos - 2
+ else posBeforePrevClosingBracket = prevClosingBracketPos - 1
+ |
+ this.charSetDelimiter(index - 2, posBeforePrevClosingBracket) = true
+ )
+ then
+ // brackets without anything in between is not valid character ranges, so
+ // the first closing bracket in `[]]` and `[^]]` does not count,
+ //
+ // and we should _not_ mark the second opening bracket in `[][]` and `[^][]`
+ // as starting a new char set. ^ ^
+ exists(int posBeforePrevClosingBracket |
+ this.charSetDelimiter(index - 2, posBeforePrevClosingBracket) = true
+ |
+ result = this.charSetStart(posBeforePrevClosingBracket).booleanNot()
+ )
+ else
+ // if not, `pos` does in fact mark a real start of a character range
+ result = true
+ )
+ )
+ )
+ }
+
+ /**
+ * Helper predicate for chars that could be character-set delimiters.
+ * Holds if the (non-escaped) char at `pos` in the string, is the (one-based) `index` occurrence of a bracket (`[` or `]`) in the string.
+ * Result if `true` is the char is `[`, and `false` if the char is `]`.
+ */
+ boolean charSetDelimiter(int index, int pos) {
+ pos =
+ rank[index](int p |
+ (this.nonEscapedCharAt(p) = "[" or this.nonEscapedCharAt(p) = "]") and
+ // Brackets that are part of POSIX expressions should not count as
+ // char-set delimiters.
+ not exists(int x, int y | this.posixStyleProperty(x, y, _, _) and pos >= x and pos < y)
+ ) and
+ (
+ this.nonEscapedCharAt(pos) = "[" and result = true
+ or
+ this.nonEscapedCharAt(pos) = "]" and result = false
+ )
+ }
+
+ /** Holds if a character set starts between `start` and `end`. */
+ predicate charSetStart(int start, int end) {
+ this.charSetStart(start) = true and
+ (
+ this.getChar(start + 1) = "^" and end = start + 2
+ or
+ not this.getChar(start + 1) = "^" and end = start + 1
+ )
+ }
+
+ /** Whether there is a character class, between start (inclusive) and end (exclusive) */
+ predicate charSet(int start, int end) {
+ exists(int innerStart, int innerEnd |
+ this.charSetStart(start, innerStart) and
+ not this.charSetStart(_, start)
+ |
+ end = innerEnd + 1 and
+ innerEnd =
+ min(int e |
+ e > innerStart and
+ this.nonEscapedCharAt(e) = "]" and
+ not exists(int x, int y | this.posixStyleProperty(x, y, _, _) and e >= x and e < y)
+ |
+ e
+ )
+ )
+ }
+
+ /**
+ * Holds if the character set starting at `charsetStart` contains either
+ * a character or a `-` found between `start` and `end`.
+ */
+ private predicate charSetToken(int charsetStart, int index, int tokenStart, int tokenEnd) {
+ tokenStart =
+ rank[index](int start, int end | this.charSetToken(charsetStart, start, end) | start) and
+ this.charSetToken(charsetStart, tokenStart, tokenEnd)
+ }
+
+ /**
+ * Holds if the character set starting at `charsetStart` contains either
+ * a character or a `-` found between `start` and `end`.
+ */
+ private predicate charSetToken(int charsetStart, int start, int end) {
+ this.charSetStart(charsetStart, start) and
+ (
+ this.escapedCharacter(start, end)
+ or
+ this.namedCharacterProperty(start, end, _, _)
+ or
+ exists(this.nonEscapedCharAt(start)) and end = start + 1
+ )
+ or
+ this.charSetToken(charsetStart, _, start) and
+ (
+ this.escapedCharacter(start, end)
+ or
+ this.namedCharacterProperty(start, end, _, _)
+ or
+ exists(this.nonEscapedCharAt(start)) and
+ end = start + 1 and
+ not this.getChar(start) = "]"
+ )
+ }
+
+ /**
+ * Holds if the character set starting at `charsetStart` contains either
+ * a character or a range found between `start` and `end`.
+ */
+ predicate charSetChild(int charsetStart, int start, int end) {
+ this.charSetToken(charsetStart, start, end) and
+ not exists(int rangeStart, int rangeEnd |
+ this.charRange(charsetStart, rangeStart, _, _, rangeEnd) and
+ rangeStart <= start and
+ rangeEnd >= end
+ )
+ or
+ this.charRange(charsetStart, start, _, _, end)
+ }
+
+ /**
+ * Holds if the character set starting at `charsetStart` contains a character range
+ * with lower bound found between `start` and `lowerEnd`
+ * and upper bound found between `upperStart` and `end`.
+ */
+ predicate charRange(int charsetStart, int start, int lowerEnd, int upperStart, int end) {
+ exists(int index |
+ this.charRangeEnd(charsetStart, index) = true and
+ this.charSetToken(charsetStart, index - 2, start, lowerEnd) and
+ this.charSetToken(charsetStart, index, upperStart, end)
+ )
+ }
+
+ /**
+ * Helper predicate for `charRange`.
+ * We can determine where character ranges end by a left to right sweep.
+ *
+ * To avoid negative recursion we return a boolean. See `escaping`,
+ * the helper for `escapingChar`, for a clean use of this pattern.
+ */
+ private boolean charRangeEnd(int charsetStart, int index) {
+ this.charSetToken(charsetStart, index, _, _) and
+ (
+ index in [1, 2] and result = false
+ or
+ index > 2 and
+ exists(int connectorStart |
+ this.charSetToken(charsetStart, index - 1, connectorStart, _) and
+ this.nonEscapedCharAt(connectorStart) = "-" and
+ result =
+ this.charRangeEnd(charsetStart, index - 2)
+ .booleanNot()
+ .booleanAnd(this.charRangeEnd(charsetStart, index - 1).booleanNot())
+ )
+ or
+ not exists(int connectorStart |
+ this.charSetToken(charsetStart, index - 1, connectorStart, _) and
+ this.nonEscapedCharAt(connectorStart) = "-"
+ ) and
+ result = false
+ )
+ }
+
+ /** Holds if the character at `pos` is a "\" that is actually escaping what comes after. */
+ predicate escapingChar(int pos) { this.escaping(pos) = true }
+
+ /**
+ * Helper predicate for `escapingChar`.
+ * In order to avoid negative recursion, we return a boolean.
+ * This way, we can refer to `escaping(pos - 1).booleanNot()`
+ * rather than to a negated version of `escaping(pos)`.
+ */
+ private boolean escaping(int pos) {
+ pos = -1 and result = false
+ or
+ this.getChar(pos) = "\\" and result = this.escaping(pos - 1).booleanNot()
+ or
+ this.getChar(pos) != "\\" and result = false
+ }
+
+ /** Gets the text of this regex */
+ string getText() { result = this.getValue() }
+
+ /** Gets the `i`th character of this regex */
+ string getChar(int i) { result = this.getText().charAt(i) }
+
+ /** Gets the `i`th character of this regex, unless it is part of a character escape sequence. */
+ string nonEscapedCharAt(int i) {
+ result = this.getText().charAt(i) and
+ not exists(int x, int y | this.escapedCharacter(x, y) and i in [x .. y - 1])
+ }
+
+ private predicate isOptionDivider(int i) { this.nonEscapedCharAt(i) = "|" }
+
+ private predicate isGroupEnd(int i) { this.nonEscapedCharAt(i) = ")" and not this.inCharSet(i) }
+
+ private predicate isGroupStart(int i) { this.nonEscapedCharAt(i) = "(" and not this.inCharSet(i) }
+
+ /**
+ * Holds if the `i`th character could not be parsed.
+ */
+ predicate failedToParse(int i) {
+ exists(this.getChar(i)) and
+ not exists(int start, int end |
+ this.topLevel(start, end) and
+ start <= i and
+ end > i
+ )
+ }
+
+ /** Matches named character properties such as `[:digit:]`. */
+ predicate namedCharacterProperty(int start, int end, string symbol, string name) {
+ this.posixStyleProperty(start, end, symbol, name)
+ }
+
+ /** Gets the name of the character property in start,end */
+ string getCharacterPropertyName(int start, int end) {
+ this.namedCharacterProperty(start, end, _, result)
+ }
+
+ /** Gets the symbol of the character property in start,end */
+ string getCharacterPropertySymbol(int start, int end) {
+ this.namedCharacterProperty(start, end, result, _)
+ }
+
+ /** Matches a POSIX bracket expression such as `[:alnum:]` within a character class. */
+ private predicate posixStyleProperty(int start, int end, string symbol, string name) {
+ this.getChar(start) = "[" and
+ this.getChar(start + 1) = symbol and
+ end =
+ min(int e |
+ e > start and
+ this.getChar(e - 2) = symbol and
+ this.getChar(e - 1) = "]"
+ |
+ e
+ ) and
+ symbol in [":", ".", "="] and
+ name = this.getText().substring(start + 2, end - 2)
+ }
+
+ /**
+ * Holds if an escaped character is found between `start` and `end`.
+ * Escaped characters include hex values, octal values and named escapes,
+ * but excludes backreferences.
+ */
+ predicate escapedCharacter(int start, int end) {
+ this.escapingChar(start) and
+ not this.numberedBackreference(start, _, _) and
+ (
+ // hex char \xhh
+ this.getChar(start + 1) = "x" and end = start + 4
+ or
+ // wide hex char \uhhhh
+ this.getChar(start + 1) = "u" and end = start + 6
+ or
+ // control char \cX
+ this.getChar(start + 1) = "c" and end = start + 3
+ or
+ // nul escape \0 (when not followed by a digit)
+ this.getChar(start + 1) = "0" and
+ end = start + 2 and
+ not exists(this.getChar(start + 2).toInt())
+ or
+ // escape not handled above; update when adding a new case
+ not this.getChar(start + 1) in ["x", "u", "c"] and
+ not exists(this.getChar(start + 1).toInt()) and
+ end = start + 2
+ )
+ }
+
+ /**
+ * Holds if the character at `index` is inside a character set.
+ */
+ predicate inCharSet(int index) {
+ exists(int x, int y | this.charSet(x, y) and index in [x + 1 .. y - 2])
+ }
+
+ /**
+ * Holds if the character at `index` is inside a posix bracket.
+ */
+ predicate inPosixBracket(int index) {
+ exists(int x, int y | this.posixStyleProperty(x, y, _, _) and index in [x + 1 .. y - 2])
+ }
+
+ /**
+ * 'simple' characters are any that don't alter the parsing of the regex.
+ */
+ private predicate simpleCharacter(int start, int end) {
+ end = start + 1 and
+ not this.charSet(start, _) and
+ not this.charSet(_, start + 1) and
+ not exists(int x, int y |
+ this.posixStyleProperty(x, y, _, _) and
+ start >= x and
+ end <= y
+ ) and
+ exists(string c | c = this.getChar(start) |
+ exists(int x, int y, int z |
+ this.charSet(x, z) and
+ this.charSetStart(x, y)
+ |
+ start = y
+ or
+ start = z - 2
+ or
+ start > y and start < z - 2 and not this.charRange(_, _, start, end, _)
+ )
+ or
+ not this.inCharSet(start) and
+ not c = "(" and
+ not c = "[" and
+ not c = ")" and
+ not c = "|" and
+ not this.qualifier(start, _, _, _)
+ )
+ }
+
+ /**
+ * Holds if a simple or escaped character is found between `start` and `end`.
+ */
+ predicate character(int start, int end) {
+ (
+ this.simpleCharacter(start, end) and
+ not exists(int x, int y | this.escapedCharacter(x, y) and x <= start and y >= end)
+ or
+ this.escapedCharacter(start, end)
+ ) and
+ not exists(int x, int y | this.groupStart(x, y) and x <= start and y >= end) and
+ not exists(int x, int y | this.backreference(x, y) and x <= start and y >= end) and
+ not exists(int x, int y | this.multiples(x, y, _, _) and x <= start and y >= end)
+ }
+
+ /**
+ * Holds if a normal character is found between `start` and `end`.
+ */
+ predicate normalCharacter(int start, int end) {
+ end = start + 1 and
+ this.character(start, end) and
+ not this.specialCharacter(start, end, _)
+ }
+
+ /**
+ * Holds if a special character is found between `start` and `end`.
+ */
+ predicate specialCharacter(int start, int end, string char) {
+ this.character(start, end) and
+ not this.inCharSet(start) and
+ (
+ end = start + 1 and
+ char = this.getChar(start) and
+ (char = "$" or char = "^" or char = ".")
+ or
+ end = start + 2 and
+ this.escapingChar(start) and
+ char = this.getText().substring(start, end) and
+ char = ["\\b", "\\B"]
+ )
+ }
+
+ /**
+ * Holds if the range [start:end) consists of only 'normal' characters.
+ */
+ predicate normalCharacterSequence(int start, int end) {
+ // a normal character inside a character set is interpreted on its own
+ this.normalCharacter(start, end) and
+ this.inCharSet(start)
+ or
+ // a maximal run of normal characters is considered as one constant
+ exists(int s, int e |
+ e = max(int i | this.normalCharacterRun(s, i)) and
+ not this.inCharSet(s)
+ |
+ // 'abc' can be considered one constant, but
+ // 'abc+' has to be broken up into 'ab' and 'c+',
+ // as the qualifier only applies to 'c'.
+ if this.qualifier(e, _, _, _)
+ then
+ end = e and start = e - 1
+ or
+ end = e - 1 and start = s and start < end
+ else (
+ end = e and
+ start = s
+ )
+ )
+ }
+
+ private predicate normalCharacterRun(int start, int end) {
+ (
+ this.normalCharacterRun(start, end - 1)
+ or
+ start = end - 1 and not this.normalCharacter(start - 1, start)
+ ) and
+ this.normalCharacter(end - 1, end)
+ }
+
+ private predicate characterItem(int start, int end) {
+ this.normalCharacterSequence(start, end) or
+ this.escapedCharacter(start, end) or
+ this.specialCharacter(start, end, _)
+ }
+
+ /** Whether the text in the range `start,end` is a group */
+ predicate group(int start, int end) {
+ this.groupContents(start, end, _, _)
+ or
+ this.emptyGroup(start, end)
+ }
+
+ /** Gets the number of the group in start,end */
+ int getGroupNumber(int start, int end) {
+ this.group(start, end) and
+ not this.nonCapturingGroupStart(start, _) and
+ result =
+ count(int i | this.group(i, _) and i < start and not this.nonCapturingGroupStart(i, _)) + 1
+ }
+
+ /** Whether the text in the range start, end is a group and can match the empty string. */
+ predicate zeroWidthMatch(int start, int end) {
+ this.emptyGroup(start, end)
+ or
+ this.negativeAssertionGroup(start, end)
+ or
+ this.positiveLookaheadAssertionGroup(start, end)
+ }
+
+ /** Holds if an empty group is found between `start` and `end`. */
+ predicate emptyGroup(int start, int end) {
+ exists(int endm1 | end = endm1 + 1 |
+ this.groupStart(start, endm1) and
+ this.isGroupEnd(endm1)
+ )
+ }
+
+ private predicate emptyMatchAtStartGroup(int start, int end) {
+ this.emptyGroup(start, end)
+ or
+ this.negativeAssertionGroup(start, end)
+ or
+ this.positiveLookaheadAssertionGroup(start, end)
+ }
+
+ private predicate emptyMatchAtEndGroup(int start, int end) {
+ this.emptyGroup(start, end)
+ or
+ this.negativeAssertionGroup(start, end)
+ }
+
+ private predicate negativeAssertionGroup(int start, int end) {
+ exists(int inStart | this.negativeLookaheadAssertionStart(start, inStart) |
+ this.groupContents(start, end, inStart, _)
+ )
+ }
+
+ /** Holds if a negative lookahead is found between `start` and `end` */
+ predicate negativeLookaheadAssertionGroup(int start, int end) {
+ exists(int inStart | this.negativeLookaheadAssertionStart(start, inStart) |
+ this.groupContents(start, end, inStart, _)
+ )
+ }
+
+ /** Holds if a positive lookahead is found between `start` and `end` */
+ predicate positiveLookaheadAssertionGroup(int start, int end) {
+ exists(int inStart | this.lookaheadAssertionStart(start, inStart) |
+ this.groupContents(start, end, inStart, _)
+ )
+ }
+
+ private predicate groupStart(int start, int end) {
+ this.nonCapturingGroupStart(start, end)
+ or
+ this.lookaheadAssertionStart(start, end)
+ or
+ this.negativeLookaheadAssertionStart(start, end)
+ or
+ this.simpleGroupStart(start, end)
+ }
+
+ /** Matches the start of a non-capturing group, e.g. `(?:` */
+ private predicate nonCapturingGroupStart(int start, int end) {
+ this.isGroupStart(start) and
+ this.getChar(start + 1) = "?" and
+ this.getChar(start + 2) = [":", "=", "!"] and
+ end = start + 3
+ }
+
+ /** Matches the start of a simple group, e.g. `(a+)`. */
+ private predicate simpleGroupStart(int start, int end) {
+ this.isGroupStart(start) and
+ this.getChar(start + 1) != "?" and
+ end = start + 1
+ }
+
+ /** Matches the start of a positive lookahead assertion, i.e. `(?=`. */
+ private predicate lookaheadAssertionStart(int start, int end) {
+ this.isGroupStart(start) and
+ this.getChar(start + 1) = "?" and
+ this.getChar(start + 2) = "=" and
+ end = start + 3
+ }
+
+ /** Matches the start of a negative lookahead assertion, i.e. `(?!`. */
+ private predicate negativeLookaheadAssertionStart(int start, int end) {
+ this.isGroupStart(start) and
+ this.getChar(start + 1) = "?" and
+ this.getChar(start + 2) = "!" and
+ end = start + 3
+ }
+
+ /** Matches the contents of a group. */
+ predicate groupContents(int start, int end, int inStart, int inEnd) {
+ this.groupStart(start, inStart) and
+ end = inEnd + 1 and
+ this.topLevel(inStart, inEnd) and
+ this.isGroupEnd(inEnd)
+ }
+
+ /** Matches a numbered backreference, e.g. `\1`. */
+ predicate numberedBackreference(int start, int end, int value) {
+ this.escapingChar(start) and
+ not this.getChar(start + 1) = "0" and
+ exists(string text, string svalue, int len |
+ end = start + len and
+ text = this.getText() and
+ len in [2 .. 3]
+ |
+ svalue = text.substring(start + 1, start + len) and
+ value = svalue.toInt() and
+ not exists(text.substring(start + 1, start + len + 1).toInt()) and
+ value > 0
+ )
+ }
+
+ /** Whether the text in the range `start,end` is a back reference */
+ predicate backreference(int start, int end) { this.numberedBackreference(start, end, _) }
+
+ /** Gets the number of the back reference in start,end */
+ int getBackRefNumber(int start, int end) { this.numberedBackreference(start, end, result) }
+
+ private predicate baseItem(int start, int end) {
+ this.characterItem(start, end) and
+ not exists(int x, int y | this.charSet(x, y) and x <= start and y >= end)
+ or
+ this.group(start, end)
+ or
+ this.charSet(start, end)
+ or
+ this.backreference(start, end)
+ }
+
+ private predicate qualifier(int start, int end, boolean maybeEmpty, boolean mayRepeatForever) {
+ this.shortQualifier(start, end, maybeEmpty, mayRepeatForever) and
+ not this.getChar(end) = "?"
+ or
+ exists(int shortEnd | this.shortQualifier(start, shortEnd, maybeEmpty, mayRepeatForever) |
+ if this.getChar(shortEnd) = "?" then end = shortEnd + 1 else end = shortEnd
+ )
+ }
+
+ private predicate shortQualifier(int start, int end, boolean maybeEmpty, boolean mayRepeatForever) {
+ (
+ this.getChar(start) = "+" and maybeEmpty = false and mayRepeatForever = true
+ or
+ this.getChar(start) = "*" and maybeEmpty = true and mayRepeatForever = true
+ or
+ this.getChar(start) = "?" and maybeEmpty = true and mayRepeatForever = false
+ ) and
+ end = start + 1
+ or
+ exists(string lower, string upper |
+ this.multiples(start, end, lower, upper) and
+ (if lower = "" or lower.toInt() = 0 then maybeEmpty = true else maybeEmpty = false) and
+ if upper = "" then mayRepeatForever = true else mayRepeatForever = false
+ )
+ }
+
+ /**
+ * Holds if a repetition quantifier is found between `start` and `end`,
+ * with the given lower and upper bounds. If a bound is omitted, the corresponding
+ * string is empty.
+ */
+ predicate multiples(int start, int end, string lower, string upper) {
+ exists(string text, string match, string inner |
+ text = this.getText() and
+ end = start + match.length() and
+ inner = match.substring(1, match.length() - 1)
+ |
+ match = text.regexpFind("\\{[0-9]+\\}", _, start) and
+ lower = inner and
+ upper = lower
+ or
+ match = text.regexpFind("\\{[0-9]+,[0-9]*\\}", _, start) and
+ exists(int commaIndex |
+ commaIndex = inner.indexOf(",") and
+ lower = inner.prefix(commaIndex) and
+ upper = inner.suffix(commaIndex + 1)
+ )
+ )
+ }
+
+ /**
+ * Whether the text in the range start,end is a qualified item, where item is a character,
+ * a character set or a group.
+ */
+ predicate qualifiedItem(int start, int end, boolean maybeEmpty, boolean mayRepeatForever) {
+ this.qualifiedPart(start, _, end, maybeEmpty, mayRepeatForever)
+ }
+
+ /**
+ * Holds if a qualified part is found between `start` and `partEnd` and the qualifier is
+ * found between `partEnd` and `end`.
+ *
+ * `maybeEmpty` is true if the part is optional.
+ * `mayRepeatForever` is true if the part may be repeated unboundedly.
+ */
+ predicate qualifiedPart(
+ int start, int partEnd, int end, boolean maybeEmpty, boolean mayRepeatForever
+ ) {
+ this.baseItem(start, partEnd) and
+ this.qualifier(partEnd, end, maybeEmpty, mayRepeatForever)
+ }
+
+ /** Holds if the range `start`, `end` contains a character, a quantifier, a character set or a group. */
+ predicate item(int start, int end) {
+ this.qualifiedItem(start, end, _, _)
+ or
+ this.baseItem(start, end) and not this.qualifier(end, _, _, _)
+ }
+
+ private predicate subsequence(int start, int end) {
+ (
+ start = 0 or
+ this.groupStart(_, start) or
+ this.isOptionDivider(start - 1)
+ ) and
+ this.item(start, end)
+ or
+ exists(int mid |
+ this.subsequence(start, mid) and
+ this.item(mid, end)
+ )
+ }
+
+ /**
+ * Whether the text in the range start,end is a sequence of 1 or more items, where an item is a character,
+ * a character set or a group.
+ */
+ predicate sequence(int start, int end) {
+ this.sequenceOrQualified(start, end) and
+ not this.qualifiedItem(start, end, _, _)
+ }
+
+ private predicate sequenceOrQualified(int start, int end) {
+ this.subsequence(start, end) and
+ not this.itemStart(end)
+ }
+
+ private predicate itemStart(int start) {
+ this.characterItem(start, _) or
+ this.isGroupStart(start) or
+ this.charSet(start, _) or
+ this.backreference(start, _) or
+ this.namedCharacterProperty(start, _, _, _)
+ }
+
+ private predicate itemEnd(int end) {
+ this.characterItem(_, end)
+ or
+ exists(int endm1 | this.isGroupEnd(endm1) and end = endm1 + 1)
+ or
+ this.charSet(_, end)
+ or
+ this.qualifier(_, end, _, _)
+ }
+
+ private predicate topLevel(int start, int end) {
+ this.subalternation(start, end, _) and
+ not this.isOptionDivider(end)
+ }
+
+ private predicate subalternation(int start, int end, int itemStart) {
+ this.sequenceOrQualified(start, end) and
+ not this.isOptionDivider(start - 1) and
+ itemStart = start
+ or
+ start = end and
+ not this.itemEnd(start) and
+ this.isOptionDivider(end) and
+ itemStart = start
+ or
+ exists(int mid |
+ this.subalternation(start, mid, _) and
+ this.isOptionDivider(mid) and
+ itemStart = mid + 1
+ |
+ this.sequenceOrQualified(itemStart, end)
+ or
+ not this.itemStart(end) and end = itemStart
+ )
+ }
+
+ /**
+ * Whether the text in the range start,end is an alternation
+ */
+ predicate alternation(int start, int end) {
+ not this.inCharSet(start) and
+ this.topLevel(start, end) and
+ exists(int less | this.subalternation(start, less, _) and less < end)
+ }
+
+ /**
+ * Whether the text in the range start,end is an alternation and the text in partStart, partEnd is one of the
+ * options in that alternation.
+ */
+ predicate alternationOption(int start, int end, int partStart, int partEnd) {
+ this.alternation(start, end) and
+ this.subalternation(start, partEnd, partStart)
+ }
+
+ /** A part of the regex that may match the start of the string. */
+ private predicate firstPart(int start, int end) {
+ start = 0 and end = this.getText().length()
+ or
+ exists(int x | this.firstPart(x, end) |
+ this.emptyMatchAtStartGroup(x, start)
+ or
+ this.qualifiedItem(x, start, true, _)
+ or
+ // ^ matches the start of the string
+ this.specialCharacter(x, start, "^")
+ )
+ or
+ exists(int y | this.firstPart(start, y) |
+ this.item(start, end)
+ or
+ this.qualifiedPart(start, end, y, _, _)
+ )
+ or
+ exists(int x, int y | this.firstPart(x, y) |
+ this.groupContents(x, y, start, end)
+ or
+ this.alternationOption(x, y, start, end)
+ )
+ }
+
+ /** A part of the regex that may match the end of the string. */
+ private predicate lastPart(int start, int end) {
+ start = 0 and end = this.getText().length()
+ or
+ exists(int y | this.lastPart(start, y) |
+ this.emptyMatchAtEndGroup(end, y)
+ or
+ this.qualifiedItem(end, y, true, _)
+ or
+ // $ matches the end of the string.
+ this.specialCharacter(end, y, "$")
+ )
+ or
+ this.lastPart(_, end) and
+ this.item(start, end)
+ or
+ exists(int y | this.lastPart(start, y) | this.qualifiedPart(start, end, y, _, _))
+ or
+ exists(int x, int y | this.lastPart(x, y) |
+ this.groupContents(x, y, start, end)
+ or
+ this.alternationOption(x, y, start, end)
+ )
+ }
+
+ /**
+ * Whether the item at [start, end) is one of the first items
+ * to be matched.
+ */
+ predicate firstItem(int start, int end) {
+ (
+ this.characterItem(start, end)
+ or
+ this.qualifiedItem(start, end, _, _)
+ or
+ this.charSet(start, end)
+ ) and
+ this.firstPart(start, end)
+ }
+
+ /**
+ * Whether the item at [start, end) is one of the last items
+ * to be matched.
+ */
+ predicate lastItem(int start, int end) {
+ (
+ this.characterItem(start, end)
+ or
+ this.qualifiedItem(start, end, _, _)
+ or
+ this.charSet(start, end)
+ ) and
+ this.lastPart(start, end)
+ }
+}
diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme
index 0853f43dc8c0..293904928d85 100644
--- a/cpp/ql/lib/semmlecode.cpp.dbscheme
+++ b/cpp/ql/lib/semmlecode.cpp.dbscheme
@@ -660,46 +660,49 @@ case @builtintype.kind of
| 24 = @float
| 25 = @double
| 26 = @long_double
-| 27 = @complex_float // C99-specific _Complex float
-| 28 = @complex_double // C99-specific _Complex double
-| 29 = @complex_long_double // C99-specific _Complex long double
-| 30 = @imaginary_float // C99-specific _Imaginary float
-| 31 = @imaginary_double // C99-specific _Imaginary double
-| 32 = @imaginary_long_double // C99-specific _Imaginary long double
-| 33 = @wchar_t // Microsoft-specific
-| 34 = @decltype_nullptr // C++11
-| 35 = @int128 // __int128
-| 36 = @unsigned_int128 // unsigned __int128
-| 37 = @signed_int128 // signed __int128
-| 38 = @float128 // __float128
-| 39 = @complex_float128 // _Complex __float128
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
// ... 40 _Decimal32
// ... 41 _Decimal64
// ... 42 _Decimal128
| 43 = @char16_t
| 44 = @char32_t
-| 45 = @std_float32 // _Float32
-| 46 = @float32x // _Float32x
-| 47 = @std_float64 // _Float64
-| 48 = @float64x // _Float64x
-| 49 = @std_float128 // _Float128
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
// ... 50 _Float128x
| 51 = @char8_t
-| 52 = @float16 // _Float16
-| 53 = @complex_float16 // _Complex _Float16
-| 54 = @fp16 // __fp16
-| 55 = @std_bfloat16 // __bf16
-| 56 = @std_float16 // std::float16_t
-| 57 = @complex_std_float32 // _Complex _Float32
-| 58 = @complex_float32x // _Complex _Float32x
-| 59 = @complex_std_float64 // _Complex _Float64
-| 60 = @complex_float64x // _Complex _Float64x
-| 61 = @complex_std_float128 // _Complex _Float128
-| 62 = @mfp8 // __mfp8
-| 63 = @scalable_vector_count // __SVCount_t
-| 64 = @complex_fp16 // _Complex __fp16
-| 65 = @complex_std_bfloat16 // _Complex __bf16
-| 66 = @complex_std_float16 // _Complex std::float16_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+| 63 = @scalable_vector_count // __SVCount_t
+| 64 = @complex_fp16 // _Complex __fp16
+| 65 = @complex_std_bfloat16 // _Complex __bf16
+| 66 = @complex_std_float16 // _Complex std::float16_t
+| 67 = @bit_precise_int // _BitInt(N)
+| 68 = @unsigned_bit_precise_int // unsigned _BitInt(N)
+| 69 = @signed_bit_precise_int // signed _BitInt(N)
;
builtintypes(
@@ -711,6 +714,11 @@ builtintypes(
int alignment: int ref
);
+bit_precise_int_types(
+ unique int id: @builtintype ref,
+ int bit_width: int ref
+)
+
/**
* Derived types are types that are directly derived from existing types and
* point to, refer to, transform type data to return a new type.
@@ -736,9 +744,11 @@ derivedtypes(
int type_id: @type ref
);
-pointerishsize(unique int id: @derivedtype ref,
+pointerishsize(
+ unique int id: @derivedtype ref,
int size: int ref,
- int alignment: int ref);
+ int alignment: int ref
+);
arraysizes(
unique int id: @derivedtype ref,
@@ -1994,6 +2004,13 @@ case @expr.kind of
| 394 = @isinvocable
| 395 = @isnothrowinvocable
| 396 = @isbitwisecloneable
+| 397 = @isvirtualbaseof
+| 398 = @isimplicitlifetime
+| 399 = @ltsynthesizesfromspaceship
+| 400 = @gtsynthesizesfromspaceship
+| 401 = @lesynthesizesfromspaceship
+| 402 = @gesynthesizesfromspaceship
+| 403 = @isstructural
;
@var_args_expr = @vastartexpr
@@ -2113,6 +2130,13 @@ case @expr.kind of
| @isinvocable
| @isnothrowinvocable
| @isbitwisecloneable
+ | @isvirtualbaseof
+ | @isimplicitlifetime
+ | @ltsynthesizesfromspaceship
+ | @gtsynthesizesfromspaceship
+ | @lesynthesizesfromspaceship
+ | @gesynthesizesfromspaceship
+ | @isstructural
;
compound_requirement_is_noexcept(
diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
index 54cdc7a85081..90a3250189fb 100644
--- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
+++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
@@ -2,7 +2,7 @@
@compilation
- 12556
+ 12794
@externalDataElement
@@ -10,19 +10,19 @@
@file
- 64766
+ 65994
@folder
- 12305
+ 12538
@diagnostic
- 356
+ 363
@location_default
- 46362405
+ 46368911
@trap
@@ -42,15 +42,15 @@
@macro_expansion
- 40315722
+ 40292268
@other_macro_reference
- 300696
+ 300521
@normal_function
- 2699010
+ 2699581
@unknown_function
@@ -58,19 +58,19 @@
@constructor
- 688614
+ 692574
@destructor
- 84823
+ 84841
@conversion_function
- 10188
+ 10190
@operator
- 647163
+ 647300
@user_defined_literal
@@ -78,31 +78,31 @@
@deduction_guide
- 5769
+ 5770
@fun_decl
- 4148376
+ 4149377
@var_decl
- 9436285
+ 9411026
@type_decl
- 1639390
+ 1639737
@namespace_decl
- 405513
+ 406672
@using_declaration
- 265844
+ 271344
@using_directive
- 6377
+ 6415
@using_enum_declaration
@@ -110,27 +110,27 @@
@static_assert
- 171628
+ 172118
@parameter
- 6930613
+ 6932082
@membervariable
- 1503078
+ 1502203
@globalvariable
- 661280
+ 634531
@localvariable
- 725852
+ 733187
@enumconstant
- 348112
+ 347910
@errortype
@@ -364,37 +364,49 @@
@complex_std_float16
122
+
+ @bit_precise_int
+ 4
+
+
+ @unsigned_bit_precise_int
+ 6
+
+
+ @signed_bit_precise_int
+ 1
+
@pointer
- 449159
+ 449255
@type_with_specifiers
- 686813
+ 686958
@array
- 89611
+ 89629
@routineptr
- 674281
+ 678157
@reference
- 958837
+ 959040
@gnu_vector
- 671
+ 684
@routinereference
- 369
+ 371
@rvalue_reference
- 286877
+ 286938
@block
@@ -406,7 +418,7 @@
@typeof
- 812
+ 811
@underlying_type
@@ -454,7 +466,7 @@
@remove_cv
- 2095
+ 2098
@remove_cvref
@@ -482,31 +494,31 @@
@remove_reference
- 5688
+ 5695
@decltype
- 101861
+ 101802
@struct
- 1039206
+ 1056347
@union
- 20745
+ 20749
@enum
- 41614
+ 41590
@template_parameter
- 863096
+ 879462
@alias
- 1757610
+ 1791463
@unknown_usertype
@@ -514,27 +526,27 @@
@class
- 320881
+ 320949
@template_template_parameter
- 6073
+ 6189
@proxy_class
- 50227
+ 51179
@scoped_enum
- 11416
+ 11418
@template_struct
- 210581
+ 214585
@template_class
- 28847
+ 28853
@template_union
@@ -542,27 +554,27 @@
@mangledname
- 6352070
+ 6345435
@type_mention
- 5941339
+ 5937883
@concept_template
- 3592
+ 3596
@routinetype
- 595664
+ 599081
@ptrtomember
- 9651
+ 9834
@specifier
- 7610
+ 7612
@gnuattribute
@@ -570,11 +582,11 @@
@stdattribute
- 347764
+ 347838
@declspec
- 330464
+ 330272
@msattribute
@@ -582,19 +594,19 @@
@alignas
- 2164
+ 2186
@attribute_arg_token
- 16448
+ 16544
@attribute_arg_constant_expr
- 71688
+ 72665
@attribute_arg_expr
- 1582
+ 1584
@attribute_arg_empty
@@ -606,23 +618,23 @@
@attribute_arg_type
- 460
+ 464
@derivation
- 492610
+ 494850
@frienddecl
- 761457
+ 765911
@comment
- 11056034
+ 11058376
@namespace
- 8591
+ 8754
@specialnamequalifyingelement
@@ -630,15 +642,15 @@
@namequalifier
- 3050545
+ 3044942
@value
- 13547098
+ 13539217
@initialiser
- 2289023
+ 2292672
@address_of
@@ -646,131 +658,131 @@
@indirect
- 401998
+ 401764
@array_to_pointer
- 1954311
+ 1953174
@parexpr
- 4916613
+ 4913752
@arithnegexpr
- 586702
+ 586361
@unaryplusexpr
- 4117
+ 4158
@complementexpr
- 38195
+ 38172
@notexpr
- 355868
+ 355661
@postincrexpr
- 84590
+ 84541
@postdecrexpr
- 57409
+ 57375
@preincrexpr
- 96742
+ 96685
@predecrexpr
- 35831
+ 35810
@conditionalexpr
- 898137
+ 897615
@addexpr
- 581041
+ 580703
@subexpr
- 466933
+ 466661
@mulexpr
- 445548
+ 445289
@divexpr
- 52399
+ 52368
@remexpr
- 15776
+ 15869
@paddexpr
- 118654
+ 118585
@psubexpr
- 68032
+ 67992
@pdiffexpr
- 42841
+ 43832
@lshiftexpr
- 552490
+ 552169
@rshiftexpr
- 201483
+ 201365
@andexpr
- 483730
+ 483448
@orexpr
- 194110
+ 193997
@xorexpr
- 73969
+ 73926
@eqexpr
- 643558
+ 643183
@neexpr
- 411988
+ 411749
@gtexpr
- 111181
+ 111116
@ltexpr
- 139469
+ 139388
@geexpr
- 81322
+ 81275
@leexpr
- 291998
+ 291828
@assignexpr
- 1281515
+ 1280769
@assignaddexpr
@@ -778,15 +790,15 @@
@assignsubexpr
- 15312
+ 15303
@assignmulexpr
- 11109
+ 11319
@assigndivexpr
- 6808
+ 6804
@assignremexpr
@@ -794,7 +806,7 @@
@assignlshiftexpr
- 3703
+ 3701
@assignrshiftexpr
@@ -802,127 +814,127 @@
@assignandexpr
- 6530
+ 6526
@assignorexpr
- 19612
+ 19601
@assignxorexpr
- 29905
+ 29888
@assignpaddexpr
- 18633
+ 18622
@assignpsubexpr
- 1576
+ 1575
@andlogicalexpr
- 346689
+ 346487
@orlogicalexpr
- 1103855
+ 1103212
@commaexpr
- 165227
+ 165262
@subscriptexpr
- 435268
+ 435015
@callexpr
- 261260
+ 263463
@vastartexpr
- 5007
+ 5021
@vaargexpr
- 1303
+ 1302
@vaendexpr
- 2941
+ 2939
@vacopyexpr
- 134
+ 135
@varaccess
- 8257017
+ 8252213
@runtime_sizeof
- 401820
+ 401586
@runtime_alignof
- 50352
+ 50646
@expr_stmt
- 147669
+ 147583
@routineexpr
- 5708356
+ 5708855
@type_operand
- 1405785
+ 1404968
@offsetofexpr
- 148579
+ 148493
@typescompexpr
- 702145
+ 701736
@literal
- 8057470
+ 8036394
@aggregateliteral
- 1397495
+ 1400988
@c_style_cast
- 6028638
+ 6023782
@temp_init
- 974536
+ 985294
@errorexpr
- 44841
+ 45075
@reference_to
- 1869126
+ 1890439
@ref_indirect
- 2079573
+ 2091838
@vacuous_destructor_call
- 7720
+ 7765
@assume
- 4150
+ 4162
@conjugation
@@ -930,11 +942,11 @@
@realpartexpr
- 73
+ 74
@imagpartexpr
- 73
+ 74
@jmulexpr
@@ -974,31 +986,31 @@
@thisaccess
- 1549814
+ 1554373
@new_expr
- 45518
+ 45784
@delete_expr
- 11312
+ 11378
@throw_expr
- 23607
+ 23918
@condition_decl
- 406398
+ 406893
@braced_init_list
- 2092
+ 2115
@type_id
- 47196
+ 47472
@sizeof_pack
@@ -1030,7 +1042,7 @@
@hastrivialconstr
- 7
+ 3
@hastrivialcopy
@@ -1054,7 +1066,7 @@
@isclassexpr
- 2374
+ 2381
@isconvtoexpr
@@ -1062,15 +1074,15 @@
@isemptyexpr
- 8715
+ 8717
@isenumexpr
- 2946
+ 2332
@ispodexpr
- 828
+ 844
@ispolyexpr
@@ -1086,83 +1098,83 @@
@hastrivialdestructor
- 2752
+ 776
@uuidof
- 26214
+ 26289
@delete_array_expr
- 1237
+ 1261
@new_array_expr
- 6597
+ 6616
@foldexpr
- 1261
+ 1263
@ctordirectinit
- 111177
+ 111793
@ctorvirtualinit
- 3961
+ 3984
@ctorfieldinit
- 202913
+ 204061
@ctordelegatinginit
- 3559
+ 3560
@dtordirectdestruct
- 38871
+ 39099
@dtorvirtualdestruct
- 3927
+ 3950
@dtorfielddestruct
- 39241
+ 39470
@static_cast
- 346536
+ 348329
@reinterpret_cast
- 39434
+ 39547
@const_cast
- 24101
+ 24242
@dynamic_cast
- 786
+ 801
@lambdaexpr
- 18970
+ 19024
@param_ref
- 163542
+ 165342
@noopexpr
- 80
+ 89
@istriviallyconstructibleexpr
- 3682
+ 2332
@isdestructibleexpr
@@ -1178,15 +1190,15 @@
@istriviallyassignableexpr
- 3682
+ 2332
@isnothrowassignableexpr
- 5032
+ 5034
@istrivialexpr
- 3310
+ 1249
@isstandardlayoutexpr
@@ -1214,11 +1226,11 @@
@isconstructibleexpr
- 3559
+ 3560
@isnothrowconstructibleexpr
- 20377
+ 20381
@hasfinalizerexpr
@@ -1254,11 +1266,11 @@
@isfinalexpr
- 9264
+ 9318
@noexceptexpr
- 30169
+ 30501
@builtinshufflevector
@@ -1266,11 +1278,11 @@
@builtinchooseexpr
- 20614
+ 20602
@builtinaddressof
- 15221
+ 15224
@vec_fill
@@ -1286,7 +1298,7 @@
@spaceshipexpr
- 1347
+ 1348
@co_await
@@ -1314,7 +1326,7 @@
@builtinshuffle
- 608
+ 619
@blockassignexpr
@@ -1322,7 +1334,7 @@
@issame
- 4511
+ 4517
@isfunction
@@ -1430,7 +1442,7 @@
@reuseexpr
- 841815
+ 842839
@istriviallycopyassignable
@@ -1526,23 +1538,23 @@
@c11_generic
- 29973
+ 29956
@requires_expr
- 16401
+ 16421
@nested_requirement
- 684
+ 685
@compound_requirement
- 10884
+ 10897
@concept_id
- 90068
+ 90178
@isinvocable
@@ -1556,81 +1568,109 @@
@isbitwisecloneable
2
+
+ @isvirtualbaseof
+ 2
+
+
+ @isimplicitlifetime
+ 2
+
+
+ @ltsynthesizesfromspaceship
+ 2
+
+
+ @gtsynthesizesfromspaceship
+ 2
+
+
+ @lesynthesizesfromspaceship
+ 2
+
+
+ @gesynthesizesfromspaceship
+ 2
+
+
+ @isstructural
+ 2
+
@lambdacapture
- 31810
+ 31901
@stmt_expr
- 2032201
+ 2031019
@stmt_if
- 990500
+ 989924
@stmt_while
- 39659
+ 39636
@stmt_goto
- 156829
+ 159803
@stmt_label
- 77512
+ 78982
@stmt_return
- 1233370
+ 1257325
@stmt_block
- 1695980
+ 1707512
@stmt_end_test_while
- 232528
+ 232393
@stmt_for
- 84413
+ 84364
@stmt_switch_case
- 830952
+ 831962
@stmt_switch
- 409306
+ 409804
@stmt_asm
- 63893
+ 63856
@stmt_decl
- 770162
+ 772371
@stmt_empty
- 426756
+ 427275
@stmt_continue
- 28099
+ 28083
@stmt_break
- 137217
+ 137609
@stmt_try_block
- 26230
+ 26569
@stmt_microsoft_try
- 209
+ 210
@stmt_set_vla_size
@@ -1642,19 +1682,19 @@
@stmt_assigned_goto
- 12425
+ 12418
@stmt_range_based_for
- 6157
+ 6225
@stmt_handler
- 42985
+ 43502
@stmt_constexpr_if
- 103236
+ 103258
@stmt_co_return
@@ -1674,51 +1714,51 @@
@ppd_if
- 581489
+ 581612
@ppd_ifdef
- 214425
+ 214300
@ppd_ifndef
- 160411
+ 160318
@ppd_elif
- 21767
+ 22180
@ppd_else
- 231147
+ 231196
@ppd_endif
- 874750
+ 874936
@ppd_plain_include
- 316386
+ 322385
@ppd_define
- 2706007
+ 2706580
@ppd_undef
- 98817
+ 98838
@ppd_pragma
- 399689
+ 399774
@ppd_include_next
- 167
+ 168
@ppd_line
- 18810
+ 19000
@ppd_error
@@ -1750,7 +1790,7 @@
@link_target
- 817
+ 816
@xmldtd
@@ -1780,11 +1820,11 @@
compilations
- 12556
+ 12794
id
- 12556
+ 12794
cwd
@@ -1802,7 +1842,7 @@
1
2
- 12556
+ 12794
@@ -1828,19 +1868,19 @@
compilation_args
- 1005291
+ 1024354
id
- 12556
+ 12794
num
- 1458
+ 1485
arg
- 29068
+ 29619
@@ -1854,77 +1894,77 @@
36
42
- 996
+ 1015
42
43
- 1090
+ 1111
43
44
- 713
+ 726
44
45
- 503
+ 513
45
51
- 944
+ 962
51
70
- 482
+ 491
71
72
- 702
+ 716
72
90
- 891
+ 908
94
96
- 388
+ 395
98
99
- 1332
+ 1357
100
102
- 94
+ 96
103
104
- 1982
+ 2020
104
119
- 1059
+ 1079
120
138
- 923
+ 940
139
140
- 451
+ 459
@@ -1940,67 +1980,67 @@
34
38
- 587
+ 598
38
39
- 1489
+ 1517
39
40
- 975
+ 994
40
42
- 1080
+ 1100
42
53
- 597
+ 609
53
54
- 702
+ 716
54
63
- 891
+ 908
64
67
- 398
+ 406
67
68
- 1395
+ 1421
68
70
- 965
+ 983
70
71
- 1395
+ 1421
73
79
- 944
+ 962
79
89
- 1122
+ 1143
89
@@ -2021,57 +2061,57 @@
43
90
- 62
+ 64
90
108
- 115
+ 117
108
183
- 104
+ 106
198
422
- 115
+ 117
422
595
- 125
+ 128
595
605
- 125
+ 128
605
749
- 115
+ 117
750
778
- 115
+ 117
781
883
- 115
+ 117
930
1190
- 83
+ 85
1197
1198
- 377
+ 384
@@ -2087,72 +2127,72 @@
1
5
- 125
+ 128
5
7
- 115
+ 117
9
12
- 73
+ 74
12
15
- 115
+ 117
15
18
- 94
+ 96
18
22
- 115
+ 117
22
27
- 125
+ 128
27
29
- 83
+ 85
29
34
- 115
+ 117
34
44
- 125
+ 128
45
63
- 115
+ 117
67
94
- 115
+ 117
94
164
- 115
+ 117
171
199
- 20
+ 21
@@ -2168,22 +2208,22 @@
1
2
- 13312
+ 13564
2
3
- 12598
+ 12837
3
103
- 2181
+ 2223
104
1198
- 975
+ 994
@@ -2199,17 +2239,17 @@
1
2
- 19249
+ 19614
2
3
- 8664
+ 8829
3
62
- 1153
+ 1175
@@ -2219,19 +2259,19 @@
compilation_expanded_args
- 1005291
+ 1024354
id
- 12556
+ 12794
num
- 1458
+ 1485
arg
- 29068
+ 29619
@@ -2245,77 +2285,77 @@
36
42
- 996
+ 1015
42
43
- 1090
+ 1111
43
44
- 713
+ 726
44
45
- 503
+ 513
45
51
- 944
+ 962
51
70
- 482
+ 491
71
72
- 702
+ 716
72
90
- 891
+ 908
94
96
- 388
+ 395
98
99
- 1332
+ 1357
100
102
- 94
+ 96
103
104
- 1982
+ 2020
104
119
- 1059
+ 1079
120
138
- 923
+ 940
139
140
- 451
+ 459
@@ -2331,67 +2371,67 @@
34
38
- 587
+ 598
38
39
- 1489
+ 1517
39
40
- 975
+ 994
40
42
- 1080
+ 1100
42
53
- 597
+ 609
53
54
- 702
+ 716
54
63
- 891
+ 908
64
67
- 398
+ 406
67
68
- 1395
+ 1421
68
70
- 965
+ 983
70
71
- 1395
+ 1421
73
79
- 944
+ 962
79
89
- 1122
+ 1143
89
@@ -2412,57 +2452,57 @@
43
90
- 62
+ 64
90
108
- 115
+ 117
108
183
- 104
+ 106
198
422
- 115
+ 117
422
595
- 125
+ 128
595
605
- 125
+ 128
605
749
- 115
+ 117
750
778
- 115
+ 117
781
883
- 115
+ 117
930
1190
- 83
+ 85
1197
1198
- 377
+ 384
@@ -2478,72 +2518,72 @@
1
5
- 125
+ 128
5
7
- 115
+ 117
9
12
- 73
+ 74
12
15
- 115
+ 117
15
18
- 94
+ 96
18
22
- 115
+ 117
22
27
- 125
+ 128
27
29
- 83
+ 85
29
34
- 115
+ 117
34
44
- 125
+ 128
45
63
- 115
+ 117
67
94
- 115
+ 117
94
164
- 115
+ 117
171
199
- 20
+ 21
@@ -2559,22 +2599,22 @@
1
2
- 13312
+ 13564
2
3
- 12598
+ 12837
3
103
- 2181
+ 2223
104
1198
- 975
+ 994
@@ -2590,17 +2630,17 @@
1
2
- 19249
+ 19614
2
3
- 8664
+ 8829
3
62
- 1153
+ 1175
@@ -2658,19 +2698,19 @@
compilation_compiling_files
- 15741
+ 15732
id
- 2723
+ 2721
num
- 4520
+ 4518
file
- 13671
+ 13663
@@ -2684,7 +2724,7 @@
1
2
- 1361
+ 1360
2
@@ -2735,7 +2775,7 @@
1
2
- 1361
+ 1360
2
@@ -2786,17 +2826,17 @@
1
2
- 2396
+ 2395
2
3
- 980
+ 979
3
4
- 490
+ 489
4
@@ -2822,17 +2862,17 @@
1
2
- 2396
+ 2395
2
3
- 980
+ 979
3
4
- 490
+ 489
4
@@ -2858,7 +2898,7 @@
1
2
- 12310
+ 12302
2
@@ -2884,12 +2924,12 @@
1
2
- 12527
+ 12520
2
4
- 1089
+ 1088
4
@@ -2904,15 +2944,15 @@
compilation_time
- 62966
+ 62929
id
- 2723
+ 2721
num
- 4520
+ 4518
kind
@@ -2920,7 +2960,7 @@
seconds
- 18682
+ 19434
@@ -2934,7 +2974,7 @@
1
2
- 1361
+ 1360
2
@@ -2985,7 +3025,7 @@
4
5
- 2723
+ 2721
@@ -2998,20 +3038,15 @@
12
-
- 2
- 3
- 54
-
3
4
- 544
+ 381
4
5
- 762
+ 979
6
@@ -3020,34 +3055,34 @@
9
- 10
- 108
-
-
- 10
11
- 163
+ 217
11
- 13
+ 12
217
- 14
- 17
+ 13
+ 18
217
- 17
- 22
- 217
+ 18
+ 21
+ 163
- 26
- 121
+ 21
+ 45
217
+
+ 52
+ 137
+ 108
+
@@ -3062,17 +3097,17 @@
1
2
- 2396
+ 2395
2
3
- 980
+ 979
3
4
- 490
+ 489
4
@@ -3098,7 +3133,7 @@
4
5
- 4520
+ 4518
@@ -3114,12 +3149,12 @@
3
4
- 925
+ 1034
4
5
- 1525
+ 1415
5
@@ -3129,12 +3164,17 @@
6
7
- 490
+ 272
7
+ 8
+ 435
+
+
+ 8
9
- 381
+ 163
9
@@ -3143,12 +3183,12 @@
13
- 41
+ 43
381
44
- 100
+ 95
163
@@ -3195,18 +3235,18 @@
12
- 4
- 5
+ 5
+ 6
108
- 189
- 190
+ 198
+ 199
54
- 198
- 199
+ 201
+ 202
54
@@ -3223,22 +3263,22 @@
1
2
- 12854
+ 13446
2
3
- 3921
+ 3919
3
5
- 1688
+ 1578
- 7
- 42
- 217
+ 5
+ 45
+ 489
@@ -3254,22 +3294,22 @@
1
2
- 11765
+ 12738
2
3
- 3867
+ 3701
3
4
- 1743
+ 1687
4
- 67
- 1307
+ 65
+ 1306
@@ -3285,12 +3325,12 @@
1
2
- 15850
+ 16603
2
3
- 2832
+ 2830
@@ -3300,15 +3340,15 @@
diagnostic_for
- 503
+ 513
diagnostic
- 356
+ 363
compilation
- 188
+ 192
file_number
@@ -3316,7 +3356,7 @@
file_number_diagnostic_number
- 52
+ 53
@@ -3330,12 +3370,12 @@
1
2
- 209
+ 213
2
3
- 146
+ 149
@@ -3351,7 +3391,7 @@
1
2
- 356
+ 363
@@ -3367,7 +3407,7 @@
1
2
- 356
+ 363
@@ -3383,17 +3423,17 @@
2
3
- 104
+ 106
3
4
- 62
+ 64
5
6
- 20
+ 21
@@ -3409,7 +3449,7 @@
1
2
- 188
+ 192
@@ -3425,17 +3465,17 @@
2
3
- 104
+ 106
3
4
- 62
+ 64
5
6
- 20
+ 21
@@ -3499,7 +3539,7 @@
1
2
- 20
+ 21
4
@@ -3530,7 +3570,7 @@
2
3
- 20
+ 21
8
@@ -3540,7 +3580,7 @@
18
19
- 20
+ 21
@@ -3556,7 +3596,7 @@
1
2
- 52
+ 53
@@ -3566,19 +3606,19 @@
compilation_finished
- 12556
+ 12794
id
- 12556
+ 12794
cpu_seconds
- 9420
+ 9791
elapsed_seconds
- 199
+ 256
@@ -3592,7 +3632,7 @@
1
2
- 12556
+ 12794
@@ -3608,7 +3648,7 @@
1
2
- 12556
+ 12794
@@ -3624,17 +3664,17 @@
1
2
- 7930
+ 8316
2
3
- 996
+ 1004
3
- 28
- 493
+ 20
+ 470
@@ -3650,12 +3690,12 @@
1
2
- 8843
+ 9182
2
3
- 576
+ 609
@@ -3671,12 +3711,12 @@
1
2
- 31
+ 74
2
3
- 31
+ 21
4
@@ -3684,54 +3724,39 @@
10
- 10
- 11
- 31
-
-
- 12
- 13
- 10
-
-
- 14
- 15
- 10
-
-
- 18
- 19
- 10
+ 6
+ 7
+ 21
- 32
- 33
- 10
+ 8
+ 12
+ 21
- 51
- 52
- 10
+ 13
+ 14
+ 21
- 159
- 160
- 10
+ 16
+ 30
+ 21
- 260
- 261
- 10
+ 41
+ 98
+ 21
- 286
- 287
- 10
+ 157
+ 229
+ 21
- 322
- 323
- 10
+ 268
+ 290
+ 21
@@ -3747,12 +3772,12 @@
1
2
- 31
+ 74
2
3
- 31
+ 21
4
@@ -3760,54 +3785,39 @@
10
- 10
- 11
- 31
+ 6
+ 7
+ 21
- 12
- 13
- 10
+ 8
+ 12
+ 21
13
14
- 10
-
-
- 18
- 19
- 10
+ 21
- 32
- 33
- 10
+ 16
+ 30
+ 21
- 51
- 52
- 10
+ 41
+ 96
+ 21
134
- 135
- 10
-
-
- 155
- 156
- 10
-
-
- 234
- 235
- 10
+ 152
+ 21
- 261
- 262
- 10
+ 204
+ 232
+ 21
@@ -4044,31 +4054,31 @@
locations_default
- 46362405
+ 46368911
id
- 46362405
+ 46368911
file
- 40263
+ 40272
beginLine
- 7381369
+ 7382933
beginColumn
- 21604
+ 21609
endLine
- 7382351
+ 7383915
endColumn
- 52907
+ 52918
@@ -4082,7 +4092,7 @@
1
2
- 46362405
+ 46368911
@@ -4098,7 +4108,7 @@
1
2
- 46362405
+ 46368911
@@ -4114,7 +4124,7 @@
1
2
- 46362405
+ 46368911
@@ -4130,7 +4140,7 @@
1
2
- 46362405
+ 46368911
@@ -4146,7 +4156,7 @@
1
2
- 46362405
+ 46368911
@@ -4162,67 +4172,67 @@
1
15
- 3068
+ 3069
15
41
- 3068
+ 3069
42
72
- 3068
+ 3069
72
114
- 3191
+ 3192
114
142
- 3191
+ 3192
143
212
- 3068
+ 3069
213
307
- 3068
+ 3069
310
435
- 3068
+ 3069
437
596
- 3068
+ 3069
607
846
- 3068
+ 3069
848
1304
- 3068
+ 3069
1354
2855
- 3068
+ 3069
3114
30788
- 3068
+ 3069
57880
@@ -4243,62 +4253,62 @@
1
13
- 3314
+ 3315
13
31
- 3314
+ 3315
31
47
- 3068
+ 3069
47
64
- 3068
+ 3069
64
84
- 3068
+ 3069
85
115
- 3068
+ 3069
116
160
- 3191
+ 3192
160
206
- 3068
+ 3069
206
291
- 3068
+ 3069
298
388
- 3068
+ 3069
395
527
- 3068
+ 3069
561
1339
- 3068
+ 3069
1385
@@ -4319,62 +4329,62 @@
1
5
- 3682
+ 3683
5
9
- 3068
+ 3069
9
15
- 3191
+ 3192
15
20
- 3191
+ 3192
20
28
- 3191
+ 3192
28
36
- 3068
+ 3069
36
43
- 3314
+ 3315
43
53
- 3191
+ 3192
53
62
- 3068
+ 3069
62
80
- 3068
+ 3069
80
95
- 3191
+ 3192
95
111
- 3068
+ 3069
112
@@ -4395,62 +4405,62 @@
1
13
- 3314
+ 3315
13
31
- 3314
+ 3315
31
46
- 3068
+ 3069
46
63
- 3068
+ 3069
63
84
- 3068
+ 3069
84
114
- 3068
+ 3069
118
160
- 3191
+ 3192
160
206
- 3068
+ 3069
207
291
- 3068
+ 3069
300
390
- 3068
+ 3069
395
562
- 3068
+ 3069
564
1350
- 3068
+ 3069
1430
@@ -4471,7 +4481,7 @@
1
12
- 3314
+ 3315
13
@@ -4481,27 +4491,27 @@
26
34
- 3191
+ 3192
34
42
- 3191
+ 3192
42
50
- 3068
+ 3069
50
61
- 3068
+ 3069
61
67
- 3314
+ 3315
67
@@ -4511,27 +4521,27 @@
76
88
- 3191
+ 3192
89
102
- 3068
+ 3069
102
116
- 3314
+ 3315
116
132
- 3068
+ 3069
132
364
- 1595
+ 1596
@@ -4547,32 +4557,32 @@
1
2
- 4878521
+ 4879555
2
3
- 768076
+ 768239
3
4
- 535333
+ 535447
4
12
- 558043
+ 558161
12
97
- 555220
+ 555337
97
639
- 86173
+ 86192
@@ -4588,27 +4598,27 @@
1
2
- 4939899
+ 4940945
2
3
- 1200296
+ 1200550
3
6
- 629609
+ 629742
6
56
- 554851
+ 554969
56
329
- 56712
+ 56724
@@ -4624,27 +4634,27 @@
1
2
- 5552936
+ 5554112
2
3
- 476534
+ 476635
3
7
- 568968
+ 569089
7
25
- 556938
+ 557056
25
94
- 225991
+ 226039
@@ -4660,12 +4670,12 @@
1
2
- 6921775
+ 6923241
2
85
- 459594
+ 459691
@@ -4681,32 +4691,32 @@
1
2
- 4946036
+ 4947084
2
3
- 731004
+ 731159
3
4
- 528091
+ 528203
4
12
- 576088
+ 576210
12
71
- 554483
+ 554600
71
252
- 45664
+ 45674
@@ -4903,7 +4913,7 @@
226
- 548
+ 547
1718
@@ -4979,7 +4989,7 @@
225
- 550
+ 549
1718
@@ -5026,7 +5036,7 @@
1
2
- 2086
+ 2087
2
@@ -5036,7 +5046,7 @@
5
8
- 1595
+ 1596
8
@@ -5070,23 +5080,23 @@
74
- 87
- 1964
+ 85
+ 1718
- 87
- 99
+ 85
+ 97
1718
- 100
- 160
+ 98
+ 155
1718
- 261
+ 155
299
- 245
+ 491
@@ -5102,32 +5112,32 @@
1
2
- 4876312
+ 4877345
2
3
- 771391
+ 771554
3
4
- 534597
+ 534710
4
12
- 556938
+ 557056
12
94
- 553746
+ 553864
94
622
- 89365
+ 89384
@@ -5143,27 +5153,27 @@
1
2
- 4936952
+ 4937998
2
3
- 1203856
+ 1204111
3
6
- 622121
+ 622253
6
51
- 554728
+ 554846
51
329
- 64691
+ 64705
@@ -5179,12 +5189,12 @@
1
2
- 6938592
+ 6940062
2
15
- 443758
+ 443852
@@ -5200,27 +5210,27 @@
1
2
- 5551586
+ 5552762
2
3
- 475061
+ 475161
3
7
- 573019
+ 573263
7
25
- 559761
+ 559757
25
89
- 222922
+ 222969
@@ -5236,32 +5246,32 @@
1
2
- 4944563
+ 4945611
2
3
- 736160
+ 736316
3
4
- 526495
+ 526606
4
12
- 577929
+ 578052
12
72
- 554237
+ 554355
72
252
- 42964
+ 42973
@@ -5277,52 +5287,52 @@
1
2
- 15344
+ 15347
2
3
- 5646
+ 5647
3
6
- 4173
+ 4420
6
- 16
- 4050
+ 17
+ 4051
- 16
- 31
- 4173
+ 17
+ 32
+ 4051
- 31
- 93
- 4050
+ 32
+ 97
+ 4051
- 96
- 660
- 4050
+ 107
+ 663
+ 4051
- 662
- 2411
- 4050
+ 699
+ 2462
+ 4051
- 2462
- 4702
- 4050
+ 2469
+ 4721
+ 4051
- 4720
+ 4757
33780
- 3314
+ 3192
@@ -5338,47 +5348,47 @@
1
2
- 17922
+ 18048
2
3
- 6014
+ 6016
3
5
- 3437
+ 3315
5
8
- 4541
+ 4542
8
17
- 4173
+ 4174
17
84
- 4050
+ 4051
88
160
- 4173
+ 4174
160
214
- 4050
+ 4051
215
267
- 4050
+ 4051
267
@@ -5399,50 +5409,50 @@
1
2
- 15589
+ 15593
2
3
- 6014
+ 6139
3
7
- 4173
+ 4051
7
18
- 4419
+ 4420
18
40
- 4173
+ 4174
41
188
- 4050
+ 4051
217
747
- 4050
+ 4051
- 766
+ 765
2171
- 4050
+ 4051
2171
2881
- 4050
+ 4051
- 2891
+ 2892
30763
2332
@@ -5460,47 +5470,47 @@
1
2
- 16571
+ 16575
2
3
- 6628
+ 6630
3
5
- 4787
+ 4788
5
9
- 4296
+ 4297
9
20
- 4173
+ 4174
20
32
- 4296
+ 4297
33
57
- 4050
+ 4051
57
76
- 4296
+ 4297
76
117
- 3805
+ 3806
@@ -5516,47 +5526,47 @@
1
2
- 15589
+ 15593
2
3
- 6014
+ 6139
3
7
- 4173
+ 4051
7
17
- 4050
+ 4051
17
30
- 4050
+ 4051
32
102
- 4050
+ 4051
104
621
- 4050
+ 4051
628
1958
- 4050
+ 4051
- 1967
+ 1966
2836
- 4050
+ 4051
2841
@@ -5571,15 +5581,15 @@
files
- 64766
+ 65994
id
- 64766
+ 65994
name
- 64766
+ 65994
@@ -5593,7 +5603,7 @@
1
2
- 64766
+ 65994
@@ -5609,7 +5619,7 @@
1
2
- 64766
+ 65994
@@ -5619,15 +5629,15 @@
folders
- 12305
+ 12538
id
- 12305
+ 12538
name
- 12305
+ 12538
@@ -5641,7 +5651,7 @@
1
2
- 12305
+ 12538
@@ -5657,7 +5667,7 @@
1
2
- 12305
+ 12538
@@ -5667,15 +5677,15 @@
containerparent
- 77050
+ 78512
parent
- 12305
+ 12538
child
- 77050
+ 78512
@@ -5689,42 +5699,42 @@
1
2
- 5989
+ 6103
2
3
- 1510
+ 1539
3
4
- 660
+ 673
4
6
- 996
+ 1015
6
10
- 965
+ 983
10
16
- 996
+ 1015
16
44
- 923
+ 940
44
151
- 262
+ 267
@@ -5740,7 +5750,7 @@
1
2
- 77050
+ 78512
@@ -5750,23 +5760,23 @@
numlines
- 794223
+ 794391
element_id
- 793118
+ 793286
num_lines
- 38790
+ 38798
num_code
- 33512
+ 33519
num_comment
- 18044
+ 18048
@@ -5780,12 +5790,12 @@
1
2
- 792014
+ 792181
2
3
- 1104
+ 1105
@@ -5801,12 +5811,12 @@
1
2
- 792014
+ 792181
2
3
- 1104
+ 1105
@@ -5822,7 +5832,7 @@
1
2
- 792873
+ 793041
2
@@ -5843,17 +5853,17 @@
1
2
- 26269
+ 26275
2
3
- 3682
+ 3683
3
5
- 3314
+ 3315
5
@@ -5863,7 +5873,7 @@
39
1981
- 2577
+ 2578
@@ -5879,12 +5889,12 @@
1
2
- 26760
+ 26766
2
3
- 4050
+ 4051
3
@@ -5899,7 +5909,7 @@
7
12
- 2086
+ 2087
@@ -5915,12 +5925,12 @@
1
2
- 26392
+ 26397
2
3
- 4050
+ 4051
3
@@ -5930,7 +5940,7 @@
4
6
- 3191
+ 3192
6
@@ -5951,12 +5961,12 @@
1
2
- 21482
+ 21486
2
3
- 3559
+ 3560
3
@@ -5966,12 +5976,12 @@
4
12
- 2577
+ 2578
12
157
- 2577
+ 2578
172
@@ -5992,17 +6002,17 @@
1
2
- 21850
+ 21854
2
3
- 3559
+ 3560
3
4
- 2086
+ 2087
4
@@ -6012,7 +6022,7 @@
6
9
- 2700
+ 2701
9
@@ -6033,12 +6043,12 @@
1
2
- 21604
+ 21609
2
3
- 4173
+ 4174
3
@@ -6048,7 +6058,7 @@
5
8
- 3068
+ 3069
8
@@ -6069,7 +6079,7 @@
1
2
- 11170
+ 11173
2
@@ -6079,7 +6089,7 @@
3
4
- 1104
+ 1105
4
@@ -6110,7 +6120,7 @@
1
2
- 11170
+ 11173
2
@@ -6120,12 +6130,12 @@
3
4
- 1104
+ 1105
4
7
- 1595
+ 1596
8
@@ -6151,7 +6161,7 @@
1
2
- 11170
+ 11173
2
@@ -6186,31 +6196,31 @@
diagnostics
- 356
+ 363
id
- 356
+ 363
severity
- 20
+ 21
error_tag
- 73
+ 74
error_message
- 146
+ 149
full_error_message
- 178
+ 181
location
- 178
+ 181
@@ -6224,7 +6234,7 @@
1
2
- 356
+ 363
@@ -6240,7 +6250,7 @@
1
2
- 356
+ 363
@@ -6256,7 +6266,7 @@
1
2
- 356
+ 363
@@ -6272,7 +6282,7 @@
1
2
- 356
+ 363
@@ -6288,7 +6298,7 @@
1
2
- 356
+ 363
@@ -6409,7 +6419,7 @@
1
2
- 41
+ 42
3
@@ -6440,7 +6450,7 @@
1
2
- 73
+ 74
@@ -6456,7 +6466,7 @@
1
2
- 52
+ 53
2
@@ -6482,7 +6492,7 @@
1
2
- 52
+ 53
3
@@ -6508,7 +6518,7 @@
1
2
- 52
+ 53
3
@@ -6534,12 +6544,12 @@
1
2
- 104
+ 106
2
3
- 31
+ 32
18
@@ -6560,7 +6570,7 @@
1
2
- 146
+ 149
@@ -6576,7 +6586,7 @@
1
2
- 146
+ 149
@@ -6592,12 +6602,12 @@
1
2
- 115
+ 117
2
3
- 31
+ 32
@@ -6613,12 +6623,12 @@
1
2
- 115
+ 117
2
3
- 31
+ 32
@@ -6634,7 +6644,7 @@
1
2
- 167
+ 171
18
@@ -6655,7 +6665,7 @@
1
2
- 178
+ 181
@@ -6671,7 +6681,7 @@
1
2
- 178
+ 181
@@ -6687,7 +6697,7 @@
1
2
- 178
+ 181
@@ -6703,7 +6713,7 @@
1
2
- 178
+ 181
@@ -6719,7 +6729,7 @@
1
2
- 167
+ 171
18
@@ -6740,7 +6750,7 @@
1
2
- 178
+ 181
@@ -6756,7 +6766,7 @@
1
2
- 178
+ 181
@@ -6772,7 +6782,7 @@
1
2
- 178
+ 181
@@ -6788,7 +6798,7 @@
1
2
- 178
+ 181
@@ -7134,7 +7144,7 @@
pch_uses
- 4118
+ 4130
pch
@@ -7142,11 +7152,11 @@
compilation
- 4118
+ 4130
id
- 4118
+ 4130
@@ -7342,7 +7352,7 @@
1
2
- 4118
+ 4130
@@ -7358,7 +7368,7 @@
1
2
- 4118
+ 4130
@@ -7374,7 +7384,7 @@
1
2
- 4118
+ 4130
@@ -7390,7 +7400,7 @@
1
2
- 4118
+ 4130
@@ -7516,23 +7526,23 @@
fileannotations
- 4171827
+ 4250935
id
- 5727
+ 5836
kind
- 20
+ 21
name
- 58315
+ 59421
value
- 39244
+ 39988
@@ -7546,12 +7556,12 @@
1
2
- 199
+ 203
2
3
- 5528
+ 5633
@@ -7567,62 +7577,62 @@
1
86
- 430
+ 438
88
206
- 430
+ 438
212
291
- 440
+ 448
291
359
- 430
+ 438
362
401
- 430
+ 438
402
479
- 430
+ 438
480
549
- 251
+ 256
550
551
- 1321
+ 1346
553
628
- 430
+ 438
631
753
- 451
+ 459
753
1231
- 440
+ 448
1234
2155
- 241
+ 245
@@ -7638,67 +7648,67 @@
1
98
- 430
+ 438
102
244
- 430
+ 438
244
351
- 430
+ 438
352
434
- 440
+ 448
434
490
- 440
+ 448
490
628
- 430
+ 438
632
702
- 62
+ 64
706
707
- 1321
+ 1346
710
939
- 430
+ 438
939
1038
- 430
+ 438
1066
1853
- 430
+ 438
1853
3292
- 430
+ 438
3423
3742
- 20
+ 21
@@ -7777,62 +7787,62 @@
1
2
- 10951
+ 11159
2
3
- 4332
+ 4414
3
5
- 5024
+ 5120
5
7
- 4070
+ 4147
7
9
- 4563
+ 4649
9
16
- 4301
+ 4382
16
19
- 4856
+ 4949
19
27
- 4227
+ 4307
27
47
- 4804
+ 4895
47
128
- 4888
+ 4981
128
459
- 4594
+ 4681
459
546
- 1699
+ 1731
@@ -7848,7 +7858,7 @@
1
2
- 58315
+ 59421
@@ -7864,57 +7874,57 @@
1
2
- 11507
+ 11726
2
3
- 7636
+ 7781
3
4
- 4070
+ 4147
4
6
- 4038
+ 4115
6
8
- 3398
+ 3463
8
11
- 4710
+ 4799
11
17
- 5360
+ 5462
17
23
- 4668
+ 4756
23
41
- 4647
+ 4735
41
95
- 4437
+ 4521
95
1726
- 3839
+ 3912
@@ -7930,72 +7940,72 @@
1
2
- 3335
+ 3399
2
4
- 1625
+ 1656
4
5
- 3168
+ 3228
5
8
- 2444
+ 2490
8
14
- 2947
+ 3003
14
17
- 1919
+ 1956
17
24
- 3021
+ 3078
24
51
- 3514
+ 3580
51
58
- 3010
+ 3067
58
80
- 2958
+ 3014
81
151
- 3063
+ 3121
151
334
- 2958
+ 3014
334
473
- 2979
+ 3035
473
547
- 2297
+ 2340
@@ -8011,7 +8021,7 @@
1
2
- 39233
+ 39977
2
@@ -8032,72 +8042,72 @@
1
2
- 3377
+ 3441
2
4
- 1898
+ 1934
4
5
- 3031
+ 3089
5
8
- 2465
+ 2511
8
14
- 3461
+ 3527
14
18
- 3430
+ 3495
18
28
- 3178
+ 3238
28
34
- 3126
+ 3185
34
41
- 3178
+ 3238
41
66
- 2968
+ 3025
66
92
- 3052
+ 3110
92
113
- 2968
+ 3025
113
145
- 3010
+ 3067
145
172
- 94
+ 96
@@ -8107,15 +8117,15 @@
inmacroexpansion
- 150039073
+ 149972783
id
- 24678024
+ 24663663
inv
- 3706403
+ 3704566
@@ -8129,37 +8139,37 @@
1
3
- 2210101
+ 2207711
3
5
- 1475401
+ 1468674
5
6
- 1620834
+ 1626688
6
7
- 6584434
+ 6580777
7
8
- 8721502
+ 8716427
8
9
- 3558069
+ 3555999
9
22
- 507680
+ 507385
@@ -8175,57 +8185,57 @@
1
2
- 531859
+ 529073
2
3
- 743444
+ 740941
3
4
- 481650
+ 480811
4
7
- 275382
+ 280649
7
8
- 282234
+ 282069
8
9
- 330341
+ 330153
9
10
- 3047
+ 3041
10
11
- 444778
+ 444519
11
337
- 307886
+ 307705
339
423
- 281836
+ 281672
423
7616
- 23941
+ 23927
@@ -8235,15 +8245,15 @@
affectedbymacroexpansion
- 48749819
+ 48637440
id
- 7046758
+ 7021656
inv
- 3804211
+ 3802004
@@ -8257,37 +8267,37 @@
1
2
- 3847809
+ 3845572
2
3
- 766524
+ 766078
3
4
- 361945
+ 361735
4
5
- 772958
+ 751505
5
12
- 535313
+ 535002
12
50
- 556427
+ 556103
50
9900
- 205778
+ 205658
@@ -8303,67 +8313,67 @@
1
4
- 313336
+ 313740
4
7
- 316698
+ 319101
7
9
- 301174
+ 300104
9
12
- 343037
+ 342540
12
13
- 456135
+ 460444
13
14
- 226164
+ 224631
14
15
- 408155
+ 409400
15
16
- 166476
+ 165315
16
17
- 377786
+ 377184
17
18
- 200694
+ 202387
18
20
- 344354
+ 342016
20
- 25
- 285475
+ 26
+ 297272
- 25
+ 26
207
- 64720
+ 47865
@@ -8373,19 +8383,19 @@
macroinvocations
- 40397045
+ 40373543
id
- 40397045
+ 40373543
macro_id
- 182471
+ 182365
location
- 5926523
+ 5923076
kind
@@ -8403,7 +8413,7 @@
1
2
- 40397045
+ 40373543
@@ -8419,7 +8429,7 @@
1
2
- 40397045
+ 40373543
@@ -8435,7 +8445,7 @@
1
2
- 40397045
+ 40373543
@@ -8451,47 +8461,47 @@
1
2
- 61114
+ 61078
2
3
- 27615
+ 27599
3
4
- 18083
+ 18073
4
5
- 10022
+ 10016
5
7
- 13835
+ 13827
7
13
- 14597
+ 14589
13
33
- 13726
+ 13718
33
187
- 13726
+ 13718
190
72214
- 9749
+ 9744
@@ -8507,42 +8517,42 @@
1
2
- 77673
+ 77627
2
3
- 30666
+ 30648
3
4
- 14379
+ 14371
4
5
- 10294
+ 10288
5
8
- 14053
+ 14044
8
18
- 14107
+ 14099
18
90
- 13726
+ 13718
90
12207
- 7571
+ 7566
@@ -8558,12 +8568,12 @@
1
2
- 177950
+ 177847
2
3
- 4520
+ 4518
@@ -8579,17 +8589,17 @@
1
2
- 5262380
+ 5259319
2
4
- 429653
+ 429403
4
72214
- 234490
+ 234353
@@ -8605,12 +8615,12 @@
1
2
- 5904354
+ 5900919
2
37
- 22168
+ 22156
@@ -8626,7 +8636,7 @@
1
2
- 5926523
+ 5923076
@@ -8699,15 +8709,15 @@
macroparent
- 33692864
+ 33673263
id
- 33692864
+ 33673263
parent_id
- 15944993
+ 15935717
@@ -8721,7 +8731,7 @@
1
2
- 33692864
+ 33673263
@@ -8737,27 +8747,27 @@
1
2
- 7816769
+ 7812221
2
3
- 1596166
+ 1595237
3
4
- 4708483
+ 4705743
4
5
- 1297402
+ 1296647
5
205
- 526172
+ 525866
@@ -8767,15 +8777,15 @@
macrolocationbind
- 6005206
+ 6014113
id
- 4196566
+ 4203558
location
- 2266167
+ 2268486
@@ -8789,27 +8799,27 @@
1
2
- 3275759
+ 3281808
2
3
- 487614
+ 488113
3
4
- 8639
+ 8647
4
5
- 411573
+ 411994
5
17
- 12979
+ 12993
@@ -8825,27 +8835,27 @@
1
2
- 1328980
+ 1330319
2
3
- 479787
+ 480278
3
4
- 7805
+ 7813
4
5
- 425601
+ 426058
5
522
- 23992
+ 24017
@@ -8855,19 +8865,19 @@
macro_argument_unexpanded
- 81936815
+ 83492408
invocation
- 26104126
+ 26600368
argument_index
- 692
+ 705
text
- 340922
+ 347387
@@ -8881,22 +8891,22 @@
1
2
- 9611464
+ 9794310
2
3
- 9706317
+ 9891058
3
4
- 4968887
+ 5063078
4
67
- 1817457
+ 1851921
@@ -8912,22 +8922,22 @@
1
2
- 9792851
+ 9979137
2
3
- 9723783
+ 9908855
3
4
- 4813253
+ 4904493
4
67
- 1774237
+ 1807881
@@ -8943,17 +8953,17 @@
46457
46458
- 608
+ 619
46659
173253
- 52
+ 53
- 646919
- 2488418
- 31
+ 646916
+ 2488534
+ 32
@@ -8969,17 +8979,17 @@
2
3
- 608
+ 619
13
1115
- 52
+ 53
7702
22873
- 31
+ 32
@@ -8995,57 +9005,57 @@
1
2
- 39432
+ 40180
2
3
- 61882
+ 63055
3
4
- 20844
+ 21239
4
5
- 34449
+ 35113
5
6
- 38992
+ 39731
6
9
- 30600
+ 31180
9
15
- 28774
+ 29320
15
26
- 25711
+ 26188
26
57
- 26959
+ 27471
57
517
- 25837
+ 26327
518
486640
- 7437
+ 7578
@@ -9061,17 +9071,17 @@
1
2
- 241517
+ 246096
2
3
- 89261
+ 90954
3
9
- 10144
+ 10336
@@ -9081,19 +9091,19 @@
macro_argument_expanded
- 81936815
+ 83492408
invocation
- 26104126
+ 26600368
argument_index
- 692
+ 705
text
- 206479
+ 210395
@@ -9107,22 +9117,22 @@
1
2
- 9611464
+ 9794310
2
3
- 9706317
+ 9891058
3
4
- 4968887
+ 5063078
4
67
- 1817457
+ 1851921
@@ -9138,22 +9148,22 @@
1
2
- 12550907
+ 12789770
2
3
- 8372817
+ 8531993
3
4
- 4196783
+ 4276333
4
9
- 983618
+ 1002270
@@ -9169,17 +9179,17 @@
46457
46458
- 608
+ 619
46659
173253
- 52
+ 53
- 646919
- 2488418
- 31
+ 646916
+ 2488534
+ 32
@@ -9195,17 +9205,17 @@
1
2
- 597
+ 609
2
96
- 52
+ 53
950
16173
- 41
+ 42
@@ -9221,57 +9231,57 @@
1
2
- 21683
+ 22094
2
3
- 26634
+ 27129
3
4
- 43167
+ 43996
4
5
- 15924
+ 16247
5
6
- 3251
+ 3313
6
7
- 18169
+ 18513
7
10
- 18830
+ 19187
10
19
- 18211
+ 18535
19
51
- 15661
+ 15958
51
251
- 15494
+ 15787
251
- 1169168
- 9451
+ 1169174
+ 9630
@@ -9287,17 +9297,17 @@
1
2
- 104336
+ 106314
2
3
- 88306
+ 89981
3
66
- 13836
+ 14099
@@ -9307,15 +9317,15 @@
functions
- 3994932
+ 3995778
id
- 3994932
+ 3995778
name
- 1666273
+ 1666626
kind
@@ -9333,7 +9343,7 @@
1
2
- 3994932
+ 3995778
@@ -9349,7 +9359,7 @@
1
2
- 3994932
+ 3995778
@@ -9365,17 +9375,17 @@
1
2
- 1421746
+ 1422047
2
4
- 138467
+ 138496
4
3162
- 106060
+ 106082
@@ -9391,7 +9401,7 @@
1
2
- 1663450
+ 1663802
2
@@ -9498,26 +9508,26 @@
builtin_functions
- 30715
+ 31201
id
- 30715
+ 31201
function_entry_point
- 1124932
+ 1131444
id
- 1121608
+ 1128067
entry_point
- 1124932
+ 1131444
@@ -9531,12 +9541,12 @@
1
2
- 1118822
+ 1125231
2
17
- 2786
+ 2836
@@ -9552,7 +9562,7 @@
1
2
- 1124932
+ 1131444
@@ -9562,15 +9572,15 @@
function_return_type
- 4011995
+ 4012845
id
- 3994932
+ 3995778
return_type
- 610950
+ 611080
@@ -9584,12 +9594,12 @@
1
2
- 3977869
+ 3978712
2
3
- 17062
+ 17066
@@ -9605,22 +9615,22 @@
1
2
- 304800
+ 304864
2
3
- 211874
+ 211919
3
5
- 47506
+ 47516
5
464
- 45910
+ 45920
475
@@ -9905,59 +9915,59 @@
purefunctions
- 130740
+ 131113
id
- 130740
+ 131113
function_deleted
- 87523
+ 87630
id
- 87523
+ 87630
function_defaulted
- 51363
+ 51426
id
- 51363
+ 51426
function_prototyped
- 3993459
+ 3994305
id
- 3993459
+ 3994305
deduction_guide_for_class
- 5769
+ 5770
id
- 5769
+ 5770
class_template
- 2209
+ 2210
@@ -9971,7 +9981,7 @@
1
2
- 5769
+ 5770
@@ -9987,7 +9997,7 @@
1
2
- 1104
+ 1105
2
@@ -10022,15 +10032,15 @@
member_function_this_type
- 662507
+ 671002
id
- 662507
+ 671002
this_type
- 173084
+ 227957
@@ -10044,7 +10054,7 @@
1
2
- 662507
+ 671002
@@ -10060,37 +10070,32 @@
1
2
- 46524
+ 100146
2
3
- 36335
+ 59164
3
4
- 31916
+ 22137
4
5
- 19763
+ 13853
5
- 6
- 12643
-
-
- 6
- 10
- 14362
+ 8
+ 18535
- 10
- 65
- 11538
+ 8
+ 152
+ 14120
@@ -10100,27 +10105,27 @@
fun_decls
- 4154268
+ 4155271
id
- 4148376
+ 4149377
function
- 3974186
+ 3975028
type_id
- 604076
+ 604204
name
- 1664800
+ 1665153
location
- 2768243
+ 2768830
@@ -10134,7 +10139,7 @@
1
2
- 4148376
+ 4149377
@@ -10150,12 +10155,12 @@
1
2
- 4142483
+ 4143484
2
3
- 5892
+ 5893
@@ -10171,7 +10176,7 @@
1
2
- 4148376
+ 4149377
@@ -10187,7 +10192,7 @@
1
2
- 4148376
+ 4149377
@@ -10203,12 +10208,12 @@
1
2
- 3814851
+ 3815536
2
5
- 159335
+ 159492
@@ -10224,12 +10229,12 @@
1
2
- 3956142
+ 3956980
2
3
- 18044
+ 18048
@@ -10245,7 +10250,7 @@
1
2
- 3974186
+ 3975028
@@ -10261,12 +10266,12 @@
1
2
- 3835842
+ 3836532
2
4
- 138344
+ 138496
@@ -10282,26 +10287,26 @@
1
2
- 290192
+ 290253
2
3
- 219240
+ 219286
3
5
- 48365
+ 48375
5
506
- 45419
+ 45428
555
- 10332
+ 10333
859
@@ -10318,22 +10323,22 @@
1
2
- 300749
+ 300812
2
3
- 210401
+ 210446
3
5
- 47628
+ 47638
5
9941
- 45296
+ 45306
@@ -10349,22 +10354,22 @@
1
2
- 485986
+ 486089
2
3
- 52293
+ 52304
3
7
- 49347
+ 49357
7
2238
- 16449
+ 16452
@@ -10380,22 +10385,22 @@
1
2
- 449159
+ 449255
2
3
- 69356
+ 69371
3
6
- 55239
+ 55251
6
4756
- 30320
+ 30326
@@ -10411,22 +10416,22 @@
1
2
- 1310039
+ 1310316
2
3
- 190883
+ 190924
3
11
- 127787
+ 127692
11
3169
- 36089
+ 36220
@@ -10442,17 +10447,17 @@
1
2
- 1421255
+ 1421556
2
4
- 138958
+ 138987
4
3162
- 104587
+ 104609
@@ -10468,12 +10473,12 @@
1
2
- 1576417
+ 1576751
2
1596
- 88383
+ 88402
@@ -10489,17 +10494,17 @@
1
2
- 1345392
+ 1345677
2
3
- 205000
+ 205043
3
1592
- 114407
+ 114431
@@ -10515,17 +10520,17 @@
1
2
- 2376164
+ 2376545
2
3
- 251770
+ 251946
3
211
- 140308
+ 140338
@@ -10541,17 +10546,17 @@
1
2
- 2395928
+ 2396313
2
3
- 232497
+ 232669
3
211
- 139817
+ 139847
@@ -10567,12 +10572,12 @@
1
2
- 2655309
+ 2655871
2
211
- 112934
+ 112958
@@ -10588,12 +10593,12 @@
1
2
- 2729698
+ 2730276
2
8
- 38545
+ 38553
@@ -10603,22 +10608,22 @@
fun_def
- 1397440
+ 1397736
id
- 1397440
+ 1397736
fun_specialized
- 7841
+ 7864
id
- 7841
+ 7864
@@ -10636,11 +10641,11 @@
fun_decl_specifiers
- 4214909
+ 4215802
id
- 1723968
+ 1724333
name
@@ -10658,22 +10663,22 @@
1
2
- 360776
+ 360852
2
3
- 258030
+ 258085
3
4
- 1082574
+ 1082804
4
5
- 22586
+ 22591
@@ -10870,26 +10875,26 @@
fun_decl_empty_throws
- 433439
+ 434678
fun_decl
- 433439
+ 434678
fun_decl_noexcept
- 139743
+ 140561
fun_decl
- 139743
+ 140561
constant
- 139307
+ 140122
@@ -10903,7 +10908,7 @@
1
2
- 139743
+ 140561
@@ -10919,12 +10924,12 @@
1
2
- 138870
+ 139683
2
3
- 436
+ 438
@@ -10934,26 +10939,26 @@
fun_decl_empty_noexcept
- 1156104
+ 1156472
fun_decl
- 1156104
+ 1156472
fun_decl_typedef_type
- 2760
+ 2788
fun_decl
- 2760
+ 2788
typedeftype_id
- 124
+ 125
@@ -10967,7 +10972,7 @@
1
2
- 2760
+ 2788
@@ -11043,11 +11048,11 @@
fun_requires
- 28932
+ 28967
id
- 10050
+ 10062
kind
@@ -11055,7 +11060,7 @@
constraint
- 28697
+ 28731
@@ -11069,7 +11074,7 @@
1
2
- 9986
+ 9998
2
@@ -11090,27 +11095,27 @@
1
2
- 7227
+ 7236
2
3
- 491
+ 492
3
6
- 855
+ 856
6
13
- 320
+ 321
13
14
- 1133
+ 1134
19
@@ -11173,7 +11178,7 @@
1
2
- 28461
+ 28496
2
@@ -11194,7 +11199,7 @@
1
2
- 28697
+ 28731
@@ -11204,19 +11209,19 @@
param_decl_bind
- 7218351
+ 7220248
id
- 7218351
+ 7220248
index
- 7856
+ 7857
fun_decl
- 3488446
+ 3489307
@@ -11230,7 +11235,7 @@
1
2
- 7218351
+ 7220248
@@ -11246,7 +11251,7 @@
1
2
- 7218351
+ 7220248
@@ -11281,12 +11286,12 @@
343
- 16310
+ 16311
613
- 28418
- 28419
+ 28419
+ 28420
122
@@ -11322,12 +11327,12 @@
343
- 16310
+ 16311
613
- 28418
- 28419
+ 28419
+ 28420
122
@@ -11344,27 +11349,27 @@
1
2
- 1486438
+ 1486752
2
3
- 972463
+ 972669
3
4
- 592291
+ 592540
4
5
- 285895
+ 285956
5
65
- 151356
+ 151388
@@ -11380,27 +11385,27 @@
1
2
- 1486438
+ 1486752
2
3
- 972463
+ 972669
3
4
- 592291
+ 592540
4
5
- 285895
+ 285956
5
65
- 151356
+ 151388
@@ -11410,27 +11415,27 @@
var_decls
- 9442668
+ 9417411
id
- 9436285
+ 9411026
variable
- 9098463
+ 9072765
type_id
- 1440773
+ 1441078
name
- 838906
+ 839084
location
- 6175671
+ 6176980
@@ -11444,7 +11449,7 @@
1
2
- 9436285
+ 9411026
@@ -11460,12 +11465,12 @@
1
2
- 9429901
+ 9404642
2
3
- 6383
+ 6384
@@ -11481,7 +11486,7 @@
1
2
- 9436285
+ 9411026
@@ -11497,7 +11502,7 @@
1
2
- 9436285
+ 9411026
@@ -11513,12 +11518,12 @@
1
2
- 8778319
+ 8752184
2
5
- 320144
+ 320580
@@ -11534,12 +11539,12 @@
1
2
- 9046170
+ 9020460
2
3
- 52293
+ 52304
@@ -11555,12 +11560,12 @@
1
2
- 8994735
+ 8969015
2
4
- 103727
+ 103749
@@ -11576,12 +11581,12 @@
1
2
- 8857496
+ 8831378
2
4
- 240967
+ 241387
@@ -11597,27 +11602,27 @@
1
2
- 839151
+ 839206
2
3
- 280617
+ 280554
3
5
- 127296
+ 127569
5
11
- 112934
+ 112835
11
- 2963
- 80772
+ 2786
+ 80912
@@ -11633,27 +11638,27 @@
1
2
- 860388
+ 860447
2
3
- 265764
+ 265697
3
5
- 122141
+ 122412
5
11
- 112566
+ 112467
11
- 2886
- 79913
+ 2709
+ 80053
@@ -11669,22 +11674,22 @@
1
2
- 1104793
+ 1105027
2
3
- 191006
+ 191046
3
7
- 116371
+ 116396
7
1038
- 28601
+ 28607
@@ -11700,27 +11705,27 @@
1
2
- 974304
+ 974511
2
3
- 215189
+ 215234
3
5
- 104587
+ 104609
5
15
- 109865
+ 109888
15
2622
- 36826
+ 36834
@@ -11736,32 +11741,32 @@
1
2
- 457507
+ 457235
2
3
- 161668
+ 162193
3
4
- 59290
+ 59303
4
7
- 64814
+ 64582
7
24
- 63341
+ 63968
24
27139
- 32284
+ 31800
@@ -11777,32 +11782,32 @@
1
2
- 468432
+ 468163
2
3
- 161668
+ 162193
3
4
- 55116
+ 55128
4
8
- 71197
+ 70844
8
- 44
- 63586
+ 43
+ 63354
- 44
+ 43
26704
- 18904
+ 19399
@@ -11818,22 +11823,22 @@
1
2
- 642744
+ 642880
2
3
- 110847
+ 110871
3
11
- 64078
+ 64091
11
3463
- 21236
+ 21241
@@ -11849,27 +11854,27 @@
1
2
- 484758
+ 484861
2
3
- 180940
+ 180978
3
4
- 51311
+ 51322
4
8
- 63955
+ 63968
8
22619
- 57940
+ 57952
@@ -11885,17 +11890,17 @@
1
2
- 5670781
+ 5668544
2
16
- 465117
+ 468777
16
2943
- 39772
+ 39658
@@ -11911,12 +11916,12 @@
1
2
- 5751431
+ 5749211
2
2935
- 424240
+ 427768
@@ -11932,12 +11937,12 @@
1
2
- 5874922
+ 5876167
2
2555
- 300749
+ 300812
@@ -11953,12 +11958,12 @@
1
2
- 6163519
+ 6164824
2
5
- 12152
+ 12155
@@ -11968,33 +11973,33 @@
var_def
- 3707686
+ 3684775
id
- 3707686
+ 3684775
var_specialized
- 641
+ 642
id
- 641
+ 642
var_decl_specifiers
- 481567
+ 481669
id
- 481567
+ 481669
name
@@ -12012,7 +12017,7 @@
1
2
- 481567
+ 481669
@@ -12053,18 +12058,18 @@
is_structured_binding
- 940
+ 942
id
- 940
+ 942
var_requires
- 384
+ 385
id
@@ -12072,7 +12077,7 @@
constraint
- 384
+ 385
@@ -12112,7 +12117,7 @@
1
2
- 384
+ 385
@@ -12122,19 +12127,19 @@
type_decls
- 1639390
+ 1639737
id
- 1639390
+ 1639737
type_id
- 1620731
+ 1621075
location
- 1543273
+ 1543600
@@ -12148,7 +12153,7 @@
1
2
- 1639390
+ 1639737
@@ -12164,7 +12169,7 @@
1
2
- 1639390
+ 1639737
@@ -12180,12 +12185,12 @@
1
2
- 1604650
+ 1604990
2
10
- 16080
+ 16084
@@ -12201,12 +12206,12 @@
1
2
- 1604773
+ 1605113
2
10
- 15958
+ 15961
@@ -12222,12 +12227,12 @@
1
2
- 1513198
+ 1513519
2
64
- 30074
+ 30081
@@ -12243,12 +12248,12 @@
1
2
- 1513321
+ 1513641
2
64
- 29952
+ 29958
@@ -12258,37 +12263,37 @@
type_def
- 1092272
+ 1092503
id
- 1092272
+ 1092503
type_decl_top
- 676616
+ 676223
type_decl
- 676616
+ 676223
type_requires
- 7634
+ 7643
id
- 2031
+ 2033
constraint
- 7612
+ 7621
@@ -12302,17 +12307,17 @@
1
2
- 1005
+ 1006
2
5
- 106
+ 107
5
6
- 598
+ 599
6
@@ -12338,7 +12343,7 @@
1
2
- 7591
+ 7600
2
@@ -12353,23 +12358,23 @@
namespace_decls
- 405513
+ 406672
id
- 405513
+ 406672
namespace_id
- 1768
+ 1773
location
- 405513
+ 406672
bodylocation
- 405513
+ 406672
@@ -12383,7 +12388,7 @@
1
2
- 405513
+ 406672
@@ -12399,7 +12404,7 @@
1
2
- 405513
+ 406672
@@ -12415,7 +12420,7 @@
1
2
- 405513
+ 406672
@@ -12431,12 +12436,12 @@
1
2
- 363
+ 364
2
3
- 185
+ 186
3
@@ -12497,12 +12502,12 @@
1
2
- 363
+ 364
2
3
- 185
+ 186
3
@@ -12563,12 +12568,12 @@
1
2
- 363
+ 364
2
3
- 185
+ 186
3
@@ -12629,7 +12634,7 @@
1
2
- 405513
+ 406672
@@ -12645,7 +12650,7 @@
1
2
- 405513
+ 406672
@@ -12661,7 +12666,7 @@
1
2
- 405513
+ 406672
@@ -12677,7 +12682,7 @@
1
2
- 405513
+ 406672
@@ -12693,7 +12698,7 @@
1
2
- 405513
+ 406672
@@ -12709,7 +12714,7 @@
1
2
- 405513
+ 406672
@@ -12719,23 +12724,23 @@
usings
- 269966
+ 275545
id
- 269966
+ 275545
element_id
- 58399
+ 59966
location
- 26666
+ 27171
kind
- 20
+ 21
@@ -12749,7 +12754,7 @@
1
2
- 269966
+ 275545
@@ -12765,7 +12770,7 @@
1
2
- 269966
+ 275545
@@ -12781,7 +12786,7 @@
1
2
- 269966
+ 275545
@@ -12797,17 +12802,17 @@
1
2
- 50730
+ 52152
2
5
- 5339
+ 5440
5
134
- 2328
+ 2372
@@ -12823,17 +12828,17 @@
1
2
- 50730
+ 52152
2
5
- 5339
+ 5440
5
134
- 2328
+ 2372
@@ -12849,7 +12854,7 @@
1
2
- 58399
+ 59966
@@ -12865,22 +12870,22 @@
1
2
- 21043
+ 21442
2
4
- 2276
+ 2319
4
132
- 1930
+ 1966
145
- 364
- 1416
+ 370
+ 1443
@@ -12896,22 +12901,22 @@
1
2
- 21043
+ 21442
2
4
- 2276
+ 2319
4
132
- 1930
+ 1966
145
- 364
- 1416
+ 370
+ 1443
@@ -12927,7 +12932,7 @@
1
2
- 26666
+ 27171
@@ -12946,8 +12951,8 @@
10
- 25342
- 25343
+ 25385
+ 25386
10
@@ -12967,8 +12972,8 @@
10
- 5353
- 5354
+ 5396
+ 5397
10
@@ -13000,15 +13005,15 @@
using_container
- 571131
+ 582421
parent
- 20151
+ 20619
child
- 269966
+ 275545
@@ -13022,42 +13027,42 @@
1
2
- 8958
+ 9139
2
3
- 1584
+ 1614
3
6
- 1762
+ 1795
6
7
- 2244
+ 2362
7
26
- 1521
+ 1549
26
136
- 797
+ 812
145
146
- 2601
+ 2650
146
437
- 681
+ 694
@@ -13073,27 +13078,27 @@
1
2
- 96332
+ 98618
2
3
- 119536
+ 121803
3
4
- 19585
+ 19956
4
5
- 26330
+ 26829
5
65
- 8182
+ 8337
@@ -13103,27 +13108,27 @@
static_asserts
- 171628
+ 172118
id
- 171628
+ 172118
condition
- 171628
+ 172118
message
- 38481
+ 38591
location
- 22434
+ 22498
enclosing
- 6202
+ 6219
@@ -13137,7 +13142,7 @@
1
2
- 171628
+ 172118
@@ -13153,7 +13158,7 @@
1
2
- 171628
+ 172118
@@ -13169,7 +13174,7 @@
1
2
- 171628
+ 172118
@@ -13185,7 +13190,7 @@
1
2
- 171628
+ 172118
@@ -13201,7 +13206,7 @@
1
2
- 171628
+ 172118
@@ -13217,7 +13222,7 @@
1
2
- 171628
+ 172118
@@ -13233,7 +13238,7 @@
1
2
- 171628
+ 172118
@@ -13249,7 +13254,7 @@
1
2
- 171628
+ 172118
@@ -13265,32 +13270,32 @@
1
2
- 28330
+ 28411
2
3
- 662
+ 664
3
4
- 3585
+ 3595
4
10
- 2043
+ 2049
12
17
- 3101
+ 3109
17
513
- 759
+ 761
@@ -13306,32 +13311,32 @@
1
2
- 28330
+ 28411
2
3
- 662
+ 664
3
4
- 3585
+ 3595
4
10
- 2043
+ 2049
12
17
- 3101
+ 3109
17
513
- 759
+ 761
@@ -13347,12 +13352,12 @@
1
2
- 35679
+ 35781
2
33
- 2802
+ 2810
@@ -13368,27 +13373,27 @@
1
2
- 30147
+ 30233
2
3
- 355
+ 356
3
4
- 3351
+ 3361
4
12
- 1865
+ 1870
12
43
- 2761
+ 2769
@@ -13404,37 +13409,37 @@
1
2
- 4255
+ 4268
2
3
- 3690
+ 3701
3
4
- 1720
+ 1725
4
5
- 104
+ 105
5
6
- 4692
+ 4705
6
13
- 428
+ 429
14
15
- 2632
+ 2640
16
@@ -13444,12 +13449,12 @@
17
18
- 4369
+ 4381
19
52
- 492
+ 494
@@ -13465,37 +13470,37 @@
1
2
- 4255
+ 4268
2
3
- 3690
+ 3701
3
4
- 1720
+ 1725
4
5
- 104
+ 105
5
6
- 4692
+ 4705
6
13
- 428
+ 429
14
15
- 2632
+ 2640
16
@@ -13505,12 +13510,12 @@
17
18
- 4369
+ 4381
19
52
- 492
+ 494
@@ -13526,17 +13531,17 @@
1
2
- 6832
+ 6851
2
3
- 7631
+ 7653
3
4
- 7736
+ 7758
4
@@ -13557,32 +13562,32 @@
1
2
- 5055
+ 5069
2
3
- 8019
+ 8042
3
4
- 1461
+ 1465
4
5
- 4716
+ 4729
5
13
- 476
+ 477
13
14
- 2632
+ 2640
16
@@ -13603,22 +13608,22 @@
1
2
- 5152
+ 5167
2
3
- 476
+ 477
3
210
- 476
+ 477
223
11052
- 96
+ 97
@@ -13634,22 +13639,22 @@
1
2
- 5152
+ 5167
2
3
- 476
+ 477
3
210
- 476
+ 477
223
11052
- 96
+ 97
@@ -13665,17 +13670,17 @@
1
2
- 5305
+ 5321
2
3
- 476
+ 477
3
2936
- 419
+ 421
@@ -13691,17 +13696,17 @@
1
2
- 5289
+ 5304
2
3
- 492
+ 494
3
1929
- 419
+ 421
@@ -13711,23 +13716,23 @@
params
- 6970509
+ 6971985
id
- 6930613
+ 6932082
function
- 3361394
+ 3362107
index
- 7856
+ 7857
type_id
- 1206679
+ 1206935
@@ -13741,7 +13746,7 @@
1
2
- 6930613
+ 6932082
@@ -13757,7 +13762,7 @@
1
2
- 6930613
+ 6932082
@@ -13773,12 +13778,12 @@
1
2
- 6890718
+ 6892178
2
3
- 39895
+ 39903
@@ -13794,27 +13799,27 @@
1
2
- 1450593
+ 1450900
2
3
- 920292
+ 920487
3
4
- 570073
+ 570194
4
5
- 276443
+ 276502
5
65
- 143991
+ 144021
@@ -13830,27 +13835,27 @@
1
2
- 1450593
+ 1450900
2
3
- 920292
+ 920487
3
4
- 570073
+ 570194
4
5
- 276443
+ 276502
5
65
- 143991
+ 144021
@@ -13866,22 +13871,22 @@
1
2
- 1757357
+ 1757730
2
3
- 1019846
+ 1020063
3
4
- 431360
+ 431451
4
11
- 152829
+ 152862
@@ -14020,27 +14025,27 @@
1
2
- 728672
+ 728826
2
3
- 237039
+ 237089
3
5
- 92925
+ 92945
5
13
- 93539
+ 93558
13
2574
- 54503
+ 54514
@@ -14056,27 +14061,27 @@
1
2
- 810672
+ 810844
2
3
- 175784
+ 175822
3
6
- 107042
+ 107064
6
27
- 90838
+ 90857
27
2562
- 22341
+ 22346
@@ -14092,17 +14097,17 @@
1
2
- 981670
+ 981878
2
3
- 167683
+ 167718
3
65
- 57326
+ 57338
@@ -14112,15 +14117,15 @@
overrides
- 159700
+ 160156
new
- 150954
+ 151385
old
- 17451
+ 17501
@@ -14134,12 +14139,12 @@
1
2
- 142215
+ 142622
2
4
- 8738
+ 8763
@@ -14155,32 +14160,32 @@
1
2
- 9392
+ 9419
2
3
- 2366
+ 2372
3
4
- 1647
+ 1652
4
6
- 1437
+ 1441
6
16
- 1332
+ 1336
16
230
- 1275
+ 1279
@@ -14190,19 +14195,19 @@
membervariables
- 1505529
+ 1504653
id
- 1503078
+ 1502203
type_id
- 458086
+ 457819
name
- 644370
+ 643996
@@ -14216,12 +14221,12 @@
1
2
- 1500736
+ 1499862
2
4
- 2342
+ 2340
@@ -14237,7 +14242,7 @@
1
2
- 1503078
+ 1502203
@@ -14253,22 +14258,22 @@
1
2
- 339887
+ 339690
2
3
- 72607
+ 72565
3
10
- 35404
+ 35384
10
4445
- 10185
+ 10179
@@ -14284,22 +14289,22 @@
1
2
- 357481
+ 357273
2
3
- 64763
+ 64726
3
57
- 34370
+ 34350
60
2186
- 1470
+ 1469
@@ -14315,22 +14320,22 @@
1
2
- 423443
+ 423197
2
3
- 122610
+ 122538
3
5
- 58118
+ 58084
5
664
- 40198
+ 40174
@@ -14346,17 +14351,17 @@
1
2
- 526499
+ 526193
2
3
- 73315
+ 73272
3
668
- 44555
+ 44529
@@ -14366,19 +14371,19 @@
globalvariables
- 661280
+ 634531
id
- 661280
+ 634531
type_id
- 10188
+ 10190
name
- 110724
+ 110748
@@ -14392,7 +14397,7 @@
1
2
- 661280
+ 634531
@@ -14408,7 +14413,7 @@
1
2
- 661280
+ 634531
@@ -14424,7 +14429,7 @@
1
2
- 6874
+ 6875
2
@@ -14443,7 +14448,7 @@
20
- 80
+ 74
859
@@ -14465,7 +14470,7 @@
1
2
- 6997
+ 6998
2
@@ -14506,22 +14511,22 @@
1
2
- 92679
+ 92699
2
8
- 9329
+ 9454
8
- 139
- 8347
+ 182
+ 8349
- 181
+ 632
1156
- 368
+ 245
@@ -14537,12 +14542,12 @@
1
2
- 93907
+ 93927
2
3
- 16571
+ 16575
3
@@ -14557,19 +14562,19 @@
localvariables
- 725852
+ 733187
id
- 725852
+ 733187
type_id
- 53389
+ 53924
name
- 101620
+ 102647
@@ -14583,7 +14588,7 @@
1
2
- 725852
+ 733187
@@ -14599,7 +14604,7 @@
1
2
- 725852
+ 733187
@@ -14615,37 +14620,37 @@
1
2
- 28869
+ 29156
2
3
- 7802
+ 7881
3
4
- 4041
+ 4082
4
6
- 4065
+ 4106
6
12
- 4113
+ 4154
12
162
- 4005
+ 4045
162
19347
- 492
+ 497
@@ -14661,22 +14666,22 @@
1
2
- 38308
+ 38691
2
3
- 6718
+ 6786
3
5
- 4477
+ 4522
5
3509
- 3885
+ 3924
@@ -14692,32 +14697,32 @@
1
2
- 62532
+ 63163
2
3
- 16037
+ 16199
3
4
- 6538
+ 6604
4
8
- 8154
+ 8237
8
137
- 7630
+ 7707
137
7546
- 728
+ 735
@@ -14733,22 +14738,22 @@
1
2
- 84575
+ 85429
2
3
- 8410
+ 8495
3
15
- 7682
+ 7760
15
1509
- 952
+ 961
@@ -14758,11 +14763,11 @@
autoderivation
- 223904
+ 224074
var
- 223904
+ 224074
derivation_type
@@ -14780,7 +14785,7 @@
1
2
- 223904
+ 224074
@@ -14809,8 +14814,8 @@
122
- 527
- 528
+ 528
+ 529
122
@@ -14826,15 +14831,15 @@
orphaned_variables
- 43672
+ 43927
var
- 43672
+ 43927
function
- 40449
+ 40686
@@ -14848,7 +14853,7 @@
1
2
- 43672
+ 43927
@@ -14864,12 +14869,12 @@
1
2
- 39610
+ 39841
2
47
- 839
+ 844
@@ -14879,19 +14884,19 @@
enumconstants
- 348112
+ 347910
id
- 348112
+ 347910
parent
- 41614
+ 41590
index
- 13944
+ 13936
type_id
@@ -14899,11 +14904,11 @@
name
- 347731
+ 347529
location
- 320714
+ 320528
@@ -14917,7 +14922,7 @@
1
2
- 348112
+ 347910
@@ -14933,7 +14938,7 @@
1
2
- 348112
+ 347910
@@ -14949,7 +14954,7 @@
1
2
- 348112
+ 347910
@@ -14965,7 +14970,7 @@
1
2
- 348112
+ 347910
@@ -14981,7 +14986,7 @@
1
2
- 348112
+ 347910
@@ -14997,57 +15002,57 @@
1
2
- 1525
+ 1524
2
3
- 5828
+ 5824
3
4
- 8715
+ 8710
4
5
- 5555
+ 5552
5
6
- 4575
+ 4572
6
7
- 2560
+ 2558
7
8
- 1960
+ 1959
8
10
- 2995
+ 2994
10
15
- 3431
+ 3429
15
33
- 3159
+ 3157
33
257
- 1307
+ 1306
@@ -15063,57 +15068,57 @@
1
2
- 1525
+ 1524
2
3
- 5828
+ 5824
3
4
- 8715
+ 8710
4
5
- 5555
+ 5552
5
6
- 4575
+ 4572
6
7
- 2560
+ 2558
7
8
- 1960
+ 1959
8
10
- 2995
+ 2994
10
15
- 3431
+ 3429
15
33
- 3159
+ 3157
33
257
- 1307
+ 1306
@@ -15129,7 +15134,7 @@
1
2
- 41614
+ 41590
@@ -15145,57 +15150,57 @@
1
2
- 1525
+ 1524
2
3
- 5828
+ 5824
3
4
- 8715
+ 8710
4
5
- 5555
+ 5552
5
6
- 4575
+ 4572
6
7
- 2560
+ 2558
7
8
- 1960
+ 1959
8
10
- 2995
+ 2994
10
15
- 3431
+ 3429
15
33
- 3159
+ 3157
33
257
- 1307
+ 1306
@@ -15211,52 +15216,52 @@
1
2
- 2124
+ 2123
2
3
- 6046
+ 6042
3
4
- 8769
+ 8764
4
5
- 5501
+ 5498
5
6
- 4575
+ 4572
6
7
- 2505
+ 2504
7
8
- 1851
+ 1850
8
11
- 3812
+ 3810
11
17
- 3213
+ 3211
17
165
- 3159
+ 3157
256
@@ -15277,22 +15282,22 @@
1
2
- 2777
+ 2776
2
3
- 2233
+ 2231
3
4
- 2287
+ 2286
4
5
- 1198
+ 1197
5
@@ -15302,7 +15307,7 @@
9
12
- 1089
+ 1088
12
@@ -15312,12 +15317,12 @@
20
59
- 1089
+ 1088
64
765
- 980
+ 979
@@ -15333,22 +15338,22 @@
1
2
- 2777
+ 2776
2
3
- 2233
+ 2231
3
4
- 2287
+ 2286
4
5
- 1198
+ 1197
5
@@ -15358,7 +15363,7 @@
9
12
- 1089
+ 1088
12
@@ -15368,12 +15373,12 @@
20
59
- 1089
+ 1088
64
765
- 980
+ 979
@@ -15389,7 +15394,7 @@
1
2
- 13944
+ 13936
@@ -15405,22 +15410,22 @@
1
2
- 2777
+ 2776
2
3
- 2233
+ 2231
3
4
- 2287
+ 2286
4
5
- 1198
+ 1197
5
@@ -15430,7 +15435,7 @@
9
12
- 1089
+ 1088
12
@@ -15440,12 +15445,12 @@
20
59
- 1089
+ 1088
64
762
- 980
+ 979
@@ -15461,22 +15466,22 @@
1
2
- 2777
+ 2776
2
3
- 2233
+ 2231
3
4
- 2287
+ 2286
4
5
- 1198
+ 1197
5
@@ -15486,7 +15491,7 @@
9
12
- 1089
+ 1088
12
@@ -15496,12 +15501,12 @@
20
59
- 1089
+ 1088
64
765
- 980
+ 979
@@ -15597,7 +15602,7 @@
1
2
- 347350
+ 347148
2
@@ -15618,7 +15623,7 @@
1
2
- 347350
+ 347148
2
@@ -15639,7 +15644,7 @@
1
2
- 347731
+ 347529
@@ -15655,7 +15660,7 @@
1
2
- 347731
+ 347529
@@ -15671,7 +15676,7 @@
1
2
- 347350
+ 347148
2
@@ -15692,7 +15697,7 @@
1
2
- 319679
+ 319493
2
@@ -15713,7 +15718,7 @@
1
2
- 320714
+ 320528
@@ -15729,7 +15734,7 @@
1
2
- 319679
+ 319493
2
@@ -15750,7 +15755,7 @@
1
2
- 320714
+ 320528
@@ -15766,7 +15771,7 @@
1
2
- 319679
+ 319493
2
@@ -15781,19 +15786,19 @@
builtintypes
- 7119
+ 7121
id
- 7119
+ 7121
name
- 7119
+ 7121
kind
- 7119
+ 7121
size
@@ -15819,7 +15824,7 @@
1
2
- 7119
+ 7121
@@ -15835,7 +15840,7 @@
1
2
- 7119
+ 7121
@@ -15851,7 +15856,7 @@
1
2
- 7119
+ 7121
@@ -15867,7 +15872,7 @@
1
2
- 7119
+ 7121
@@ -15883,7 +15888,7 @@
1
2
- 7119
+ 7121
@@ -15899,7 +15904,7 @@
1
2
- 7119
+ 7121
@@ -15915,7 +15920,7 @@
1
2
- 7119
+ 7121
@@ -15931,7 +15936,7 @@
1
2
- 7119
+ 7121
@@ -15947,7 +15952,7 @@
1
2
- 7119
+ 7121
@@ -15963,7 +15968,7 @@
1
2
- 7119
+ 7121
@@ -15979,7 +15984,7 @@
1
2
- 7119
+ 7121
@@ -15995,7 +16000,7 @@
1
2
- 7119
+ 7121
@@ -16011,7 +16016,7 @@
1
2
- 7119
+ 7121
@@ -16027,7 +16032,7 @@
1
2
- 7119
+ 7121
@@ -16043,7 +16048,7 @@
1
2
- 7119
+ 7121
@@ -16471,17 +16476,75 @@
+
+ bit_precise_int_types
+ 11
+
+
+ id
+ 11
+
+
+ bit_width
+ 6
+
+
+
+
+ id
+ bit_width
+
+
+ 12
+
+
+ 1
+ 2
+ 11
+
+
+
+
+
+
+ bit_width
+ id
+
+
+ 12
+
+
+ 1
+ 2
+ 2
+
+
+ 2
+ 3
+ 3
+
+
+ 3
+ 4
+ 1
+
+
+
+
+
+
+
derivedtypes
- 2997672
+ 2998307
id
- 2997672
+ 2998307
name
- 1445315
+ 1445621
kind
@@ -16489,7 +16552,7 @@
type_id
- 1925654
+ 1926062
@@ -16503,7 +16566,7 @@
1
2
- 2997672
+ 2998307
@@ -16519,7 +16582,7 @@
1
2
- 2997672
+ 2998307
@@ -16535,7 +16598,7 @@
1
2
- 2997672
+ 2998307
@@ -16551,17 +16614,17 @@
1
2
- 1327838
+ 1328120
2
23
- 108760
+ 108783
23
4289
- 8715
+ 8717
@@ -16577,7 +16640,7 @@
1
2
- 1445315
+ 1445621
@@ -16593,17 +16656,17 @@
1
2
- 1327961
+ 1328242
2
23
- 108638
+ 108661
23
4289
- 8715
+ 8717
@@ -16742,22 +16805,22 @@
1
2
- 1302919
+ 1303195
2
3
- 372438
+ 372516
3
4
- 121650
+ 121675
4
137
- 128647
+ 128674
@@ -16773,22 +16836,22 @@
1
2
- 1304392
+ 1304668
2
3
- 372438
+ 372516
3
4
- 120176
+ 120202
4
137
- 128647
+ 128674
@@ -16804,22 +16867,22 @@
1
2
- 1304760
+ 1305037
2
3
- 373051
+ 373130
3
4
- 121895
+ 121921
4
6
- 125946
+ 125973
@@ -16829,11 +16892,11 @@
pointerishsize
- 2221248
+ 2221718
id
- 2221248
+ 2221718
size
@@ -16855,7 +16918,7 @@
1
2
- 2221248
+ 2221718
@@ -16871,7 +16934,7 @@
1
2
- 2221248
+ 2221718
@@ -16955,19 +17018,19 @@
arraysizes
- 79299
+ 79316
id
- 79299
+ 79316
num_elements
- 17553
+ 17557
bytesize
- 19886
+ 19890
alignment
@@ -16985,7 +17048,7 @@
1
2
- 79299
+ 79316
@@ -17001,7 +17064,7 @@
1
2
- 79299
+ 79316
@@ -17017,7 +17080,7 @@
1
2
- 79299
+ 79316
@@ -17038,7 +17101,7 @@
2
3
- 10679
+ 10681
3
@@ -17079,7 +17142,7 @@
1
2
- 11538
+ 11541
2
@@ -17094,7 +17157,7 @@
5
11
- 1104
+ 1105
@@ -17110,7 +17173,7 @@
1
2
- 11538
+ 11541
2
@@ -17146,7 +17209,7 @@
2
3
- 12520
+ 12523
3
@@ -17156,7 +17219,7 @@
4
5
- 2700
+ 2701
5
@@ -17166,7 +17229,7 @@
7
17
- 1595
+ 1596
24
@@ -17187,12 +17250,12 @@
1
2
- 14362
+ 14365
2
3
- 3559
+ 3560
3
@@ -17218,17 +17281,17 @@
1
2
- 14607
+ 14610
2
3
- 3314
+ 3315
3
5
- 1595
+ 1596
5
@@ -17394,15 +17457,15 @@
typedefbase
- 1757610
+ 1791463
id
- 1757610
+ 1791463
type_id
- 835234
+ 851307
@@ -17416,7 +17479,7 @@
1
2
- 1757610
+ 1791463
@@ -17432,22 +17495,22 @@
1
2
- 660833
+ 673460
2
3
- 80512
+ 82124
3
6
- 63707
+ 64968
6
4525
- 30180
+ 30752
@@ -17457,15 +17520,15 @@
decltypes
- 814720
+ 814246
id
- 27572
+ 27556
expr
- 814720
+ 814246
kind
@@ -17473,7 +17536,7 @@
base_type
- 3342
+ 3340
parentheses_would_change_meaning
@@ -17491,17 +17554,17 @@
1
2
- 9740
+ 9734
2
3
- 3649
+ 3647
4
5
- 3627
+ 3625
6
@@ -17511,12 +17574,12 @@
23
24
- 3254
+ 3252
29
30
- 3144
+ 3142
32
@@ -17526,7 +17589,7 @@
171
172
- 3078
+ 3076
173
@@ -17547,7 +17610,7 @@
1
2
- 27572
+ 27556
@@ -17563,7 +17626,7 @@
1
2
- 27572
+ 27556
@@ -17579,7 +17642,7 @@
1
2
- 27572
+ 27556
@@ -17595,7 +17658,7 @@
1
2
- 814720
+ 814246
@@ -17611,7 +17674,7 @@
1
2
- 814720
+ 814246
@@ -17627,7 +17690,7 @@
1
2
- 814720
+ 814246
@@ -17643,7 +17706,7 @@
1
2
- 814720
+ 814246
@@ -17723,12 +17786,12 @@
1
2
- 1209
+ 1208
2
3
- 1033
+ 1032
3
@@ -17769,7 +17832,7 @@
1
2
- 1165
+ 1164
2
@@ -17815,7 +17878,7 @@
1
2
- 3342
+ 3340
@@ -17831,7 +17894,7 @@
1
2
- 3342
+ 3340
@@ -17905,15 +17968,15 @@
type_operators
- 7954
+ 7964
id
- 7954
+ 7964
arg_type
- 7184
+ 7193
kind
@@ -17921,7 +17984,7 @@
base_type
- 5217
+ 5223
@@ -17935,7 +17998,7 @@
1
2
- 7954
+ 7964
@@ -17951,7 +18014,7 @@
1
2
- 7954
+ 7964
@@ -17967,7 +18030,7 @@
1
2
- 7954
+ 7964
@@ -17983,12 +18046,12 @@
1
2
- 6415
+ 6422
2
3
- 769
+ 770
@@ -18004,12 +18067,12 @@
1
2
- 6415
+ 6422
2
3
- 769
+ 770
@@ -18025,7 +18088,7 @@
1
2
- 7163
+ 7171
2
@@ -18139,12 +18202,12 @@
1
2
- 3571
+ 3575
2
3
- 940
+ 941
3
@@ -18170,12 +18233,12 @@
1
2
- 3720
+ 3725
2
3
- 1026
+ 1027
3
@@ -18201,12 +18264,12 @@
1
2
- 4020
+ 4024
2
3
- 1176
+ 1177
3
@@ -18221,19 +18284,19 @@
usertypes
- 4203790
+ 4280384
id
- 4203790
+ 4280384
name
- 950343
+ 966130
kind
- 125
+ 128
@@ -18247,7 +18310,7 @@
1
2
- 4203790
+ 4280384
@@ -18263,7 +18326,7 @@
1
2
- 4203790
+ 4280384
@@ -18279,22 +18342,22 @@
1
2
- 681205
+ 692231
2
3
- 160794
+ 163458
3
8
- 72561
+ 74001
8
- 33452
- 35782
+ 33429
+ 36439
@@ -18310,12 +18373,12 @@
1
2
- 898500
+ 913304
2
10
- 51842
+ 52825
@@ -18349,8 +18412,8 @@
10
- 1662
- 1663
+ 1559
+ 1560
10
@@ -18364,13 +18427,13 @@
10
- 20074
- 20075
+ 20075
+ 20076
10
- 21723
- 21724
+ 21724
+ 21725
10
@@ -18379,13 +18442,13 @@
10
- 99064
- 99065
+ 98824
+ 98825
10
- 167547
- 167548
+ 167596
+ 167597
10
@@ -18450,13 +18513,13 @@
10
- 12272
- 12273
+ 12260
+ 12261
10
- 61190
- 61191
+ 60993
+ 60994
10
@@ -18467,19 +18530,19 @@
usertypesize
- 1421775
+ 1444984
id
- 1421775
+ 1444984
size
- 1468
+ 1496
alignment
- 83
+ 85
@@ -18493,7 +18556,7 @@
1
2
- 1421775
+ 1444984
@@ -18509,7 +18572,7 @@
1
2
- 1421775
+ 1444984
@@ -18525,52 +18588,52 @@
1
2
- 461
+ 470
2
3
- 188
+ 192
3
4
- 94
+ 96
4
6
- 94
+ 96
6
9
- 115
+ 117
9
19
- 115
+ 117
19
30
- 115
+ 117
30
115
- 115
+ 117
118
- 1731
- 115
+ 1735
+ 117
1840
- 106128
- 52
+ 105871
+ 53
@@ -18586,17 +18649,17 @@
1
2
- 1195
+ 1218
2
3
- 178
+ 181
3
6
- 94
+ 96
@@ -18635,18 +18698,18 @@
10
- 2147
- 2148
+ 2044
+ 2045
10
- 11942
- 11943
+ 11951
+ 11952
10
- 121323
- 121324
+ 121066
+ 121067
10
@@ -18663,7 +18726,7 @@
1
2
- 20
+ 21
3
@@ -18703,26 +18766,26 @@
usertype_final
- 11293
+ 11295
id
- 11293
+ 11295
usertype_uuid
- 47615
+ 47751
id
- 47615
+ 47751
uuid
- 47074
+ 47208
@@ -18736,7 +18799,7 @@
1
2
- 47615
+ 47751
@@ -18752,12 +18815,12 @@
1
2
- 46533
+ 46666
2
3
- 541
+ 542
@@ -18767,15 +18830,15 @@
usertype_alias_kind
- 1757610
+ 1791463
id
- 1757610
+ 1791463
alias_kind
- 20
+ 21
@@ -18789,7 +18852,7 @@
1
2
- 1757610
+ 1791463
@@ -18803,13 +18866,13 @@
12
- 36943
- 36944
+ 36949
+ 36950
10
- 130604
- 130605
+ 130647
+ 130648
10
@@ -18820,26 +18883,26 @@
nontype_template_parameters
- 754374
+ 758786
id
- 754374
+ 758786
type_template_type_constraint
- 26986
+ 27019
id
- 13300
+ 13316
constraint
- 25852
+ 25884
@@ -18853,27 +18916,27 @@
1
2
- 10157
+ 10169
2
3
- 898
+ 899
3
5
- 1026
+ 1027
5
14
- 1111
+ 1113
14
17
- 106
+ 107
@@ -18889,12 +18952,12 @@
1
2
- 24719
+ 24749
2
3
- 1133
+ 1134
@@ -18904,15 +18967,15 @@
mangled_name
- 8184676
+ 8178430
id
- 8184676
+ 8178430
mangled_name
- 6352070
+ 6345435
is_complete
@@ -18930,7 +18993,7 @@
1
2
- 8184676
+ 8178430
@@ -18946,7 +19009,7 @@
1
2
- 8184676
+ 8178430
@@ -18962,12 +19025,12 @@
1
2
- 5997431
+ 5990721
2
1120
- 354638
+ 354713
@@ -18983,7 +19046,7 @@
1
2
- 6352070
+ 6345435
@@ -19002,8 +19065,8 @@
122
- 66669
- 66670
+ 66604
+ 66605
122
@@ -19023,8 +19086,8 @@
122
- 51740
- 51741
+ 51675
+ 51676
122
@@ -19035,59 +19098,59 @@
is_pod_class
- 608655
+ 611169
id
- 608655
+ 611169
is_standard_layout_class
- 1183332
+ 1203088
id
- 1183332
+ 1203088
is_complete
- 1403669
+ 1427635
id
- 1403669
+ 1427635
is_class_template
- 230554
+ 234937
id
- 230554
+ 234937
class_instantiation
- 1183835
+ 1203697
to
- 1180845
+ 1200629
from
- 71774
+ 73103
@@ -19101,12 +19164,12 @@
1
2
- 1178758
+ 1198481
2
8
- 2087
+ 2148
@@ -19122,47 +19185,47 @@
1
2
- 20340
+ 20779
2
3
- 12777
+ 13030
3
4
- 7101
+ 7215
4
5
- 4657
+ 4756
5
7
- 6189
+ 6327
7
10
- 5685
+ 5750
10
17
- 5864
+ 5964
17
- 52
- 5402
+ 53
+ 5547
- 52
+ 53
4358
- 3755
+ 3730
@@ -19172,19 +19235,19 @@
class_template_argument
- 3001639
+ 3053715
type_id
- 1423558
+ 1447923
index
- 1174
+ 1197
arg_type
- 844622
+ 860596
@@ -19198,27 +19261,27 @@
1
2
- 599423
+ 609806
2
3
- 434747
+ 441933
3
4
- 263557
+ 267956
4
8
- 107724
+ 109777
8
113
- 18106
+ 18449
@@ -19234,22 +19297,22 @@
1
2
- 628313
+ 638860
2
3
- 448888
+ 456705
3
4
- 263630
+ 268052
4
113
- 82726
+ 84305
@@ -19270,32 +19333,32 @@
4
5
- 744
+ 758
5
30
- 94
+ 96
33
90
- 94
+ 96
95
453
- 94
+ 96
643
- 7142
- 94
+ 7143
+ 96
- 11996
- 135692
- 41
+ 11997
+ 135446
+ 42
@@ -19316,32 +19379,32 @@
4
5
- 744
+ 758
5
16
- 104
+ 106
16
35
- 94
+ 96
37
155
- 94
+ 96
196
3290
- 94
+ 96
- 11129
- 46222
- 31
+ 11131
+ 46221
+ 32
@@ -19357,27 +19420,27 @@
1
2
- 524281
+ 534234
2
3
- 174662
+ 177964
3
5
- 77711
+ 79356
5
- 44
- 63413
+ 46
+ 64680
- 44
- 13910
- 4552
+ 46
+ 13877
+ 4361
@@ -19393,17 +19456,17 @@
1
2
- 737475
+ 751823
2
3
- 87866
+ 89137
3
22
- 19281
+ 19636
@@ -19413,19 +19476,19 @@
class_template_argument_value
- 508958
+ 511935
type_id
- 209162
+ 210385
index
- 302
+ 303
arg_value
- 508824
+ 511800
@@ -19439,17 +19502,17 @@
1
2
- 159884
+ 160819
2
3
- 42732
+ 42982
3
8
- 6545
+ 6584
@@ -19465,22 +19528,22 @@
1
2
- 152130
+ 153020
2
3
- 39878
+ 40112
3
52
- 15911
+ 16004
54
154
- 1242
+ 1249
@@ -19608,12 +19671,12 @@
1
2
- 508690
+ 511665
2
3
- 134
+ 135
@@ -19629,7 +19692,7 @@
1
2
- 508824
+ 511800
@@ -19639,15 +19702,15 @@
class_template_generated_from
- 61420
+ 62595
template
- 61420
+ 62595
from
- 3734
+ 3805
@@ -19661,7 +19724,7 @@
1
2
- 61420
+ 62595
@@ -19677,47 +19740,47 @@
1
2
- 1510
+ 1539
2
3
- 472
+ 481
3
5
- 209
+ 213
5
6
- 178
+ 181
6
7
- 262
+ 267
7
10
- 262
+ 267
10
16
- 283
+ 288
16
63
- 335
+ 342
63
603
- 220
+ 224
@@ -19727,15 +19790,15 @@
is_proxy_class_for
- 50227
+ 51179
id
- 50227
+ 51179
templ_param_id
- 46922
+ 47812
@@ -19749,7 +19812,7 @@
1
2
- 50227
+ 51179
@@ -19765,12 +19828,12 @@
1
2
- 46167
+ 47043
2
82
- 755
+ 769
@@ -19780,19 +19843,19 @@
type_mentions
- 5941339
+ 5937883
id
- 5941339
+ 5937883
type_id
- 278065
+ 277903
location
- 5885018
+ 5881594
kind
@@ -19810,7 +19873,7 @@
1
2
- 5941339
+ 5937883
@@ -19826,7 +19889,7 @@
1
2
- 5941339
+ 5937883
@@ -19842,7 +19905,7 @@
1
2
- 5941339
+ 5937883
@@ -19858,42 +19921,42 @@
1
2
- 137480
+ 137400
2
3
- 31210
+ 31192
3
4
- 11656
+ 11649
4
5
- 14979
+ 14970
5
7
- 19935
+ 19924
7
12
- 21787
+ 21775
12
28
- 21025
+ 21012
28
8941
- 19990
+ 19978
@@ -19909,42 +19972,42 @@
1
2
- 137480
+ 137400
2
3
- 31210
+ 31192
3
4
- 11656
+ 11649
4
5
- 14979
+ 14970
5
7
- 19935
+ 19924
7
12
- 21787
+ 21775
12
28
- 21025
+ 21012
28
8941
- 19990
+ 19978
@@ -19960,7 +20023,7 @@
1
2
- 278065
+ 277903
@@ -19976,12 +20039,12 @@
1
2
- 5839318
+ 5835921
2
4
- 45699
+ 45673
@@ -19997,12 +20060,12 @@
1
2
- 5839318
+ 5835921
2
4
- 45699
+ 45673
@@ -20018,7 +20081,7 @@
1
2
- 5885018
+ 5881594
@@ -20076,26 +20139,26 @@
is_function_template
- 1311389
+ 1311667
id
- 1311389
+ 1311667
function_instantiation
- 959643
+ 965154
to
- 959643
+ 965154
from
- 180058
+ 181044
@@ -20109,7 +20172,7 @@
1
2
- 959643
+ 965154
@@ -20125,27 +20188,27 @@
1
2
- 108961
+ 109531
2
3
- 42195
+ 42441
3
9
- 14232
+ 14316
9
104
- 13527
+ 13607
119
- 1532
- 1141
+ 1531
+ 1147
@@ -20155,19 +20218,19 @@
function_template_argument
- 2464632
+ 2478845
function_id
- 1448091
+ 1456460
index
- 469
+ 472
arg_type
- 293619
+ 295303
@@ -20181,22 +20244,22 @@
1
2
- 787539
+ 792112
2
3
- 407146
+ 409494
3
4
- 169350
+ 170307
4
15
- 84054
+ 84546
@@ -20212,22 +20275,22 @@
1
2
- 806405
+ 811087
2
3
- 405266
+ 407603
3
4
- 167202
+ 168146
4
9
- 69217
+ 69622
@@ -20243,7 +20306,7 @@
1
2
- 167
+ 168
7
@@ -20276,18 +20339,18 @@
33
- 7549
- 7550
+ 7548
+ 7549
33
- 19678
- 19679
+ 19676
+ 19677
33
- 43139
- 43140
+ 43136
+ 43137
33
@@ -20304,7 +20367,7 @@
1
2
- 167
+ 168
4
@@ -20347,8 +20410,8 @@
33
- 6081
- 6082
+ 6080
+ 6081
33
@@ -20365,37 +20428,37 @@
1
2
- 172204
+ 173211
2
3
- 25914
+ 26032
3
4
- 19536
+ 19650
4
6
- 22457
+ 22588
6
11
- 22960
+ 23094
11
76
- 22960
+ 23094
79
2452
- 7586
+ 7630
@@ -20411,17 +20474,17 @@
1
2
- 253002
+ 254448
2
3
- 31688
+ 31873
3
15
- 8929
+ 8981
@@ -20431,19 +20494,19 @@
function_template_argument_value
- 453873
+ 456460
function_id
- 193888
+ 194955
index
- 469
+ 472
arg_value
- 451221
+ 453793
@@ -20457,17 +20520,17 @@
1
2
- 149176
+ 149981
2
3
- 42262
+ 42509
3
8
- 2450
+ 2464
@@ -20483,22 +20546,22 @@
1
2
- 142362
+ 143127
2
3
- 36085
+ 36296
3
54
- 14669
+ 14755
54
166
- 772
+ 776
@@ -20514,7 +20577,7 @@
1
2
- 167
+ 168
2
@@ -20552,13 +20615,13 @@
33
- 1850
- 1851
+ 1849
+ 1850
33
- 2547
- 2548
+ 2546
+ 2547
33
@@ -20575,7 +20638,7 @@
1
2
- 167
+ 168
2
@@ -20613,13 +20676,13 @@
33
- 3813
- 3814
+ 3812
+ 3813
33
- 4291
- 4292
+ 4290
+ 4291
33
@@ -20636,12 +20699,12 @@
1
2
- 448569
+ 451125
2
3
- 2651
+ 2667
@@ -20657,7 +20720,7 @@
1
2
- 451221
+ 453793
@@ -20667,15 +20730,15 @@
function_template_generated_from
- 864410
+ 869466
template
- 864410
+ 869466
from
- 22154
+ 22284
@@ -20689,7 +20752,7 @@
1
2
- 864410
+ 869466
@@ -20705,62 +20768,62 @@
1
2
- 3591
+ 3612
2
3
- 1174
+ 1181
3
5
- 1678
+ 1688
5
8
- 1779
+ 1789
8
14
- 1678
+ 1688
16
20
- 1577
+ 1586
20
23
- 1678
+ 1688
23
32
- 1846
+ 1857
33
66
- 2047
+ 2059
70
79
- 1376
+ 1384
83
110
- 1846
+ 1857
111
370
- 1879
+ 1890
@@ -20770,26 +20833,26 @@
is_variable_template
- 57694
+ 57706
id
- 57694
+ 57706
variable_instantiation
- 596956
+ 566265
to
- 596956
+ 566265
from
- 36089
+ 36097
@@ -20803,7 +20866,7 @@
1
2
- 596956
+ 566265
@@ -20819,12 +20882,12 @@
1
2
- 14362
+ 14733
2
3
- 3928
+ 3683
3
@@ -20834,7 +20897,7 @@
4
6
- 2700
+ 2701
6
@@ -20844,22 +20907,22 @@
8
11
- 3191
+ 3192
11
- 30
+ 25
2823
- 30
+ 25
94
2823
103
1155
- 982
+ 859
@@ -20869,11 +20932,11 @@
variable_template_argument
- 1128116
+ 1073718
variable_id
- 575474
+ 548707
index
@@ -20881,7 +20944,7 @@
arg_type
- 463276
+ 461778
@@ -20895,22 +20958,22 @@
1
2
- 189165
+ 179996
2
3
- 288964
+ 272696
3
4
- 77703
+ 77720
4
17
- 19640
+ 18294
@@ -20926,22 +20989,22 @@
1
2
- 206841
+ 196203
2
3
- 276198
+ 261400
3
4
- 75616
+ 75632
4
17
- 16817
+ 15470
@@ -20955,43 +21018,43 @@
12
- 27
- 28
+ 22
+ 23
859
- 33
- 34
+ 28
+ 29
368
- 40
- 41
+ 35
+ 36
122
- 72
- 73
+ 67
+ 68
122
- 160
- 161
+ 149
+ 150
122
- 793
- 794
+ 782
+ 783
122
- 3147
- 3148
+ 3003
+ 3004
122
- 4688
- 4689
+ 4469
+ 4470
122
@@ -21036,13 +21099,13 @@
122
- 1465
- 1466
+ 1448
+ 1449
122
- 2164
- 2165
+ 2157
+ 2158
122
@@ -21059,22 +21122,22 @@
1
2
- 359671
+ 361098
2
3
- 57694
+ 56233
3
- 16
- 35476
+ 17
+ 35606
- 16
+ 17
227
- 10434
+ 8840
@@ -21090,12 +21153,12 @@
1
2
- 429887
+ 429364
2
7
- 33389
+ 32414
@@ -21105,11 +21168,11 @@
variable_template_argument_value
- 19763
+ 19767
variable_id
- 14730
+ 14733
index
@@ -21117,7 +21180,7 @@
arg_value
- 19763
+ 19767
@@ -21131,7 +21194,7 @@
1
2
- 13257
+ 13260
2
@@ -21152,7 +21215,7 @@
1
2
- 10434
+ 10436
2
@@ -21240,7 +21303,7 @@
1
2
- 19763
+ 19767
@@ -21256,7 +21319,7 @@
1
2
- 19763
+ 19767
@@ -21314,26 +21377,26 @@
is_alias_template
- 107518
+ 108147
id
- 107518
+ 108147
alias_instantiation
- 460184
+ 462875
to
- 460184
+ 462875
from
- 92312
+ 92852
@@ -21347,7 +21410,7 @@
1
2
- 460184
+ 462875
@@ -21363,47 +21426,47 @@
1
2
- 16549
+ 16645
2
3
- 16817
+ 16915
3
4
- 20040
+ 20157
4
5
- 12487
+ 12560
5
7
- 6713
+ 6752
7
8
- 4800
+ 4828
8
10
- 7821
+ 7867
10
143
- 6948
+ 6989
163
795
- 134
+ 135
@@ -21413,19 +21476,19 @@
alias_template_argument
- 994218
+ 1000033
type_id
- 567635
+ 570955
index
- 302
+ 303
arg_type
- 127860
+ 128608
@@ -21439,22 +21502,22 @@
1
2
- 276499
+ 278117
2
3
- 182542
+ 183610
3
4
- 87008
+ 87517
4
10
- 21584
+ 21710
@@ -21470,22 +21533,22 @@
1
2
- 277741
+ 279366
2
3
- 181334
+ 182395
3
4
- 88451
+ 88969
4
10
- 20107
+ 20224
@@ -21613,32 +21676,32 @@
1
2
- 78247
+ 78704
2
3
- 20308
+ 20427
3
4
- 5438
+ 5469
4
6
- 10473
+ 10534
6
76
- 10842
+ 10905
84
4474
- 2551
+ 2566
@@ -21654,17 +21717,17 @@
1
2
- 108928
+ 109565
2
3
- 17321
+ 17422
3
9
- 1611
+ 1620
@@ -21674,19 +21737,19 @@
alias_template_argument_value
- 173378
+ 174393
type_id
- 160790
+ 161731
index
- 134
+ 135
arg_value
- 173378
+ 174393
@@ -21700,12 +21763,12 @@
1
2
- 159548
+ 160482
2
3
- 1242
+ 1249
@@ -21721,12 +21784,12 @@
1
2
- 158877
+ 159806
2
42
- 1913
+ 1924
@@ -21804,7 +21867,7 @@
1
2
- 173378
+ 174393
@@ -21820,7 +21883,7 @@
1
2
- 173378
+ 174393
@@ -21830,15 +21893,15 @@
alias_template_generated_from
- 99932
+ 100516
template
- 99932
+ 100516
from
- 1913
+ 1924
@@ -21852,7 +21915,7 @@
1
2
- 99932
+ 100516
@@ -21868,42 +21931,42 @@
1
2
- 134
+ 135
2
4
- 134
+ 135
4
8
- 134
+ 135
9
18
- 167
+ 168
18
20
- 134
+ 135
20
21
- 201
+ 202
31
32
- 134
+ 135
43
50
- 134
+ 135
64
@@ -21913,22 +21976,22 @@
65
66
- 134
+ 135
74
84
- 167
+ 168
111
112
- 268
+ 270
150
294
- 100
+ 101
@@ -21938,15 +22001,15 @@
template_template_instantiation
- 6014
+ 6114
to
- 4664
+ 5718
from
- 1104
+ 3976
@@ -21960,12 +22023,12 @@
1
2
- 3314
+ 5601
2
- 3
- 1350
+ 18
+ 117
@@ -21981,22 +22044,17 @@
1
2
- 736
+ 2490
2
3
- 122
+ 1325
- 14
- 15
- 122
-
-
- 27
- 28
- 122
+ 3
+ 20
+ 160
@@ -22006,19 +22064,19 @@
template_template_argument
- 9609
+ 9791
type_id
- 6073
+ 6189
index
- 104
+ 106
arg_type
- 9021
+ 9192
@@ -22032,22 +22090,22 @@
1
2
- 4982
+ 5077
2
3
- 419
+ 427
3
8
- 503
+ 513
8
11
- 167
+ 171
@@ -22063,22 +22121,22 @@
1
2
- 5003
+ 5098
2
4
- 555
+ 566
4
10
- 461
+ 470
10
11
- 52
+ 53
@@ -22216,12 +22274,12 @@
1
2
- 8990
+ 9160
3
43
- 31
+ 32
@@ -22237,12 +22295,12 @@
1
2
- 9000
+ 9171
2
11
- 20
+ 21
@@ -22252,7 +22310,7 @@
template_template_argument_value
- 1104
+ 1105
type_id
@@ -22264,7 +22322,7 @@
arg_value
- 1104
+ 1105
@@ -22342,7 +22400,7 @@
1
2
- 1104
+ 1105
@@ -22358,7 +22416,7 @@
1
2
- 1104
+ 1105
@@ -22368,19 +22426,19 @@
concept_templates
- 3592
+ 3596
concept_id
- 3592
+ 3596
name
- 3592
+ 3596
location
- 3592
+ 3596
@@ -22394,7 +22452,7 @@
1
2
- 3592
+ 3596
@@ -22410,7 +22468,7 @@
1
2
- 3592
+ 3596
@@ -22426,7 +22484,7 @@
1
2
- 3592
+ 3596
@@ -22442,7 +22500,7 @@
1
2
- 3592
+ 3596
@@ -22458,7 +22516,7 @@
1
2
- 3592
+ 3596
@@ -22474,7 +22532,7 @@
1
2
- 3592
+ 3596
@@ -22484,15 +22542,15 @@
concept_instantiation
- 90068
+ 90178
to
- 90068
+ 90178
from
- 3421
+ 3425
@@ -22506,7 +22564,7 @@
1
2
- 90068
+ 90178
@@ -22527,7 +22585,7 @@
2
3
- 106
+ 107
3
@@ -22547,7 +22605,7 @@
6
8
- 213
+ 214
8
@@ -22557,17 +22615,17 @@
10
12
- 277
+ 278
12
15
- 213
+ 214
15
19
- 213
+ 214
19
@@ -22592,7 +22650,7 @@
79
387
- 213
+ 214
@@ -22602,22 +22660,22 @@
is_type_constraint
- 36673
+ 36717
concept_id
- 36673
+ 36717
concept_template_argument
- 112649
+ 112786
concept_id
- 76104
+ 76197
index
@@ -22625,7 +22683,7 @@
arg_type
- 21490
+ 21516
@@ -22639,17 +22697,17 @@
1
2
- 46295
+ 46352
2
3
- 24612
+ 24642
3
7
- 5196
+ 5202
@@ -22665,17 +22723,17 @@
1
2
- 49888
+ 49949
2
3
- 22324
+ 22351
3
7
- 3891
+ 3896
@@ -22773,42 +22831,42 @@
1
2
- 10542
+ 10555
2
3
- 2908
+ 2911
3
4
- 1069
+ 1070
4
5
- 1347
+ 1348
5
6
- 1133
+ 1134
6
9
- 1625
+ 1627
9
14
- 1945
+ 1948
14
259
- 919
+ 920
@@ -22824,12 +22882,12 @@
1
2
- 18090
+ 18112
2
3
- 3271
+ 3275
3
@@ -22844,19 +22902,19 @@
concept_template_argument_value
- 104
+ 105
concept_id
- 82
+ 83
index
- 14
+ 15
arg_value
- 104
+ 105
@@ -22870,7 +22928,7 @@
1
2
- 82
+ 83
@@ -22886,7 +22944,7 @@
1
2
- 59
+ 60
2
@@ -22949,7 +23007,7 @@
1
2
- 104
+ 105
@@ -22965,7 +23023,7 @@
1
2
- 104
+ 105
@@ -22975,15 +23033,15 @@
routinetypes
- 595664
+ 599081
id
- 595664
+ 599081
return_type
- 279722
+ 281324
@@ -22997,7 +23055,7 @@
1
2
- 595664
+ 599081
@@ -23013,17 +23071,17 @@
1
2
- 230679
+ 231995
2
3
- 34709
+ 34912
3
- 4677
- 14333
+ 4676
+ 14417
@@ -23033,19 +23091,19 @@
routinetypeargs
- 1178768
+ 1178082
routine
- 416090
+ 415848
index
- 980
+ 979
type_id
- 112097
+ 112032
@@ -23059,32 +23117,32 @@
1
2
- 82956
+ 82908
2
3
- 126096
+ 126022
3
4
- 107903
+ 107840
4
5
- 49294
+ 49265
5
7
- 33171
+ 33152
7
19
- 16667
+ 16657
@@ -23100,27 +23158,27 @@
1
2
- 88948
+ 88896
2
3
- 138733
+ 138652
3
4
- 114657
+ 114591
4
5
- 40742
+ 40719
5
10
- 32899
+ 32880
10
@@ -23318,47 +23376,47 @@
1
2
- 33280
+ 33261
2
3
- 15578
+ 15569
3
4
- 13290
+ 13282
4
5
- 9804
+ 9798
5
6
- 6372
+ 6369
6
8
- 9477
+ 9472
8
13
- 9532
+ 9526
13
26
- 8660
+ 8655
26
926
- 6100
+ 6097
@@ -23374,22 +23432,22 @@
1
2
- 79416
+ 79369
2
3
- 17539
+ 17528
3
5
- 9477
+ 9472
5
17
- 5664
+ 5661
@@ -23399,19 +23457,19 @@
ptrtomembers
- 9651
+ 9834
id
- 9651
+ 9834
type_id
- 7920
+ 8070
class_id
- 4836
+ 4927
@@ -23425,7 +23483,7 @@
1
2
- 9651
+ 9834
@@ -23441,7 +23499,7 @@
1
2
- 9651
+ 9834
@@ -23457,12 +23515,12 @@
1
2
- 7710
+ 7856
2
84
- 209
+ 213
@@ -23478,12 +23536,12 @@
1
2
- 7710
+ 7856
2
84
- 209
+ 213
@@ -23499,22 +23557,22 @@
1
2
- 3881
+ 3954
2
3
- 514
+ 523
8
9
- 398
+ 406
10
65
- 41
+ 42
@@ -23530,22 +23588,22 @@
1
2
- 3881
+ 3954
2
3
- 514
+ 523
8
9
- 398
+ 406
10
65
- 41
+ 42
@@ -23555,15 +23613,15 @@
specifiers
- 7610
+ 7612
id
- 7610
+ 7612
str
- 7610
+ 7612
@@ -23577,7 +23635,7 @@
1
2
- 7610
+ 7612
@@ -23593,7 +23651,7 @@
1
2
- 7610
+ 7612
@@ -23603,15 +23661,15 @@
typespecifiers
- 853570
+ 868944
type_id
- 848462
+ 863749
spec_id
- 94
+ 96
@@ -23625,12 +23683,12 @@
1
2
- 843353
+ 858554
2
3
- 5108
+ 5194
@@ -23659,13 +23717,13 @@
10
- 530
- 531
+ 533
+ 534
10
- 821
- 822
+ 820
+ 821
10
@@ -23674,18 +23732,18 @@
10
- 4192
- 4193
+ 4195
+ 4196
10
- 18435
- 18436
+ 18331
+ 18332
10
- 55214
- 55215
+ 55237
+ 55238
10
@@ -23696,11 +23754,11 @@
funspecifiers
- 9569842
+ 9572483
func_id
- 3954300
+ 3955752
spec_id
@@ -23718,27 +23776,27 @@
1
2
- 1510375
+ 1511309
2
3
- 500471
+ 500822
3
4
- 1019724
+ 1019694
4
5
- 682148
+ 682047
5
8
- 241581
+ 241878
@@ -23827,8 +23885,8 @@
122
- 6170
- 6171
+ 6172
+ 6173
122
@@ -23842,8 +23900,8 @@
122
- 22794
- 22795
+ 22797
+ 22798
122
@@ -23854,15 +23912,15 @@
varspecifiers
- 3209301
+ 3148468
var_id
- 2456201
+ 2429095
spec_id
- 1104
+ 1105
@@ -23876,17 +23934,17 @@
1
2
- 1805109
+ 1807824
2
3
- 549573
+ 523660
3
5
- 101518
+ 97610
@@ -23905,8 +23963,8 @@
122
- 240
- 241
+ 242
+ 243
122
@@ -23920,28 +23978,28 @@
122
- 2749
- 2750
+ 2566
+ 2567
122
- 2812
- 2813
+ 2749
+ 2750
122
- 3506
- 3507
+ 3255
+ 3256
122
- 4918
- 4919
+ 4944
+ 4945
122
- 8493
- 8494
+ 8461
+ 8462
122
@@ -23952,15 +24010,15 @@
explicit_specifier_exprs
- 40631
+ 40640
func_id
- 40631
+ 40640
constant
- 40631
+ 40640
@@ -23974,7 +24032,7 @@
1
2
- 40631
+ 40640
@@ -23990,7 +24048,7 @@
1
2
- 40631
+ 40640
@@ -24000,11 +24058,11 @@
attributes
- 643971
+ 644108
id
- 643971
+ 644108
kind
@@ -24012,7 +24070,7 @@
name
- 2086
+ 2087
name_space
@@ -24020,7 +24078,7 @@
location
- 637956
+ 638091
@@ -24034,7 +24092,7 @@
1
2
- 643971
+ 644108
@@ -24050,7 +24108,7 @@
1
2
- 643971
+ 644108
@@ -24066,7 +24124,7 @@
1
2
- 643971
+ 644108
@@ -24082,7 +24140,7 @@
1
2
- 643971
+ 644108
@@ -24299,7 +24357,7 @@
1
2
- 2086
+ 2087
@@ -24485,12 +24543,12 @@
1
2
- 632187
+ 632321
2
5
- 5769
+ 5770
@@ -24506,7 +24564,7 @@
1
2
- 637956
+ 638091
@@ -24522,12 +24580,12 @@
1
2
- 632923
+ 633057
2
3
- 5032
+ 5034
@@ -24543,7 +24601,7 @@
1
2
- 637956
+ 638091
@@ -24553,11 +24611,11 @@
attribute_args
- 82169
+ 82121
id
- 82169
+ 82121
kind
@@ -24565,7 +24623,7 @@
attribute
- 70920
+ 70879
index
@@ -24573,7 +24631,7 @@
location
- 56912
+ 56879
@@ -24587,7 +24645,7 @@
1
2
- 82169
+ 82121
@@ -24603,7 +24661,7 @@
1
2
- 82169
+ 82121
@@ -24619,7 +24677,7 @@
1
2
- 82169
+ 82121
@@ -24635,7 +24693,7 @@
1
2
- 82169
+ 82121
@@ -24755,12 +24813,12 @@
1
2
- 65477
+ 65439
2
7
- 5322
+ 5318
7
@@ -24781,12 +24839,12 @@
1
2
- 69411
+ 69370
2
3
- 1509
+ 1508
@@ -24802,12 +24860,12 @@
1
2
- 67890
+ 67851
2
8
- 3029
+ 3027
@@ -24823,12 +24881,12 @@
1
2
- 68420
+ 68380
2
6
- 2499
+ 2498
@@ -25008,17 +25066,17 @@
1
2
- 41309
+ 41285
2
3
- 11801
+ 11794
3
25
- 3801
+ 3799
@@ -25034,12 +25092,12 @@
1
2
- 47426
+ 47398
2
3
- 9486
+ 9480
@@ -25055,17 +25113,17 @@
1
2
- 42656
+ 42632
2
3
- 12239
+ 12232
3
11
- 2015
+ 2014
@@ -25081,7 +25139,7 @@
1
2
- 56664
+ 56631
2
@@ -25096,15 +25154,15 @@
attribute_arg_value
- 16448
+ 16544
arg
- 16448
+ 16544
value
- 503
+ 506
@@ -25118,7 +25176,7 @@
1
2
- 16448
+ 16544
@@ -25134,7 +25192,7 @@
1
2
- 201
+ 202
5
@@ -25189,11 +25247,11 @@
attribute_arg_type
- 460
+ 464
arg
- 460
+ 464
type_id
@@ -25211,7 +25269,7 @@
1
2
- 460
+ 464
@@ -25252,15 +25310,15 @@
attribute_arg_constant
- 71688
+ 72665
arg
- 71688
+ 72665
constant
- 71688
+ 72665
@@ -25274,7 +25332,7 @@
1
2
- 71688
+ 72665
@@ -25290,7 +25348,7 @@
1
2
- 71688
+ 72665
@@ -25300,15 +25358,15 @@
attribute_arg_expr
- 1582
+ 1584
arg
- 1582
+ 1584
expr
- 1582
+ 1584
@@ -25322,7 +25380,7 @@
1
2
- 1582
+ 1584
@@ -25338,7 +25396,7 @@
1
2
- 1582
+ 1584
@@ -25401,15 +25459,15 @@
typeattributes
- 94766
+ 94786
type_id
- 93048
+ 93067
spec_id
- 31916
+ 31923
@@ -25423,7 +25481,7 @@
1
2
- 91329
+ 91348
2
@@ -25444,7 +25502,7 @@
1
2
- 27497
+ 27502
2
@@ -25464,15 +25522,15 @@
funcattributes
- 834364
+ 834541
func_id
- 788699
+ 788866
spec_id
- 607513
+ 607642
@@ -25486,12 +25544,12 @@
1
2
- 747454
+ 747612
2
7
- 41245
+ 41254
@@ -25507,12 +25565,12 @@
1
2
- 561234
+ 561353
2
45
- 45787
+ 45797
55
@@ -25590,15 +25648,15 @@
namespaceattributes
- 5907
+ 5942
namespace_id
- 134
+ 135
spec_id
- 5907
+ 5942
@@ -25638,7 +25696,7 @@
1
2
- 5907
+ 5942
@@ -25648,15 +25706,15 @@
stmtattributes
- 2223
+ 2226
stmt_id
- 2223
+ 2226
spec_id
- 577
+ 578
@@ -25670,7 +25728,7 @@
1
2
- 2223
+ 2226
@@ -25701,7 +25759,7 @@
9
10
- 106
+ 107
13
@@ -25716,15 +25774,15 @@
unspecifiedtype
- 7371180
+ 7365375
type_id
- 7371180
+ 7365375
unspecified_type_id
- 4135732
+ 4133170
@@ -25738,7 +25796,7 @@
1
2
- 7371180
+ 7365375
@@ -25754,22 +25812,22 @@
1
2
- 2670039
+ 2667167
2
3
- 1104793
+ 1105027
3
8
- 311674
+ 311740
8
895
- 49224
+ 49235
@@ -25779,19 +25837,19 @@
member
- 4123947
+ 4121629
parent
- 534719
+ 532868
index
- 29215
+ 29221
child
- 4119405
+ 4117086
@@ -25805,57 +25863,57 @@
1
2
- 127419
+ 126709
2
3
- 81754
+ 80544
3
4
- 31916
+ 31923
4
5
- 44191
+ 44201
5
6
- 41613
+ 41622
6
7
- 33389
+ 33396
7
9
- 41613
+ 41622
9
13
- 40509
+ 40517
13
18
- 40631
+ 40640
18
- 42
- 40140
+ 41
+ 40026
- 42
+ 41
239
- 11538
+ 11664
@@ -25871,57 +25929,57 @@
1
2
- 127173
+ 126464
2
3
- 81877
+ 80666
3
4
- 31670
+ 31677
4
5
- 44437
+ 44446
5
6
- 41613
+ 41622
6
7
- 32284
+ 32291
7
9
- 41982
+ 41991
9
13
- 40877
+ 40886
13
18
- 40754
+ 40763
18
42
- 40140
+ 40149
42
265
- 11907
+ 11909
@@ -25937,12 +25995,12 @@
1
2
- 6383
+ 6384
2
3
- 2577
+ 2578
3
@@ -25957,12 +26015,12 @@
10
19
- 2209
+ 2210
19
26
- 2209
+ 2210
26
@@ -25972,22 +26030,22 @@
36
50
- 2209
+ 2210
54
141
- 2209
+ 2210
150
468
- 2209
+ 2210
480
- 4311
- 2086
+ 4295
+ 2087
@@ -26003,12 +26061,12 @@
1
2
- 5401
+ 5402
2
3
- 3559
+ 3560
3
@@ -26023,17 +26081,17 @@
10
20
- 2209
+ 2210
20
27
- 2209
+ 2210
27
37
- 2577
+ 2578
37
@@ -26043,16 +26101,16 @@
58
155
- 2209
+ 2210
164
528
- 2209
+ 2210
548
- 4332
+ 4316
1841
@@ -26069,7 +26127,7 @@
1
2
- 4119405
+ 4117086
@@ -26085,12 +26143,12 @@
1
2
- 4114864
+ 4112543
2
3
- 4541
+ 4542
@@ -26100,15 +26158,15 @@
enclosingfunction
- 114616
+ 116832
child
- 114616
+ 116832
parent
- 68858
+ 70206
@@ -26122,7 +26180,7 @@
1
2
- 114616
+ 116832
@@ -26138,22 +26196,22 @@
1
2
- 37324
+ 38074
2
3
- 24410
+ 24873
3
5
- 6042
+ 6156
5
45
- 1080
+ 1100
@@ -26163,27 +26221,27 @@
derivations
- 492610
+ 494850
derivation
- 492610
+ 494850
sub
- 471194
+ 473309
index
- 234
+ 236
super
- 239877
+ 240908
location
- 34877
+ 35081
@@ -26197,7 +26255,7 @@
1
2
- 492610
+ 494850
@@ -26213,7 +26271,7 @@
1
2
- 492610
+ 494850
@@ -26229,7 +26287,7 @@
1
2
- 492610
+ 494850
@@ -26245,7 +26303,7 @@
1
2
- 492610
+ 494850
@@ -26261,12 +26319,12 @@
1
2
- 454914
+ 456933
2
9
- 16280
+ 16375
@@ -26282,12 +26340,12 @@
1
2
- 454914
+ 456933
2
8
- 16280
+ 16375
@@ -26303,12 +26361,12 @@
1
2
- 454914
+ 456933
2
9
- 16280
+ 16375
@@ -26324,12 +26382,12 @@
1
2
- 454914
+ 456933
2
8
- 16280
+ 16375
@@ -26345,7 +26403,7 @@
25
26
- 100
+ 101
26
@@ -26363,8 +26421,8 @@
33
- 14037
- 14038
+ 14018
+ 14019
33
@@ -26381,7 +26439,7 @@
25
26
- 134
+ 135
52
@@ -26394,8 +26452,8 @@
33
- 14037
- 14038
+ 14018
+ 14019
33
@@ -26435,8 +26493,8 @@
33
- 6742
- 6743
+ 6731
+ 6732
33
@@ -26453,7 +26511,7 @@
1
2
- 134
+ 135
7
@@ -26484,12 +26542,12 @@
1
2
- 230108
+ 231252
2
1758
- 9768
+ 9656
@@ -26505,12 +26563,12 @@
1
2
- 230108
+ 231252
2
1758
- 9768
+ 9656
@@ -26526,12 +26584,12 @@
1
2
- 239440
+ 240469
2
4
- 436
+ 438
@@ -26547,12 +26605,12 @@
1
2
- 234506
+ 235641
2
81
- 5370
+ 5267
@@ -26568,27 +26626,27 @@
1
2
- 25847
+ 25998
2
- 5
- 3188
+ 4
+ 2498
- 5
- 21
- 2618
+ 4
+ 12
+ 2633
- 21
- 186
- 2618
+ 13
+ 85
+ 2633
- 205
+ 87
985
- 604
+ 1316
@@ -26604,27 +26662,27 @@
1
2
- 25847
+ 25998
2
- 5
- 3188
+ 4
+ 2498
- 5
- 21
- 2618
+ 4
+ 12
+ 2633
- 21
- 186
- 2618
+ 13
+ 85
+ 2633
- 205
+ 87
985
- 604
+ 1316
@@ -26640,7 +26698,7 @@
1
2
- 34877
+ 35081
@@ -26656,22 +26714,22 @@
1
2
- 28163
+ 28328
2
4
- 2551
+ 2599
4
24
- 2651
+ 2633
24
933
- 1510
+ 1519
@@ -26681,15 +26739,15 @@
derspecifiers
- 494356
+ 496606
der_id
- 492174
+ 494411
spec_id
- 134
+ 135
@@ -26703,12 +26761,12 @@
1
2
- 489992
+ 492217
2
3
- 2181
+ 2194
@@ -26737,8 +26795,8 @@
33
- 13466
- 13467
+ 13447
+ 13448
33
@@ -26749,15 +26807,15 @@
direct_base_offsets
- 466092
+ 468176
der_id
- 466092
+ 468176
offset
- 503
+ 506
@@ -26771,7 +26829,7 @@
1
2
- 466092
+ 468176
@@ -26787,17 +26845,17 @@
1
2
- 100
+ 101
2
3
- 134
+ 135
3
4
- 100
+ 101
4
@@ -26820,8 +26878,8 @@
33
- 13735
- 13736
+ 13716
+ 13717
33
@@ -26832,19 +26890,19 @@
virtual_base_offsets
- 5740
+ 5773
sub
- 5740
+ 5773
super
- 100
+ 101
offset
- 335
+ 337
@@ -26858,7 +26916,7 @@
1
2
- 5740
+ 5773
@@ -26874,7 +26932,7 @@
1
2
- 5740
+ 5773
@@ -26932,7 +26990,7 @@
2
3
- 302
+ 303
153
@@ -26958,7 +27016,7 @@
2
3
- 302
+ 303
@@ -26968,23 +27026,23 @@
frienddecls
- 761457
+ 765911
id
- 761457
+ 765911
type_id
- 53910
+ 54225
decl_id
- 99898
+ 100482
location
- 6008
+ 6043
@@ -26998,7 +27056,7 @@
1
2
- 761457
+ 765911
@@ -27014,7 +27072,7 @@
1
2
- 761457
+ 765911
@@ -27030,7 +27088,7 @@
1
2
- 761457
+ 765911
@@ -27046,42 +27104,42 @@
1
2
- 5538
+ 5571
2
3
- 24806
+ 24951
3
8
- 4733
+ 4760
8
17
- 4699
+ 4727
17
27
- 4430
+ 4456
27
45
- 4263
+ 4288
45
81
- 4699
+ 4727
102
121
- 738
+ 742
@@ -27097,42 +27155,42 @@
1
2
- 5538
+ 5571
2
3
- 24806
+ 24951
3
8
- 4733
+ 4760
8
17
- 4699
+ 4727
17
27
- 4430
+ 4456
27
45
- 4263
+ 4288
45
81
- 4699
+ 4727
102
121
- 738
+ 742
@@ -27148,12 +27206,12 @@
1
2
- 52567
+ 52875
2
13
- 1342
+ 1350
@@ -27169,32 +27227,32 @@
1
2
- 66968
+ 67359
2
3
- 8056
+ 8103
3
9
- 9130
+ 9183
9
24
- 7552
+ 7596
24
136
- 7586
+ 7630
- 136
+ 137
191
- 604
+ 607
@@ -27210,32 +27268,32 @@
1
2
- 66968
+ 67359
2
3
- 8056
+ 8103
3
9
- 9130
+ 9183
9
24
- 7552
+ 7596
24
136
- 7586
+ 7630
- 136
+ 137
191
- 604
+ 607
@@ -27251,12 +27309,12 @@
1
2
- 98690
+ 99267
2
6
- 1208
+ 1215
@@ -27272,12 +27330,12 @@
1
2
- 5639
+ 5672
2
22495
- 369
+ 371
@@ -27293,12 +27351,12 @@
1
2
- 5874
+ 5908
2
1509
- 134
+ 135
@@ -27314,12 +27372,12 @@
1
2
- 5672
+ 5706
2
2844
- 335
+ 337
@@ -27329,19 +27387,19 @@
comments
- 11056034
+ 11058376
id
- 11056034
+ 11058376
contents
- 4236514
+ 4237411
location
- 11056034
+ 11058376
@@ -27355,7 +27413,7 @@
1
2
- 11056034
+ 11058376
@@ -27371,7 +27429,7 @@
1
2
- 11056034
+ 11058376
@@ -27387,17 +27445,17 @@
1
2
- 3867144
+ 3867964
2
6
- 318425
+ 318493
6
34447
- 50943
+ 50954
@@ -27413,17 +27471,17 @@
1
2
- 3867144
+ 3867964
2
6
- 318425
+ 318493
6
34447
- 50943
+ 50954
@@ -27439,7 +27497,7 @@
1
2
- 11056034
+ 11058376
@@ -27455,7 +27513,7 @@
1
2
- 11056034
+ 11058376
@@ -27465,15 +27523,15 @@
commentbinding
- 3852168
+ 3859983
id
- 3297194
+ 3297892
element
- 3689273
+ 3697053
@@ -27487,12 +27545,12 @@
1
2
- 3236553
+ 3230240
2
1706
- 60640
+ 67652
@@ -27508,12 +27566,12 @@
1
2
- 3526377
+ 3534122
2
3
- 162895
+ 162930
@@ -27523,15 +27581,15 @@
exprconv
- 9635850
+ 9630246
converted
- 9635744
+ 9630141
conversion
- 9635850
+ 9630246
@@ -27545,7 +27603,7 @@
1
2
- 9635639
+ 9630035
2
@@ -27566,7 +27624,7 @@
1
2
- 9635850
+ 9630246
@@ -27576,30 +27634,30 @@
compgenerated
- 9880588
+ 9855321
id
- 9880588
+ 9855321
synthetic_destructor_call
- 1661391
+ 1663283
element
- 1237286
+ 1238727
i
- 384
+ 385
destructor_call
- 1661391
+ 1663283
@@ -27613,17 +27671,17 @@
1
2
- 823574
+ 824576
2
3
- 406954
+ 407385
3
19
- 6757
+ 6765
@@ -27639,17 +27697,17 @@
1
2
- 823574
+ 824576
2
3
- 406954
+ 407385
3
19
- 6757
+ 6765
@@ -27708,13 +27766,13 @@
21
- 19347
- 19348
+ 19344
+ 19345
21
- 57861
- 57862
+ 57858
+ 57859
21
@@ -27774,13 +27832,13 @@
21
- 19347
- 19348
+ 19344
+ 19345
21
- 57861
- 57862
+ 57858
+ 57859
21
@@ -27797,7 +27855,7 @@
1
2
- 1661391
+ 1663283
@@ -27813,7 +27871,7 @@
1
2
- 1661391
+ 1663283
@@ -27823,15 +27881,15 @@
namespaces
- 8591
+ 8754
id
- 8591
+ 8754
name
- 4542
+ 4628
@@ -27845,7 +27903,7 @@
1
2
- 8591
+ 8754
@@ -27861,17 +27919,17 @@
1
2
- 3713
+ 3783
2
3
- 524
+ 534
3
149
- 304
+ 309
@@ -27892,7 +27950,7 @@
namespacembrs
- 2487871
+ 2457335
parentid
@@ -27900,7 +27958,7 @@
memberid
- 2487871
+ 2457335
@@ -27972,8 +28030,8 @@
245
- 19521
- 19522
+ 19268
+ 19269
122
@@ -27990,7 +28048,7 @@
1
2
- 2487871
+ 2457335
@@ -28000,19 +28058,19 @@
exprparents
- 19459867
+ 19448545
expr_id
- 19459867
+ 19448545
child_index
- 20040
+ 20029
parent_id
- 12943755
+ 12936225
@@ -28026,7 +28084,7 @@
1
2
- 19459867
+ 19448545
@@ -28042,7 +28100,7 @@
1
2
- 19459867
+ 19448545
@@ -28058,7 +28116,7 @@
1
2
- 3856
+ 3853
2
@@ -28073,17 +28131,17 @@
4
5
- 8978
+ 8973
5
8
- 1660
+ 1659
8
11
- 1632
+ 1631
11
@@ -28109,7 +28167,7 @@
1
2
- 3856
+ 3853
2
@@ -28124,17 +28182,17 @@
4
5
- 8978
+ 8973
5
8
- 1660
+ 1659
8
11
- 1632
+ 1631
11
@@ -28160,17 +28218,17 @@
1
2
- 7396922
+ 7392619
2
3
- 5084149
+ 5081191
3
712
- 462684
+ 462414
@@ -28186,17 +28244,17 @@
1
2
- 7396922
+ 7392619
2
3
- 5084149
+ 5081191
3
712
- 462684
+ 462414
@@ -28206,22 +28264,22 @@
expr_isload
- 6902994
+ 6890582
expr_id
- 6902994
+ 6890582
conversionkinds
- 6052094
+ 6047238
expr_id
- 6052094
+ 6047238
kind
@@ -28239,7 +28297,7 @@
1
2
- 6052094
+ 6047238
@@ -28268,8 +28326,8 @@
1
- 40990
- 40991
+ 40996
+ 40997
1
@@ -28278,13 +28336,13 @@
1
- 92949
- 92950
+ 92848
+ 92849
1
- 5833488
- 5833489
+ 5828727
+ 5828728
1
@@ -28295,11 +28353,11 @@
iscall
- 5772743
+ 5777774
caller
- 5772743
+ 5777774
kind
@@ -28317,7 +28375,7 @@
1
2
- 5772743
+ 5777774
@@ -28341,8 +28399,8 @@
21
- 268245
- 268246
+ 268152
+ 268153
21
@@ -28353,11 +28411,11 @@
numtemplatearguments
- 729040
+ 684871
expr_id
- 729040
+ 684871
num
@@ -28375,7 +28433,7 @@
1
2
- 729040
+ 684871
@@ -28399,8 +28457,8 @@
122
- 27
- 28
+ 22
+ 23
122
@@ -28409,8 +28467,8 @@
122
- 68
- 69
+ 62
+ 63
122
@@ -28419,13 +28477,13 @@
122
- 2001
- 2002
+ 1843
+ 1844
122
- 3393
- 3394
+ 3201
+ 3202
122
@@ -28484,23 +28542,23 @@
namequalifiers
- 3050545
+ 3044942
id
- 3050545
+ 3044942
qualifiableelement
- 3050545
+ 3044942
qualifyingelement
- 54656
+ 54380
location
- 558950
+ 557018
@@ -28514,7 +28572,7 @@
1
2
- 3050545
+ 3044942
@@ -28530,7 +28588,7 @@
1
2
- 3050545
+ 3044942
@@ -28546,7 +28604,7 @@
1
2
- 3050545
+ 3044942
@@ -28562,7 +28620,7 @@
1
2
- 3050545
+ 3044942
@@ -28578,7 +28636,7 @@
1
2
- 3050545
+ 3044942
@@ -28594,7 +28652,7 @@
1
2
- 3050545
+ 3044942
@@ -28610,27 +28668,22 @@
1
2
- 37913
+ 37916
2
3
- 8382
+ 8435
3
5
- 4127
+ 4132
5
- 476
- 4105
-
-
- 1600
41956
- 128
+ 3896
@@ -28646,27 +28699,22 @@
1
2
- 37913
+ 37916
2
3
- 8382
+ 8435
3
5
- 4127
+ 4132
5
- 476
- 4105
-
-
- 1600
41956
- 128
+ 3896
@@ -28682,22 +28730,22 @@
1
2
- 41441
+ 41235
2
3
- 7420
+ 7407
3
7
- 4148
+ 4132
7
20059
- 1646
+ 1605
@@ -28713,22 +28761,22 @@
1
2
- 83311
+ 84418
2
6
- 42339
+ 39008
6
7
- 396669
+ 397215
7
192
- 36630
+ 36375
@@ -28744,22 +28792,22 @@
1
2
- 83311
+ 84418
2
6
- 42339
+ 39008
6
7
- 396669
+ 397215
7
192
- 36630
+ 36375
@@ -28775,22 +28823,22 @@
1
2
- 119492
+ 117047
2
4
- 14070
+ 14066
4
5
- 412920
+ 413487
5
60
- 12466
+ 12417
@@ -28800,15 +28848,15 @@
varbind
- 8257017
+ 8252213
expr
- 8257017
+ 8252213
var
- 1050679
+ 1050068
@@ -28822,7 +28870,7 @@
1
2
- 8257017
+ 8252213
@@ -28838,52 +28886,52 @@
1
2
- 171585
+ 171485
2
3
- 188755
+ 188645
3
4
- 145690
+ 145605
4
5
- 116670
+ 116602
5
6
- 83175
+ 83126
6
7
- 65836
+ 65798
7
9
- 80838
+ 80791
9
13
- 81598
+ 81551
13
27
- 79150
+ 79103
27
5137
- 37379
+ 37357
@@ -28893,15 +28941,15 @@
funbind
- 5787669
+ 5788371
expr
- 5785316
+ 5785909
fun
- 274909
+ 275051
@@ -28915,12 +28963,12 @@
1
2
- 5782964
+ 5783447
2
3
- 2352
+ 2462
@@ -28936,27 +28984,27 @@
1
2
- 180650
+ 180848
2
3
- 38212
+ 38237
3
4
- 16764
+ 17127
4
8
- 23286
+ 23229
8
37798
- 15995
+ 15607
@@ -28966,19 +29014,19 @@
expr_allocator
- 44756
+ 44839
expr
- 44756
+ 44839
func
- 64
+ 101
form
- 21
+ 33
@@ -28992,7 +29040,7 @@
1
2
- 44756
+ 44839
@@ -29008,7 +29056,7 @@
1
2
- 44756
+ 44839
@@ -29022,19 +29070,19 @@
12
- 2
- 3
- 21
+ 1
+ 2
+ 33
- 369
- 370
- 21
+ 591
+ 592
+ 33
- 1722
- 1723
- 21
+ 736
+ 737
+ 33
@@ -29050,7 +29098,7 @@
1
2
- 64
+ 101
@@ -29064,9 +29112,9 @@
12
- 2093
- 2094
- 21
+ 1328
+ 1329
+ 33
@@ -29082,7 +29130,7 @@
3
4
- 21
+ 33
@@ -29092,15 +29140,15 @@
expr_deallocator
- 53037
+ 53347
expr
- 53037
+ 53347
func
- 100
+ 101
form
@@ -29118,7 +29166,7 @@
1
2
- 53037
+ 53347
@@ -29134,7 +29182,7 @@
1
2
- 53037
+ 53347
@@ -29176,7 +29224,7 @@
1
2
- 100
+ 101
@@ -29239,15 +29287,15 @@
expr_cond_guard
- 898137
+ 897615
cond
- 898137
+ 897615
guard
- 898137
+ 897615
@@ -29261,7 +29309,7 @@
1
2
- 898137
+ 897615
@@ -29277,7 +29325,7 @@
1
2
- 898137
+ 897615
@@ -29287,15 +29335,15 @@
expr_cond_true
- 898134
+ 897611
cond
- 898134
+ 897611
true
- 898134
+ 897611
@@ -29309,7 +29357,7 @@
1
2
- 898134
+ 897611
@@ -29325,7 +29373,7 @@
1
2
- 898134
+ 897611
@@ -29335,15 +29383,15 @@
expr_cond_false
- 898137
+ 897615
cond
- 898137
+ 897615
false
- 898137
+ 897615
@@ -29357,7 +29405,7 @@
1
2
- 898137
+ 897615
@@ -29373,7 +29421,7 @@
1
2
- 898137
+ 897615
@@ -29383,15 +29431,15 @@
values
- 13547098
+ 13539217
id
- 13547098
+ 13539217
str
- 114026
+ 113960
@@ -29405,7 +29453,7 @@
1
2
- 13547098
+ 13539217
@@ -29421,27 +29469,27 @@
1
2
- 77935
+ 77890
2
3
- 15228
+ 15220
3
6
- 8841
+ 8836
6
52
- 8587
+ 8582
52
681857
- 3432
+ 3430
@@ -29451,15 +29499,15 @@
valuetext
- 6647904
+ 6631932
id
- 6647904
+ 6631932
text
- 1095330
+ 1095191
@@ -29473,7 +29521,7 @@
1
2
- 6647904
+ 6631932
@@ -29489,22 +29537,22 @@
1
2
- 833965
+ 833960
2
3
- 146908
+ 146907
3
7
- 86571
+ 86513
7
- 593706
- 27886
+ 594510
+ 27811
@@ -29514,15 +29562,15 @@
valuebind
- 13655359
+ 13647415
val
- 13547098
+ 13539217
expr
- 13655359
+ 13647415
@@ -29536,12 +29584,12 @@
1
2
- 13456848
+ 13449020
2
6
- 90250
+ 90197
@@ -29557,7 +29605,7 @@
1
2
- 13655359
+ 13647415
@@ -29567,15 +29615,15 @@
fieldoffsets
- 1503078
+ 1502203
id
- 1503078
+ 1502203
byteoffset
- 31374
+ 31356
bitoffset
@@ -29593,7 +29641,7 @@
1
2
- 1503078
+ 1502203
@@ -29609,7 +29657,7 @@
1
2
- 1503078
+ 1502203
@@ -29625,32 +29673,32 @@
1
2
- 17702
+ 17692
2
3
- 2451
+ 2449
3
5
- 2668
+ 2667
5
12
- 2614
+ 2613
12
35
- 2396
+ 2395
35
200
- 2396
+ 2395
210
@@ -29671,7 +29719,7 @@
1
2
- 30339
+ 30321
2
@@ -29773,11 +29821,11 @@
bitfield
- 29829
+ 29835
id
- 29829
+ 29835
bits
@@ -29799,7 +29847,7 @@
1
2
- 29829
+ 29835
@@ -29815,7 +29863,7 @@
1
2
- 29829
+ 29835
@@ -29959,23 +30007,23 @@
initialisers
- 2289023
+ 2292672
init
- 2289023
+ 2292672
var
- 998370
+ 998332
expr
- 2289023
+ 2292672
location
- 525173
+ 526641
@@ -29989,7 +30037,7 @@
1
2
- 2289023
+ 2292672
@@ -30005,7 +30053,7 @@
1
2
- 2289023
+ 2292672
@@ -30021,7 +30069,7 @@
1
2
- 2289023
+ 2292672
@@ -30037,17 +30085,17 @@
1
2
- 874745
+ 874353
2
15
- 51071
+ 51217
16
25
- 72553
+ 72760
@@ -30063,17 +30111,17 @@
1
2
- 874745
+ 874353
2
15
- 51071
+ 51217
16
25
- 72553
+ 72760
@@ -30089,7 +30137,7 @@
1
2
- 998362
+ 998324
2
@@ -30110,7 +30158,7 @@
1
2
- 2289023
+ 2292672
@@ -30126,7 +30174,7 @@
1
2
- 2289023
+ 2292672
@@ -30142,7 +30190,7 @@
1
2
- 2289023
+ 2292672
@@ -30158,22 +30206,22 @@
1
2
- 414711
+ 415896
2
3
- 33393
+ 33497
3
6
- 41518
+ 41612
6
113696
- 35549
+ 35635
@@ -30189,17 +30237,17 @@
1
2
- 453031
+ 454326
2
3
- 34225
+ 34331
3
12835
- 37916
+ 37984
@@ -30215,22 +30263,22 @@
1
2
- 414711
+ 415896
2
3
- 33393
+ 33497
3
6
- 41518
+ 41612
6
113696
- 35549
+ 35635
@@ -30240,26 +30288,26 @@
braced_initialisers
- 67191
+ 67930
init
- 67191
+ 67930
expr_ancestor
- 1667335
+ 1669235
exp
- 1667335
+ 1669235
ancestor
- 834480
+ 835495
@@ -30273,7 +30321,7 @@
1
2
- 1667335
+ 1669235
@@ -30289,17 +30337,17 @@
1
2
- 16978
+ 16999
2
3
- 807494
+ 808519
3
19
- 10007
+ 9976
@@ -30309,19 +30357,19 @@
exprs
- 25217889
+ 25203218
id
- 25217889
+ 25203218
kind
- 1451
+ 1450
location
- 10588753
+ 10582593
@@ -30335,7 +30383,7 @@
1
2
- 25217889
+ 25203218
@@ -30351,7 +30399,7 @@
1
2
- 25217889
+ 25203218
@@ -30529,22 +30577,22 @@
1
2
- 8906278
+ 8901097
2
3
- 820855
+ 820377
3
16
- 797438
+ 796974
16
71733
- 64181
+ 64143
@@ -30560,17 +30608,17 @@
1
2
- 9045722
+ 9040460
2
3
- 774505
+ 774055
3
32
- 768525
+ 768078
@@ -30580,15 +30628,15 @@
expr_reuse
- 841815
+ 842839
reuse
- 841815
+ 842839
original
- 841815
+ 842839
value_category
@@ -30606,7 +30654,7 @@
1
2
- 841815
+ 842839
@@ -30622,7 +30670,7 @@
1
2
- 841815
+ 842839
@@ -30638,7 +30686,7 @@
1
2
- 841815
+ 842839
@@ -30654,7 +30702,7 @@
1
2
- 841815
+ 842839
@@ -30706,15 +30754,15 @@
expr_types
- 25217889
+ 25203218
id
- 25217889
+ 25203218
typeid
- 214267
+ 214142
value_category
@@ -30732,7 +30780,7 @@
1
2
- 25217889
+ 25203218
@@ -30748,7 +30796,7 @@
1
2
- 25217889
+ 25203218
@@ -30764,52 +30812,52 @@
1
2
- 52527
+ 52497
2
3
- 35201
+ 35181
3
4
- 14511
+ 14503
4
5
- 14533
+ 14525
5
8
- 17567
+ 17557
8
14
- 17392
+ 17381
14
24
- 16446
+ 16437
24
49
- 16072
+ 16063
49
134
- 16182
+ 16173
134
441492
- 13830
+ 13822
@@ -30825,12 +30873,12 @@
1
2
- 185969
+ 185861
2
3
- 28297
+ 28281
@@ -30893,15 +30941,15 @@
new_allocated_type
- 45518
+ 45784
expr
- 45518
+ 45784
type_id
- 26988
+ 27146
@@ -30915,7 +30963,7 @@
1
2
- 45518
+ 45784
@@ -30931,17 +30979,17 @@
1
2
- 11345
+ 11412
2
3
- 14266
+ 14349
3
19
- 1376
+ 1384
@@ -30951,15 +30999,15 @@
new_array_allocated_type
- 6597
+ 6616
expr
- 6597
+ 6616
type_id
- 2834
+ 2842
@@ -30973,7 +31021,7 @@
1
2
- 6597
+ 6616
@@ -30994,7 +31042,7 @@
2
3
- 2503
+ 2510
3
@@ -31014,30 +31062,30 @@
param_ref_to_this
- 25020
+ 25272
expr
- 25020
+ 25272
aggregate_field_init
- 5717385
+ 5720718
aggregate
- 1243071
+ 1245402
initializer
- 5717207
+ 5720540
field
- 3229
+ 3236
position
@@ -31059,12 +31107,12 @@
1
2
- 19692
+ 21021
2
3
- 669033
+ 670035
3
@@ -31110,12 +31158,12 @@
1
2
- 19688
+ 21017
2
3
- 668965
+ 669967
3
@@ -31161,12 +31209,12 @@
1
2
- 19692
+ 21021
2
3
- 669033
+ 670035
3
@@ -31212,7 +31260,7 @@
1
2
- 1242989
+ 1245320
2
@@ -31233,7 +31281,7 @@
1
2
- 5717207
+ 5720540
@@ -31249,7 +31297,7 @@
1
2
- 5717029
+ 5720362
2
@@ -31270,7 +31318,7 @@
1
2
- 5717207
+ 5720540
@@ -31286,7 +31334,7 @@
1
2
- 5717207
+ 5720540
@@ -31307,12 +31355,12 @@
2
3
- 272
+ 273
3
6
- 274
+ 275
6
@@ -31331,18 +31379,18 @@
74
- 339
- 243
+ 316
+ 244
- 353
- 252555
- 252
+ 338
+ 252258
+ 244
- 392631
+ 252554
392632
- 2
+ 14
@@ -31363,12 +31411,12 @@
2
3
- 272
+ 273
3
6
- 274
+ 275
6
@@ -31387,18 +31435,18 @@
74
- 339
- 243
+ 316
+ 244
- 353
- 252555
- 252
+ 338
+ 252258
+ 244
- 392631
+ 252554
392632
- 2
+ 14
@@ -31414,7 +31462,7 @@
1
2
- 3215
+ 3222
2
@@ -31435,7 +31483,7 @@
1
2
- 3203
+ 3210
2
@@ -31505,12 +31553,12 @@
554346
- 1223380
+ 1224382
2
- 1243071
- 1243072
+ 1245402
+ 1245403
1
@@ -31576,12 +31624,12 @@
554346
- 1223380
+ 1224382
2
- 1243071
- 1243072
+ 1245402
+ 1245403
1
@@ -31647,12 +31695,12 @@
318
- 885
+ 886
2
- 1285
- 1286
+ 1291
+ 1292
1
@@ -31688,13 +31736,13 @@
12
- 480
- 481
+ 1482
+ 1483
1
- 1242673
- 1242674
+ 1244002
+ 1244003
1
@@ -31709,13 +31757,13 @@
12
- 710
- 711
+ 1712
+ 1713
1
- 5716497
- 5716498
+ 5718828
+ 5718829
1
@@ -31730,13 +31778,13 @@
12
- 218
- 219
+ 219
+ 220
1
- 3037
- 3038
+ 3043
+ 3044
1
@@ -31768,15 +31816,15 @@
aggregate_array_init
- 1349502
+ 1353666
aggregate
- 152357
+ 153359
initializer
- 1349502
+ 1353666
element_index
@@ -31802,27 +31850,27 @@
1
2
- 14696
+ 14702
2
3
- 13903
+ 13963
3
4
- 61677
+ 61827
4
5
- 17014
+ 17356
5
6
- 19009
+ 19453
6
@@ -31831,13 +31879,13 @@
10
- 58
- 11429
+ 61
+ 11514
- 58
+ 61
62923
- 1763
+ 1678
@@ -31853,27 +31901,27 @@
1
2
- 14696
+ 14702
2
3
- 13903
+ 13963
3
4
- 61677
+ 61827
4
5
- 17014
+ 17356
5
6
- 19009
+ 19453
6
@@ -31882,13 +31930,13 @@
10
- 58
- 11429
+ 61
+ 11514
- 58
+ 61
62923
- 1763
+ 1678
@@ -31904,27 +31952,27 @@
1
2
- 14696
+ 14702
2
3
- 13903
+ 13963
3
4
- 61677
+ 61827
4
5
- 17014
+ 17356
5
6
- 19009
+ 19453
6
@@ -31933,13 +31981,13 @@
10
- 58
- 11429
+ 61
+ 11514
- 58
+ 61
62923
- 1763
+ 1678
@@ -31955,7 +32003,7 @@
1
2
- 152357
+ 153359
@@ -31971,7 +32019,7 @@
1
2
- 1349502
+ 1353666
@@ -31987,7 +32035,7 @@
1
2
- 1349502
+ 1353666
@@ -32003,7 +32051,7 @@
1
2
- 1349502
+ 1353666
@@ -32019,7 +32067,7 @@
1
2
- 1349502
+ 1353666
@@ -32059,7 +32107,7 @@
37
- 152357
+ 153359
2151
@@ -32100,7 +32148,7 @@
37
- 152357
+ 153359
2151
@@ -32183,7 +32231,7 @@
37
- 152358
+ 153360
2151
@@ -32224,7 +32272,7 @@
37
- 152358
+ 153360
2151
@@ -32286,8 +32334,8 @@
1
- 152354
- 152355
+ 153356
+ 153357
1
@@ -32307,8 +32355,8 @@
1
- 1349486
- 1349487
+ 1353650
+ 1353651
1
@@ -32361,15 +32409,15 @@
condition_decl_bind
- 406398
+ 406893
expr
- 406398
+ 406893
decl
- 406398
+ 406893
@@ -32383,7 +32431,7 @@
1
2
- 406398
+ 406893
@@ -32399,7 +32447,7 @@
1
2
- 406398
+ 406893
@@ -32409,15 +32457,15 @@
typeid_bind
- 47196
+ 47472
expr
- 47196
+ 47472
type_id
- 15709
+ 15801
@@ -32431,7 +32479,7 @@
1
2
- 47196
+ 47472
@@ -32447,17 +32495,17 @@
1
2
- 2920
+ 2937
2
3
- 12386
+ 12459
3
328
- 402
+ 405
@@ -32467,15 +32515,15 @@
uuidof_bind
- 26214
+ 26289
expr
- 26214
+ 26289
type_id
- 26214
+ 26289
@@ -32489,7 +32537,7 @@
1
2
- 26214
+ 26289
@@ -32505,7 +32553,7 @@
1
2
- 26214
+ 26289
@@ -32515,15 +32563,15 @@
sizeof_bind
- 242078
+ 241937
expr
- 242078
+ 241937
type_id
- 11156
+ 11150
@@ -32537,7 +32585,7 @@
1
2
- 242078
+ 241937
@@ -32553,17 +32601,17 @@
1
2
- 3859
+ 3856
2
3
- 2753
+ 2751
3
4
- 1019
+ 1018
4
@@ -32578,17 +32626,17 @@
6
7
- 1117
+ 1116
7
42
- 852
+ 851
42
6061
- 167
+ 166
@@ -32646,11 +32694,11 @@
lambdas
- 18970
+ 19024
expr
- 18970
+ 19024
default_capture
@@ -32676,7 +32724,7 @@
1
2
- 18970
+ 19024
@@ -32692,7 +32740,7 @@
1
2
- 18970
+ 19024
@@ -32708,7 +32756,7 @@
1
2
- 18970
+ 19024
@@ -32892,15 +32940,15 @@
lambda_capture
- 31810
+ 31901
id
- 31810
+ 31901
lambda
- 15424
+ 15468
index
@@ -32908,7 +32956,7 @@
field
- 31810
+ 31901
captured_by_reference
@@ -32920,7 +32968,7 @@
location
- 17888
+ 17939
@@ -32934,7 +32982,7 @@
1
2
- 31810
+ 31901
@@ -32950,7 +32998,7 @@
1
2
- 31810
+ 31901
@@ -32966,7 +33014,7 @@
1
2
- 31810
+ 31901
@@ -32982,7 +33030,7 @@
1
2
- 31810
+ 31901
@@ -32998,7 +33046,7 @@
1
2
- 31810
+ 31901
@@ -33014,7 +33062,7 @@
1
2
- 31810
+ 31901
@@ -33030,27 +33078,27 @@
1
2
- 8156
+ 8179
2
3
- 3545
+ 3555
3
4
- 1663
+ 1668
4
6
- 1251
+ 1255
6
18
- 807
+ 809
@@ -33066,27 +33114,27 @@
1
2
- 8156
+ 8179
2
3
- 3545
+ 3555
3
4
- 1663
+ 1668
4
6
- 1251
+ 1255
6
18
- 807
+ 809
@@ -33102,27 +33150,27 @@
1
2
- 8156
+ 8179
2
3
- 3545
+ 3555
3
4
- 1663
+ 1668
4
6
- 1251
+ 1255
6
18
- 807
+ 809
@@ -33138,12 +33186,12 @@
1
2
- 14189
+ 14229
2
3
- 1235
+ 1239
@@ -33159,7 +33207,7 @@
1
2
- 15303
+ 15347
2
@@ -33180,27 +33228,27 @@
1
2
- 8746
+ 8771
2
3
- 3698
+ 3709
3
4
- 1397
+ 1401
4
7
- 1284
+ 1287
7
18
- 298
+ 299
@@ -33509,7 +33557,7 @@
2
3
- 104
+ 105
@@ -33525,7 +33573,7 @@
1
2
- 88
+ 89
2
@@ -33642,7 +33690,7 @@
1
2
- 31810
+ 31901
@@ -33658,7 +33706,7 @@
1
2
- 31810
+ 31901
@@ -33674,7 +33722,7 @@
1
2
- 31810
+ 31901
@@ -33690,7 +33738,7 @@
1
2
- 31810
+ 31901
@@ -33706,7 +33754,7 @@
1
2
- 31810
+ 31901
@@ -33722,7 +33770,7 @@
1
2
- 31810
+ 31901
@@ -33980,17 +34028,17 @@
1
2
- 15667
+ 15711
2
6
- 1413
+ 1417
6
68
- 807
+ 809
@@ -34006,17 +34054,17 @@
1
2
- 16240
+ 16286
2
13
- 1445
+ 1449
13
68
- 201
+ 202
@@ -34032,12 +34080,12 @@
1
2
- 17201
+ 17250
2
8
- 686
+ 688
@@ -34053,17 +34101,17 @@
1
2
- 15667
+ 15711
2
6
- 1413
+ 1417
6
68
- 807
+ 809
@@ -34079,7 +34127,7 @@
1
2
- 17863
+ 17914
2
@@ -34100,7 +34148,7 @@
1
2
- 17888
+ 17939
@@ -34110,11 +34158,11 @@
fold
- 1261
+ 1263
expr
- 1261
+ 1263
operator
@@ -34136,7 +34184,7 @@
1
2
- 1261
+ 1263
@@ -34152,7 +34200,7 @@
1
2
- 1261
+ 1263
@@ -34236,11 +34284,11 @@
stmts
- 6310367
+ 6328585
id
- 6310367
+ 6328585
kind
@@ -34248,7 +34296,7 @@
location
- 2668742
+ 2676368
@@ -34262,7 +34310,7 @@
1
2
- 6310367
+ 6328585
@@ -34278,7 +34326,7 @@
1
2
- 6310367
+ 6328585
@@ -34367,28 +34415,28 @@
8
- 74923
- 74924
+ 74926
+ 74927
8
- 95366
- 95367
+ 95367
+ 95368
8
- 117878
- 117879
+ 117880
+ 117881
8
- 198406
- 198407
+ 198412
+ 198413
8
- 213672
- 213673
+ 213683
+ 213684
8
@@ -34516,22 +34564,22 @@
1
2
- 2218981
+ 2225135
2
3
- 177039
+ 177731
3
11
- 202889
+ 203469
11
1816
- 69832
+ 70031
@@ -34547,12 +34595,12 @@
1
2
- 2592497
+ 2599906
2
10
- 76244
+ 76462
@@ -34717,15 +34765,15 @@
if_then
- 990500
+ 989924
if_stmt
- 990500
+ 989924
then_id
- 990500
+ 989924
@@ -34739,7 +34787,7 @@
1
2
- 990500
+ 989924
@@ -34755,7 +34803,7 @@
1
2
- 990500
+ 989924
@@ -34765,15 +34813,15 @@
if_else
- 434390
+ 434918
if_stmt
- 434390
+ 434918
else_id
- 434390
+ 434918
@@ -34787,7 +34835,7 @@
1
2
- 434390
+ 434918
@@ -34803,7 +34851,7 @@
1
2
- 434390
+ 434918
@@ -34861,15 +34909,15 @@
constexpr_if_then
- 103236
+ 103258
constexpr_if_stmt
- 103236
+ 103258
then_id
- 103236
+ 103258
@@ -34883,7 +34931,7 @@
1
2
- 103236
+ 103258
@@ -34899,7 +34947,7 @@
1
2
- 103236
+ 103258
@@ -34909,15 +34957,15 @@
constexpr_if_else
- 74021
+ 74036
constexpr_if_stmt
- 74021
+ 74036
else_id
- 74021
+ 74036
@@ -34931,7 +34979,7 @@
1
2
- 74021
+ 74036
@@ -34947,7 +34995,7 @@
1
2
- 74021
+ 74036
@@ -35053,15 +35101,15 @@
while_body
- 39659
+ 39636
while_stmt
- 39659
+ 39636
body_id
- 39659
+ 39636
@@ -35075,7 +35123,7 @@
1
2
- 39659
+ 39636
@@ -35091,7 +35139,7 @@
1
2
- 39659
+ 39636
@@ -35101,15 +35149,15 @@
do_body
- 232528
+ 232393
do_stmt
- 232528
+ 232393
body_id
- 232528
+ 232393
@@ -35123,7 +35171,7 @@
1
2
- 232528
+ 232393
@@ -35139,7 +35187,7 @@
1
2
- 232528
+ 232393
@@ -35197,19 +35245,19 @@
switch_case
- 830952
+ 831962
switch_stmt
- 409306
+ 409804
index
- 384
+ 385
case_id
- 830952
+ 831962
@@ -35228,12 +35276,12 @@
2
3
- 406441
+ 406935
3
19
- 2844
+ 2847
@@ -35254,12 +35302,12 @@
2
3
- 406441
+ 406935
3
19
- 2844
+ 2847
@@ -35417,7 +35465,7 @@
1
2
- 830952
+ 831962
@@ -35433,7 +35481,7 @@
1
2
- 830952
+ 831962
@@ -35443,15 +35491,15 @@
switch_body
- 409306
+ 409804
switch_stmt
- 409306
+ 409804
body_id
- 409306
+ 409804
@@ -35465,7 +35513,7 @@
1
2
- 409306
+ 409804
@@ -35481,7 +35529,7 @@
1
2
- 409306
+ 409804
@@ -35491,15 +35539,15 @@
for_initialization
- 73267
+ 73224
for_stmt
- 73267
+ 73224
init_id
- 73267
+ 73224
@@ -35513,7 +35561,7 @@
1
2
- 73267
+ 73224
@@ -35529,7 +35577,7 @@
1
2
- 73267
+ 73224
@@ -35539,15 +35587,15 @@
for_condition
- 76363
+ 76319
for_stmt
- 76363
+ 76319
condition_id
- 76363
+ 76319
@@ -35561,7 +35609,7 @@
1
2
- 76363
+ 76319
@@ -35577,7 +35625,7 @@
1
2
- 76363
+ 76319
@@ -35587,15 +35635,15 @@
for_update
- 73407
+ 73365
for_stmt
- 73407
+ 73365
update_id
- 73407
+ 73365
@@ -35609,7 +35657,7 @@
1
2
- 73407
+ 73365
@@ -35625,7 +35673,7 @@
1
2
- 73407
+ 73365
@@ -35635,15 +35683,15 @@
for_body
- 84413
+ 84364
for_stmt
- 84413
+ 84364
body_id
- 84413
+ 84364
@@ -35657,7 +35705,7 @@
1
2
- 84413
+ 84364
@@ -35673,7 +35721,7 @@
1
2
- 84413
+ 84364
@@ -35683,19 +35731,19 @@
stmtparents
- 5589515
+ 5605658
id
- 5589515
+ 5605658
index
- 15683
+ 15728
parent
- 2355552
+ 2362355
@@ -35709,7 +35757,7 @@
1
2
- 5589515
+ 5605658
@@ -35725,7 +35773,7 @@
1
2
- 5589515
+ 5605658
@@ -35741,52 +35789,52 @@
1
2
- 5152
+ 5167
2
3
- 1284
+ 1287
3
4
- 266
+ 267
4
5
- 2010
+ 2016
7
8
- 1308
+ 1312
8
12
- 1017
+ 1020
12
29
- 1380
+ 1384
29
39
- 1179
+ 1182
42
78
- 1187
+ 1190
78
- 207977
- 896
+ 207983
+ 898
@@ -35802,52 +35850,52 @@
1
2
- 5152
+ 5167
2
3
- 1284
+ 1287
3
4
- 266
+ 267
4
5
- 2010
+ 2016
7
8
- 1308
+ 1312
8
12
- 1017
+ 1020
12
29
- 1380
+ 1384
29
39
- 1179
+ 1182
42
78
- 1187
+ 1190
78
- 207977
- 896
+ 207983
+ 898
@@ -35863,32 +35911,32 @@
1
2
- 1338178
+ 1342027
2
3
- 514505
+ 516007
3
4
- 150687
+ 151118
4
6
- 154814
+ 155272
6
16
- 178500
+ 179010
16
1943
- 18865
+ 18919
@@ -35904,32 +35952,32 @@
1
2
- 1338178
+ 1342027
2
3
- 514505
+ 516007
3
4
- 150687
+ 151118
4
6
- 154814
+ 155272
6
16
- 178500
+ 179010
16
1943
- 18865
+ 18919
@@ -35939,30 +35987,30 @@
ishandler
- 42985
+ 43502
block
- 42985
+ 43502
stmt_decl_bind
- 724033
+ 728652
stmt
- 713534
+ 688271
num
- 72
+ 125
decl
- 724033
+ 728583
@@ -35976,12 +36024,12 @@
1
2
- 706121
+ 666111
2
- 10
- 7413
+ 32
+ 22160
@@ -35997,12 +36045,12 @@
1
2
- 706121
+ 666111
2
- 10
- 7413
+ 32
+ 22160
@@ -36016,48 +36064,53 @@
12
- 14
- 15
+ 1
+ 2
+ 52
+
+
+ 2
+ 3
8
- 15
- 16
+ 3
+ 5
8
- 18
- 19
+ 7
+ 11
8
- 21
- 22
+ 11
+ 15
8
- 25
- 26
+ 21
+ 45
8
- 60
- 61
+ 86
+ 121
8
- 229
- 230
+ 205
+ 357
8
- 918
- 919
+ 1067
+ 2544
8
- 88354
- 88355
+ 5483
+ 170293
8
@@ -36072,48 +36125,53 @@
12
- 14
- 15
+ 1
+ 2
+ 52
+
+
+ 2
+ 3
8
- 15
- 16
+ 3
+ 5
8
- 18
- 19
+ 7
+ 11
8
- 21
- 22
+ 11
+ 15
8
- 25
- 26
+ 21
+ 45
8
- 60
- 61
+ 86
+ 121
8
- 229
- 230
+ 205
+ 357
8
- 918
- 919
+ 1067
+ 2544
8
- 88354
- 88355
+ 5483
+ 170276
8
@@ -36130,7 +36188,12 @@
1
2
- 724033
+ 728559
+
+
+ 2
+ 8
+ 24
@@ -36146,7 +36209,7 @@
1
2
- 724033
+ 728583
@@ -36156,19 +36219,19 @@
stmt_decl_entry_bind
- 724033
+ 728652
stmt
- 713534
+ 688271
num
- 72
+ 125
decl_entry
- 724033
+ 728652
@@ -36182,12 +36245,12 @@
1
2
- 706121
+ 666111
2
- 10
- 7413
+ 32
+ 22160
@@ -36203,12 +36266,12 @@
1
2
- 706121
+ 666111
2
- 10
- 7413
+ 32
+ 22160
@@ -36222,48 +36285,53 @@
12
- 14
- 15
+ 1
+ 2
+ 52
+
+
+ 2
+ 3
8
- 15
- 16
+ 3
+ 5
8
- 18
- 19
+ 7
+ 11
8
- 21
- 22
+ 11
+ 15
8
- 25
- 26
+ 21
+ 45
8
- 60
- 61
+ 86
+ 121
8
- 229
- 230
+ 205
+ 357
8
- 918
- 919
+ 1067
+ 2544
8
- 88354
- 88355
+ 5483
+ 170293
8
@@ -36278,48 +36346,53 @@
12
- 14
- 15
+ 1
+ 2
+ 52
+
+
+ 2
+ 3
8
- 15
- 16
+ 3
+ 5
8
- 18
- 19
+ 7
+ 11
8
- 21
- 22
+ 11
+ 15
8
- 25
- 26
+ 21
+ 45
8
- 60
- 61
+ 86
+ 121
8
- 229
- 230
+ 205
+ 357
8
- 918
- 919
+ 1067
+ 2544
8
- 88354
- 88355
+ 5483
+ 170293
8
@@ -36336,7 +36409,7 @@
1
2
- 724033
+ 728652
@@ -36352,7 +36425,7 @@
1
2
- 724033
+ 728652
@@ -36362,15 +36435,15 @@
blockscope
- 1614225
+ 1625740
block
- 1614225
+ 1625740
enclosing
- 1400877
+ 1404735
@@ -36384,7 +36457,7 @@
1
2
- 1614225
+ 1625740
@@ -36400,17 +36473,17 @@
1
2
- 1270635
+ 1267589
2
4
- 115144
+ 122044
4
29
- 15098
+ 15102
@@ -36420,19 +36493,19 @@
jumpinfo
- 348275
+ 348073
id
- 348275
+ 348073
str
- 28944
+ 28928
target
- 72696
+ 72654
@@ -36446,7 +36519,7 @@
1
2
- 348275
+ 348073
@@ -36462,7 +36535,7 @@
1
2
- 348275
+ 348073
@@ -36478,32 +36551,32 @@
2
3
- 13595
+ 13587
3
4
- 6058
+ 6054
4
5
- 2013
+ 2012
5
6
- 1888
+ 1887
6
10
- 2197
+ 2196
10
25
- 2189
+ 2187
25
@@ -36524,17 +36597,17 @@
1
2
- 23187
+ 23174
2
3
- 3626
+ 3624
3
3321
- 2130
+ 2129
@@ -36555,27 +36628,27 @@
2
3
- 36206
+ 36185
3
4
- 17631
+ 17620
4
5
- 7378
+ 7374
5
8
- 6417
+ 6413
8
2124
- 5030
+ 5027
@@ -36591,7 +36664,7 @@
1
2
- 72696
+ 72654
@@ -36601,11 +36674,11 @@
preprocdirects
- 5321789
+ 5322916
id
- 5321789
+ 5322916
kind
@@ -36613,7 +36686,7 @@
location
- 5318720
+ 5319847
@@ -36627,7 +36700,7 @@
1
2
- 5321789
+ 5322916
@@ -36643,7 +36716,7 @@
1
2
- 5321789
+ 5322916
@@ -36791,7 +36864,7 @@
1
2
- 5318597
+ 5319724
26
@@ -36812,7 +36885,7 @@
1
2
- 5318720
+ 5319847
@@ -36822,15 +36895,15 @@
preprocpair
- 1122961
+ 1123198
begin
- 874750
+ 874936
elseelifend
- 1122961
+ 1123198
@@ -36844,17 +36917,17 @@
1
2
- 639184
+ 639319
2
3
- 226728
+ 226776
3
9
- 8838
+ 8840
@@ -36870,7 +36943,7 @@
1
2
- 1122961
+ 1123198
@@ -36880,41 +36953,41 @@
preproctrue
- 432219
+ 432311
branch
- 432219
+ 432311
preprocfalse
- 280740
+ 280799
branch
- 280740
+ 280799
preproctext
- 4282669
+ 4283577
id
- 4282669
+ 4283577
head
- 2907815
+ 2908431
body
- 1656453
+ 1656804
@@ -36928,7 +37001,7 @@
1
2
- 4282669
+ 4283577
@@ -36944,7 +37017,7 @@
1
2
- 4282669
+ 4283577
@@ -36960,12 +37033,12 @@
1
2
- 2712390
+ 2712964
2
798
- 195425
+ 195467
@@ -36981,12 +37054,12 @@
1
2
- 2827902
+ 2828501
2
5
- 79913
+ 79930
@@ -37002,17 +37075,17 @@
1
2
- 1510620
+ 1510940
2
10
- 125209
+ 125236
10
13605
- 20622
+ 20627
@@ -37028,17 +37101,17 @@
1
2
- 1514794
+ 1515115
2
12
- 124841
+ 124868
12
3246
- 16817
+ 16820
@@ -37048,15 +37121,15 @@
includes
- 316459
+ 322460
id
- 316459
+ 322460
included
- 58294
+ 59399
@@ -37070,7 +37143,7 @@
1
2
- 316459
+ 322460
@@ -37086,37 +37159,37 @@
1
2
- 28848
+ 29395
2
3
- 9378
+ 9556
3
4
- 4919
+ 5013
4
6
- 5318
+ 5419
6
11
- 4489
+ 4574
11
47
- 4374
+ 4457
47
793
- 965
+ 983
@@ -37174,15 +37247,15 @@
link_targets
- 817
+ 816
id
- 817
+ 816
binary
- 817
+ 816
@@ -37196,7 +37269,7 @@
1
2
- 817
+ 816
@@ -37212,7 +37285,7 @@
1
2
- 817
+ 816
@@ -37222,15 +37295,15 @@
link_parent
- 30993807
+ 31162056
element
- 3938571
+ 3960190
link_target
- 335
+ 337
@@ -37244,17 +37317,17 @@
1
2
- 537390
+ 540567
2
9
- 27022
+ 27180
9
10
- 3374158
+ 3392442
@@ -37273,48 +37346,48 @@
33
- 100775
- 100776
+ 100732
+ 100733
33
- 100895
- 100896
+ 100852
+ 100853
33
- 100953
- 100954
+ 100910
+ 100911
33
- 100974
- 100975
+ 100931
+ 100932
33
- 100996
- 100997
+ 100953
+ 100954
33
- 101038
- 101039
+ 100995
+ 100996
33
- 103041
- 103042
+ 102998
+ 102999
33
- 106539
- 106540
+ 106496
+ 106497
33
- 108099
- 108100
+ 108057
+ 108058
33
diff --git a/cpp/ql/lib/upgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme b/cpp/ql/lib/upgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme
new file mode 100644
index 000000000000..0853f43dc8c0
--- /dev/null
+++ b/cpp/ql/lib/upgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme
@@ -0,0 +1,2578 @@
+
+/*- Compilations -*/
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- Diagnostic messages -*/
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+/*- C++ dbscheme -*/
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+/**
+ * Gives the TRAP filename that `trap` is associated with.
+ * For debugging only.
+ */
+trap_filename(
+ int trap: @trap,
+ string filename: string ref
+);
+
+/**
+ * Gives the tag name for `tag`.
+ * For debugging only.
+ */
+tag_name(
+ int tag: @tag,
+ string name: string ref
+);
+
+@trap_or_tag = @tag | @trap;
+
+/**
+ * Gives the name for the source file.
+ */
+source_file_name(
+ int sf: @source_file,
+ string name: string ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that `source_file`
+ * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the
+ * TRAP file corresponding to `foo.c`, something it transitively
+ * includes, or a template instantiation it transitively uses.
+ */
+source_file_uses_trap(
+ int source_file: @source_file ref,
+ int trap_file: @trap ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that the TRAP file
+ * `trap_file` uses tag `tag`.
+ */
+trap_uses_tag(
+ int trap_file: @trap ref,
+ int tag: @tag ref
+);
+
+/**
+ * Holds if there is a definition of `element` in TRAP file or tag `t`.
+ */
+in_trap_or_tag(
+ int element: @element ref,
+ int t: @trap_or_tag ref
+);
+
+pch_uses(
+ int pch: @pch ref,
+ int compilation: @compilation ref,
+ int id: @file ref
+)
+
+#keyset[pch, compilation]
+pch_creations(
+ int pch: @pch,
+ int compilation: @compilation ref,
+ int from: @file ref
+)
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location_default ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+case @function.kind of
+ 0 = @unknown_function
+| 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+builtin_functions(
+ int id: @function ref
+)
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+// ... 40 _Decimal32
+// ... 41 _Decimal64
+// ... 42 _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+| 63 = @scalable_vector_count // __SVCount_t
+| 64 = @complex_fp16 // _Complex __fp16
+| 65 = @complex_std_bfloat16 // _Complex __bf16
+| 66 = @complex_std_float16 // _Complex std::float16_t
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+| 11 = @scalable_vector // Arm SVE
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+tupleelements(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+case @type_operator.kind of
+ 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+case @usertype.kind of
+ 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+class_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+)
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location_default ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+function_template_generated_from(
+ unique int template: @function ref,
+ int from: @function ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+variable_template_generated_from(
+ unique int template: @variable ref,
+ int from: @variable ref
+);
+
+is_alias_template(unique int id: @usertype ref);
+alias_instantiation(
+ unique int to: @usertype ref,
+ int from: @usertype ref
+);
+alias_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+alias_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+alias_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+namespaceattributes(
+ int namespace_id: @namespace ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype
+ | @decltype
+ | @derivedtype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_default ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+| 394 = @isinvocable
+| 395 = @isnothrowinvocable
+| 396 = @isbitwisecloneable
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ | @isinvocable
+ | @isnothrowinvocable
+ | @isbitwisecloneable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+param_ref_to_this(
+ int expr: @param_ref ref
+)
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 17 = @ppd_embed
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+embeds(
+ unique int id: @ppd_embed ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- Database metadata -*/
+
+/**
+ * The CLI will automatically emit applicable tuples for this table,
+ * such as `databaseMetadata("isOverlay", "true")` when building an
+ * overlay database.
+ */
+databaseMetadata(
+ string metadataKey: string ref,
+ string value: string ref
+);
+
+/*- Overlay support -*/
+
+/**
+ * The CLI will automatically emit tuples for each new/modified/deleted file
+ * when building an overlay database.
+ */
+overlayChangedFiles(
+ string path: string ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/ql/lib/upgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..6aec212e408f
--- /dev/null
+++ b/cpp/ql/lib/upgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/semmlecode.cpp.dbscheme
@@ -0,0 +1,2588 @@
+
+/*- Compilations -*/
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- Diagnostic messages -*/
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+/*- C++ dbscheme -*/
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+/**
+ * Gives the TRAP filename that `trap` is associated with.
+ * For debugging only.
+ */
+trap_filename(
+ int trap: @trap,
+ string filename: string ref
+);
+
+/**
+ * Gives the tag name for `tag`.
+ * For debugging only.
+ */
+tag_name(
+ int tag: @tag,
+ string name: string ref
+);
+
+@trap_or_tag = @tag | @trap;
+
+/**
+ * Gives the name for the source file.
+ */
+source_file_name(
+ int sf: @source_file,
+ string name: string ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that `source_file`
+ * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the
+ * TRAP file corresponding to `foo.c`, something it transitively
+ * includes, or a template instantiation it transitively uses.
+ */
+source_file_uses_trap(
+ int source_file: @source_file ref,
+ int trap_file: @trap ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that the TRAP file
+ * `trap_file` uses tag `tag`.
+ */
+trap_uses_tag(
+ int trap_file: @trap ref,
+ int tag: @tag ref
+);
+
+/**
+ * Holds if there is a definition of `element` in TRAP file or tag `t`.
+ */
+in_trap_or_tag(
+ int element: @element ref,
+ int t: @trap_or_tag ref
+);
+
+pch_uses(
+ int pch: @pch ref,
+ int compilation: @compilation ref,
+ int id: @file ref
+)
+
+#keyset[pch, compilation]
+pch_creations(
+ int pch: @pch,
+ int compilation: @compilation ref,
+ int from: @file ref
+)
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location_default ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+case @function.kind of
+ 0 = @unknown_function
+| 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+builtin_functions(
+ int id: @function ref
+)
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+// ... 40 _Decimal32
+// ... 41 _Decimal64
+// ... 42 _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+| 63 = @scalable_vector_count // __SVCount_t
+| 64 = @complex_fp16 // _Complex __fp16
+| 65 = @complex_std_bfloat16 // _Complex __bf16
+| 66 = @complex_std_float16 // _Complex std::float16_t
+| 67 = @bit_precise_int // _BitInt(N)
+| 68 = @unsigned_bit_precise_int // unsigned _BitInt(N)
+| 69 = @signed_bit_precise_int // signed _BitInt(N)
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+bit_precise_int_types(
+ unique int id: @builtintype ref,
+ int bit_width: int ref
+)
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+| 11 = @scalable_vector // Arm SVE
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(
+ unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+tupleelements(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+case @type_operator.kind of
+ 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+case @usertype.kind of
+ 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+class_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+)
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location_default ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+function_template_generated_from(
+ unique int template: @function ref,
+ int from: @function ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+variable_template_generated_from(
+ unique int template: @variable ref,
+ int from: @variable ref
+);
+
+is_alias_template(unique int id: @usertype ref);
+alias_instantiation(
+ unique int to: @usertype ref,
+ int from: @usertype ref
+);
+alias_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+alias_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+alias_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+namespaceattributes(
+ int namespace_id: @namespace ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype
+ | @decltype
+ | @derivedtype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_default ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+| 394 = @isinvocable
+| 395 = @isnothrowinvocable
+| 396 = @isbitwisecloneable
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ | @isinvocable
+ | @isnothrowinvocable
+ | @isbitwisecloneable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+param_ref_to_this(
+ int expr: @param_ref ref
+)
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 17 = @ppd_embed
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+embeds(
+ unique int id: @ppd_embed ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- Database metadata -*/
+
+/**
+ * The CLI will automatically emit applicable tuples for this table,
+ * such as `databaseMetadata("isOverlay", "true")` when building an
+ * overlay database.
+ */
+databaseMetadata(
+ string metadataKey: string ref,
+ string value: string ref
+);
+
+/*- Overlay support -*/
+
+/**
+ * The CLI will automatically emit tuples for each new/modified/deleted file
+ * when building an overlay database.
+ */
+overlayChangedFiles(
+ string path: string ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/ql/lib/upgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/upgrade.properties b/cpp/ql/lib/upgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/upgrade.properties
new file mode 100644
index 000000000000..92084ebe9ad6
--- /dev/null
+++ b/cpp/ql/lib/upgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/upgrade.properties
@@ -0,0 +1,2 @@
+description: Support C23 _BitInt
+compatibility: partial
diff --git a/cpp/ql/lib/upgrades/6aec212e408fad907b19368a3376a4d9837783d2/old.dbscheme b/cpp/ql/lib/upgrades/6aec212e408fad907b19368a3376a4d9837783d2/old.dbscheme
new file mode 100644
index 000000000000..6aec212e408f
--- /dev/null
+++ b/cpp/ql/lib/upgrades/6aec212e408fad907b19368a3376a4d9837783d2/old.dbscheme
@@ -0,0 +1,2588 @@
+
+/*- Compilations -*/
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- Diagnostic messages -*/
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+/*- C++ dbscheme -*/
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+/**
+ * Gives the TRAP filename that `trap` is associated with.
+ * For debugging only.
+ */
+trap_filename(
+ int trap: @trap,
+ string filename: string ref
+);
+
+/**
+ * Gives the tag name for `tag`.
+ * For debugging only.
+ */
+tag_name(
+ int tag: @tag,
+ string name: string ref
+);
+
+@trap_or_tag = @tag | @trap;
+
+/**
+ * Gives the name for the source file.
+ */
+source_file_name(
+ int sf: @source_file,
+ string name: string ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that `source_file`
+ * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the
+ * TRAP file corresponding to `foo.c`, something it transitively
+ * includes, or a template instantiation it transitively uses.
+ */
+source_file_uses_trap(
+ int source_file: @source_file ref,
+ int trap_file: @trap ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that the TRAP file
+ * `trap_file` uses tag `tag`.
+ */
+trap_uses_tag(
+ int trap_file: @trap ref,
+ int tag: @tag ref
+);
+
+/**
+ * Holds if there is a definition of `element` in TRAP file or tag `t`.
+ */
+in_trap_or_tag(
+ int element: @element ref,
+ int t: @trap_or_tag ref
+);
+
+pch_uses(
+ int pch: @pch ref,
+ int compilation: @compilation ref,
+ int id: @file ref
+)
+
+#keyset[pch, compilation]
+pch_creations(
+ int pch: @pch,
+ int compilation: @compilation ref,
+ int from: @file ref
+)
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location_default ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+case @function.kind of
+ 0 = @unknown_function
+| 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+builtin_functions(
+ int id: @function ref
+)
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+// ... 40 _Decimal32
+// ... 41 _Decimal64
+// ... 42 _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+| 63 = @scalable_vector_count // __SVCount_t
+| 64 = @complex_fp16 // _Complex __fp16
+| 65 = @complex_std_bfloat16 // _Complex __bf16
+| 66 = @complex_std_float16 // _Complex std::float16_t
+| 67 = @bit_precise_int // _BitInt(N)
+| 68 = @unsigned_bit_precise_int // unsigned _BitInt(N)
+| 69 = @signed_bit_precise_int // signed _BitInt(N)
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+bit_precise_int_types(
+ unique int id: @builtintype ref,
+ int bit_width: int ref
+)
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+| 11 = @scalable_vector // Arm SVE
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(
+ unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+tupleelements(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+case @type_operator.kind of
+ 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+case @usertype.kind of
+ 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+class_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+)
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location_default ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+function_template_generated_from(
+ unique int template: @function ref,
+ int from: @function ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+variable_template_generated_from(
+ unique int template: @variable ref,
+ int from: @variable ref
+);
+
+is_alias_template(unique int id: @usertype ref);
+alias_instantiation(
+ unique int to: @usertype ref,
+ int from: @usertype ref
+);
+alias_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+alias_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+alias_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+namespaceattributes(
+ int namespace_id: @namespace ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype
+ | @decltype
+ | @derivedtype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_default ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+| 394 = @isinvocable
+| 395 = @isnothrowinvocable
+| 396 = @isbitwisecloneable
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ | @isinvocable
+ | @isnothrowinvocable
+ | @isbitwisecloneable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+param_ref_to_this(
+ int expr: @param_ref ref
+)
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 17 = @ppd_embed
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+embeds(
+ unique int id: @ppd_embed ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- Database metadata -*/
+
+/**
+ * The CLI will automatically emit applicable tuples for this table,
+ * such as `databaseMetadata("isOverlay", "true")` when building an
+ * overlay database.
+ */
+databaseMetadata(
+ string metadataKey: string ref,
+ string value: string ref
+);
+
+/*- Overlay support -*/
+
+/**
+ * The CLI will automatically emit tuples for each new/modified/deleted file
+ * when building an overlay database.
+ */
+overlayChangedFiles(
+ string path: string ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/ql/lib/upgrades/6aec212e408fad907b19368a3376a4d9837783d2/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/6aec212e408fad907b19368a3376a4d9837783d2/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..293904928d85
--- /dev/null
+++ b/cpp/ql/lib/upgrades/6aec212e408fad907b19368a3376a4d9837783d2/semmlecode.cpp.dbscheme
@@ -0,0 +1,2602 @@
+
+/*- Compilations -*/
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The expanded arguments that were passed to the extractor for a
+ * compiler invocation. This is similar to `compilation_args`, but
+ * for a `@someFile` argument, it includes the arguments from that
+ * file, rather than just taking the argument literally.
+ */
+#keyset[id, num]
+compilation_expanded_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*- External data -*/
+
+/**
+ * External data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/*- Source location prefix -*/
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/*- Files and folders -*/
+
+/**
+ * The location of an element.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @file | @folder
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+/*- Lines of code -*/
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref
+);
+
+/*- Diagnostic messages -*/
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+/*- C++ dbscheme -*/
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+/**
+ * Gives the TRAP filename that `trap` is associated with.
+ * For debugging only.
+ */
+trap_filename(
+ int trap: @trap,
+ string filename: string ref
+);
+
+/**
+ * Gives the tag name for `tag`.
+ * For debugging only.
+ */
+tag_name(
+ int tag: @tag,
+ string name: string ref
+);
+
+@trap_or_tag = @tag | @trap;
+
+/**
+ * Gives the name for the source file.
+ */
+source_file_name(
+ int sf: @source_file,
+ string name: string ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that `source_file`
+ * (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the
+ * TRAP file corresponding to `foo.c`, something it transitively
+ * includes, or a template instantiation it transitively uses.
+ */
+source_file_uses_trap(
+ int source_file: @source_file ref,
+ int trap_file: @trap ref
+);
+
+/**
+ * In `build-mode: none` overlay mode, indicates that the TRAP file
+ * `trap_file` uses tag `tag`.
+ */
+trap_uses_tag(
+ int trap_file: @trap ref,
+ int tag: @tag ref
+);
+
+/**
+ * Holds if there is a definition of `element` in TRAP file or tag `t`.
+ */
+in_trap_or_tag(
+ int element: @element ref,
+ int t: @trap_or_tag ref
+);
+
+pch_uses(
+ int pch: @pch ref,
+ int compilation: @compilation ref,
+ int id: @file ref
+)
+
+#keyset[pch, compilation]
+pch_creations(
+ int pch: @pch,
+ int compilation: @compilation ref,
+ int from: @file ref
+)
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location_default ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+case @function.kind of
+ 0 = @unknown_function
+| 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+builtin_functions(
+ int id: @function ref
+)
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+// ... 40 _Decimal32
+// ... 41 _Decimal64
+// ... 42 _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+| 63 = @scalable_vector_count // __SVCount_t
+| 64 = @complex_fp16 // _Complex __fp16
+| 65 = @complex_std_bfloat16 // _Complex __bf16
+| 66 = @complex_std_float16 // _Complex std::float16_t
+| 67 = @bit_precise_int // _BitInt(N)
+| 68 = @unsigned_bit_precise_int // unsigned _BitInt(N)
+| 69 = @signed_bit_precise_int // signed _BitInt(N)
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+bit_precise_int_types(
+ unique int id: @builtintype ref,
+ int bit_width: int ref
+)
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+| 11 = @scalable_vector // Arm SVE
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(
+ unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+tupleelements(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+case @type_operator.kind of
+ 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+case @usertype.kind of
+ 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+class_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+)
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location_default ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+function_template_generated_from(
+ unique int template: @function ref,
+ int from: @function ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+variable_template_generated_from(
+ unique int template: @variable ref,
+ int from: @variable ref
+);
+
+is_alias_template(unique int id: @usertype ref);
+alias_instantiation(
+ unique int to: @usertype ref,
+ int from: @usertype ref
+);
+alias_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+alias_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+alias_template_generated_from(
+ unique int template: @usertype ref,
+ int from: @usertype ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+namespaceattributes(
+ int namespace_id: @namespace ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype
+ | @decltype
+ | @derivedtype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_default ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+| 394 = @isinvocable
+| 395 = @isnothrowinvocable
+| 396 = @isbitwisecloneable
+| 397 = @isvirtualbaseof
+| 398 = @isimplicitlifetime
+| 399 = @ltsynthesizesfromspaceship
+| 400 = @gtsynthesizesfromspaceship
+| 401 = @lesynthesizesfromspaceship
+| 402 = @gesynthesizesfromspaceship
+| 403 = @isstructural
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ | @isinvocable
+ | @isnothrowinvocable
+ | @isbitwisecloneable
+ | @isvirtualbaseof
+ | @isimplicitlifetime
+ | @ltsynthesizesfromspaceship
+ | @gtsynthesizesfromspaceship
+ | @lesynthesizesfromspaceship
+ | @gesynthesizesfromspaceship
+ | @isstructural
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+param_ref_to_this(
+ int expr: @param_ref ref
+)
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_default ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 17 = @ppd_embed
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+embeds(
+ unique int id: @ppd_embed ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- Database metadata -*/
+
+/**
+ * The CLI will automatically emit applicable tuples for this table,
+ * such as `databaseMetadata("isOverlay", "true")` when building an
+ * overlay database.
+ */
+databaseMetadata(
+ string metadataKey: string ref,
+ string value: string ref
+);
+
+/*- Overlay support -*/
+
+/**
+ * The CLI will automatically emit tuples for each new/modified/deleted file
+ * when building an overlay database.
+ */
+overlayChangedFiles(
+ string path: string ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/ql/lib/upgrades/6aec212e408fad907b19368a3376a4d9837783d2/upgrade.properties b/cpp/ql/lib/upgrades/6aec212e408fad907b19368a3376a4d9837783d2/upgrade.properties
new file mode 100644
index 000000000000..db0e7e92d0e9
--- /dev/null
+++ b/cpp/ql/lib/upgrades/6aec212e408fad907b19368a3376a4d9837783d2/upgrade.properties
@@ -0,0 +1,2 @@
+description: Add new builtin operations
+compatibility: backwards
diff --git a/cpp/ql/lib/utils/test/InlineExpectationsTestQuery.ql b/cpp/ql/lib/utils/test/InlineExpectationsTestQuery.ql
index 8e6977ba5321..e71d67bc528c 100644
--- a/cpp/ql/lib/utils/test/InlineExpectationsTestQuery.ql
+++ b/cpp/ql/lib/utils/test/InlineExpectationsTestQuery.ql
@@ -6,16 +6,4 @@ private import cpp
private import codeql.util.test.InlineExpectationsTest as T
private import internal.InlineExpectationsTestImpl
import T::TestPostProcessing
-import T::TestPostProcessing::Make
-
-private module Input implements T::TestPostProcessing::InputSig {
- string getRelativeUrl(Location location) {
- exists(File f, int startline, int startcolumn, int endline, int endcolumn |
- location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
- f = location.getFile()
- |
- result =
- f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
- )
- }
-}
+import T::TestPostProcessing::Make
diff --git a/cpp/ql/lib/utils/test/internal/InlineExpectationsTestImpl.qll b/cpp/ql/lib/utils/test/internal/InlineExpectationsTestImpl.qll
index d2c8efbf3165..18493c8ad19c 100644
--- a/cpp/ql/lib/utils/test/internal/InlineExpectationsTestImpl.qll
+++ b/cpp/ql/lib/utils/test/internal/InlineExpectationsTestImpl.qll
@@ -25,4 +25,14 @@ module Impl implements InlineExpectationsTestSig {
}
class Location = C::Location;
+
+ string getRelativeUrl(Location location) {
+ exists(C::File f, int startline, int startcolumn, int endline, int endcolumn |
+ location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
+ f = location.getFile()
+ |
+ result =
+ f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
+ )
+ }
}
diff --git a/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql b/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql
index be175660bd9c..a35ec36837b1 100644
--- a/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql
+++ b/cpp/ql/src/Best Practices/BlockWithTooManyStatements.ql
@@ -5,9 +5,11 @@
* @problem.severity recommendation
* @precision high
* @id cpp/complex-block
- * @tags testability
+ * @tags quality
+ * testability
* readability
* maintainability
+ * complexity
*/
import cpp
diff --git a/cpp/ql/src/Best Practices/ComplexCondition.ql b/cpp/ql/src/Best Practices/ComplexCondition.ql
index 20ecd1b1adeb..b93d0b371e0b 100644
--- a/cpp/ql/src/Best Practices/ComplexCondition.ql
+++ b/cpp/ql/src/Best Practices/ComplexCondition.ql
@@ -5,9 +5,11 @@
* @problem.severity recommendation
* @precision high
* @id cpp/complex-condition
- * @tags testability
+ * @tags quality
+ * testability
* readability
* maintainability
+ * complexity
* statistical
* non-attributable
*/
diff --git a/cpp/ql/src/Best Practices/Exceptions/AccidentalRethrow.ql b/cpp/ql/src/Best Practices/Exceptions/AccidentalRethrow.ql
index 1e902579a495..be5a04fedb96 100644
--- a/cpp/ql/src/Best Practices/Exceptions/AccidentalRethrow.ql
+++ b/cpp/ql/src/Best Practices/Exceptions/AccidentalRethrow.ql
@@ -5,8 +5,10 @@
* @problem.severity warning
* @precision high
* @id cpp/rethrow-no-exception
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
+ * error-handling
* exceptions
*/
diff --git a/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.qhelp b/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.qhelp
index 3c60845c4a54..82bed0bc088e 100644
--- a/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.qhelp
+++ b/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.qhelp
@@ -43,7 +43,7 @@ void good() {
C++ FAQ:
What should I throw?,
What should I catch?.
- Wikibooks:
+ Wikibooks:
Throwing objects.
diff --git a/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.ql b/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.ql
index 28e7541fc744..9ac27287ae3b 100644
--- a/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.ql
+++ b/cpp/ql/src/Best Practices/Exceptions/CatchingByValue.ql
@@ -5,8 +5,11 @@
* @problem.severity warning
* @precision very-high
* @id cpp/catch-by-value
- * @tags efficiency
+ * @tags quality
+ * reliability
+ * efficiency
* correctness
+ * error-handling
* exceptions
*/
diff --git a/cpp/ql/src/Best Practices/Exceptions/LeakyCatch.ql b/cpp/ql/src/Best Practices/Exceptions/LeakyCatch.ql
index d3848962abda..97ccbdc63e07 100644
--- a/cpp/ql/src/Best Practices/Exceptions/LeakyCatch.ql
+++ b/cpp/ql/src/Best Practices/Exceptions/LeakyCatch.ql
@@ -5,8 +5,11 @@
* @problem.severity warning
* @precision high
* @id cpp/catch-missing-free
- * @tags efficiency
+ * @tags quality
+ * reliability
+ * efficiency
* correctness
+ * error-handling
* exceptions
* external/cwe/cwe-401
*/
diff --git a/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.qhelp b/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.qhelp
index a05903bd350e..cbbe423c647d 100644
--- a/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.qhelp
+++ b/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.qhelp
@@ -36,7 +36,7 @@ void good() {
C++ FAQ:
What should I throw?,
What should I catch?.
- Wikibooks:
+ Wikibooks:
Throwing objects.
diff --git a/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.ql b/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.ql
index 85c21a28f560..ad73b220868c 100644
--- a/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.ql
+++ b/cpp/ql/src/Best Practices/Exceptions/ThrowingPointers.ql
@@ -5,8 +5,11 @@
* @problem.severity warning
* @precision high
* @id cpp/throwing-pointer
- * @tags efficiency
+ * @tags quality
+ * reliability
+ * efficiency
* correctness
+ * error-handling
* exceptions
*/
diff --git a/cpp/ql/src/Best Practices/GuardedFree.ql b/cpp/ql/src/Best Practices/GuardedFree.ql
index 3afe1a92e954..76b921e56688 100644
--- a/cpp/ql/src/Best Practices/GuardedFree.ql
+++ b/cpp/ql/src/Best Practices/GuardedFree.ql
@@ -6,8 +6,10 @@
* @problem.severity recommendation
* @precision very-high
* @id cpp/guarded-free
- * @tags maintainability
+ * @tags quality
+ * maintainability
* readability
+ * useless-code
*/
import cpp
diff --git a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.ql b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.ql
index 64e5760ed2b4..b4c0e7854605 100644
--- a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.ql
+++ b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.ql
@@ -5,7 +5,8 @@
* @problem.severity recommendation
* @precision very-high
* @id cpp/declaration-hides-parameter
- * @tags maintainability
+ * @tags quality
+ * maintainability
* readability
*/
diff --git a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql
index d10d346c5135..b5d40675c823 100644
--- a/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql
+++ b/cpp/ql/src/Best Practices/Hiding/DeclarationHidesVariable.ql
@@ -5,7 +5,8 @@
* @problem.severity recommendation
* @precision high
* @id cpp/declaration-hides-variable
- * @tags maintainability
+ * @tags quality
+ * maintainability
* readability
*/
diff --git a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.qhelp b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.qhelp
index 6ffb30be5840..d12e1821b2d7 100644
--- a/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.qhelp
+++ b/cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.qhelp
@@ -21,7 +21,7 @@
cplusplus.com:
C++: array.
-Wikipedia:
+Wikipedia:
Bounds checking.
diff --git a/cpp/ql/src/Best Practices/Likely Errors/Slicing.qhelp b/cpp/ql/src/Best Practices/Likely Errors/Slicing.qhelp
index 576d77c8839c..282f592e0f61 100644
--- a/cpp/ql/src/Best Practices/Likely Errors/Slicing.qhelp
+++ b/cpp/ql/src/Best Practices/Likely Errors/Slicing.qhelp
@@ -20,7 +20,7 @@ These assignments slice off all the fields added by the derived type, and can ca
- Wikipedia: Object slicing.
+ Wikipedia: Object slicing.
DevX.com: Slicing in C++.
diff --git a/cpp/ql/src/Best Practices/Likely Errors/Slicing.ql b/cpp/ql/src/Best Practices/Likely Errors/Slicing.ql
index 52fec3ccbba8..ab9f5a27f0d5 100644
--- a/cpp/ql/src/Best Practices/Likely Errors/Slicing.ql
+++ b/cpp/ql/src/Best Practices/Likely Errors/Slicing.ql
@@ -5,7 +5,8 @@
* @problem.severity warning
* @precision high
* @id cpp/slicing
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
* types
*/
diff --git a/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsNumbers.qhelp b/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsNumbers.qhelp
index aa97965996f2..4a5e0cff636e 100644
--- a/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsNumbers.qhelp
+++ b/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsNumbers.qhelp
@@ -35,7 +35,7 @@ then replace all the relevant occurrences in the code.
-Magic number (Wikipedia)
+Magic number (Wikipedia)
Mats Henricson and Erik Nyquist, Industrial Strength C++, published by Prentice Hall PTR (1997).
diff --git a/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsString.qhelp b/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsString.qhelp
index 19182fe5b19d..c1ccb94f59ea 100644
--- a/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsString.qhelp
+++ b/cpp/ql/src/Best Practices/Magic Constants/MagicConstantsString.qhelp
@@ -34,7 +34,7 @@ constant.
-Magic string (Wikipedia)
+Magic string (Wikipedia)
Mats Henricson and Erik Nyquist, Industrial Strength C++, published by Prentice Hall PTR (1997).
diff --git a/cpp/ql/src/Best Practices/RuleOfThree.qhelp b/cpp/ql/src/Best Practices/RuleOfThree.qhelp
index f9ac2b396b9b..1c8eace82f76 100644
--- a/cpp/ql/src/Best Practices/RuleOfThree.qhelp
+++ b/cpp/ql/src/Best Practices/RuleOfThree.qhelp
@@ -15,6 +15,6 @@
-Wikipedia: Rule of three (C++ programming)
+Wikipedia: Rule of three (C++ programming)
diff --git a/cpp/ql/src/Best Practices/RuleOfTwo.qhelp b/cpp/ql/src/Best Practices/RuleOfTwo.qhelp
index b8d4e13d283e..167740b03d97 100644
--- a/cpp/ql/src/Best Practices/RuleOfTwo.qhelp
+++ b/cpp/ql/src/Best Practices/RuleOfTwo.qhelp
@@ -38,7 +38,7 @@ should never be called.
- Rule of Three [Wikipedia]
+ Rule of Three [Wikipedia]
The Law of The Big Two
diff --git a/cpp/ql/src/Best Practices/RuleOfTwo.ql b/cpp/ql/src/Best Practices/RuleOfTwo.ql
index efc30c0829ee..c519bc4043ad 100644
--- a/cpp/ql/src/Best Practices/RuleOfTwo.ql
+++ b/cpp/ql/src/Best Practices/RuleOfTwo.ql
@@ -7,8 +7,9 @@
* @problem.severity warning
* @precision high
* @id cpp/rule-of-two
- * @tags reliability
- * readability
+ * @tags quality
+ * reliability
+ * correctness
* language-features
*/
diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql b/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql
index 4ba1ad93f565..6d5948300db1 100644
--- a/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql
+++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedLocals.ql
@@ -46,6 +46,8 @@ predicate declarationHasSideEffects(Variable v) {
)
or
v.getType() instanceof TemplateDependentType // may have a constructor/destructor
+ or
+ v.getInitializer().getExpr().mayBeImpure()
}
from LocalVariable v, Function f
@@ -57,5 +59,6 @@ where
not declarationHasSideEffects(v) and
not exists(AsmStmt s | f = s.getEnclosingFunction()) and
not v.getAnAttribute().getName() = "unused" and
+ not v.getAnAttribute().getName() = "maybe_unused" and
not f.hasErrors() // Unextracted expressions may use `v`
select v, "Variable " + v.getName() + " is not used."
diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql
index 03176b8a7791..442f75027d82 100644
--- a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql
+++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql
@@ -15,16 +15,20 @@ import cpp
predicate declarationHasSideEffects(Variable v) {
exists(Class c | c = v.getUnspecifiedType() | c.hasConstructor() or c.hasDestructor())
+ or
+ v.getInitializer().getExpr().mayBeImpure()
}
from Variable v
where
v.isStatic() and
+ not v.isCompilerGenerated() and
v.hasDefinition() and
not v.isConstexpr() and
not exists(VariableAccess a | a.getTarget() = v) and
not v instanceof MemberVariable and
not declarationHasSideEffects(v) and
not v.getAnAttribute().hasName("used") and
- not v.getAnAttribute().hasName("unused")
+ not v.getAnAttribute().hasName("unused") and
+ not v.getAnAttribute().hasName("maybe_unused")
select v, "Static variable " + v.getName() + " is never read."
diff --git a/cpp/ql/src/Best Practices/UseOfGoto.ql b/cpp/ql/src/Best Practices/UseOfGoto.ql
index 26d72d69a0a2..5f360f72b869 100644
--- a/cpp/ql/src/Best Practices/UseOfGoto.ql
+++ b/cpp/ql/src/Best Practices/UseOfGoto.ql
@@ -6,8 +6,10 @@
* @problem.severity warning
* @precision high
* @id cpp/use-of-goto
- * @tags maintainability
+ * @tags quality
+ * maintainability
* readability
+ * complexity
* language-features
*/
diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md
index 945a605d7e3d..59508a4a2044 100644
--- a/cpp/ql/src/CHANGELOG.md
+++ b/cpp/ql/src/CHANGELOG.md
@@ -1,3 +1,46 @@
+## 1.10.0
+
+### Query Metadata Changes
+
+* Added a new `cpp-code-quality` query suite containing queries that identify maintainability and reliability issues in C and C++ code.
+
+### Minor Analysis Improvements
+
+* The `cpp/suspicious-pointer-scaling` query no longer reports false positives for intentional pointer arithmetic from `std::byte*` buffers.
+* The `cpp/unused-local-variable` and `cpp/unused-static-variable` queries no longer report variables marked with the C++17 `[[maybe_unused]]` attribute.
+
+## 1.9.2
+
+### Minor Analysis Improvements
+
+* The `cpp/resource-not-released-in-destructor` query now recognizes resources released through local aliases, reducing false-positive results.
+
+## 1.9.1
+
+No user-facing changes.
+
+## 1.9.0
+
+### New Queries
+
+* Added a new query, `cpp/ambiguous-assignment-of-comparison`, to detect potentially
+ ambiguous expressions where a comparison result is assigned to a variable and the
+ assignment is used as a truth value.
+
+## 1.8.3
+
+### Minor Analysis Improvements
+
+* The `cpp/leap-year/unsafe-array-for-days-of-the-year` query ("Unsafe array for days of the year") no longer reports an alert on the `__PRETTY_FUNCTION__` variable (and related variables) when the enclosing function has a signature that is exactly 364 characters.
+
+## 1.8.2
+
+No user-facing changes.
+
+## 1.8.1
+
+No user-facing changes.
+
## 1.8.0
### Query Metadata Changes
diff --git a/cpp/ql/src/Critical/LargeParameter.ql b/cpp/ql/src/Critical/LargeParameter.ql
index 2df622a4c81c..42fd8215369a 100644
--- a/cpp/ql/src/Critical/LargeParameter.ql
+++ b/cpp/ql/src/Critical/LargeParameter.ql
@@ -5,7 +5,10 @@
* @problem.severity recommendation
* @precision very-high
* @id cpp/large-parameter
- * @tags efficiency
+ * @tags quality
+ * reliability
+ * performance
+ * efficiency
* readability
* statistical
* non-attributable
diff --git a/cpp/ql/src/Critical/NewArrayDeleteMismatch.ql b/cpp/ql/src/Critical/NewArrayDeleteMismatch.ql
index c41a8c5ce29c..d91db6a5a5a6 100644
--- a/cpp/ql/src/Critical/NewArrayDeleteMismatch.ql
+++ b/cpp/ql/src/Critical/NewArrayDeleteMismatch.ql
@@ -5,7 +5,9 @@
* @problem.severity warning
* @precision high
* @id cpp/new-array-delete-mismatch
- * @tags reliability
+ * @tags quality
+ * reliability
+ * correctness
*/
import NewDelete
diff --git a/cpp/ql/src/Critical/NewDeleteArrayMismatch.ql b/cpp/ql/src/Critical/NewDeleteArrayMismatch.ql
index 497ddfe19c4a..c449828da804 100644
--- a/cpp/ql/src/Critical/NewDeleteArrayMismatch.ql
+++ b/cpp/ql/src/Critical/NewDeleteArrayMismatch.ql
@@ -5,7 +5,9 @@
* @problem.severity warning
* @precision high
* @id cpp/new-delete-array-mismatch
- * @tags reliability
+ * @tags quality
+ * reliability
+ * correctness
*/
import NewDelete
diff --git a/cpp/ql/src/Documentation/DocumentApi.qhelp b/cpp/ql/src/Documentation/DocumentApi.qhelp
index 4154e5cebc4e..80225102cc9b 100644
--- a/cpp/ql/src/Documentation/DocumentApi.qhelp
+++ b/cpp/ql/src/Documentation/DocumentApi.qhelp
@@ -22,10 +22,10 @@ Add comments to document the purpose of the function. In particular, ensure that
- C++ Programming Wikibook: Comments
+ C++ Programming Wikibook: Comments
- Wikipedia: Need for comments
+ Wikipedia: Need for comments
diff --git a/cpp/ql/src/Documentation/FixmeComments.qhelp b/cpp/ql/src/Documentation/FixmeComments.qhelp
index a4a0b9966a15..a884aee2bc8b 100644
--- a/cpp/ql/src/Documentation/FixmeComments.qhelp
+++ b/cpp/ql/src/Documentation/FixmeComments.qhelp
@@ -25,7 +25,7 @@ Fix the functionality indicated by the comment. If the comment no longer applies
- Wikipedia: Comment tags
+ Wikipedia: Comment tags
The case against TODO (and FIXME)
diff --git a/cpp/ql/src/Documentation/FixmeComments.ql b/cpp/ql/src/Documentation/FixmeComments.ql
index 5ccbf1292758..0699e1852279 100644
--- a/cpp/ql/src/Documentation/FixmeComments.ql
+++ b/cpp/ql/src/Documentation/FixmeComments.ql
@@ -5,7 +5,8 @@
* @problem.severity recommendation
* @precision very-high
* @id cpp/fixme-comment
- * @tags maintainability
+ * @tags quality
+ * maintainability
* documentation
* external/cwe/cwe-546
*/
diff --git a/cpp/ql/src/Documentation/TodoComments.qhelp b/cpp/ql/src/Documentation/TodoComments.qhelp
index ad246ebf358f..30eb359cd972 100644
--- a/cpp/ql/src/Documentation/TodoComments.qhelp
+++ b/cpp/ql/src/Documentation/TodoComments.qhelp
@@ -25,7 +25,7 @@ Implement the functionality indicated by the comment. If the comment no longer a
- Wikipedia: Comment tags
+ Wikipedia: Comment tags
TODO or not TODO
diff --git a/cpp/ql/src/Documentation/UncommentedFunction.qhelp b/cpp/ql/src/Documentation/UncommentedFunction.qhelp
index 7fe5c61d9da3..1604ca496de3 100644
--- a/cpp/ql/src/Documentation/UncommentedFunction.qhelp
+++ b/cpp/ql/src/Documentation/UncommentedFunction.qhelp
@@ -23,10 +23,10 @@ cohesive functions.
- C++ Programming, Coding style conventions
+ C++ Programming, Coding style conventions
- Wikipedia: Need for comments
+ Wikipedia: Need for comments
diff --git a/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.qhelp b/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.qhelp
index 20cb7ebe94fc..43e11ff20e8c 100644
--- a/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.qhelp
+++ b/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.qhelp
@@ -44,7 +44,7 @@ the second file, for example to ANOTHER_HEADER_FILE_H.
- Wikipedia: Include guard
+ Wikipedia: Include guard
diff --git a/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.ql b/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.ql
index c06cfeabe0d0..7b2a8bb1d1de 100644
--- a/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.ql
+++ b/cpp/ql/src/Header Cleanup/Cleanup-DuplicateIncludeGuard.ql
@@ -5,7 +5,7 @@
* @problem.severity error
* @precision high
* @id cpp/duplicate-include-guard
- * @tags reliability
+ * @tags quality
* maintainability
* modularity
*/
diff --git a/cpp/ql/src/Likely Bugs/AmbiguouslySignedBitField.ql b/cpp/ql/src/Likely Bugs/AmbiguouslySignedBitField.ql
index 1fabf449ab35..3244d6748e9f 100644
--- a/cpp/ql/src/Likely Bugs/AmbiguouslySignedBitField.ql
+++ b/cpp/ql/src/Likely Bugs/AmbiguouslySignedBitField.ql
@@ -29,7 +29,7 @@ where
// GLib's gboolean is a typedef for a type representing BoolType.
not bf.getType().hasName("gboolean") and
// If this is true, then there cannot be unsigned sign extension or overflow.
- not bf.getDeclaredNumBits() = bf.getType().getSize() * 8 and
+ not bf.getDeclaredNumBits() = bf.getType().getBitWidth() and
not bf.isAnonymous() and
not bf.isFromUninstantiatedTemplate(_)
select bf,
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.qhelp b/cpp/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.qhelp
index 13df1938bc3a..6d36cc6230f2 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.qhelp
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.qhelp
@@ -26,7 +26,7 @@ As a result, this check incorrectly considers all negative numbers as even.
MSDN Library: Multiplicative Operators and the Modulus Operator.
- Wikipedia: Modulo Operation - Common pitfalls.
+ Wikipedia: Modulo Operation - Common pitfalls.
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/BitwiseSignCheck.ql b/cpp/ql/src/Likely Bugs/Arithmetic/BitwiseSignCheck.ql
index dd27e4b7aee2..fba2fcf3f022 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/BitwiseSignCheck.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/BitwiseSignCheck.ql
@@ -5,7 +5,8 @@
* @problem.severity warning
* @precision high
* @id cpp/bitwise-sign-check
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
*/
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.ql b/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.ql
index d4b23265eed5..cd893ca705ee 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/ComparisonPrecedence.ql
@@ -7,7 +7,8 @@
* @problem.severity warning
* @precision very-high
* @id cpp/comparison-precedence
- * @tags maintainability
+ * @tags quality
+ * maintainability
* readability
*/
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/FloatComparison.ql b/cpp/ql/src/Likely Bugs/Arithmetic/FloatComparison.ql
index 1f2a7ca506fd..7f1dfad0c6cf 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/FloatComparison.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/FloatComparison.ql
@@ -7,7 +7,8 @@
* @problem.severity recommendation
* @precision high
* @id cpp/equality-on-floats
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
*/
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
index d2602c5bd28a..1ab9ee67c404 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql
@@ -7,7 +7,8 @@
* @problem.severity warning
* @precision high
* @id cpp/comparison-of-identical-expressions
- * @tags readability
+ * @tags quality
+ * readability
* maintainability
*/
diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/UnsignedGEZero.ql b/cpp/ql/src/Likely Bugs/Arithmetic/UnsignedGEZero.ql
index 7f89569c3ba5..ff2ad98085e3 100644
--- a/cpp/ql/src/Likely Bugs/Arithmetic/UnsignedGEZero.ql
+++ b/cpp/ql/src/Likely Bugs/Arithmetic/UnsignedGEZero.ql
@@ -7,7 +7,9 @@
* @problem.severity warning
* @precision very-high
* @id cpp/unsigned-comparison-zero
- * @tags maintainability
+ * @tags quality
+ * reliability
+ * correctness
* readability
*/
diff --git a/cpp/ql/src/Likely Bugs/ContinueInFalseLoop.ql b/cpp/ql/src/Likely Bugs/ContinueInFalseLoop.ql
index 5b16fc7cf8f0..b83392c4dfb6 100644
--- a/cpp/ql/src/Likely Bugs/ContinueInFalseLoop.ql
+++ b/cpp/ql/src/Likely Bugs/ContinueInFalseLoop.ql
@@ -7,7 +7,9 @@
* @id cpp/continue-in-false-loop
* @problem.severity warning
* @precision high
- * @tags correctness
+ * @tags quality
+ * reliability
+ * correctness
*/
import cpp
diff --git a/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.ql b/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.ql
index 924b5d87f90f..b50460262134 100644
--- a/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.ql
+++ b/cpp/ql/src/Likely Bugs/Conversion/ArrayArgSizeMismatch.ql
@@ -6,7 +6,9 @@
* @id cpp/array-arg-size-mismatch
* @problem.severity warning
* @precision high
- * @tags reliability
+ * @tags quality
+ * reliability
+ * correctness
*/
import cpp
diff --git a/cpp/ql/src/Likely Bugs/Conversion/ConversionChangesSign.ql b/cpp/ql/src/Likely Bugs/Conversion/ConversionChangesSign.ql
index c89c71fb50b7..35843512ac05 100644
--- a/cpp/ql/src/Likely Bugs/Conversion/ConversionChangesSign.ql
+++ b/cpp/ql/src/Likely Bugs/Conversion/ConversionChangesSign.ql
@@ -23,7 +23,7 @@ where
not (
e1.isConstant() and
0 <= e1.getValue().toInt() and
- e1.getValue().toInt() <= ((it2.getSize() * 8 - 1) * 2.log()).exp()
+ e1.getValue().toInt() <= ((it2.getBitWidth() - 1) * 2.log()).exp()
) and
not e1.isConstant()
select e1,
diff --git a/cpp/ql/src/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql b/cpp/ql/src/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql
index 237d20c8f628..b9fb6b970b88 100644
--- a/cpp/ql/src/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql
+++ b/cpp/ql/src/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql
@@ -6,7 +6,8 @@
* @problem.severity warning
* @precision high
* @id cpp/implicit-bitfield-downcast
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
* types
*/
@@ -20,8 +21,8 @@ where
then fct = va.getFullyConverted().getType().(ReferenceType).getBaseType()
else fct = va.getFullyConverted().getType()
) and
- fi.getNumBits() > fct.getSize() * 8 and
- va.getExplicitlyConverted().getType().getSize() > fct.getSize() and
+ fi.getNumBits() > fct.getBitWidth() and
+ va.getExplicitlyConverted().getType().getBitWidth() > fct.getBitWidth() and
va.getTarget() = fi and
not fct.getUnspecifiedType() instanceof BoolType
select va, "Implicit downcast of bitfield $@.", fi, fi.toString()
diff --git a/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.ql b/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.ql
index 5b539faa5b4e..5a8fa0b8fa96 100644
--- a/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Format/TooManyFormatArguments.ql
@@ -7,7 +7,8 @@
* @problem.severity recommendation
* @precision high
* @id cpp/too-many-format-arguments
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
*/
diff --git a/cpp/ql/src/Likely Bugs/Leap Year/UnsafeArrayForDaysOfYear.ql b/cpp/ql/src/Likely Bugs/Leap Year/UnsafeArrayForDaysOfYear.ql
index b27db937b577..e6b1ccaa6687 100644
--- a/cpp/ql/src/Likely Bugs/Leap Year/UnsafeArrayForDaysOfYear.ql
+++ b/cpp/ql/src/Likely Bugs/Leap Year/UnsafeArrayForDaysOfYear.ql
@@ -26,6 +26,7 @@ where
or
exists(Variable var |
var = element and
+ not var.isCompilerGenerated() and
var.getType() instanceof LeapYearUnsafeDaysOfTheYearArrayType and
allocType = "an array allocation"
)
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.cpp b/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.cpp
new file mode 100644
index 000000000000..c99ee284346c
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.cpp
@@ -0,0 +1,12 @@
+int read_status();
+
+int check_status() {
+ int status;
+ if (status = read_status() < 0) // BAD: assigns the comparison result.
+ return status;
+
+ if ((status = read_status()) < 0) // GOOD: assigns first, then compares.
+ return status;
+
+ return 0;
+}
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.qhelp
new file mode 100644
index 000000000000..e8404940bfe9
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.qhelp
@@ -0,0 +1,31 @@
+
+
+
+
+Assignment operators have lower precedence than comparison operators. For example,
+status = read_status() < 0 assigns the comparison result (zero or one) to
+status. This can be unintended when the programmer meant to assign the return value
+first and then compare it with zero.
+
+
+
+Use parentheses to make the intended order of operations explicit. To assign first and compare the
+assigned value, parenthesize the assignment. To intentionally assign the comparison result,
+parenthesize the comparison. An explicit cast around the comparison also makes that order clear.
+
+
+
+In the first condition, status receives either zero or one instead of the value
+returned by read_status(). The second condition explicitly performs the assignment
+before the comparison.
+
+
+
+
+SEI CERT C Coding Standard: EXP00-C. Use parentheses for precedence of operation.
+C++ reference: Operator precedence.
+
+
+
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.ql b/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.ql
new file mode 100644
index 000000000000..2bfe9f7159f5
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/AmbiguousAssignmentOfComparison.ql
@@ -0,0 +1,71 @@
+/**
+ * @name Ambiguous assignment of comparison result used as truth value
+ * @description Using an assignment of an unparenthesized comparison as
+ * a truth value may indicate unintended operator grouping.
+ * @kind problem
+ * @problem.severity warning
+ * @precision high
+ * @id cpp/ambiguous-assignment-of-comparison
+ * @tags quality
+ * reliability
+ * correctness
+ * external/cwe/cwe-783
+ */
+
+import cpp
+
+/** Holds if the value of `expression` is directly used as a truth value. */
+private predicate isDirectlyUsedAsTruthValue(Expr expression) {
+ expression.isCondition()
+ or
+ expression = any(UnaryLogicalOperation operation).getAnOperand()
+ or
+ expression = any(BinaryLogicalOperation operation).getAnOperand()
+}
+
+/**
+ * Holds if the value of `expression` is used as a truth value, possibly after contributing to a
+ * comma, conditional, or comparison expression.
+ */
+private predicate isUsedAsTruthValue(Expr expression) {
+ isDirectlyUsedAsTruthValue(expression)
+ or
+ exists(CommaExpr comma |
+ expression = comma.getRightOperand() and
+ isUsedAsTruthValue(comma)
+ )
+ or
+ exists(ConditionalExpr conditional |
+ expression = [conditional.getThen(), conditional.getElse()] and
+ isUsedAsTruthValue(conditional)
+ )
+ or
+ exists(ComparisonOperation comparison |
+ expression = comparison.getAnOperand() and
+ isUsedAsTruthValue(comparison)
+ )
+}
+
+/**
+ * Holds if `comparison` is explicitly grouped using parentheses or an explicit cast.
+ */
+private predicate isExplicitlyGrouped(ComparisonOperation comparison) {
+ comparison.isParenthesised()
+ or
+ exists(Cast cast | cast = comparison.getConversion+() and not cast.isImplicit())
+}
+
+from Assignment assignment, ComparisonOperation comparison
+where
+ assignment.getRValue() = comparison and
+ not isExplicitlyGrouped(comparison) and
+ isUsedAsTruthValue(assignment) and
+ // A Boolean lvalue makes assigning the comparison result type-appropriate and normally
+ // intentional.
+ not assignment.getLValue().getUnspecifiedType() instanceof BoolType and
+ not assignment.isUnevaluated() and
+ not assignment.isFromUninstantiatedTemplate(_)
+select assignment,
+ "The '" + assignment.getOperator() +
+ "' operation assigns the result of an unparenthesized comparison, and its result is used as " +
+ "a truth value."
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.qhelp
index 91ae1ce665b1..bef47aecc51c 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.qhelp
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.qhelp
@@ -30,7 +30,7 @@ An assignment is only flagged if its right hand side is a compile-time constant.
Tutorialspoint - The C++ Programming Language: Operators in C++
- Wikipedia: Operators in C and C++
+ Wikipedia: Operators in C and C++
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql b/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql
index 3d2f6830bf54..6e71233672e2 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql
@@ -6,7 +6,8 @@
* @problem.severity error
* @precision high
* @id cpp/assign-where-compare-meant
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
* external/cwe/cwe-481
*/
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.qhelp
index 6c1921cda991..437db4cb05c1 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.qhelp
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.qhelp
@@ -28,7 +28,7 @@ The rule flags every occurrence of an equality operator in a position where its
Tutorialspoint - The C++ Programming Language: Operators in C++
- Wikipedia: Operators in C and C++
+ Wikipedia: Operators in C and C++
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql b/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql
index 46c271b11d7e..709545af661e 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql
@@ -6,7 +6,8 @@
* @problem.severity error
* @precision high
* @id cpp/compare-where-assign-meant
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
* external/cwe/cwe-482
*/
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/DubiousNullCheck.ql b/cpp/ql/src/Likely Bugs/Likely Typos/DubiousNullCheck.ql
index 819ecbae8ec8..99c7753fa3bc 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/DubiousNullCheck.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/DubiousNullCheck.ql
@@ -6,8 +6,9 @@
* @problem.severity warning
* @precision very-high
* @id cpp/dubious-null-check
- * @tags reliability
- * readability
+ * @tags quality
+ * reliability
+ * correctness
*/
import cpp
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql b/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql
index bf724de3d70c..137ae31d4d8d 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/FutileConditional.ql
@@ -6,8 +6,9 @@
* @problem.severity recommendation
* @precision high
* @id cpp/empty-if
- * @tags reliability
- * readability
+ * @tags quality
+ * maintainability
+ * useless-code
*/
import cpp
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql b/cpp/ql/src/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql
index a1b5d7b8f358..dea16e9606d5 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql
@@ -6,7 +6,8 @@
* @problem.severity warning
* @precision high
* @id cpp/logical-operator-applied-to-flag
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
* external/cwe/cwe-480
*/
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql b/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql
index 5b1d54b51f8f..3f633600667a 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql
@@ -7,7 +7,9 @@
* @problem.severity error
* @precision high
* @id cpp/string-copy-return-value-as-boolean
- * @tags correctness
+ * @tags quality
+ * reliability
+ * correctness
*/
import cpp
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql
index 958d7aa3c559..7173dfb70c58 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql
@@ -5,7 +5,9 @@
* @problem.severity error
* @precision high
* @id cpp/inconsistent-loop-direction
- * @tags correctness
+ * @tags quality
+ * reliability
+ * correctness
* external/cwe/cwe-835
* @msrc.severity important
*/
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql b/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql
index f2cf4367d86d..5393c17b3ea3 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql
+++ b/cpp/ql/src/Likely Bugs/Memory Management/Padding/Suboptimal64BitType.ql
@@ -14,7 +14,7 @@ from
PaddedType t, Architecture arch, WideCharType wc, int holes, int size, int percentage, int optimum
where
arch.pointerSize() = 64 and // Select 64-bit architecture
- arch.wideCharSize() = (wc.getSize() * 8) and // Select Windows(sizeof(wchar_t == 2)) or non-Windows(sizeof(wchar_t == 4))
+ arch.wideCharSize() = wc.getBitWidth() and // Select Windows(sizeof(wchar_t == 2)) or non-Windows(sizeof(wchar_t == 4))
t.isPrecise() and
optimum = t.optimalSize(arch) and
size = arch.paddedSize(t) and
diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString.ql
index feca6558ef6e..e028fc8219e1 100644
--- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString.ql
+++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString.ql
@@ -8,7 +8,8 @@
* @problem.severity warning
* @precision high
* @id cpp/return-c-str-of-std-string
- * @tags reliability
+ * @tags quality
+ * reliability
* correctness
*/
diff --git a/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.qhelp b/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.qhelp
index 88af1203ef9e..3c3c615cd1d6 100644
--- a/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.qhelp
+++ b/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.qhelp
@@ -60,7 +60,7 @@ public:
Dr Dobb's Journal:
Delegating constructors?
- Wikipedia:
+ Wikipedia:
Object construction improvement in C++11.
diff --git a/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.ql b/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.ql
index 38cd86a594d9..55d2d620e015 100644
--- a/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.ql
+++ b/cpp/ql/src/Likely Bugs/OO/IncorrectConstructorDelegation.ql
@@ -7,8 +7,9 @@
* @problem.severity warning
* @precision high
* @id cpp/constructor-delegation
- * @tags maintainability
- * readability
+ * @tags quality
+ * reliability
+ * correctness
* language-features
*/
diff --git a/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructorInBaseClass.ql b/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructorInBaseClass.ql
index 7a223f56f57b..366118513aa3 100644
--- a/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructorInBaseClass.ql
+++ b/cpp/ql/src/Likely Bugs/OO/NonVirtualDestructorInBaseClass.ql
@@ -5,8 +5,9 @@
* @problem.severity warning
* @precision high
* @id cpp/virtual-destructor
- * @tags reliability
- * readability
+ * @tags quality
+ * reliability
+ * correctness
* language-features
*/
diff --git a/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.ql b/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.ql
index 75252eb45097..2b702d814e58 100644
--- a/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.ql
+++ b/cpp/ql/src/Likely Bugs/OO/ThrowInDestructor.ql
@@ -6,8 +6,10 @@
* @problem.severity warning
* @precision very-high
* @id cpp/throw-in-destructor
- * @tags reliability
- * readability
+ * @tags quality
+ * reliability
+ * correctness
+ * error-handling
* language-features
*/
diff --git a/cpp/ql/src/Likely Bugs/ReturnConstTypeMember.ql b/cpp/ql/src/Likely Bugs/ReturnConstTypeMember.ql
index 661abfd07e9c..45a65d3ea44e 100644
--- a/cpp/ql/src/Likely Bugs/ReturnConstTypeMember.ql
+++ b/cpp/ql/src/Likely Bugs/ReturnConstTypeMember.ql
@@ -5,8 +5,10 @@
* @problem.severity warning
* @precision very-high
* @id cpp/member-const-no-effect
- * @tags maintainability
+ * @tags quality
+ * maintainability
* readability
+ * useless-code
* language-features
*/
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql
index 8e921faf2117..18b3799003b7 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql
@@ -7,8 +7,9 @@
* @problem.severity warning
* @precision high
* @id cpp/implicit-function-declaration
- * @tags correctness
- * maintainability
+ * @tags quality
+ * reliability
+ * correctness
*/
import cpp
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
index 4e7f85097b8e..59f745b14956 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
@@ -7,8 +7,9 @@
* @problem.severity warning
* @precision very-high
* @id cpp/futile-params
- * @tags correctness
- * maintainability
+ * @tags quality
+ * reliability
+ * correctness
*/
import cpp
diff --git a/cpp/ql/src/Metrics/Files/FCommentRatio.qhelp b/cpp/ql/src/Metrics/Files/FCommentRatio.qhelp
index 4a5c928f5cd4..33829320b3e1 100644
--- a/cpp/ql/src/Metrics/Files/FCommentRatio.qhelp
+++ b/cpp/ql/src/Metrics/Files/FCommentRatio.qhelp
@@ -18,10 +18,10 @@ documenting the public functions first.
- C++ Programming, Coding style conventions
+ C++ Programming, Coding style conventions
- Wikipedia: Need for comments
+ Wikipedia: Need for comments
diff --git a/cpp/ql/src/Metrics/Files/FCyclomaticComplexity.qhelp b/cpp/ql/src/Metrics/Files/FCyclomaticComplexity.qhelp
index be463857db9a..6bd6e7b47183 100644
--- a/cpp/ql/src/Metrics/Files/FCyclomaticComplexity.qhelp
+++ b/cpp/ql/src/Metrics/Files/FCyclomaticComplexity.qhelp
@@ -67,10 +67,10 @@ T. J. McCabe, A Complexity Measure. IEEE Transactions on Software Engin
Dave Thomas, Refactoring as Meta Programming?, in Journal of Object Technology, vol. 4, no. 1, January-February 2005, pp. 7-11.
-Wikipedia: Cyclomatic complexity
+Wikipedia: Cyclomatic complexity
-Wikipedia: Code refactoring
+Wikipedia: Code refactoring
diff --git a/cpp/ql/src/Metrics/Files/FLinesOfCode.qhelp b/cpp/ql/src/Metrics/Files/FLinesOfCode.qhelp
index 4eb6c1c5b009..b8dfc4e70f24 100644
--- a/cpp/ql/src/Metrics/Files/FLinesOfCode.qhelp
+++ b/cpp/ql/src/Metrics/Files/FLinesOfCode.qhelp
@@ -19,7 +19,7 @@
M. Fowler. Refactoring. Addison-Wesley, 1999.
- Wikipedia: Code refactoring
+ Wikipedia: Code refactoring
Refactoring as Meta Programming?
diff --git a/cpp/ql/src/Metrics/Files/FLinesOfComments.qhelp b/cpp/ql/src/Metrics/Files/FLinesOfComments.qhelp
index d1b1d9849181..ed7aabe9971c 100644
--- a/cpp/ql/src/Metrics/Files/FLinesOfComments.qhelp
+++ b/cpp/ql/src/Metrics/Files/FLinesOfComments.qhelp
@@ -18,10 +18,10 @@ should be given to long files.
- C++ Programming, Coding style conventions
+ C++ Programming, Coding style conventions
- Wikipedia: Need for comments
+ Wikipedia: Need for comments
diff --git a/cpp/ql/src/Metrics/Files/FTodoComments.qhelp b/cpp/ql/src/Metrics/Files/FTodoComments.qhelp
index a0906beb799e..7eb47a72c156 100644
--- a/cpp/ql/src/Metrics/Files/FTodoComments.qhelp
+++ b/cpp/ql/src/Metrics/Files/FTodoComments.qhelp
@@ -21,7 +21,7 @@ for fixing them.
- Wikipedia: Comment tags
+ Wikipedia: Comment tags
TODO or not TODO
diff --git a/cpp/ql/src/Metrics/Functions/FunLinesOfComments.qhelp b/cpp/ql/src/Metrics/Functions/FunLinesOfComments.qhelp
index 6232b6bd4418..05728eb3ad33 100644
--- a/cpp/ql/src/Metrics/Functions/FunLinesOfComments.qhelp
+++ b/cpp/ql/src/Metrics/Functions/FunLinesOfComments.qhelp
@@ -18,10 +18,10 @@ should be given to long, complex functions.
- C++ Programming, Coding style conventions
+ C++ Programming, Coding style conventions
- Wikipedia: Need for comments
+ Wikipedia: Need for comments
diff --git a/cpp/ql/src/Metrics/Functions/FunPercentageOfComments.qhelp b/cpp/ql/src/Metrics/Functions/FunPercentageOfComments.qhelp
index 5f998e3e476d..92bb1dc7e41f 100644
--- a/cpp/ql/src/Metrics/Functions/FunPercentageOfComments.qhelp
+++ b/cpp/ql/src/Metrics/Functions/FunPercentageOfComments.qhelp
@@ -17,10 +17,10 @@ documentation.
- C++ Programming, Coding style conventions
+ C++ Programming, Coding style conventions
- Wikipedia: Need for comments
+ Wikipedia: Need for comments
diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.qhelp b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.qhelp
index 2e888bf80df5..f9153b95700e 100644
--- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.qhelp
+++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.qhelp
@@ -34,7 +34,7 @@ should be safe against command injection.
Sanitize data passed to complex subsystems.
OWASP:
-Command Injection.
+Command Injection.
diff --git a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp
index 4ad7a40fed60..bfbc7c32746b 100644
--- a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp
+++ b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp
@@ -38,7 +38,7 @@ OWASP:
(Cross Site Scripting) Prevention Cheat Sheet.
-Wikipedia: Cross-site scripting.
+Wikipedia: Cross-site scripting.
IETF Tools: The Common Gateway Specification (CGI).
diff --git a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql
index 802888be271a..eb5d23b5fd6a 100644
--- a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql
+++ b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql
@@ -33,15 +33,20 @@ Expr asSinkExpr(DataFlow::Node node) {
result = node.asExpr()
}
+private predicate isSink(DataFlow::Node sink, string extraText) {
+ exists(SqlLikeFunction runSql, string callChain |
+ runSql.outermostWrapperFunctionCall(asSinkExpr(sink), callChain) and
+ extraText = " and then passed to " + callChain
+ )
+ or
+ // sink defined using models-as-data
+ sinkNode(sink, "sql-injection") and extraText = ""
+}
+
module SqlTaintedConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
- predicate isSink(DataFlow::Node node) {
- exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(asSinkExpr(node), _))
- or
- // sink defined using models-as-data
- sinkNode(node, "sql-injection")
- }
+ predicate isSink(DataFlow::Node node) { isSink(node, _) }
predicate isBarrier(DataFlow::Node node) {
node.asExpr().getUnspecifiedType() instanceof IntegralType
@@ -57,32 +62,17 @@ module SqlTaintedConfig implements DataFlow::ConfigSig {
}
predicate observeDiffInformedIncrementalMode() { any() }
-
- Location getASelectedSinkLocation(DataFlow::Node sink) {
- exists(Expr taintedArg | result = [taintedArg.getLocation(), sink.getLocation()] |
- taintedArg = asSinkExpr(sink)
- )
- }
}
module SqlTainted = TaintTracking::Global;
from
- Expr taintedArg, FlowSource taintSource, SqlTainted::PathNode sourceNode,
- SqlTainted::PathNode sinkNode, string extraText
+ FlowSource taintSource, SqlTainted::PathNode sourceNode, SqlTainted::PathNode sinkNode,
+ string extraText
where
- (
- exists(SqlLikeFunction runSql, string callChain |
- runSql.outermostWrapperFunctionCall(taintedArg, callChain) and
- extraText = " and then passed to " + callChain
- )
- or
- sinkNode(sinkNode.getNode(), "sql-injection") and
- extraText = ""
- ) and
SqlTainted::flowPath(sourceNode, sinkNode) and
- taintedArg = asSinkExpr(sinkNode.getNode()) and
+ isSink(sinkNode.getNode(), extraText) and
taintSource = sourceNode.getNode()
-select taintedArg, sourceNode, sinkNode,
+select sinkNode.getNode(), sourceNode, sinkNode,
"This argument to a SQL query function is derived from $@" + extraText + ".", taintSource,
"user input (" + taintSource.getSourceType() + ")"
diff --git a/cpp/ql/src/Security/CWE/CWE-311/ClearText.qll b/cpp/ql/src/Security/CWE/CWE-311/ClearText.qll
new file mode 100644
index 000000000000..32e7f24301ac
--- /dev/null
+++ b/cpp/ql/src/Security/CWE/CWE-311/ClearText.qll
@@ -0,0 +1,37 @@
+private import cpp
+private import semmle.code.cpp.dataflow.new.DataFlow
+
+/**
+ * Holds if `node` should be a barrier for the CWE-311 queries
+ * because it is of a non-char integral type.
+ */
+predicate isBarrier(DataFlow::Node node) {
+ exists(IntegralType type |
+ type = node.asCertainDefinition().getUnspecifiedType() and
+ not type instanceof CharType and
+ not type instanceof WideCharType and
+ not type instanceof Char8Type and
+ not type instanceof Char16Type and
+ not type instanceof Char32Type
+ )
+}
+
+private Expr asExprOrIndirectExpr(DataFlow::Node node, int indirectionIndex) {
+ indirectionIndex = 0 and
+ result = node.asExpr()
+ or
+ result = node.asIndirectExpr(indirectionIndex)
+}
+
+/**
+ * Holds if `source` is the relevant `DataFlow::Node` for
+ * expression `e`.
+ */
+predicate isSource(DataFlow::Node source, Expr e) {
+ exists(int indirectionIndex |
+ e = asExprOrIndirectExpr(source, indirectionIndex) and
+ if e.getUnspecifiedType() instanceof ReferenceType
+ then indirectionIndex = 1
+ else indirectionIndex = 0
+ )
+}
diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql
index 17f4b7ae0fdb..83220002e29c 100644
--- a/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql
+++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql
@@ -19,6 +19,7 @@ import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.ir.dataflow.TaintTracking
import FromSensitiveFlow::PathGraph
+import ClearText as ClearText
/**
* A taint flow configuration for flow from a sensitive expression to a `FileWrite` sink.
@@ -28,9 +29,7 @@ module FromSensitiveConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _, _) }
- predicate isBarrier(DataFlow::Node node) {
- node.asExpr().getUnspecifiedType() instanceof IntegralType
- }
+ predicate isBarrier = ClearText::isBarrier/1;
predicate observeDiffInformedIncrementalMode() { any() }
@@ -61,7 +60,7 @@ predicate isSinkImpl(DataFlow::Node sink, FileWrite w, Expr dest) {
predicate isSourceImpl(DataFlow::Node source, SensitiveExpr sensitive) {
not isFileName(globalValueNumber(sensitive)) and // file names are not passwords
- source.asExpr() = sensitive
+ ClearText::isSource(source, sensitive)
}
/**
diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql
index 207aec189b2e..1182628cc837 100644
--- a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql
+++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql
@@ -19,6 +19,7 @@ import semmle.code.cpp.ir.dataflow.TaintTracking
import semmle.code.cpp.models.interfaces.FlowSource
import semmle.code.cpp.commons.File
import FromSensitiveFlow::PathGraph
+import ClearText as ClearText
class SourceVariable extends Variable {
SourceVariable() {
@@ -218,12 +219,12 @@ predicate isSinkEncrypt(DataFlow::Node sink, Encrypted enc) { sink.asExpr() = en
* function returning sensitive data.
*/
predicate isSourceImpl(DataFlow::Node source) {
- exists(VariableAccess e |
- e = source.asExpr() and
- e.getTarget() instanceof SourceVariable
+ exists(Expr e |
+ e.(VariableAccess).getTarget() instanceof SourceVariable or
+ e.(FunctionCall).getTarget() instanceof SourceFunction
+ |
+ ClearText::isSource(source, e)
)
- or
- source.asExpr().(FunctionCall).getTarget() instanceof SourceFunction
}
/**
@@ -235,9 +236,7 @@ module FromSensitiveConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { isSinkSendRecv(sink, _) }
- predicate isBarrier(DataFlow::Node node) {
- node.asExpr().getUnspecifiedType() instanceof IntegralType
- }
+ predicate isBarrier = ClearText::isBarrier/1;
predicate isBarrierIn(DataFlow::Node node) {
// As any use of a sensitive variable is a potential source, we need to block flow into
@@ -266,9 +265,7 @@ module ToEncryptionConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { isSinkEncrypt(sink, _) }
- predicate isBarrier(DataFlow::Node node) {
- node.asExpr().getUnspecifiedType() instanceof IntegralType
- }
+ predicate isBarrier = ClearText::isBarrier/1;
predicate isBarrierIn(DataFlow::Node node) {
// As any use of a sensitive variable is a potential source, we need to block flow into
@@ -291,9 +288,7 @@ module FromEncryptionConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { FromSensitiveFlow::flowTo(sink) }
- predicate isBarrier(DataFlow::Node node) {
- node.asExpr().getUnspecifiedType() instanceof IntegralType
- }
+ predicate isBarrier = ClearText::isBarrier/1;
predicate observeDiffInformedIncrementalMode() {
none() // only used negatively
diff --git a/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql b/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql
index 682d83874333..1cb3be1f0c91 100644
--- a/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql
+++ b/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql
@@ -35,22 +35,25 @@ predicate privateHostNameFlowsToExpr(Expr e) {
TaintTracking::localExprTaint(any(StringLiteral p | p.getValue() instanceof PrivateHostName), e)
}
-/**
- * A string containing an HTTP URL not in a private domain.
- */
-class HttpStringLiteral extends StringLiteral {
- HttpStringLiteral() {
+private class HttpStringLiteralCandidate extends StringLiteral {
+ HttpStringLiteralCandidate() {
exists(string s | this.getValue() = s |
s = "http"
or
exists(string tail |
tail = s.regexpCapture("http://(.*)", 1) and not tail instanceof PrivateHostName
)
- ) and
- not privateHostNameFlowsToExpr(this.getParent*())
+ )
}
}
+/**
+ * A string containing an HTTP URL not in a private domain.
+ */
+class HttpStringLiteral extends HttpStringLiteralCandidate {
+ HttpStringLiteral() { not privateHostNameFlowsToExpr(this.getParent*()) }
+}
+
/**
* Taint tracking configuration for HTTP connections.
*/
diff --git a/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScaling.ql b/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScaling.ql
index a8f71c4e1d0d..49ab69ff2490 100644
--- a/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScaling.ql
+++ b/cpp/ql/src/Security/CWE/CWE-468/IncorrectPointerScaling.ql
@@ -22,11 +22,12 @@ where
destBase = baseType(destType) and
destBase.getSize() != sourceBase.getSize() and
not dest.isInMacroExpansion() and
- // If the source type is a `char*` or `void*` then don't
+ // If the source type is a `char*`, `void*` or `std::byte*` then don't
// produce a result, because it is likely to be a false
// positive.
not sourceBase instanceof CharType and
not sourceBase instanceof VoidType and
+ not sourceBase.(Enum).hasQualifiedName("std", "byte") and
// Low-level pointer tricks often involve casting a struct pointer to a
// char pointer, then accessing it at byte offsets. For example, this can
// be necessary in order to resume an interrupted `write(2)`.
diff --git a/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.qhelp b/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.qhelp
index 17b34f1f37e7..72a559d43e2b 100644
--- a/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.qhelp
+++ b/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.qhelp
@@ -36,7 +36,7 @@ rules for the following CWEs:
-Wikipedia: Morris worm.
+Wikipedia: Morris worm.
E. Spafford. The Internet Worm Program: An Analysis. Purdue Technical Report CSD-TR-823, (online), 1988.
diff --git a/cpp/ql/src/change-notes/2026-10-29-unused-variable-initializers.md b/cpp/ql/src/change-notes/2026-10-29-unused-variable-initializers.md
new file mode 100644
index 000000000000..1cc9f421d377
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-10-29-unused-variable-initializers.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The `cpp/unused-local-variable` and `cpp/unused-static-variable` queries no longer report variables whose initializers may have side effects.
diff --git a/cpp/ql/src/change-notes/2026-10-30-unused-static-compiler-generated.md b/cpp/ql/src/change-notes/2026-10-30-unused-static-compiler-generated.md
new file mode 100644
index 000000000000..4ede33c64a12
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-10-30-unused-static-compiler-generated.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The `cpp/unused-static-variable` query no longer reports compiler-generated variables, such as placeholders for empty function parameter packs.
diff --git a/cpp/ql/src/change-notes/2026-11-04-char-types-cwe-311.md b/cpp/ql/src/change-notes/2026-11-04-char-types-cwe-311.md
new file mode 100644
index 000000000000..f23f0f3b005e
--- /dev/null
+++ b/cpp/ql/src/change-notes/2026-11-04-char-types-cwe-311.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The `cpp/cleartext-transmission` and `cpp/cleartext-storage-file` queries now track flow through character types. As a result, these queries may find additional results.
\ No newline at end of file
diff --git a/cpp/ql/src/change-notes/released/1.10.0.md b/cpp/ql/src/change-notes/released/1.10.0.md
new file mode 100644
index 000000000000..17b337e8419f
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.10.0.md
@@ -0,0 +1,10 @@
+## 1.10.0
+
+### Query Metadata Changes
+
+* Added a new `cpp-code-quality` query suite containing queries that identify maintainability and reliability issues in C and C++ code.
+
+### Minor Analysis Improvements
+
+* The `cpp/suspicious-pointer-scaling` query no longer reports false positives for intentional pointer arithmetic from `std::byte*` buffers.
+* The `cpp/unused-local-variable` and `cpp/unused-static-variable` queries no longer report variables marked with the C++17 `[[maybe_unused]]` attribute.
diff --git a/cpp/ql/src/change-notes/released/1.8.1.md b/cpp/ql/src/change-notes/released/1.8.1.md
new file mode 100644
index 000000000000..0b1a7cdad10a
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.8.1.md
@@ -0,0 +1,3 @@
+## 1.8.1
+
+No user-facing changes.
diff --git a/cpp/ql/src/change-notes/released/1.8.2.md b/cpp/ql/src/change-notes/released/1.8.2.md
new file mode 100644
index 000000000000..12e641fd7205
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.8.2.md
@@ -0,0 +1,3 @@
+## 1.8.2
+
+No user-facing changes.
diff --git a/cpp/ql/src/change-notes/released/1.8.3.md b/cpp/ql/src/change-notes/released/1.8.3.md
new file mode 100644
index 000000000000..46bddcbc40ea
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.8.3.md
@@ -0,0 +1,5 @@
+## 1.8.3
+
+### Minor Analysis Improvements
+
+* The `cpp/leap-year/unsafe-array-for-days-of-the-year` query ("Unsafe array for days of the year") no longer reports an alert on the `__PRETTY_FUNCTION__` variable (and related variables) when the enclosing function has a signature that is exactly 364 characters.
diff --git a/cpp/ql/src/change-notes/released/1.9.0.md b/cpp/ql/src/change-notes/released/1.9.0.md
new file mode 100644
index 000000000000..61431fce84ed
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.9.0.md
@@ -0,0 +1,7 @@
+## 1.9.0
+
+### New Queries
+
+* Added a new query, `cpp/ambiguous-assignment-of-comparison`, to detect potentially
+ ambiguous expressions where a comparison result is assigned to a variable and the
+ assignment is used as a truth value.
diff --git a/cpp/ql/src/change-notes/released/1.9.1.md b/cpp/ql/src/change-notes/released/1.9.1.md
new file mode 100644
index 000000000000..bc5c4bd30411
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.9.1.md
@@ -0,0 +1,3 @@
+## 1.9.1
+
+No user-facing changes.
diff --git a/cpp/ql/src/change-notes/released/1.9.2.md b/cpp/ql/src/change-notes/released/1.9.2.md
new file mode 100644
index 000000000000..297a6627e0b5
--- /dev/null
+++ b/cpp/ql/src/change-notes/released/1.9.2.md
@@ -0,0 +1,5 @@
+## 1.9.2
+
+### Minor Analysis Improvements
+
+* The `cpp/resource-not-released-in-destructor` query now recognizes resources released through local aliases, reducing false-positive results.
diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml
index dc8a37cc443d..753e9ac28449 100644
--- a/cpp/ql/src/codeql-pack.release.yml
+++ b/cpp/ql/src/codeql-pack.release.yml
@@ -1,2 +1,2 @@
---
-lastReleaseVersion: 1.8.0
+lastReleaseVersion: 1.10.0
diff --git a/cpp/ql/src/codeql-suites/cpp-security-and-quality.qls b/cpp/ql/src/codeql-suites/cpp-security-and-quality.qls
index b4f85c4e306e..d6df483208da 100644
--- a/cpp/ql/src/codeql-suites/cpp-security-and-quality.qls
+++ b/cpp/ql/src/codeql-suites/cpp-security-and-quality.qls
@@ -1,5 +1,92 @@
- description: Security-and-quality queries for C and C++
- queries: .
-- apply: security-and-quality-selectors.yml
+- apply: security-and-frozen-quality-selectors.yml
from: codeql/suite-helpers
+- include:
+ id:
+ - cpp/ambiguous-assignment-of-comparison
+ - cpp/ambiguously-signed-bit-field
+ - cpp/array-arg-size-mismatch
+ - cpp/array-in-interface
+ - cpp/assign-where-compare-meant
+ - cpp/assignment-does-not-return-this
+ - cpp/bitwise-sign-check
+ - cpp/catch-by-value
+ - cpp/catch-missing-free
+ - cpp/commented-out-code
+ - cpp/compare-where-assign-meant
+ - cpp/comparison-of-identical-expressions
+ - cpp/comparison-precedence
+ - cpp/complex-block
+ - cpp/complex-condition
+ - cpp/constant-comparison
+ - cpp/constructor-delegation
+ - cpp/continue-in-false-loop
+ - cpp/dead-code-goto
+ - cpp/declaration-hides-parameter
+ - cpp/declaration-hides-variable
+ - cpp/dubious-null-check
+ - cpp/duplicate-include-guard
+ - cpp/empty-block
+ - cpp/empty-if
+ - cpp/equality-on-floats
+ - cpp/fixme-comment
+ - cpp/function-in-block
+ - cpp/futile-params
+ - cpp/guarded-free
+ - cpp/implicit-bitfield-downcast
+ - cpp/implicit-function-declaration
+ - cpp/include-non-header
+ - cpp/incomplete-parity-check
+ - cpp/inconsistent-call-on-result
+ - cpp/inconsistent-loop-direction
+ - cpp/inconsistent-null-check
+ - cpp/inconsistent-virtual-inheritance
+ - cpp/integer-used-for-enum
+ - cpp/irregular-enum-init
+ - cpp/large-parameter
+ - cpp/leap-year/adding-365-days-per-year
+ - cpp/leap-year/unchecked-after-arithmetic-year-modification
+ - cpp/leap-year/unchecked-return-value-for-time-conversion-function
+ - cpp/local-variable-hides-global-variable
+ - cpp/logical-operator-applied-to-flag
+ - cpp/long-switch
+ - cpp/loop-variable-changed
+ - cpp/loop-variable-float
+ - cpp/lossy-function-result-cast
+ - cpp/lossy-pointer-cast
+ - cpp/member-const-no-effect
+ - cpp/missing-case-in-switch
+ - cpp/missing-header-guard
+ - cpp/missing-return
+ - cpp/mistyped-function-arguments
+ - cpp/nested-loops-with-same-variable
+ - cpp/new-array-delete-mismatch
+ - cpp/new-delete-array-mismatch
+ - cpp/non-member-const-no-effect
+ - cpp/poorly-documented-function
+ - cpp/redefined-default-parameter
+ - cpp/resource-not-released-in-destructor
+ - cpp/rethrow-no-exception
+ - cpp/return-c-str-of-std-string
+ - cpp/rule-of-two
+ - cpp/short-global-name
+ - cpp/sizeof-side-effect
+ - cpp/slicing
+ - cpp/stack-address-escape
+ - cpp/string-copy-return-value-as-boolean
+ - cpp/throw-in-destructor
+ - cpp/throwing-pointer
+ - cpp/too-many-format-arguments
+ - cpp/trivial-switch
+ - cpp/undisciplined-multiple-inheritance
+ - cpp/unsigned-comparison-zero
+ - cpp/unused-local-variable
+ - cpp/unused-static-function
+ - cpp/unused-static-variable
+ - cpp/use-in-own-initializer
+ - cpp/use-of-goto
+ - cpp/useless-expression
+ - cpp/virtual-call-in-constructor
+ - cpp/virtual-destructor
- apply: codeql-suites/exclude-slow-queries.yml
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-078/WordexpTainted.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-078/WordexpTainted.qhelp
index 6dd9662c57d5..eb13e3785542 100644
--- a/cpp/ql/src/experimental/Security/CWE/CWE-078/WordexpTainted.qhelp
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-078/WordexpTainted.qhelp
@@ -31,7 +31,7 @@ is performed, making this safe from command injection.
Sanitize data passed to complex subsystems.
OWASP:
-Command Injection.
+Command Injection.
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpy.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpy.qhelp
new file mode 100644
index 000000000000..9b1dcdc4cdf4
--- /dev/null
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpy.qhelp
@@ -0,0 +1,28 @@
+
+
+
+
+Firmware and embedded drivers often copy data into buffers using lengths read from
+allowlisted MMIO register macros such as READ_REG or GET_MMIO.
+When those lengths are not validated against the destination buffer size, an attacker who
+can influence hardware registers or DMA metadata can trigger buffer overflows.
+
+
+
+
+Always validate MMIO/DMA-derived lengths before passing them to memcpy,
+memmove, or strncpy. Compare against a compile-time maximum
+and reject or clamp out-of-range values before copying.
+
+
+
+Bad: length from an MMIO register used directly as the copy size.
+
+Good: defensive bounds check before the copy.
+
+
+
+
+
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpy.ql b/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpy.ql
new file mode 100644
index 000000000000..67a0c98e2db4
--- /dev/null
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpy.ql
@@ -0,0 +1,64 @@
+/**
+ * @name MMIO/DMA unsanitized memory copy
+ * @description Memory copy sizes derived from allowlisted MMIO/DMA register-read
+ * macros without bounds validation may overflow destination buffers.
+ * @kind path-problem
+ * @problem.severity error
+ * @precision low
+ * @id cpp/mmio-unsanitized-memcpy
+ * @tags security
+ * experimental
+ * external/cwe/cwe-120
+ * external/cwe/cwe-787
+ */
+
+import cpp
+import semmle.code.cpp.dataflow.new.TaintTracking
+import semmle.code.cpp.controlflow.IRGuards
+import MmioFlow::PathGraph
+
+/** Holds if `source` reads MMIO/DMA state through an allowlisted register macro. */
+predicate isMmioSource(DataFlow::Node source) {
+ exists(MacroInvocation mi |
+ mi.getMacro().hasName(["READ_REG", "GET_MMIO", "REG_READ", "DMA_READ"]) and
+ source.asExpr() = mi.getExpr()
+ )
+}
+
+predicate isMemcpySizeSink(DataFlow::Node sink, FunctionCall fc) {
+ fc.getTarget().hasName(["memcpy", "memmove", "strncpy", "wmemcpy", "wmemmove"]) and
+ sink.asExpr() = fc.getArgument(2)
+}
+
+/** Recognizes relational comparison bounds checks using public IRGuards API. */
+predicate lessThanOrEqual(IRGuardCondition g, Expr e, boolean branch) {
+ exists(Operand left |
+ g.comparesLt(left, _, _, true, branch) or
+ g.comparesEq(left, _, _, true, branch)
+ |
+ left.getDef().getConvertedResultExpression() = e
+ )
+}
+
+module MmioConfig implements DataFlow::ConfigSig {
+ predicate isSource(DataFlow::Node source) { isMmioSource(source) }
+
+ predicate isSink(DataFlow::Node sink) { isMemcpySizeSink(sink, _) }
+
+ predicate isBarrier(DataFlow::Node node) {
+ node = DataFlow::BarrierGuard::getABarrierNode() or
+ node = DataFlow::BarrierGuard::getAnIndirectBarrierNode()
+ }
+
+ predicate observeDiffInformedIncrementalMode() { any() }
+}
+
+module MmioFlow = TaintTracking::Global;
+
+from FunctionCall memcpyCall, MmioFlow::PathNode source, MmioFlow::PathNode sink
+where
+ MmioFlow::flowPath(source, sink) and
+ isMemcpySizeSink(sink.getNode(), memcpyCall)
+select sink.getNode(), source, sink,
+ "Memory copy size argument is derived from $@ without sufficient bounds validation.",
+ source.getNode(), "an MMIO/DMA hardware register read"
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpyBad.c b/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpyBad.c
new file mode 100644
index 000000000000..13e68fc7561d
--- /dev/null
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpyBad.c
@@ -0,0 +1,9 @@
+#define READ_REG(addr) (*(volatile unsigned int *)(addr))
+#define MAX_DMA_LEN 64
+
+void *memcpy(void *dest, const void *src, unsigned long n);
+
+void bad_mmio_memcpy(char *dst, char *src) {
+ unsigned int len = READ_REG(0x40001000);
+ memcpy(dst, src, len);
+}
diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpyGood.c b/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpyGood.c
new file mode 100644
index 000000000000..38c37a3f3c64
--- /dev/null
+++ b/cpp/ql/src/experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpyGood.c
@@ -0,0 +1,10 @@
+#define READ_REG(addr) (*(volatile unsigned int *)(addr))
+#define MAX_DMA_LEN 64
+
+void *memcpy(void *dest, const void *src, unsigned long n);
+
+void good_mmio_memcpy(char *dst, char *src) {
+ unsigned int len = READ_REG(0x40001000);
+ if (len <= MAX_DMA_LEN)
+ memcpy(dst, src, len);
+}
diff --git a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql
index 59a6838c23e3..4f86f64bc435 100644
--- a/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql
+++ b/cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql
@@ -7,7 +7,8 @@
* @problem.severity recommendation
* @precision high
* @id cpp/missing-header-guard
- * @tags efficiency
+ * @tags quality
+ * efficiency
* maintainability
* modularity
* external/jsf
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql
index ec7d446ac58a..761879c98702 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 71.1.ql
@@ -5,7 +5,9 @@
* @problem.severity warning
* @precision high
* @id cpp/virtual-call-in-constructor
- * @tags reliability
+ * @tags quality
+ * reliability
+ * correctness
* readability
* language-features
* external/jsf
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.qhelp b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.qhelp
index a5b94460d43b..aa58cc17cbc7 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.qhelp
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.qhelp
@@ -87,7 +87,7 @@ to a straightforward RAII pattern. This can be achieved in several steps:
S. Meyers. Effective C++ 3d ed. pp 61-66. Addison-Wesley Professional, 2005.
- Resource Acquisition Is Initialization
+ Resource Acquisition Is Initialization
diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
index 85b779903ebf..c0014f5f3464 100644
--- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
+++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql
@@ -5,8 +5,10 @@
* @problem.severity warning
* @precision high
* @id cpp/resource-not-released-in-destructor
- * @tags efficiency
- * readability
+ * @tags quality
+ * reliability
+ * correctness
+ * efficiency
* external/cwe/cwe-404
* external/jsf
*/
@@ -89,7 +91,7 @@ Expr exprOrDereference(Expr e) {
*/
private predicate exprReleases(Expr e, Expr released, string kind) {
// `e` is a call to a release function and `released` is the released argument
- releaseExpr(e, released, kind)
+ releaseExpr(e, pragma[only_bind_into](globalValueNumber(released).getAnExpr()), kind)
or
exists(int arg, VariableAccess access, Function f |
// `e` is a call to a function that releases one of it's parameters,
diff --git a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql
index cd08362ad35a..87086db9e9a9 100644
--- a/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql
+++ b/cpp/ql/src/jsf/4.20 Unions and Bit Fields/AV Rule 154.ql
@@ -22,7 +22,7 @@ where
not bf.getUnderlyingType() instanceof Enum and
not bf.getUnspecifiedType() instanceof BoolType and
not bf.getType().hasName("BOOL") and // At least for C programs on Windows, BOOL is a common typedef for a type representing BoolType.
- not bf.getDeclaredNumBits() = bf.getType().getSize() * 8 and // If this is true, then there cannot be unsigned sign extension or overflow.
+ not bf.getDeclaredNumBits() = bf.getType().getBitWidth() and // If this is true, then there cannot be unsigned sign extension or overflow.
not bf.isAnonymous()
select bf,
"Bit field " + bf.getName() + " of type " + bf.getUnderlyingType().getName() +
diff --git a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql
index 16727add3fff..7e03caef0b91 100644
--- a/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql
+++ b/cpp/ql/src/jsf/4.23 Type Conversions/AV Rule 180.ql
@@ -61,10 +61,10 @@ class ImplicitConversion extends Expr {
int getSourceSize() {
if this instanceof IntConstantExpr
then result = this.(IntConstantExpr).getRequiredSizeBits()
- else result = this.getUnderlyingSourceType().getSize() * 8
+ else result = this.getUnderlyingSourceType().getBitWidth()
}
- int getTargetSize() { result = this.getUnderlyingTargetType().getSize() * 8 }
+ int getTargetSize() { result = this.getUnderlyingTargetType().getBitWidth() }
predicate isSourceSignedInt() {
if this instanceof IntConstantExpr
diff --git a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql
index 4f76b4c10eaa..17f6b41b5c7d 100644
--- a/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql
+++ b/cpp/ql/src/jsf/4.24 Control Flow Structures/AV Rule 197.ql
@@ -5,7 +5,8 @@
* @problem.severity recommendation
* @precision high
* @id cpp/loop-variable-float
- * @tags correctness
+ * @tags quality
+ * correctness
* reliability
* external/jsf
*/
diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml
index ad0a0cd8943b..0bc1233931a4 100644
--- a/cpp/ql/src/qlpack.yml
+++ b/cpp/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-queries
-version: 1.8.1-dev
+version: 1.10.1-dev
groups:
- cpp
- queries
diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-120/MmioUnsanitizedMemcpy/MmioUnsanitizedMemcpy.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-120/MmioUnsanitizedMemcpy/MmioUnsanitizedMemcpy.expected
new file mode 100644
index 000000000000..322b2ef7c419
--- /dev/null
+++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-120/MmioUnsanitizedMemcpy/MmioUnsanitizedMemcpy.expected
@@ -0,0 +1,28 @@
+#select
+| test.c:26:20:26:22 | len | test.c:25:18:25:37 | * ... | test.c:26:20:26:22 | len | Memory copy size argument is derived from $@ without sufficient bounds validation. | test.c:25:18:25:37 | * ... | an MMIO/DMA hardware register read |
+| test.c:31:21:31:23 | len | test.c:30:18:30:37 | * ... | test.c:31:21:31:23 | len | Memory copy size argument is derived from $@ without sufficient bounds validation. | test.c:30:18:30:37 | * ... | an MMIO/DMA hardware register read |
+| test.c:36:21:36:23 | len | test.c:35:18:35:37 | * ... | test.c:36:21:36:23 | len | Memory copy size argument is derived from $@ without sufficient bounds validation. | test.c:35:18:35:37 | * ... | an MMIO/DMA hardware register read |
+| test.c:41:20:41:22 | len | test.c:40:18:40:37 | * ... | test.c:41:20:41:22 | len | Memory copy size argument is derived from $@ without sufficient bounds validation. | test.c:40:18:40:37 | * ... | an MMIO/DMA hardware register read |
+edges
+| test.c:25:18:25:37 | * ... | test.c:25:18:25:37 | * ... | provenance | |
+| test.c:25:18:25:37 | * ... | test.c:26:20:26:22 | len | provenance | |
+| test.c:30:18:30:37 | * ... | test.c:30:18:30:37 | * ... | provenance | |
+| test.c:30:18:30:37 | * ... | test.c:31:21:31:23 | len | provenance | |
+| test.c:35:18:35:37 | * ... | test.c:35:18:35:37 | * ... | provenance | |
+| test.c:35:18:35:37 | * ... | test.c:36:21:36:23 | len | provenance | |
+| test.c:40:18:40:37 | * ... | test.c:40:18:40:37 | * ... | provenance | |
+| test.c:40:18:40:37 | * ... | test.c:41:20:41:22 | len | provenance | |
+nodes
+| test.c:25:18:25:37 | * ... | semmle.label | * ... |
+| test.c:25:18:25:37 | * ... | semmle.label | * ... |
+| test.c:26:20:26:22 | len | semmle.label | len |
+| test.c:30:18:30:37 | * ... | semmle.label | * ... |
+| test.c:30:18:30:37 | * ... | semmle.label | * ... |
+| test.c:31:21:31:23 | len | semmle.label | len |
+| test.c:35:18:35:37 | * ... | semmle.label | * ... |
+| test.c:35:18:35:37 | * ... | semmle.label | * ... |
+| test.c:36:21:36:23 | len | semmle.label | len |
+| test.c:40:18:40:37 | * ... | semmle.label | * ... |
+| test.c:40:18:40:37 | * ... | semmle.label | * ... |
+| test.c:41:20:41:22 | len | semmle.label | len |
+subpaths
diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-120/MmioUnsanitizedMemcpy/MmioUnsanitizedMemcpy.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-120/MmioUnsanitizedMemcpy/MmioUnsanitizedMemcpy.qlref
new file mode 100644
index 000000000000..671ab2524272
--- /dev/null
+++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-120/MmioUnsanitizedMemcpy/MmioUnsanitizedMemcpy.qlref
@@ -0,0 +1,2 @@
+query: experimental/Security/CWE/CWE-120/MmioUnsanitizedMemcpy.ql
+postprocess: utils/test/InlineExpectationsTestQuery.ql
diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-120/MmioUnsanitizedMemcpy/test.c b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-120/MmioUnsanitizedMemcpy/test.c
new file mode 100644
index 000000000000..bf5c1bb583f4
--- /dev/null
+++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-120/MmioUnsanitizedMemcpy/test.c
@@ -0,0 +1,83 @@
+/* Test case for MmioUnsanitizedMemcpy.ql
+ * Allowlisted MMIO/DMA register macros flowing into memcpy/memmove/strncpy size parameters.
+ */
+
+typedef unsigned int uint32_t;
+
+void *memcpy(void *dest, const void *src, unsigned long n);
+void *memmove(void *dest, const void *src, unsigned long n);
+char *strncpy(char *dest, const char *src, unsigned long n);
+
+#define READ_REG(addr) (*(volatile uint32_t *)(addr))
+#define GET_MMIO(addr) (*(volatile uint32_t *)(addr))
+#define REG_READ(addr) (*(volatile uint32_t *)(addr))
+#define DMA_READ(addr) (*(volatile uint32_t *)(addr))
+#define MAX_DMA_LEN 64
+
+struct VolatileField {
+ volatile uint32_t len;
+};
+
+volatile uint32_t mmio_len_reg;
+struct VolatileField vf;
+
+static void bad_read_reg(char *dst, char *src) {
+ uint32_t len = READ_REG(0x40001000); // $ Source
+ memcpy(dst, src, len); // $ Alert
+}
+
+static void bad_get_mmio(char *dst, char *src) {
+ uint32_t len = GET_MMIO(0x50000000); // $ Source
+ memmove(dst, src, len); // $ Alert
+}
+
+static void bad_reg_read(char *dst, char *src) {
+ uint32_t len = REG_READ(0x51000000); // $ Source
+ strncpy(dst, src, len); // $ Alert
+}
+
+static void bad_dma_read(char *dst, char *src) {
+ uint32_t len = DMA_READ(0x60000000); // $ Source
+ memcpy(dst, src, len); // $ Alert
+}
+
+static void good_bounded(char *dst, char *src) {
+ uint32_t len = READ_REG(0x40001000);
+ if (len <= MAX_DMA_LEN)
+ memcpy(dst, src, len); // GOOD
+}
+
+static void good_early_return(char *dst, char *src) {
+ uint32_t len = DMA_READ(0x60000000);
+ if (len > MAX_DMA_LEN)
+ return;
+ memcpy(dst, src, len); // GOOD
+}
+
+static void good_constant_size(char *dst, char *src) {
+ uint32_t len = READ_REG(0x40001000);
+ memcpy(dst, src, 32); // GOOD
+}
+
+static void negative_volatile_global(char *dst, char *src) {
+ uint32_t len = mmio_len_reg;
+ memcpy(dst, src, len); // GOOD
+}
+
+static void negative_volatile_field(char *dst, char *src) {
+ uint32_t len = vf.len;
+ memcpy(dst, src, len); // GOOD
+}
+
+static void negative_volatile_deref(char *dst, char *src) {
+ volatile uint32_t *reg = (volatile uint32_t *)0x40001000;
+ uint32_t len = *reg;
+ memcpy(dst, src, len); // GOOD
+}
+
+static uint32_t GET_MMIO_fn(unsigned long addr);
+
+static void negative_get_mmio_function(char *dst, char *src) {
+ uint32_t len = GET_MMIO_fn(0x50000000);
+ memcpy(dst, src, len); // GOOD
+}
diff --git a/cpp/ql/test/include/iterator.h b/cpp/ql/test/include/iterator.h
index 5cd7f2312842..77758bfa8da6 100644
--- a/cpp/ql/test/include/iterator.h
+++ b/cpp/ql/test/include/iterator.h
@@ -65,7 +65,7 @@ namespace std {
};
template
- constexpr back_insert_iterator back_inserter(Container& x) { // $ ir-def=*x
+ constexpr back_insert_iterator back_inserter(Container& x) {
return back_insert_iterator(x);
}
@@ -89,7 +89,7 @@ namespace std {
constexpr front_insert_iterator operator++(int);
};
template
- constexpr front_insert_iterator front_inserter(Container& x) { // $ ir-def=*x
+ constexpr front_insert_iterator front_inserter(Container& x) {
return front_insert_iterator(x);
}
}
diff --git a/cpp/ql/test/include/type_traits.h b/cpp/ql/test/include/type_traits.h
index dba04f36cad6..421ae3bd50cc 100644
--- a/cpp/ql/test/include/type_traits.h
+++ b/cpp/ql/test/include/type_traits.h
@@ -1,9 +1,10 @@
#if !defined(CODEQL_TYPE_TRAITS_H)
#define CODEQL_TYPE_TRAITS_H
-typedef unsigned long size_t;
+using size_t = decltype(sizeof(0));
namespace std {
+ using size_t = decltype(sizeof(0));
template
struct remove_const { typedef T type; };
diff --git a/cpp/ql/test/library-tests/blocks/c/code_blocks.ql b/cpp/ql/test/library-tests/blocks/c/code_blocks.ql
index 1662525cae6e..647923eea563 100644
--- a/cpp/ql/test/library-tests/blocks/c/code_blocks.ql
+++ b/cpp/ql/test/library-tests/blocks/c/code_blocks.ql
@@ -1,20 +1,16 @@
import cpp
-predicate paramsString(Function f, int n, string res) {
- if n = -1
- then res = ""
- else
- exists(string sep |
- (if n = 0 then sep = "" else sep = ", ") and
- exists(string prefixRes |
- paramsString(f, n - 1, prefixRes) and
- res = prefixRes + sep + f.getParameter(n) + "(" + f.getParameter(n).getType() + ")"
- )
+string paramsString(Function f) {
+ result =
+ concat(int i |
+ exists(f.getParameter(i))
+ |
+ f.getParameter(i) + "(" + f.getParameter(i).getType() + ")", ", " order by i
)
}
from BlockExpr e, Function f, string params
where
f = e.getFunction() and
- paramsString(f, f.getNumberOfParameters() - 1, params)
+ params = paramsString(f)
select e, e.getType() as te, te.explain(), e.getFunction(), f.getType() as tf, tf.explain(), params
diff --git a/cpp/ql/test/library-tests/blocks/cpp/code_blocks.ql b/cpp/ql/test/library-tests/blocks/cpp/code_blocks.ql
index 1662525cae6e..647923eea563 100644
--- a/cpp/ql/test/library-tests/blocks/cpp/code_blocks.ql
+++ b/cpp/ql/test/library-tests/blocks/cpp/code_blocks.ql
@@ -1,20 +1,16 @@
import cpp
-predicate paramsString(Function f, int n, string res) {
- if n = -1
- then res = ""
- else
- exists(string sep |
- (if n = 0 then sep = "" else sep = ", ") and
- exists(string prefixRes |
- paramsString(f, n - 1, prefixRes) and
- res = prefixRes + sep + f.getParameter(n) + "(" + f.getParameter(n).getType() + ")"
- )
+string paramsString(Function f) {
+ result =
+ concat(int i |
+ exists(f.getParameter(i))
+ |
+ f.getParameter(i) + "(" + f.getParameter(i).getType() + ")", ", " order by i
)
}
from BlockExpr e, Function f, string params
where
f = e.getFunction() and
- paramsString(f, f.getNumberOfParameters() - 1, params)
+ params = paramsString(f)
select e, e.getType() as te, te.explain(), e.getFunction(), f.getType() as tf, tf.explain(), params
diff --git a/cpp/ql/test/library-tests/builtins/builtins/builtins.expected b/cpp/ql/test/library-tests/builtins/builtins/builtins.expected
index 48007d6b0e18..2e8e7fd247d6 100644
--- a/cpp/ql/test/library-tests/builtins/builtins/builtins.expected
+++ b/cpp/ql/test/library-tests/builtins/builtins/builtins.expected
@@ -1,4 +1,12 @@
| choose_expr.c:3:13:3:42 | __builtin_choose_expr |
+| spaceship.cpp:22:41:22:101 | __builtin_lt_synthesizes_from_spaceship |
+| spaceship.cpp:23:41:23:89 | __builtin_lt_synthesizes_from_spaceship |
+| spaceship.cpp:24:41:24:101 | __builtin_gt_synthesizes_from_spaceship |
+| spaceship.cpp:25:41:25:89 | __builtin_gt_synthesizes_from_spaceship |
+| spaceship.cpp:26:41:26:101 | __builtin_le_synthesizes_from_spaceship |
+| spaceship.cpp:27:41:27:89 | __builtin_le_synthesizes_from_spaceship |
+| spaceship.cpp:28:41:28:101 | __builtin_ge_synthesizes_from_spaceship |
+| spaceship.cpp:29:41:29:89 | __builtin_ge_synthesizes_from_spaceship |
| types.c:4:9:4:57 | __builtin_types_compatible_p |
| types.c:6:16:6:65 | __builtin_types_compatible_p |
| varargs.c:7:5:7:32 | __builtin_va_start |
diff --git a/cpp/ql/test/library-tests/builtins/builtins/expr.expected b/cpp/ql/test/library-tests/builtins/builtins/expr.expected
new file mode 100644
index 000000000000..a642c211d5c5
--- /dev/null
+++ b/cpp/ql/test/library-tests/builtins/builtins/expr.expected
@@ -0,0 +1,106 @@
+| atomic.cpp:3:10:3:27 | call to __atomic_fetch_add_4 | ptr,1,0 | |
+| atomic.cpp:3:10:3:38 | (int)... | | |
+| atomic.cpp:3:29:3:31 | (volatile void *)... | | |
+| atomic.cpp:3:29:3:31 | ptr | | |
+| atomic.cpp:3:34:3:34 | 1 | | 1 |
+| atomic.cpp:3:34:3:34 | (unsigned int)... | | 1 |
+| atomic.cpp:3:37:3:37 | 0 | | 0 |
+| atomic.cpp:8:10:8:27 | call to __atomic_fetch_add_1 | ptr,1,0 | |
+| atomic.cpp:8:10:8:38 | (char)... | | |
+| atomic.cpp:8:10:8:38 | (double)... | | |
+| atomic.cpp:8:29:8:31 | (volatile void *)... | | |
+| atomic.cpp:8:29:8:31 | ptr | | |
+| atomic.cpp:8:34:8:34 | 1 | | 1 |
+| atomic.cpp:8:34:8:34 | (unsigned char)... | | 1 |
+| atomic.cpp:8:37:8:37 | 0 | | 0 |
+| atomic.cpp:13:10:13:29 | call to __atomic_fetch_add_4 | ptr,1,0 | |
+| atomic.cpp:13:10:13:40 | (int)... | | |
+| atomic.cpp:13:31:13:33 | (volatile void *)... | | |
+| atomic.cpp:13:31:13:33 | ptr | | |
+| atomic.cpp:13:36:13:36 | 1 | | 1 |
+| atomic.cpp:13:36:13:36 | (unsigned int)... | | 1 |
+| atomic.cpp:13:39:13:39 | 0 | | 0 |
+| atomic.cpp:18:10:18:29 | call to __atomic_fetch_add_1 | ptr,1,0 | |
+| atomic.cpp:18:10:18:40 | (char)... | | |
+| atomic.cpp:18:31:18:33 | (volatile void *)... | | |
+| atomic.cpp:18:31:18:33 | ptr | | |
+| atomic.cpp:18:36:18:36 | 1 | | 1 |
+| atomic.cpp:18:36:18:36 | (unsigned char)... | | 1 |
+| atomic.cpp:18:39:18:39 | 0 | | 0 |
+| choose_expr.c:3:13:3:42 | __builtin_choose_expr | 1,5,6 | |
+| choose_expr.c:3:35:3:35 | 1 | | 1 |
+| choose_expr.c:3:38:3:38 | 5 | | 5 |
+| choose_expr.c:3:41:3:41 | 6 | | 6 |
+| spaceship.cpp:6:45:6:45 | n | this | |
+| spaceship.cpp:6:45:6:45 | this | | |
+| spaceship.cpp:9:53:9:56 | {...} | - ... | |
+| spaceship.cpp:9:54:9:55 | - ... | 1 | -1 |
+| spaceship.cpp:9:55:9:55 | 1 | | 1 |
+| spaceship.cpp:10:54:10:56 | {...} | 0 | |
+| spaceship.cpp:10:55:10:55 | 0 | | 0 |
+| spaceship.cpp:11:56:11:58 | {...} | 1 | |
+| spaceship.cpp:11:57:11:57 | 1 | | 1 |
+| spaceship.cpp:18:12:18:14 | rhs | | |
+| spaceship.cpp:18:12:18:24 | ... <=> ... | rhs,i | |
+| spaceship.cpp:18:20:18:22 | lhs | | |
+| spaceship.cpp:18:24:18:24 | i | lhs | |
+| spaceship.cpp:22:41:22:101 | __builtin_lt_synthesizes_from_spaceship | const S &,const int & | 1 |
+| spaceship.cpp:22:41:22:101 | const S & | | |
+| spaceship.cpp:22:41:22:101 | const int & | | |
+| spaceship.cpp:23:41:23:89 | __builtin_lt_synthesizes_from_spaceship | int,int | 0 |
+| spaceship.cpp:23:41:23:89 | int | | |
+| spaceship.cpp:23:41:23:89 | int | | |
+| spaceship.cpp:24:41:24:101 | __builtin_gt_synthesizes_from_spaceship | const S &,const int & | 1 |
+| spaceship.cpp:24:41:24:101 | const S & | | |
+| spaceship.cpp:24:41:24:101 | const int & | | |
+| spaceship.cpp:25:41:25:89 | __builtin_gt_synthesizes_from_spaceship | int,int | 0 |
+| spaceship.cpp:25:41:25:89 | int | | |
+| spaceship.cpp:25:41:25:89 | int | | |
+| spaceship.cpp:26:41:26:101 | __builtin_le_synthesizes_from_spaceship | const S &,const int & | 1 |
+| spaceship.cpp:26:41:26:101 | const S & | | |
+| spaceship.cpp:26:41:26:101 | const int & | | |
+| spaceship.cpp:27:41:27:89 | __builtin_le_synthesizes_from_spaceship | int,int | 0 |
+| spaceship.cpp:27:41:27:89 | int | | |
+| spaceship.cpp:27:41:27:89 | int | | |
+| spaceship.cpp:28:41:28:101 | __builtin_ge_synthesizes_from_spaceship | const S &,const int & | 1 |
+| spaceship.cpp:28:41:28:101 | const S & | | |
+| spaceship.cpp:28:41:28:101 | const int & | | |
+| spaceship.cpp:29:41:29:89 | __builtin_ge_synthesizes_from_spaceship | int,int | 0 |
+| spaceship.cpp:29:41:29:89 | int | | |
+| spaceship.cpp:29:41:29:89 | int | | |
+| types.c:4:9:4:57 | __builtin_types_compatible_p | typeof(...),long | 0 |
+| types.c:4:9:4:57 | long | | |
+| types.c:4:9:4:57 | typeof(...) | | |
+| types.c:4:49:4:49 | s | | |
+| types.c:5:9:5:12 | call to puts | long | |
+| types.c:5:14:5:19 | array to pointer conversion | | |
+| types.c:5:14:5:19 | long | | long |
+| types.c:6:16:6:65 | __builtin_types_compatible_p | typeof(...),char * | 1 |
+| types.c:6:16:6:65 | char * | | |
+| types.c:6:16:6:65 | typeof(...) | | |
+| types.c:6:56:6:56 | s | | |
+| types.c:7:9:7:12 | call to puts | str | |
+| types.c:7:14:7:18 | array to pointer conversion | | |
+| types.c:7:14:7:18 | str | | str |
+| types.c:9:12:9:14 | (...) | | 0 |
+| types.c:9:13:9:13 | 0 | | 0 |
+| varargs.c:7:5:7:32 | __builtin_va_start | ap,args | |
+| varargs.c:7:24:7:25 | ap | | |
+| varargs.c:7:24:7:25 | array to pointer conversion | | |
+| varargs.c:7:28:7:31 | args | | |
+| varargs.c:8:10:8:10 | i | | |
+| varargs.c:8:10:8:14 | ... = ... | i,0 | |
+| varargs.c:8:14:8:14 | 0 | | 0 |
+| varargs.c:8:17:8:17 | i | | |
+| varargs.c:8:17:8:24 | ... < ... | i,args | |
+| varargs.c:8:21:8:24 | args | | |
+| varargs.c:8:27:8:27 | i | | |
+| varargs.c:8:27:8:29 | ... ++ | i | |
+| varargs.c:9:9:9:9 | j | | |
+| varargs.c:9:9:9:37 | ... = ... | j,__builtin_va_arg | |
+| varargs.c:9:13:9:37 | __builtin_va_arg | ap | |
+| varargs.c:9:30:9:31 | ap | | |
+| varargs.c:9:30:9:31 | array to pointer conversion | | |
+| varargs.c:11:5:11:24 | __builtin_va_end | ap | |
+| varargs.c:11:22:11:23 | ap | | |
+| varargs.c:11:22:11:23 | array to pointer conversion | | |
diff --git a/cpp/ql/test/library-tests/builtins/builtins/expr.ql b/cpp/ql/test/library-tests/builtins/builtins/expr.ql
new file mode 100644
index 000000000000..c638cf501562
--- /dev/null
+++ b/cpp/ql/test/library-tests/builtins/builtins/expr.ql
@@ -0,0 +1,5 @@
+import cpp
+
+from Expr e, string value
+where if exists(e.getValue()) then value = e.getValue().toString() else value = ""
+select e, concat(int i | | e.getChild(i).toString(), "," order by i), value
diff --git a/cpp/ql/test/library-tests/builtins/builtins/spaceship.cpp b/cpp/ql/test/library-tests/builtins/builtins/spaceship.cpp
new file mode 100644
index 000000000000..94f978587b1f
--- /dev/null
+++ b/cpp/ql/test/library-tests/builtins/builtins/spaceship.cpp
@@ -0,0 +1,29 @@
+// semmle-extractor-options: --clang --clang_version 240000 -std=c++23
+
+namespace std {
+ struct strong_ordering {
+ int n;
+ constexpr operator int() const { return n; }
+ static const strong_ordering less, equal, greater;
+ };
+ constexpr strong_ordering strong_ordering::less = {-1};
+ constexpr strong_ordering strong_ordering::equal = {0};
+ constexpr strong_ordering strong_ordering::greater = {1};
+}
+
+struct S {
+ int i;
+
+ friend auto operator<=>(S lhs, int rhs) {
+ return rhs <=> lhs.i;
+ }
+};
+
+bool b_lt_synthesizes_from_spaceship1 = __builtin_lt_synthesizes_from_spaceship(const S&, const int&);
+bool b_lt_synthesizes_from_spaceship2 = __builtin_lt_synthesizes_from_spaceship(int, int);
+bool b_gt_synthesizes_from_spaceship1 = __builtin_gt_synthesizes_from_spaceship(const S&, const int&);
+bool b_gt_synthesizes_from_spaceship2 = __builtin_gt_synthesizes_from_spaceship(int, int);
+bool b_le_synthesizes_from_spaceship1 = __builtin_le_synthesizes_from_spaceship(const S&, const int&);
+bool b_le_synthesizes_from_spaceship2 = __builtin_le_synthesizes_from_spaceship(int, int);
+bool b_ge_synthesizes_from_spaceship1 = __builtin_ge_synthesizes_from_spaceship(const S&, const int&);
+bool b_ge_synthesizes_from_spaceship2 = __builtin_ge_synthesizes_from_spaceship(int, int);
diff --git a/cpp/ql/test/library-tests/builtins/type_traits/clang.cpp b/cpp/ql/test/library-tests/builtins/type_traits/clang.cpp
index 3db47a824ede..67664754f4e5 100644
--- a/cpp/ql/test/library-tests/builtins/type_traits/clang.cpp
+++ b/cpp/ql/test/library-tests/builtins/type_traits/clang.cpp
@@ -122,10 +122,20 @@ bool b_is_scoped_enum2 = __is_scoped_enum(int);
bool b_is_trivially_relocatable1 = __is_trivially_relocatable(int);
bool b_is_trivially_relocatable2 = __is_trivially_relocatable(void);
-struct S3{
+struct S3 {
S3(S3 &);
S3& operator=(S3&);
};
-bool bok_is_bitwise_cloneable1 = __is_bitwise_cloneable(int);
-bool bok_is_bitwise_cloneable2 = __is_bitwise_cloneable(S3);
+bool b_is_bitwise_cloneable1 = __is_bitwise_cloneable(int);
+bool b_is_bitwise_cloneable2 = __is_bitwise_cloneable(S3);
+
+struct S4 : virtual S3 {
+ ~S4() = delete;
+};
+
+bool b_is_virtual_base_of1 = __builtin_is_virtual_base_of(int, S4);
+bool b_is_virtual_base_of2 = __builtin_is_virtual_base_of(S3, S4);
+
+bool b_is_implicit_lifetime1 = __builtin_is_implicit_lifetime(int);
+bool b_is_implicit_lifetime2 = __builtin_is_implicit_lifetime(S4);
diff --git a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected
index 1728a48f4237..1580d5dba959 100644
--- a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected
+++ b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected
@@ -165,10 +165,20 @@
| clang.cpp:122:36:122:66 | int | | |
| clang.cpp:123:36:123:67 | __is_trivially_relocatable | void | 0 |
| clang.cpp:123:36:123:67 | void | | |
-| clang.cpp:130:34:130:60 | __is_bitwise_cloneable | int | 1 |
-| clang.cpp:130:34:130:60 | int | | |
-| clang.cpp:131:34:131:59 | S3 | | |
-| clang.cpp:131:34:131:59 | __is_bitwise_cloneable | S3 | 0 |
+| clang.cpp:130:32:130:58 | __is_bitwise_cloneable | int | 1 |
+| clang.cpp:130:32:130:58 | int | | |
+| clang.cpp:131:32:131:57 | S3 | | |
+| clang.cpp:131:32:131:57 | __is_bitwise_cloneable | S3 | 0 |
+| clang.cpp:137:30:137:66 | S4 | | |
+| clang.cpp:137:30:137:66 | __builtin_is_virtual_base_of | int,S4 | 0 |
+| clang.cpp:137:30:137:66 | int | | |
+| clang.cpp:138:30:138:65 | S3 | | |
+| clang.cpp:138:30:138:65 | S4 | | |
+| clang.cpp:138:30:138:65 | __builtin_is_virtual_base_of | S3,S4 | 1 |
+| clang.cpp:140:32:140:66 | __builtin_is_implicit_lifetime | int | 1 |
+| clang.cpp:140:32:140:66 | int | | |
+| clang.cpp:141:32:141:65 | S4 | | |
+| clang.cpp:141:32:141:65 | __builtin_is_implicit_lifetime | S4 | 0 |
| file://:0:0:0:0 | 0 | | 0 |
| file://:0:0:0:0 | 0 | | 0 |
| file://:0:0:0:0 | 1 | | 1 |
@@ -225,6 +235,10 @@
| gcc.cpp:37:32:37:67 | __is_nothrow_invocable | f_type,bool | 0 |
| gcc.cpp:37:32:37:67 | bool | | |
| gcc.cpp:37:32:37:67 | f_type | | |
+| gcc.cpp:39:25:39:52 | __builtin_is_structural | int | 1 |
+| gcc.cpp:39:25:39:52 | int | | |
+| gcc.cpp:40:25:40:54 | __builtin_is_structural | int && | 0 |
+| gcc.cpp:40:25:40:54 | int && | | |
| ms.cpp:38:41:38:45 | 0 | | 0 |
| ms.cpp:88:27:88:45 | __has_assign | empty | 0 |
| ms.cpp:88:27:88:45 | empty | | |
diff --git a/cpp/ql/test/library-tests/builtins/type_traits/expr.ql b/cpp/ql/test/library-tests/builtins/type_traits/expr.ql
index a7d2b436ebde..c638cf501562 100644
--- a/cpp/ql/test/library-tests/builtins/type_traits/expr.ql
+++ b/cpp/ql/test/library-tests/builtins/type_traits/expr.ql
@@ -1,15 +1,5 @@
import cpp
-string childrenFrom(Expr e, int i) {
- (
- if i = 0
- then result = e.getChild(i).toString() + childrenFrom(e, i + 1)
- else result = "," + e.getChild(i).toString() + childrenFrom(e, i + 1)
- )
- or
- i = e.getNumChild() and result = ""
-}
-
from Expr e, string value
where if exists(e.getValue()) then value = e.getValue().toString() else value = ""
-select e, childrenFrom(e, 0), value
+select e, concat(int i | | e.getChild(i).toString(), "," order by i), value
diff --git a/cpp/ql/test/library-tests/builtins/type_traits/gcc.cpp b/cpp/ql/test/library-tests/builtins/type_traits/gcc.cpp
index 15f59812d2e9..7c6189b81aff 100644
--- a/cpp/ql/test/library-tests/builtins/type_traits/gcc.cpp
+++ b/cpp/ql/test/library-tests/builtins/type_traits/gcc.cpp
@@ -1,4 +1,4 @@
-// semmle-extractor-options: --gnu_version 150000
+// semmle-extractor-options: --gnu_version 170000
__attribute__ ((aligned(8))) int v;
bool b_has_attribute1 = __builtin_has_attribute(v, aligned);
@@ -35,3 +35,6 @@ bool b_is_invocable2 = __is_invocable(f_type, bool);
bool b_is_nothrow_invocable1 = __is_nothrow_invocable(f_type);
bool b_is_nothrow_invocable2 = __is_nothrow_invocable(f_type, bool);
+
+bool b_is_structural1 = __builtin_is_structural(int);
+bool b_is_structural2 = __builtin_is_structural(int&&);
diff --git a/cpp/ql/test/library-tests/compiler_generated/compilerGenerated.expected b/cpp/ql/test/library-tests/compiler_generated/compilerGenerated.expected
index b61085ff7c69..c78e4af1d6a4 100644
--- a/cpp/ql/test/library-tests/compiler_generated/compilerGenerated.expected
+++ b/cpp/ql/test/library-tests/compiler_generated/compilerGenerated.expected
@@ -16,5 +16,31 @@
| cpp.cpp:15:5:15:12 | call to ~MyClass | Expr |
| cpp.cpp:15:12:15:12 | reuse of m | Expr |
| cpp.cpp:16:1:16:1 | return ... | Stmt |
+| cpp.cpp:19:26:19:44 | __PRETTY_FUNCTION__ | Variable |
+| cpp.cpp:19:26:19:44 | array to pointer conversion | Expr |
+| cpp.cpp:19:26:19:44 | initializer for __PRETTY_FUNCTION__ | Initializer |
+| cpp.cpp:19:26:19:44 | void uses_pretty_function() | Expr |
+| cpp.cpp:20:1:20:1 | return ... | Stmt |
+| cpp.cpp:23:29:23:32 | args | Variable |
+| cpp.cpp:23:37:23:37 | return ... | Stmt |
+| cpp.cpp:23:37:23:37 | return ... | Stmt |
+| cpp.cpp:27:1:27:1 | return ... | Stmt |
+| cpp.cpp:31:5:31:5 | (__begin) | Variable |
+| cpp.cpp:31:5:31:5 | (__end) | Variable |
+| cpp.cpp:31:5:31:5 | (__range) | Variable |
+| cpp.cpp:31:5:33:5 | declaration | Stmt |
+| cpp.cpp:31:5:33:5 | declaration | Stmt |
+| cpp.cpp:31:5:33:5 | declaration | Stmt |
+| cpp.cpp:31:17:31:18 | (reference to) | Expr |
+| cpp.cpp:34:1:34:1 | return ... | Stmt |
+| file://:0:0:0:0 | (__begin) | Expr |
+| file://:0:0:0:0 | (__begin) | Expr |
+| file://:0:0:0:0 | (__begin) | Expr |
+| file://:0:0:0:0 | (__end) | Expr |
+| file://:0:0:0:0 | (reference dereference) | Expr |
+| file://:0:0:0:0 | (reference dereference) | Expr |
+| file://:0:0:0:0 | * ... | Expr |
+| file://:0:0:0:0 | array to pointer conversion | Expr |
+| file://:0:0:0:0 | array to pointer conversion | Expr |
| file://:0:0:0:0 | operator delete | Function |
| file://:0:0:0:0 | operator new | Function |
diff --git a/cpp/ql/test/library-tests/compiler_generated/compilerGenerated.ql b/cpp/ql/test/library-tests/compiler_generated/compilerGenerated.ql
index 0eb620f0c792..1ed4a9395e19 100644
--- a/cpp/ql/test/library-tests/compiler_generated/compilerGenerated.ql
+++ b/cpp/ql/test/library-tests/compiler_generated/compilerGenerated.ql
@@ -9,4 +9,6 @@ where
e.(Variable).isCompilerGenerated() and type = "Variable"
or
e.(Stmt).isCompilerGenerated() and type = "Stmt"
+ or
+ e.(Initializer).isCompilerGenerated() and type = "Initializer"
select e, type
diff --git a/cpp/ql/test/library-tests/compiler_generated/cpp.cpp b/cpp/ql/test/library-tests/compiler_generated/cpp.cpp
index 058bba7ba411..7525be8d40e8 100644
--- a/cpp/ql/test/library-tests/compiler_generated/cpp.cpp
+++ b/cpp/ql/test/library-tests/compiler_generated/cpp.cpp
@@ -15,3 +15,20 @@ void g1(void) {
delete m;
}
+void uses_pretty_function() {
+ const char* pretty = __PRETTY_FUNCTION__;
+}
+
+template
+void parameter_pack(Args... args) { }
+
+void test_parameter_pack() {
+ parameter_pack();
+}
+
+void ranged_for() {
+ int vs[] = {1, 2, 3};
+ for(int i : vs) {
+
+ }
+}
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/cpp11_g/cfg.ql b/cpp/ql/test/library-tests/cpp11_g/cfg.ql
index 105b4e709ee7..f4df06adde03 100644
--- a/cpp/ql/test/library-tests/cpp11_g/cfg.ql
+++ b/cpp/ql/test/library-tests/cpp11_g/cfg.ql
@@ -1,16 +1,12 @@
import cpp
-string arguments(Function f, int i) {
- result = "," and i = -1
- or
- result = "" and i = min(int j | function_template_argument(unresolveElement(f), j, _)) - 1
- or
- result = arguments(f, i - 1) + "," + f.getTemplateArgument(i).toString()
+string arguments(Function f) {
+ result = concat(int i | | f.getTemplateArgument(i).toString(), "," order by i)
}
string name(Function f) {
if f.isConstructedFrom(_)
- then result = f.toString() + "<" + max(arguments(f, _)).suffix(1) + ">"
+ then result = f.toString() + "<" + arguments(f) + ">"
else
if f instanceof TemplateFunction
then result = f.toString() + " prototype instantiation"
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.ql
index 8f534be558d7..a7118463d96a 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.ql
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/has-parameter-flow-out.ql
@@ -27,7 +27,7 @@ module IRTest {
private string stars(int k) {
k = [0 .. max(DataFlow::Node n, int i | n.isFinalValueOfParameter(_, i) | i)] and
- (if k = 0 then result = "" else result = "*" + stars(k - 1))
+ result = concat(int i | i in [1 .. k] | "*")
}
module IRParameterDefTest implements TestSig {
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/asio_streams.cpp b/cpp/ql/test/library-tests/dataflow/external-models/asio_streams.cpp
index 401091122b8e..8e6440df98a1 100644
--- a/cpp/ql/test/library-tests/dataflow/external-models/asio_streams.cpp
+++ b/cpp/ql/test/library-tests/dataflow/external-models/asio_streams.cpp
@@ -1,24 +1,9 @@
// --- stub library headers ---
-namespace std {
- typedef unsigned long size_t;
- #define SIZE_MAX 0xFFFFFFFF
+#include "../taint-tests/stl.h"
- template class allocator {
- };
-
- template struct char_traits {
- };
-
- template, class Allocator = allocator >
- class basic_string {
- public:
- basic_string(const charT* s, const Allocator& a = Allocator());
- };
-
- typedef basic_string string;
-};
+#define SIZE_MAX 0xFFFFFFFF
namespace boost {
namespace system {
@@ -29,14 +14,50 @@ namespace boost {
};
namespace asio {
- template
- class basic_stream_socket /*: public basic_socket*/ {
- };
+ class any_io_executor { };
+
+ class socket_base { };
+
+ template
+ class basic_socket : public socket_base { };
+
+ template
+ class basic_stream_socket : public basic_socket { };
namespace ip {
+ class resolver_base {
+ public:
+ enum flags { passive = 1 };
+ };
+
+ template
+ class basic_resolver {
+ public:
+ class results_type {
+ };
+
+ results_type resolve(const std::string &host, const std::string &service);
+ results_type resolve(const std::string &host, const std::string &service, boost::system::error_code &ec);
+ results_type resolve(const std::string &host, const std::string &service, resolver_base::flags resolve_flags);
+ results_type resolve(const std::string &host, const std::string &service, resolver_base::flags resolve_flags, boost::system::error_code &ec);
+ results_type resolve(std::string_view host, std::string_view service);
+ results_type resolve(std::string_view host, std::string_view service, boost::system::error_code &ec);
+ results_type resolve(std::string_view host, std::string_view service, resolver_base::flags resolve_flags);
+ results_type resolve(std::string_view host, std::string_view service, resolver_base::flags resolve_flags, boost::system::error_code &ec);
+ results_type resolve(const InternetProtocol &protocol, const std::string &host, const std::string &service);
+ results_type resolve(const InternetProtocol &protocol, const std::string &host, const std::string &service, boost::system::error_code &ec);
+ results_type resolve(const InternetProtocol &protocol, const std::string &host, const std::string &service, resolver_base::flags resolve_flags);
+ results_type resolve(const InternetProtocol &protocol, const std::string &host, const std::string &service, resolver_base::flags resolve_flags, boost::system::error_code &ec);
+ results_type resolve(const InternetProtocol &protocol, std::string_view host, std::string_view service);
+ results_type resolve(const InternetProtocol &protocol, std::string_view host, std::string_view service, boost::system::error_code &ec);
+ results_type resolve(const InternetProtocol &protocol, std::string_view host, std::string_view service, resolver_base::flags resolve_flags);
+ results_type resolve(const InternetProtocol &protocol, std::string_view host, std::string_view service, resolver_base::flags resolve_flags, boost::system::error_code &ec);
+ };
+
class tcp {
public:
typedef basic_stream_socket socket;
+ typedef basic_resolver resolver;
};
};
@@ -76,6 +97,7 @@ void sink(char *);
void sink(std::string);
void sink(boost::asio::streambuf);
void sink(boost::asio::mutable_buffer);
+void sink(boost::asio::ip::tcp::resolver::results_type);
char *getenv(const char *name);
int send(int, const void*, int, int);
@@ -105,3 +127,65 @@ void test(boost::asio::ip::tcp::socket &socket) {
// ...
}
}
+
+void test_resolve_host() {
+ boost::asio::ip::tcp::resolver resolver;
+ boost::asio::ip::tcp protocol;
+ boost::asio::ip::resolver_base::flags flags = boost::asio::ip::resolver_base::passive;
+ boost::system::error_code error;
+ std::string host(source());
+ std::string service("");
+ std::string_view host_view(source());
+ std::string_view service_view("");
+
+ sink(resolver.resolve(host, service)); // $ ir
+ sink(resolver.resolve(host, service, error)); // $ ir
+ sink(resolver.resolve(host, service, flags)); // $ ir
+ sink(resolver.resolve(host, service, flags, error)); // $ ir
+
+ sink(resolver.resolve(host_view, service_view)); // $ MISSING: ir
+ sink(resolver.resolve(host_view, service_view, error)); // $ MISSING: ir
+ sink(resolver.resolve(host_view, service_view, flags)); // $ MISSING: ir
+ sink(resolver.resolve(host_view, service_view, flags, error)); // $ MISSING: ir
+
+ sink(resolver.resolve(protocol, host, service)); // $ ir
+ sink(resolver.resolve(protocol, host, service, error)); // $ ir
+ sink(resolver.resolve(protocol, host, service, flags)); // $ ir
+ sink(resolver.resolve(protocol, host, service, flags, error)); // $ ir
+
+ sink(resolver.resolve(protocol, host_view, service_view)); // $ MISSING: ir
+ sink(resolver.resolve(protocol, host_view, service_view, error)); // $ MISSING: ir
+ sink(resolver.resolve(protocol, host_view, service_view, flags)); // $ MISSING: ir
+ sink(resolver.resolve(protocol, host_view, service_view, flags, error)); // $ MISSING: ir
+}
+
+void test_resolve_service() {
+ boost::asio::ip::tcp::resolver resolver;
+ boost::asio::ip::tcp protocol;
+ boost::asio::ip::resolver_base::flags flags = boost::asio::ip::resolver_base::passive;
+ boost::system::error_code error;
+ std::string host("");
+ std::string service(source());
+ std::string_view host_view("");
+ std::string_view service_view(source());
+
+ sink(resolver.resolve(host, service)); // $ ir
+ sink(resolver.resolve(host, service, error)); // $ ir
+ sink(resolver.resolve(host, service, flags)); // $ ir
+ sink(resolver.resolve(host, service, flags, error)); // $ ir
+
+ sink(resolver.resolve(host_view, service_view)); // $ MISSING: ir
+ sink(resolver.resolve(host_view, service_view, error)); // $ MISSING: ir
+ sink(resolver.resolve(host_view, service_view, flags)); // $ MISSING: ir
+ sink(resolver.resolve(host_view, service_view, flags, error)); // $ MISSING: ir
+
+ sink(resolver.resolve(protocol, host, service)); // $ ir
+ sink(resolver.resolve(protocol, host, service, error)); // $ ir
+ sink(resolver.resolve(protocol, host, service, flags)); // $ ir
+ sink(resolver.resolve(protocol, host, service, flags, error)); // $ ir
+
+ sink(resolver.resolve(protocol, host_view, service_view)); // $ MISSING: ir
+ sink(resolver.resolve(protocol, host_view, service_view, error)); // $ MISSING: ir
+ sink(resolver.resolve(protocol, host_view, service_view, flags)); // $ MISSING: ir
+ sink(resolver.resolve(protocol, host_view, service_view, flags, error)); // $ MISSING: ir
+}
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/azure.cpp b/cpp/ql/test/library-tests/dataflow/external-models/azure.cpp
index 14407a8b5bed..512fbeeb5203 100644
--- a/cpp/ql/test/library-tests/dataflow/external-models/azure.cpp
+++ b/cpp/ql/test/library-tests/dataflow/external-models/azure.cpp
@@ -1,3 +1,4 @@
+#include "../taint-tests/stl.h"
using uint16_t = unsigned short;
using int64_t = long long;
using size_t = unsigned long;
@@ -5,51 +6,13 @@ using uint8_t = unsigned char;
using int32_t = int;
using uint32_t = unsigned int;
-namespace std
-{
- class string
- {
- public:
- string();
- string(const char *);
- ~string();
- };
-
- template
- class map
- {
- public:
- map();
- ~map();
-
- V& operator[](const K& key);
- };
-
- template
- class vector
- {
- public:
- vector();
- ~vector();
-
- T& operator[](size_t);
- };
-
- template
- class unique_ptr {
- public:
- unique_ptr();
- ~unique_ptr();
-
- T* get();
- };
-}
-
namespace Azure
{
template
class Nullable
{
+ T m_value;
+
public:
Nullable();
Nullable(const T);
@@ -284,6 +247,9 @@ void test_RawResponse(Azure::Core::Http::RawResponse& resp) {
}
void test_GetHeader() {
+ // We instantiate the `std::pair` class since we need the `FieldContent` for
+ // `std::pair::second` to be present in the test DB.
+ std::pair();
Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
{
auto headerValue = request.GetHeader("Content-Type").Value();
@@ -294,4 +260,11 @@ void test_GetHeader() {
std::string contentType = headers["Content-Type"];
sink(contentType); // $ ir
}
+}
+
+void test_QueryParameters() {
+ Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
+ Azure::Core::Url url;
+ url.SetQueryParameters(request.GetHeaders());
+ sink(url.GetQueryParameters()["query"]); // $ ir
}
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/bal.cpp b/cpp/ql/test/library-tests/dataflow/external-models/bal.cpp
new file mode 100644
index 000000000000..ad72d3321c80
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/external-models/bal.cpp
@@ -0,0 +1,467 @@
+#include "bsl.h"
+
+// --- stub library headers ---
+
+namespace BloombergLP {
+namespace bdlar {
+ class AnyRef {};
+ class AnyConstRef {};
+}
+
+namespace balber {
+ class BerDecoder {
+ public:
+ template int decode(bsl::streambuf *streamBuf, TYPE *variable);
+ template int decode(bsl::istream& stream, TYPE *variable);
+ template int decodeAny(bsl::streambuf *streamBuf, TYPE *variable);
+ int decodeAny(bsl::streambuf *streamBuf, bdlar::AnyRef *variable);
+ template int decodeAny(bsl::istream& stream, TYPE *variable);
+ int decodeAny(bsl::istream& stream, bdlar::AnyRef *variable);
+ };
+ class BerEncoder {
+ public:
+ template int encode(bsl::streambuf *streamBuf, const TYPE& value);
+ template int encode(bsl::ostream& stream, const TYPE& value);
+ template int encodeAny(bsl::streambuf *streamBuf, const TYPE& value);
+ int encodeAny(bsl::streambuf *streamBuf, const bdlar::AnyConstRef& any);
+ template int encodeAny(bsl::ostream& stream, const TYPE& value);
+ int encodeAny(bsl::ostream& stream, const bdlar::AnyConstRef& any);
+ };
+}
+
+namespace baljsn {
+ class DecoderOptions {};
+ class EncoderOptions {};
+ class Decoder {
+ public:
+ template int decode(bsl::streambuf *streamBuf, TYPE *value, const DecoderOptions& options);
+ template int decode(bsl::streambuf *streamBuf, TYPE *value, const DecoderOptions *options);
+ template int decode(bsl::istream& stream, TYPE *value, const DecoderOptions& options);
+ template int decode(bsl::istream& stream, TYPE *value, const DecoderOptions *options);
+ template int decode(bsl::streambuf *streamBuf, TYPE *value);
+ template int decode(bsl::istream& stream, TYPE *value);
+ template int decodeAny(bsl::streambuf *streamBuf, TYPE *value, const DecoderOptions& options);
+ template int decodeAny(bsl::streambuf *streamBuf, TYPE *value, const DecoderOptions *options = 0);
+ int decodeAny(bsl::streambuf *streamBuf, bdlar::AnyRef *value, const DecoderOptions& options);
+ template int decodeAny(bsl::istream& stream, TYPE *value, const DecoderOptions& options);
+ template int decodeAny(bsl::istream& stream, TYPE *value, const DecoderOptions *options = 0);
+ int decodeAny(bsl::istream& stream, bdlar::AnyRef *value, const DecoderOptions& options);
+ };
+ class Encoder {
+ public:
+ template int encode(bsl::streambuf *streamBuf, const TYPE& value, const EncoderOptions& options);
+ template int encode(bsl::streambuf *streamBuf, const TYPE& value, const EncoderOptions *options);
+ template int encode(bsl::ostream& stream, const TYPE& value, const EncoderOptions& options);
+ template int encode(bsl::ostream& stream, const TYPE& value, const EncoderOptions *options);
+ template int encode(bsl::streambuf *streamBuf, const TYPE& value);
+ template int encode(bsl::ostream& stream, const TYPE& value);
+ template int encodeAny(bsl::streambuf *streamBuf, const TYPE& value, const EncoderOptions& options);
+ template int encodeAny(bsl::streambuf *streamBuf, const TYPE& value, const EncoderOptions *options = 0);
+ int encodeAny(bsl::streambuf *streamBuf, const bdlar::AnyConstRef& any, const EncoderOptions& options);
+ int encodeAny(bsl::streambuf *streamBuf, const bdlar::AnyConstRef& any, const EncoderOptions *options = 0);
+ template int encodeAny(bsl::ostream& stream, const TYPE& value, const EncoderOptions& options);
+ template int encodeAny(bsl::ostream& stream, const TYPE& value, const EncoderOptions *options = 0);
+ int encodeAny(bsl::ostream& stream, const bdlar::AnyConstRef& any, const EncoderOptions& options);
+ int encodeAny(bsl::ostream& stream, const bdlar::AnyConstRef& any, const EncoderOptions *options = 0);
+ };
+}
+
+namespace balxml {
+ class Formatter {};
+ class Decoder {
+ public:
+ int open(bsl::istream& stream, const char *uri = 0);
+ int open(bsl::streambuf *buffer, const char *uri = 0);
+ int open(const char *buffer, bsl::size_t length, const char *uri = 0);
+ int open(const char *filename);
+ template bsl::istream& decode(bsl::istream& stream, TYPE *object, const char *uri = 0);
+ template int decode(bsl::streambuf *buffer, TYPE *object, const char *uri = 0);
+ template int decode(const char *buffer, bsl::size_t length, TYPE *object, const char *uri = 0);
+ template int decode(const char *filename, TYPE *object);
+ template int decode(TYPE *object);
+ template bsl::istream& decodeAny(bsl::istream& stream, TYPE *object, const char *uri = 0);
+ bsl::istream& decodeAny(bsl::istream& stream, bdlar::AnyRef *object, const char *uri = 0);
+ template int decodeAny(bsl::streambuf *buffer, TYPE *object, const char *uri = 0);
+ int decodeAny(bsl::streambuf *buffer, bdlar::AnyRef *object, const char *uri = 0);
+ template int decodeAny(TYPE *object);
+ int decodeAny(bdlar::AnyRef *object);
+ };
+ class Encoder {
+ public:
+ template int encode(bsl::streambuf *buffer, const TYPE& object);
+ template int encodeToStream(bsl::ostream& stream, const TYPE& object);
+ template bsl::ostream& encode(bsl::ostream& stream, const TYPE& object);
+ template int encode(Formatter& formatter, const TYPE& object);
+ template int encodeAny(bsl::streambuf *buffer, const TYPE& object);
+ int encodeAny(bsl::streambuf *buffer, const bdlar::AnyConstRef& object);
+ template int encodeAnyToStream(bsl::ostream& stream, const TYPE& object);
+ int encodeAnyToStream(bsl::ostream& stream, const bdlar::AnyConstRef& object);
+ template bsl::ostream& encodeAny(bsl::ostream& stream, const TYPE& object);
+ bsl::ostream& encodeAny(bsl::ostream& stream, const bdlar::AnyConstRef& object);
+ template int encodeAny(Formatter& formatter, const TYPE& object);
+ int encodeAny(Formatter& formatter, const bdlar::AnyConstRef& object);
+ };
+}
+}
+
+// --- test code ---
+
+char *source();
+void sink(char);
+void sink(bsl::string s);
+
+// Stand-in for a bdlat sequence type.
+struct Record {
+ char name[16];
+};
+
+// A tainted stream is made by reinterpreting a tainted bsl::string, as in bslx.cpp. baljsn
+// and balxml only accept bdlat sequence/choice types; the stubs do not enforce that, and
+// most tests decode into a bsl::string so the result can be read back. The *_struct_* tests
+// show whole-object taint without general object-to-field flow. TaintInheritingContent
+// (FlowSteps.qll) enables inheritance for selected fields; Record::name is not modeled this way.
+
+// ===== balber (BER) =====
+
+// Decoding a tainted stream taints the decoded object.
+void test_balber_decode() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ bsl::string out;
+ BloombergLP::balber::BerDecoder decoder;
+ decoder.decode(sb, &out);
+ sink(*out.data()); // $ ir
+}
+
+void test_balber_decode_istream() {
+ bsl::string data(source());
+ bsl::istream *is = (bsl::istream *)data.data();
+ bsl::string out;
+ BloombergLP::balber::BerDecoder decoder;
+ decoder.decode(*is, &out);
+ sink(*out.data()); // $ ir
+}
+
+void test_balber_decodeAny() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ bsl::string out;
+ BloombergLP::balber::BerDecoder decoder;
+ decoder.decodeAny(sb, &out);
+ sink(*out.data()); // $ ir
+}
+
+// Encoding a tainted object taints the destination stream.
+void test_balber_encode() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balber::BerEncoder encoder;
+ encoder.encode((bsl::streambuf *)buf, obj);
+ sink(buf[0]); // $ ir
+}
+
+void test_balber_encodeAny() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balber::BerEncoder encoder;
+ encoder.encodeAny((bsl::streambuf *)buf, obj);
+ sink(buf[0]); // $ ir
+}
+
+// ===== baljsn (JSON) =====
+
+// The non-deprecated overloads take a trailing DecoderOptions/EncoderOptions.
+void test_baljsn_decode_options() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ bsl::string out;
+ BloombergLP::baljsn::DecoderOptions options;
+ BloombergLP::baljsn::Decoder decoder;
+ decoder.decode(sb, &out, options);
+ sink(*out.data()); // $ ir
+}
+
+void test_baljsn_decode_istream_options_ptr() {
+ bsl::string data(source());
+ bsl::istream *is = (bsl::istream *)data.data();
+ bsl::string out;
+ BloombergLP::baljsn::DecoderOptions options;
+ BloombergLP::baljsn::Decoder decoder;
+ decoder.decode(*is, &out, &options);
+ sink(*out.data()); // $ ir
+}
+
+void test_baljsn_decodeAny() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ bsl::string out;
+ BloombergLP::baljsn::Decoder decoder;
+ decoder.decodeAny(sb, &out);
+ sink(*out.data()); // $ ir
+}
+
+void test_baljsn_encode_options() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::baljsn::EncoderOptions options;
+ BloombergLP::baljsn::Encoder encoder;
+ encoder.encode((bsl::streambuf *)buf, obj, options);
+ sink(buf[0]); // $ ir
+}
+
+void test_baljsn_encodeAny() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::baljsn::Encoder encoder;
+ encoder.encodeAny((bsl::streambuf *)buf, obj);
+ sink(buf[0]); // $ ir
+}
+
+// A decoded struct carries taint as a whole: re-encoding it taints the output stream.
+void test_baljsn_struct_round_trip() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ Record rec;
+ BloombergLP::baljsn::Decoder decoder;
+ decoder.decode(sb, &rec);
+ char buf[16];
+ BloombergLP::baljsn::Encoder encoder;
+ encoder.encode((bsl::streambuf *)buf, rec);
+ sink(buf[0]); // $ ir
+}
+
+void test_baljsn_struct_field_no_flow() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ Record rec;
+ BloombergLP::baljsn::Decoder decoder;
+ decoder.decode(sb, &rec);
+ sink(rec.name[0]); // no flow: Record::name does not inherit whole-object taint
+}
+
+// ===== balxml (XML) =====
+
+void test_balxml_decode_istream() {
+ bsl::string data(source());
+ bsl::istream *is = (bsl::istream *)data.data();
+ bsl::string out;
+ BloombergLP::balxml::Decoder decoder;
+ decoder.decode(*is, &out);
+ sink(*out.data()); // $ ir
+}
+
+void test_balxml_decode_istream_return() {
+ bsl::string data(source());
+ bsl::istream *is = (bsl::istream *)data.data();
+ bsl::string out;
+ BloombergLP::balxml::Decoder decoder;
+ bsl::istream &r = decoder.decode(*is, &out, "uri");
+ sink(*(char *)&r); // $ ir
+ sink(out); // $ ir
+}
+
+void test_balxml_decode_streambuf() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ bsl::string out;
+ BloombergLP::balxml::Decoder decoder;
+ decoder.decode(sb, &out);
+ sink(*out.data()); // $ ir
+}
+
+void test_balxml_decode_buffer_length() {
+ bsl::string data(source());
+ bsl::string out;
+ BloombergLP::balxml::Decoder decoder;
+ decoder.decode(data.data(), data.size(), &out);
+ sink(*out.data()); // $ ir
+}
+
+// decode(const char *filename, TYPE *) is not modelled.
+void test_balxml_decode_filename_no_flow() {
+ bsl::string filename(source());
+ bsl::string out;
+ BloombergLP::balxml::Decoder decoder;
+ decoder.decode(filename.data(), &out);
+ sink(*out.data()); // no flow: the input is a path, not data
+}
+
+// The two-step open() + decode(TYPE *) form is not modelled.
+void test_balxml_open_decode_no_flow() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ bsl::string out;
+ BloombergLP::balxml::Decoder decoder;
+ decoder.open(sb);
+ decoder.decode(&out);
+ sink(*out.data()); // $ MISSING: ir (not modelled)
+}
+
+void test_balxml_decodeAny_istream() {
+ bsl::string data(source());
+ bsl::istream *is = (bsl::istream *)data.data();
+ bsl::string out;
+ BloombergLP::balxml::Decoder decoder;
+ decoder.decodeAny(*is, &out);
+ sink(*out.data()); // $ ir
+}
+
+void test_balxml_decodeAny_istream_return() {
+ bsl::string data(source());
+ bsl::istream *is = (bsl::istream *)data.data();
+ bsl::string out;
+ BloombergLP::balxml::Decoder decoder;
+ bsl::istream &r = decoder.decodeAny(*is, &out);
+ sink(*(char *)&r); // $ ir
+ sink(out); // $ ir
+}
+
+void test_balxml_decodeAny_streambuf() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ bsl::string out;
+ BloombergLP::balxml::Decoder decoder;
+ decoder.decodeAny(sb, &out);
+ sink(*out.data()); // $ ir
+}
+
+void test_balxml_decodeAny_AnyRef_istream() {
+ bsl::string data(source());
+ bsl::istream *is = (bsl::istream *)data.data();
+ BloombergLP::bdlar::AnyRef any;
+ BloombergLP::balxml::Decoder decoder;
+ decoder.decodeAny(*is, &any);
+ sink(*(char *)&any); // $ ir
+}
+
+void test_balxml_decodeAny_AnyRef_istream_return() {
+ bsl::string data(source());
+ bsl::istream *is = (bsl::istream *)data.data();
+ BloombergLP::bdlar::AnyRef any;
+ BloombergLP::balxml::Decoder decoder;
+ bsl::istream &r = decoder.decodeAny(*is, &any);
+ sink(*(char *)&r); // $ ir
+ sink(*(char *)&any); // $ ir
+}
+
+void test_balxml_decodeAny_AnyRef_streambuf() {
+ bsl::string data(source());
+ bsl::streambuf *sb = (bsl::streambuf *)data.data();
+ BloombergLP::bdlar::AnyRef any;
+ BloombergLP::balxml::Decoder decoder;
+ decoder.decodeAny(sb, &any);
+ sink(*(char *)&any); // $ ir
+}
+
+void test_balxml_encode_streambuf() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ encoder.encode((bsl::streambuf *)buf, obj);
+ sink(buf[0]); // $ ir
+}
+
+void test_balxml_encode_ostream() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ encoder.encode(*(bsl::ostream *)buf, obj);
+ sink(buf[0]); // $ ir
+}
+
+void test_balxml_encode_ostream_return_from_object() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ bsl::ostream &r = encoder.encode(*(bsl::ostream *)buf, obj);
+ sink(*(char *)&r); // $ ir
+ sink(buf[0]); // $ ir
+}
+
+void test_balxml_encode_ostream_return_from_stream() {
+ bsl::string data(source());
+ bsl::ostream *os = (bsl::ostream *)data.data();
+ bsl::string obj;
+ BloombergLP::balxml::Encoder encoder;
+ bsl::ostream &r = encoder.encode(*os, obj);
+ sink(*(char *)&r); // $ ir
+}
+
+void test_balxml_encodeToStream() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ encoder.encodeToStream(*(bsl::ostream *)buf, obj);
+ sink(buf[0]); // $ ir
+}
+
+// encode(Formatter &, const TYPE &) is not modelled.
+void test_balxml_encode_formatter_no_flow() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balxml::Formatter *formatter = (BloombergLP::balxml::Formatter *)buf;
+ BloombergLP::balxml::Encoder encoder;
+ encoder.encode(*formatter, obj);
+ sink(buf[0]); // no flow: not modelled
+}
+
+void test_balxml_encodeAny_streambuf() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ encoder.encodeAny((bsl::streambuf *)buf, obj);
+ sink(buf[0]); // $ ir
+}
+
+void test_balxml_encodeAny_ostream() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ encoder.encodeAny(*(bsl::ostream *)buf, obj);
+ sink(buf[0]); // $ ir
+}
+
+void test_balxml_encodeAny_ostream_return_from_object() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ bsl::ostream &r = encoder.encodeAny(*(bsl::ostream *)buf, obj);
+ sink(*(char *)&r); // $ ir
+ sink(buf[0]); // $ ir
+}
+
+void test_balxml_encodeAnyToStream() {
+ bsl::string obj(source());
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ encoder.encodeAnyToStream(*(bsl::ostream *)buf, obj);
+ sink(buf[0]); // $ ir
+}
+
+void test_balxml_encodeAny_AnyConstRef_streambuf() {
+ bsl::string data(source());
+ BloombergLP::bdlar::AnyConstRef *any = (BloombergLP::bdlar::AnyConstRef *)data.data();
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ encoder.encodeAny((bsl::streambuf *)buf, *any);
+ sink(buf[0]); // $ ir
+}
+
+void test_balxml_encodeAny_AnyConstRef_ostream() {
+ bsl::string data(source());
+ BloombergLP::bdlar::AnyConstRef *any = (BloombergLP::bdlar::AnyConstRef *)data.data();
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ encoder.encodeAny(*(bsl::ostream *)buf, *any);
+ sink(buf[0]); // $ ir
+}
+
+void test_balxml_encodeAny_AnyConstRef_ostream_return_from_object() {
+ bsl::string data(source());
+ BloombergLP::bdlar::AnyConstRef *any = (BloombergLP::bdlar::AnyConstRef *)data.data();
+ char buf[16];
+ BloombergLP::balxml::Encoder encoder;
+ bsl::ostream &r = encoder.encodeAny(*(bsl::ostream *)buf, *any);
+ sink(*(char *)&r); // $ ir
+ sink(buf[0]); // $ ir
+}
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/bdlbb.cpp b/cpp/ql/test/library-tests/dataflow/external-models/bdlbb.cpp
new file mode 100644
index 000000000000..6d600dd9c1a4
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/external-models/bdlbb.cpp
@@ -0,0 +1,81 @@
+#include "bsl.h"
+
+// --- stub library headers ---
+
+namespace BloombergLP {
+namespace bdlbb {
+ class BlobBuffer {
+ public:
+ char *data() const;
+ bsl::shared_ptr &buffer();
+ const bsl::shared_ptr &buffer() const;
+ };
+
+ class Blob {
+ public:
+ const BlobBuffer &buffer(int index) const;
+ };
+
+ struct BlobUtil {
+ static void copy(char *dstBuffer, const Blob &srcBlob, int position, int length);
+ static void copy(Blob *dstBlob, int dstOffset, const char *srcBuffer, int length);
+ static void copy(Blob *dstBlob, int dstOffset, const Blob &srcBlob, int srcOffset,
+ int length);
+ static char *getContiguousRangeOrCopy(char *dstBuffer, const Blob &srcBlob, int position,
+ int length, int alignment);
+ };
+}
+}
+
+// --- test code ---
+
+char *source();
+void sink(char);
+
+// A blob populated from a tainted buffer taints the bytes read back out of it.
+void test_BlobUtil_copy() {
+ bsl::string s(source());
+ BloombergLP::bdlbb::Blob blob;
+ BloombergLP::bdlbb::BlobUtil::copy(&blob, 0, s.data(), s.size());
+ char dst[16];
+ BloombergLP::bdlbb::BlobUtil::copy(dst, blob, 0, 16);
+ sink(*dst); // $ ir
+}
+
+void test_accessor_chain() {
+ bsl::string s(source());
+ BloombergLP::bdlbb::Blob blob;
+ BloombergLP::bdlbb::BlobUtil::copy(&blob, 0, s.data(), s.size());
+ const char *p = blob.buffer(0).data();
+ sink(*p); // $ ir
+}
+
+// The get() step comes from the built-in smart pointer model, not from bdlbb.model.yml.
+void test_accessor_chain_shared_ptr() {
+ bsl::string s(source());
+ BloombergLP::bdlbb::Blob blob;
+ BloombergLP::bdlbb::BlobUtil::copy(&blob, 0, s.data(), s.size());
+ const char *p = blob.buffer(0).buffer().get();
+ sink(*p); // $ ir
+}
+
+void test_getContiguousRangeOrCopy() {
+ bsl::string s(source());
+ BloombergLP::bdlbb::Blob blob;
+ BloombergLP::bdlbb::BlobUtil::copy(&blob, 0, s.data(), s.size());
+ char dst[16];
+ char *r = BloombergLP::bdlbb::BlobUtil::getContiguousRangeOrCopy(dst, blob, 0, 16, 1);
+ sink(*r); // $ ir
+}
+
+// A blob copied into another blob carries the taint across.
+void test_BlobUtil_copy_blob_to_blob() {
+ bsl::string s(source());
+ BloombergLP::bdlbb::Blob src;
+ BloombergLP::bdlbb::BlobUtil::copy(&src, 0, s.data(), s.size());
+ BloombergLP::bdlbb::Blob dst;
+ BloombergLP::bdlbb::BlobUtil::copy(&dst, 0, src, 0, 16);
+ char out[16];
+ BloombergLP::bdlbb::BlobUtil::copy(out, dst, 0, 16);
+ sink(*out); // $ ir
+}
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/bmqa.cpp b/cpp/ql/test/library-tests/dataflow/external-models/bmqa.cpp
new file mode 100644
index 000000000000..2cd303489c00
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/external-models/bmqa.cpp
@@ -0,0 +1,394 @@
+#include "bsl.h"
+
+// --- stub library headers ---
+
+namespace BloombergLP {
+namespace bslma {
+ class Allocator {};
+}
+namespace bsls {
+ struct Types { typedef long long Int64; };
+}
+
+namespace bdlbb {
+ class Blob {};
+ class BlobBufferFactory {};
+ struct BlobUtil {
+ static void copy(char *dstBuffer, const Blob &srcBlob, int position, int length);
+ static void copy(Blob *dstBlob, int dstOffset, const char *srcBuffer, int length);
+ };
+}
+
+namespace bmqa {
+ class MessageProperties;
+ class Message {
+ public:
+ Message& setData(const bdlbb::Blob* data);
+ Message& setData(const char* data, bsl::size_t length);
+ Message& setDataRef(const bdlbb::Blob* data);
+ Message& setDataRef(const char* data, bsl::size_t length);
+ Message& setPropertiesRef(const MessageProperties* properties);
+ Message clone(bslma::Allocator* basicAllocator = 0) const;
+ int getData(bdlbb::Blob* blob) const;
+ int loadProperties(MessageProperties* buffer) const;
+ };
+ class MessageProperties {
+ public:
+ explicit MessageProperties(bslma::Allocator* basicAllocator = 0);
+ MessageProperties(const MessageProperties& other, bslma::Allocator* basicAllocator = 0);
+ MessageProperties& operator=(const MessageProperties& rhs);
+ int setPropertyAsBool(bsl::string_view name, bool value);
+ int setPropertyAsChar(bsl::string_view name, char value);
+ int setPropertyAsShort(bsl::string_view name, short value);
+ int setPropertyAsInt32(bsl::string_view name, bsl::int32_t value);
+ int setPropertyAsInt64(bsl::string_view name, bsls::Types::Int64 value);
+ int setPropertyAsString(bsl::string_view name, bsl::string_view value);
+ int setPropertyAsBinary(bsl::string_view name, bsl::span value);
+ int streamIn(const bdlbb::Blob& blob);
+ const bdlbb::Blob& streamOut(bdlbb::BlobBufferFactory* bufferFactory) const;
+ bsl::int32_t getPropertyAsInt32(bsl::string_view name) const;
+ const bsl::string& getPropertyAsString(bsl::string_view name) const;
+ const bsl::vector& getPropertyAsBinary(bsl::string_view name) const;
+ const bsl::string& getPropertyAsStringOr(bsl::string_view name, const bsl::string& value) const;
+ const bsl::vector& getPropertyAsBinaryOr(bsl::string_view name, const bsl::vector& value) const;
+ };
+ class MessagePropertiesIterator {
+ public:
+ MessagePropertiesIterator();
+ explicit MessagePropertiesIterator(const MessageProperties* properties);
+ MessagePropertiesIterator& operator=(const MessagePropertiesIterator& rhs);
+ bool hasNext();
+ const bsl::string& name() const;
+ bsl::int32_t getAsInt32() const;
+ const bsl::string& getAsString() const;
+ const bsl::vector& getAsBinary() const;
+ };
+ class MessageIterator {
+ public:
+ bool nextMessage();
+ const Message& message() const;
+ };
+ class MessageEvent {
+ public:
+ MessageIterator messageIterator() const;
+ };
+}
+}
+
+// --- test code ---
+
+char *source();
+void sink(char);
+void sink(int);
+
+// A received message or event is made by reinterpreting a tainted bsl::string.
+
+void test_getData() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bdlbb::Blob blob;
+ msg->getData(&blob);
+ char dst[16];
+ BloombergLP::bdlbb::BlobUtil::copy(dst, blob, 0, 16);
+ sink(*dst); // $ ir
+}
+
+void test_event_iterator_message_getData() {
+ bsl::string data(source());
+ BloombergLP::bmqa::MessageEvent *event = (BloombergLP::bmqa::MessageEvent *)data.data();
+ BloombergLP::bmqa::MessageIterator it = event->messageIterator();
+ while (it.nextMessage()) {
+ const BloombergLP::bmqa::Message &msg = it.message();
+ BloombergLP::bdlbb::Blob blob;
+ msg.getData(&blob);
+ char dst[16];
+ BloombergLP::bdlbb::BlobUtil::copy(dst, blob, 0, 16);
+ sink(*dst); // $ ir
+ }
+}
+
+void test_setDataRef_getData_round_trip() {
+ bsl::string s(source());
+ BloombergLP::bdlbb::Blob in;
+ BloombergLP::bdlbb::BlobUtil::copy(&in, 0, s.data(), s.size());
+ BloombergLP::bmqa::Message msg;
+ msg.setDataRef(&in);
+ BloombergLP::bdlbb::Blob out;
+ msg.getData(&out);
+ char dst[16];
+ BloombergLP::bdlbb::BlobUtil::copy(dst, out, 0, 16);
+ sink(*dst); // $ ir
+}
+
+void test_setDataRef_chars_getData() {
+ bsl::string s(source());
+ BloombergLP::bmqa::Message msg;
+ msg.setDataRef(s.data(), s.size());
+ BloombergLP::bdlbb::Blob out;
+ msg.getData(&out);
+ char dst[16];
+ BloombergLP::bdlbb::BlobUtil::copy(dst, out, 0, 16);
+ sink(*dst); // $ ir
+}
+
+void test_setData_getData() {
+ bsl::string s(source());
+ BloombergLP::bmqa::Message msg;
+ msg.setData(s.data(), s.size());
+ BloombergLP::bdlbb::Blob out;
+ msg.getData(&out);
+ char dst[16];
+ BloombergLP::bdlbb::BlobUtil::copy(dst, out, 0, 16);
+ sink(*dst); // $ ir
+}
+
+void test_clone_getData() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::Message copy = msg->clone();
+ BloombergLP::bdlbb::Blob blob;
+ copy.getData(&blob);
+ char dst[16];
+ BloombergLP::bdlbb::BlobUtil::copy(dst, blob, 0, 16);
+ sink(*dst); // $ ir
+}
+
+void test_loadProperties_getPropertyAsString() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ const bsl::string &value = props.getPropertyAsString("key");
+ sink(value.data()[0]); // $ ir
+}
+
+void test_loadProperties_getPropertyAsBinary() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ const bsl::vector &value = props.getPropertyAsBinary("key");
+ sink(value.data()[0]); // $ ir
+}
+
+void test_loadProperties_getPropertyAsBinary_index() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ const bsl::vector &value = props.getPropertyAsBinary("key");
+ sink(value[0]); // $ ir
+}
+
+void test_getPropertyAsStringOr() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ bsl::string dflt;
+ const bsl::string &value = props.getPropertyAsStringOr("key", dflt);
+ sink(*value.data()); // $ ir
+}
+
+// The default value is returned when the property is absent.
+void test_getPropertyAsStringOr_default() {
+ bsl::string dflt(source());
+ BloombergLP::bmqa::MessageProperties props;
+ const bsl::string &value = props.getPropertyAsStringOr("key", dflt);
+ sink(*value.data()); // $ ir
+}
+
+void test_getPropertyAsBinaryOr() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ bsl::vector dflt;
+ const bsl::vector &value = props.getPropertyAsBinaryOr("key", dflt);
+ sink(*value.data()); // $ ir
+}
+
+void test_getPropertyAsBinaryOr_default() {
+ char c = *source();
+ bsl::vector dflt;
+ dflt.push_back(c);
+ BloombergLP::bmqa::MessageProperties props;
+ const bsl::vector &value = props.getPropertyAsBinaryOr("key", dflt);
+ sink(*value.data()); // $ ir
+}
+
+void test_getPropertyAsInt32_no_flow() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ sink(props.getPropertyAsInt32("key")); // no flow: scalar getters are not modelled
+}
+
+void test_streamIn_getPropertyAsString() {
+ bsl::string s(source());
+ BloombergLP::bdlbb::Blob blob;
+ BloombergLP::bdlbb::BlobUtil::copy(&blob, 0, s.data(), s.size());
+ BloombergLP::bmqa::MessageProperties props;
+ props.streamIn(blob);
+ sink(*props.getPropertyAsString("key").data()); // $ ir
+}
+
+void test_setPropertiesRef_loadProperties() {
+ bsl::string s(source());
+ BloombergLP::bdlbb::Blob blob;
+ BloombergLP::bdlbb::BlobUtil::copy(&blob, 0, s.data(), s.size());
+ BloombergLP::bmqa::MessageProperties in;
+ in.streamIn(blob);
+ BloombergLP::bmqa::Message msg;
+ msg.setPropertiesRef(&in);
+ BloombergLP::bmqa::MessageProperties out;
+ msg.loadProperties(&out);
+ sink(*out.getPropertyAsString("key").data()); // $ ir
+}
+
+void test_streamOut() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ BloombergLP::bdlbb::BlobBufferFactory factory;
+ const BloombergLP::bdlbb::Blob &blob = props.streamOut(&factory);
+ char dst[16];
+ BloombergLP::bdlbb::BlobUtil::copy(dst, blob, 0, 16);
+ sink(*dst); // $ ir
+}
+
+void test_copy_constructor() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ BloombergLP::bmqa::MessageProperties copy(props);
+ sink(*copy.getPropertyAsString("key").data()); // $ ir
+}
+
+void test_assignment() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ BloombergLP::bmqa::MessageProperties copy;
+ copy = props;
+ sink(*copy.getPropertyAsString("key").data()); // $ ir
+}
+
+void test_assignment_result() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ BloombergLP::bmqa::MessageProperties copy;
+ sink(*(copy = props).getPropertyAsString("key").data()); // $ ir
+}
+
+void test_setPropertyAsString() {
+ bsl::string data(source());
+ bsl::string_view *value = (bsl::string_view *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsString("key", *value);
+ sink(*props.getPropertyAsString("key").data()); // $ ir
+}
+
+void test_setPropertyAsString_from_chars() {
+ bsl::string_view value(source());
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsString("key", value);
+ sink(*props.getPropertyAsString("key").data()); // $ ir
+}
+
+void test_setPropertyAsBinary() {
+ bsl::string data(source());
+ bsl::span *value = (bsl::span *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsBinary("key", *value);
+ sink(*props.getPropertyAsBinary("key").data()); // $ ir
+}
+
+// A stored property name is exposed again by the iterator.
+void test_setPropertyAsBool_name() {
+ bsl::string_view name(source());
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsBool(name, true);
+ BloombergLP::bmqa::MessagePropertiesIterator it(&props);
+ sink(*it.name().data()); // $ ir
+}
+
+void test_setPropertyAsChar_name() {
+ bsl::string_view name(source());
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsChar(name, 'c');
+ BloombergLP::bmqa::MessagePropertiesIterator it(&props);
+ sink(*it.name().data()); // $ ir
+}
+
+void test_setPropertyAsShort_name() {
+ bsl::string_view name(source());
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsShort(name, 1);
+ BloombergLP::bmqa::MessagePropertiesIterator it(&props);
+ sink(*it.name().data()); // $ ir
+}
+
+void test_setPropertyAsInt32_name() {
+ bsl::string_view name(source());
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsInt32(name, 1);
+ BloombergLP::bmqa::MessagePropertiesIterator it(&props);
+ sink(*it.name().data()); // $ ir
+}
+
+void test_setPropertyAsInt64_name() {
+ bsl::string_view name(source());
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsInt64(name, 1);
+ BloombergLP::bmqa::MessagePropertiesIterator it(&props);
+ sink(*it.name().data()); // $ ir
+}
+
+void test_setPropertyAsString_name() {
+ bsl::string_view name(source());
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsString(name, "value");
+ BloombergLP::bmqa::MessagePropertiesIterator it(&props);
+ sink(*it.name().data()); // $ ir
+}
+
+void test_setPropertyAsBinary_name() {
+ bsl::string_view name(source());
+ BloombergLP::bmqa::MessageProperties props;
+ props.setPropertyAsBinary(name, bsl::span());
+ BloombergLP::bmqa::MessagePropertiesIterator it(&props);
+ sink(*it.name().data()); // $ ir
+}
+
+void test_iterator() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ BloombergLP::bmqa::MessagePropertiesIterator it(&props);
+ while (it.hasNext()) {
+ sink(*it.name().data()); // $ ir
+ sink(*it.getAsString().data()); // $ ir
+ sink(*it.getAsBinary().data()); // $ ir
+ sink(it.getAsInt32()); // no flow: scalar getters are not modelled
+ }
+}
+
+void test_iterator_assignment() {
+ bsl::string data(source());
+ BloombergLP::bmqa::Message *msg = (BloombergLP::bmqa::Message *)data.data();
+ BloombergLP::bmqa::MessageProperties props;
+ msg->loadProperties(&props);
+ BloombergLP::bmqa::MessagePropertiesIterator it(&props);
+ BloombergLP::bmqa::MessagePropertiesIterator copy;
+ copy = it;
+ sink(*copy.getAsString().data()); // $ ir
+ sink(*(copy = it).name().data()); // $ ir
+}
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/bsl.h b/cpp/ql/test/library-tests/dataflow/external-models/bsl.h
new file mode 100644
index 000000000000..2183b996faa6
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/external-models/bsl.h
@@ -0,0 +1,49 @@
+#ifndef CODEQL_TEST_BSL_STRING_H
+#define CODEQL_TEST_BSL_STRING_H
+
+namespace bsl {
+ typedef unsigned long size_t;
+ typedef int int32_t;
+ template class allocator {};
+ template struct char_traits {};
+ template, class Allocator = allocator >
+ class basic_string {
+ public:
+ basic_string();
+ basic_string(const charT* s, const Allocator& a = Allocator());
+ const charT* data() const;
+ size_t size() const;
+ };
+ typedef basic_string string;
+ template >
+ class basic_string_view {
+ public:
+ basic_string_view();
+ basic_string_view(const charT* s);
+ const charT* data() const;
+ };
+ typedef basic_string_view string_view;
+ template >
+ class vector {
+ public:
+ vector();
+ const T* data() const;
+ const T& operator[](size_t i) const;
+ void push_back(const T& value);
+ };
+ template class span {
+ public:
+ span();
+ span(T* p, size_t n);
+ T* data() const;
+ };
+ template class shared_ptr {
+ public:
+ T *get() const;
+ };
+ class streambuf {};
+ class istream {};
+ class ostream {};
+}
+
+#endif
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/bslx.cpp b/cpp/ql/test/library-tests/dataflow/external-models/bslx.cpp
new file mode 100644
index 000000000000..22178f3c3e49
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/external-models/bslx.cpp
@@ -0,0 +1,341 @@
+#include "../taint-tests/stl.h"
+
+// BDE spells the standard string as `bsl::string`; alias it onto the stub above.
+namespace bsl {
+ using std::string;
+}
+
+// BDE wraps every package-group namespace in `BloombergLP`; this stub reproduces that.
+namespace BloombergLP {
+namespace bslstl {
+ template class StringRefImp {};
+ typedef StringRefImp StringRef;
+}
+namespace bsls {
+ // `bsls::Types` provides the fixed-width integer aliases used by the stream API.
+ struct Types {
+ typedef long long Int64;
+ typedef unsigned long long Uint64;
+ };
+}
+namespace bslx {
+ class ByteInStream {
+ public:
+ ByteInStream();
+ ByteInStream(const char *buffer, std::size_t numBytes);
+ void reset();
+ void reset(const char *buffer, std::size_t numBytes);
+ void reset(const bslstl::StringRef &srcData);
+ ByteInStream &getLength(int &variable);
+ ByteInStream &getVersion(int &variable);
+ ByteInStream &getInt8(char &variable);
+ ByteInStream &getUint8(unsigned char &variable);
+ ByteInStream &getInt16(short &variable);
+ ByteInStream &getUint16(unsigned short &variable);
+ ByteInStream &getInt24(int &variable);
+ ByteInStream &getUint24(unsigned int &variable);
+ ByteInStream &getInt32(int &variable);
+ ByteInStream &getUint32(unsigned int &variable);
+ ByteInStream &getInt40(bsls::Types::Int64 &variable);
+ ByteInStream &getUint40(bsls::Types::Uint64 &variable);
+ ByteInStream &getInt48(bsls::Types::Int64 &variable);
+ ByteInStream &getUint48(bsls::Types::Uint64 &variable);
+ ByteInStream &getInt56(bsls::Types::Int64 &variable);
+ ByteInStream &getUint56(bsls::Types::Uint64 &variable);
+ ByteInStream &getInt64(bsls::Types::Int64 &variable);
+ ByteInStream &getUint64(bsls::Types::Uint64 &variable);
+ ByteInStream &getFloat32(float &variable);
+ ByteInStream &getFloat64(double &variable);
+ ByteInStream &getString(bsl::string &variable);
+ ByteInStream &getArrayInt8(char *variables, int numVariables);
+ ByteInStream &getArrayUint8(unsigned char *variables, int numVariables);
+ ByteInStream &getArrayInt16(short *variables, int numVariables);
+ ByteInStream &getArrayUint16(unsigned short *variables, int numVariables);
+ ByteInStream &getArrayInt24(int *variables, int numVariables);
+ ByteInStream &getArrayUint24(unsigned int *variables, int numVariables);
+ ByteInStream &getArrayInt32(int *variables, int numVariables);
+ ByteInStream &getArrayUint32(unsigned int *variables, int numVariables);
+ ByteInStream &getArrayInt40(bsls::Types::Int64 *variables, int numVariables);
+ ByteInStream &getArrayUint40(bsls::Types::Uint64 *variables, int numVariables);
+ ByteInStream &getArrayInt48(bsls::Types::Int64 *variables, int numVariables);
+ ByteInStream &getArrayUint48(bsls::Types::Uint64 *variables, int numVariables);
+ ByteInStream &getArrayInt56(bsls::Types::Int64 *variables, int numVariables);
+ ByteInStream &getArrayUint56(bsls::Types::Uint64 *variables, int numVariables);
+ ByteInStream &getArrayInt64(bsls::Types::Int64 *variables, int numVariables);
+ ByteInStream &getArrayUint64(bsls::Types::Uint64 *variables, int numVariables);
+ ByteInStream &getArrayFloat32(float *variables, int numVariables);
+ ByteInStream &getArrayFloat64(double *variables, int numVariables);
+ };
+
+ template
+ class GenericInStream {
+ public:
+ GenericInStream(STREAMBUF *streamBuf);
+ GenericInStream &getLength(int &variable);
+ GenericInStream &getVersion(int &variable);
+ GenericInStream &getInt8(char &variable);
+ GenericInStream &getUint8(unsigned char &variable);
+ GenericInStream &getInt16(short &variable);
+ GenericInStream &getUint16(unsigned short &variable);
+ GenericInStream &getInt24(int &variable);
+ GenericInStream &getUint24(unsigned int &variable);
+ GenericInStream &getInt32(int &variable);
+ GenericInStream &getUint32(unsigned int &variable);
+ GenericInStream &getInt40(bsls::Types::Int64 &variable);
+ GenericInStream &getUint40(bsls::Types::Uint64 &variable);
+ GenericInStream &getInt48(bsls::Types::Int64 &variable);
+ GenericInStream &getUint48(bsls::Types::Uint64 &variable);
+ GenericInStream &getInt56(bsls::Types::Int64 &variable);
+ GenericInStream &getUint56(bsls::Types::Uint64 &variable);
+ GenericInStream &getInt64(bsls::Types::Int64 &variable);
+ GenericInStream &getUint64(bsls::Types::Uint64 &variable);
+ GenericInStream &getFloat32(float &variable);
+ GenericInStream &getFloat64(double &variable);
+ GenericInStream &getString(bsl::string &variable);
+ GenericInStream &getArrayInt8(char *variables, int numVariables);
+ GenericInStream &getArrayUint8(unsigned char *variables, int numVariables);
+ GenericInStream &getArrayInt16(short *variables, int numVariables);
+ GenericInStream &getArrayUint16(unsigned short *variables, int numVariables);
+ GenericInStream &getArrayInt24(int *variables, int numVariables);
+ GenericInStream &getArrayUint24(unsigned int *variables, int numVariables);
+ GenericInStream &getArrayInt32(int *variables, int numVariables);
+ GenericInStream &getArrayUint32(unsigned int *variables, int numVariables);
+ GenericInStream &getArrayInt40(bsls::Types::Int64 *variables, int numVariables);
+ GenericInStream &getArrayUint40(bsls::Types::Uint64 *variables, int numVariables);
+ GenericInStream &getArrayInt48(bsls::Types::Int64 *variables, int numVariables);
+ GenericInStream &getArrayUint48(bsls::Types::Uint64 *variables, int numVariables);
+ GenericInStream &getArrayInt56(bsls::Types::Int64 *variables, int numVariables);
+ GenericInStream &getArrayUint56(bsls::Types::Uint64 *variables, int numVariables);
+ GenericInStream &getArrayInt64(bsls::Types::Int64 *variables, int numVariables);
+ GenericInStream &getArrayUint64(bsls::Types::Uint64 *variables, int numVariables);
+ GenericInStream &getArrayFloat32(float *variables, int numVariables);
+ GenericInStream &getArrayFloat64(double *variables, int numVariables);
+ };
+
+ namespace InStreamFunctions {
+ template
+ STREAM &bdexStreamIn(STREAM &stream, TYPE &variable);
+ template
+ STREAM &bdexStreamIn(STREAM &stream, TYPE &variable, int version);
+ template
+ STREAM &bdexStreamIn(STREAM &stream, int &variable, int version = 0) {
+ return stream.getInt32(variable);
+ }
+ }
+}
+}
+
+struct MyStreamBuf {};
+
+char *source();
+void sink(int);
+void sink(char);
+
+// --- flow tests (source -> sink) ---
+
+void test_ByteInStream_getInt32_no_flow() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ int x = 0;
+ stream.getInt32(x);
+ sink(x); // no flow: scalar outputs are deliberately not modeled
+}
+
+void test_ByteInStream_getArrayInt8() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ char buf[16];
+ stream.getArrayInt8(buf, 16);
+ sink(*buf); // $ ir
+}
+
+void test_ByteInStream_getString() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ std::string out;
+ stream.getString(out);
+ sink(*out.data()); // $ ir
+}
+
+void test_ByteInStream_chained() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ int a = 0;
+ bsl::string out;
+ stream.getInt32(a).getString(out);
+ sink(*out.data()); // $ ir
+}
+
+void test_ByteInStream_reset() {
+ BloombergLP::bslx::ByteInStream stream;
+ std::string data = std::string(source());
+ stream.reset(data.data(), data.size());
+ bsl::string out;
+ stream.getString(out);
+ sink(*out.data()); // $ ir
+}
+
+void test_GenericInStream_flow() {
+ std::string data = std::string(source());
+ MyStreamBuf *sb = (MyStreamBuf *)data.data();
+ BloombergLP::bslx::GenericInStream stream(sb);
+ bsl::string out;
+ stream.getString(out);
+ sink(*out.data()); // $ ir
+}
+
+void test_GenericInStream_getInt32_no_flow() {
+ std::string data = std::string(source());
+ MyStreamBuf *sb = (MyStreamBuf *)data.data();
+ BloombergLP::bslx::GenericInStream stream(sb);
+ int x = 0;
+ stream.getInt32(x);
+ sink(x); // no flow: scalar outputs are deliberately not modeled
+}
+
+void test_bdexStreamIn() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ bsl::string obj;
+ BloombergLP::bslx::InStreamFunctions::bdexStreamIn(stream, obj);
+ sink(*obj.data()); // $ ir
+}
+
+// --- coverage: verify flow through every modeled getter in a fluent chain ---
+
+void coverage_ByteInStream() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ int i = 0;
+ unsigned int ui = 0;
+ char c = 0;
+ unsigned char uc = 0;
+ short s = 0;
+ unsigned short us = 0;
+ BloombergLP::bsls::Types::Int64 ll = 0;
+ BloombergLP::bsls::Types::Uint64 ull = 0;
+ float f = 0;
+ double d = 0;
+ bsl::string str;
+ char cbuf[16];
+ unsigned char ucbuf[16];
+ short sbuf[16];
+ unsigned short usbuf[16];
+ int ibuf[16];
+ unsigned int uibuf[16];
+ BloombergLP::bsls::Types::Int64 llbuf[16];
+ BloombergLP::bsls::Types::Uint64 ullbuf[16];
+ float fbuf[16];
+ double dbuf[16];
+ bsl::string out;
+ stream.getLength(i).getVersion(i).getInt8(c).getUint8(uc).getInt16(s).getUint16(us).getInt24(i).getUint24(ui).getInt32(i).getUint32(ui).getInt40(ll).getUint40(ull).getInt48(ll).getUint48(ull).getInt56(ll).getUint56(ull).getInt64(ll).getUint64(ull).getFloat32(f).getFloat64(d).getString(str).getArrayInt8(cbuf, 16).getArrayUint8(ucbuf, 16).getArrayInt16(sbuf, 16).getArrayUint16(usbuf, 16).getArrayInt24(ibuf, 16).getArrayUint24(uibuf, 16).getArrayInt32(ibuf, 16).getArrayUint32(uibuf, 16).getArrayInt40(llbuf, 16).getArrayUint40(ullbuf, 16).getArrayInt48(llbuf, 16).getArrayUint48(ullbuf, 16).getArrayInt56(llbuf, 16).getArrayUint56(ullbuf, 16).getArrayInt64(llbuf, 16).getArrayUint64(ullbuf, 16).getArrayFloat32(fbuf, 16).getArrayFloat64(dbuf, 16).getString(out);
+ sink(*out.data()); // $ ir
+}
+
+void coverage_GenericInStream() {
+ std::string data = std::string(source());
+ MyStreamBuf *sb = (MyStreamBuf *)data.data();
+ BloombergLP::bslx::GenericInStream stream(sb);
+ int i = 0;
+ unsigned int ui = 0;
+ char c = 0;
+ unsigned char uc = 0;
+ short s = 0;
+ unsigned short us = 0;
+ BloombergLP::bsls::Types::Int64 ll = 0;
+ BloombergLP::bsls::Types::Uint64 ull = 0;
+ float f = 0;
+ double d = 0;
+ bsl::string str;
+ char cbuf[16];
+ unsigned char ucbuf[16];
+ short sbuf[16];
+ unsigned short usbuf[16];
+ int ibuf[16];
+ unsigned int uibuf[16];
+ BloombergLP::bsls::Types::Int64 llbuf[16];
+ BloombergLP::bsls::Types::Uint64 ullbuf[16];
+ float fbuf[16];
+ double dbuf[16];
+ bsl::string out;
+ stream.getLength(i).getVersion(i).getInt8(c).getUint8(uc).getInt16(s).getUint16(us).getInt24(i).getUint24(ui).getInt32(i).getUint32(ui).getInt40(ll).getUint40(ull).getInt48(ll).getUint48(ull).getInt56(ll).getUint56(ull).getInt64(ll).getUint64(ull).getFloat32(f).getFloat64(d).getString(str).getArrayInt8(cbuf, 16).getArrayUint8(ucbuf, 16).getArrayInt16(sbuf, 16).getArrayUint16(usbuf, 16).getArrayInt24(ibuf, 16).getArrayUint24(uibuf, 16).getArrayInt32(ibuf, 16).getArrayUint32(uibuf, 16).getArrayInt40(llbuf, 16).getArrayUint40(ullbuf, 16).getArrayInt48(llbuf, 16).getArrayUint48(ullbuf, 16).getArrayInt56(llbuf, 16).getArrayUint56(ullbuf, 16).getArrayInt64(llbuf, 16).getArrayUint64(ullbuf, 16).getArrayFloat32(fbuf, 16).getArrayFloat64(dbuf, 16).getString(out);
+ sink(*out.data()); // $ ir
+}
+
+void test_bdexStreamIn_integer() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ int x = 0;
+ BloombergLP::bslx::InStreamFunctions::bdexStreamIn(stream, x);
+ sink(x); // $ ir
+ BloombergLP::bslx::InStreamFunctions::bdexStreamIn(stream, x, 0);
+ sink(x); // $ ir
+ bsl::string out;
+ BloombergLP::bslx::InStreamFunctions::bdexStreamIn(stream, x, 0).getString(out);
+ sink(*out.data()); // $ ir
+}
+
+void test_bdexStreamIn_versioned_string() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ bsl::string out;
+ BloombergLP::bslx::InStreamFunctions::bdexStreamIn(stream, out, 1);
+ sink(*out.data()); // $ ir
+}
+
+struct BdexObject {
+ int value;
+};
+
+void sink(BdexObject);
+
+void test_bdexStreamIn_object() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ BdexObject out;
+ BloombergLP::bslx::InStreamFunctions::bdexStreamIn(stream, out, 1);
+ sink(out); // $ ir
+}
+
+namespace StringRefTest {
+ BloombergLP::bslstl::StringRef source();
+}
+
+void test_ByteInStream_reset_stringref() {
+ BloombergLP::bslx::ByteInStream stream;
+ BloombergLP::bslstl::StringRef data = StringRefTest::source();
+ stream.reset(data);
+ bsl::string out;
+ stream.getString(out);
+ sink(*out.data()); // $ ir
+}
+
+void test_ByteInStream_reset_rewind() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ stream.reset();
+ bsl::string out;
+ stream.getString(out);
+ sink(*out.data()); // $ ir
+}
+
+void test_ByteInStream_reset_clean_buffer() {
+ BloombergLP::bslx::ByteInStream stream;
+ const char data[] = "clean";
+ stream.reset(data, *source());
+ stream.reset();
+ bsl::string out;
+ stream.getString(out);
+ sink(*out.data()); // no flow: the tainted length does not taint the buffer
+}
+
+void test_ByteInStream_reset_replaces_buffer() {
+ std::string data = std::string(source());
+ BloombergLP::bslx::ByteInStream stream(data.data(), data.size());
+ const char clean[] = "clean";
+ stream.reset(clean, sizeof(clean));
+ bsl::string out;
+ stream.getString(out);
+ // Known false positive: this summary does not kill taint from the old buffer.
+ sink(*out.data()); // $ SPURIOUS: ir
+}
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 24ba3b2aa686..e4d8ca07ccf0 100644
--- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected
+++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected
@@ -1,239 +1,1482 @@
models
-| 1 | Sink: ; ; false; ymlSink; ; ; Argument[0]; test-sink; manual |
-| 2 | Sink: boost::asio; ; false; write; ; ; Argument[*1]; remote-sink; manual |
-| 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; 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; RegEnumValueA; ; ; Argument[*2,*6]; windows-registry; manual |
-| 20 | Source: ; ; false; RegEnumValueW; ; ; Argument[*2,*6]; windows-registry; manual |
-| 21 | Source: ; ; false; RegGetValueA; ; ; Argument[*5]; windows-registry; manual |
-| 22 | Source: ; ; false; RegGetValueW; ; ; Argument[*5]; windows-registry; manual |
-| 23 | Source: ; ; false; RegQueryMultipleValuesA; ; ; Argument[*3]; windows-registry; manual |
-| 24 | Source: ; ; false; RegQueryMultipleValuesW; ; ; Argument[*3]; windows-registry; manual |
-| 25 | Source: ; ; false; RegQueryValueA; ; ; Argument[*2]; windows-registry; manual |
-| 26 | Source: ; ; false; RegQueryValueExA; ; ; Argument[*4]; windows-registry; manual |
-| 27 | Source: ; ; false; RegQueryValueExW; ; ; Argument[*4]; windows-registry; manual |
-| 28 | Source: ; ; false; RegQueryValueW; ; ; Argument[*2]; windows-registry; manual |
-| 29 | Source: ; ; false; WinHttpQueryHeaders; ; ; Argument[*3]; remote; manual |
-| 30 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[**8]; remote; manual |
-| 31 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*5]; remote; manual |
-| 32 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*6]; remote; manual |
-| 33 | Source: ; ; false; WinHttpReadData; ; ; Argument[*1]; remote; manual |
-| 34 | Source: ; ; false; WinHttpReadDataEx; ; ; Argument[*1]; remote; manual |
-| 35 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
-| 36 | Source: Azure::Core::Http; RawResponse; true; ExtractBodyStream; ; ; ReturnValue[*]; remote; manual |
-| 37 | Source: Azure::Core::Http; RawResponse; true; GetBody; ; ; ReturnValue[*]; remote; manual |
-| 38 | Source: Azure::Core::Http; RawResponse; true; GetHeaders; ; ; ReturnValue[*]; remote; manual |
-| 39 | Source: Azure::Core::Http; Request; true; GetBodyStream; ; ; ReturnValue[*]; remote; manual |
-| 40 | Source: Azure::Core::Http; Request; true; GetHeader; ; ; ReturnValue; remote; manual |
-| 41 | Source: Azure::Core::Http; Request; true; GetHeaders; ; ; ReturnValue; remote; manual |
-| 42 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
-| 43 | Summary: ; ; false; CLSIDFromProgID; ; ; Argument[*0]; Argument[*1]; taint; manual |
-| 44 | Summary: ; ; false; CLSIDFromString; ; ; Argument[*0]; Argument[*1]; taint; manual |
-| 45 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
-| 46 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
-| 47 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
-| 48 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
-| 49 | Summary: ; ; false; GUIDFromString; ; ; Argument[*0]; Argument[*1]; taint; manual |
-| 50 | Summary: ; ; false; IIDFromString; ; ; Argument[*0]; Argument[*1]; taint; manual |
-| 51 | Summary: ; ; false; ProgIDFromCLSID; ; ; Argument[*0]; Argument[**1]; taint; manual |
-| 52 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
-| 53 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 54 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 55 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 56 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
-| 57 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 58 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
-| 59 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 60 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
-| 61 | Summary: ; ; false; StringFromCLSID; ; ; Argument[*0]; Argument[**1]; taint; manual |
-| 62 | Summary: ; ; false; StringFromGUID2; ; ; Argument[*0]; Argument[*1]; taint; manual |
-| 63 | Summary: ; ; false; StringFromIID; ; ; Argument[*0]; Argument[**1]; taint; manual |
-| 64 | Summary: ; ; false; WinHttpCrackUrl; ; ; Argument[*0]; Argument[*3]; taint; manual |
-| 65 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
-| 66 | Summary: ; ; false; callWithNonTypeTemplate; (const T &); ; Argument[*0]; ReturnValue; value; manual |
-| 67 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
-| 68 | Summary: ; ; false; read_field_from_struct; ; ; Argument[*0].Field[MyNamespace::MyStructInNamespace::myField]; ReturnValue; value; manual |
-| 69 | Summary: ; ; false; read_field_from_struct_2; ; ; Argument[*0].Field[MyGlobalStruct::myField]; ReturnValue; value; manual |
-| 70 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
-| 71 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
-| 72 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
-| 73 | Summary: ; MyString; true; operator[]; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
-| 74 | Summary: ; MyString; true; operator[]; ; ; ReturnValue[*]; Argument[-1]; taint; manual |
-| 75 | Summary: ; ReverseFlow; true; get_ptr; ; ; ReturnValue[*]; Argument[-1].Field[ReverseFlow::value]; value; manual |
-| 76 | Summary: ; TemplateClass1; true; templateFunction2; (U,V); ; Argument[1]; ReturnValue; value; manual |
-| 77 | Summary: ; TemplateClass1; false; templateFunction; (T,U); ; Argument[0]; ReturnValue; value; manual |
-| 78 | Summary: ; TemplateClass2; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual |
-| 79 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
-| 80 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
-| 81 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
-| 82 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
-| 83 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
+| 1 | Sink: ; ; false; sink_from_callback_return_template; ; ; Argument[0].ReturnValue; test-sink; manual |
+| 2 | Sink: ; ; false; sink_ptr_from_callback_return_ptr; ; ; Argument[0].ReturnValue[*]; test-sink; manual |
+| 3 | Sink: ; ; false; ymlSink; ; ; Argument[0]; test-sink; manual |
+| 4 | Sink: boost::asio; ; false; write; ; ; Argument[*1]; remote-sink; manual |
+| 5 | Source: ; ; false; GetCommandLineA; ; ; ReturnValue[*]; local; manual |
+| 6 | Source: ; ; false; GetEnvironmentStringsA; ; ; ReturnValue[*]; local; manual |
+| 7 | Source: ; ; false; GetEnvironmentVariableA; ; ; Argument[*1]; local; manual |
+| 8 | Source: ; ; false; HttpReceiveClientCertificate; ; ; Argument[*3]; remote; manual |
+| 9 | Source: ; ; false; HttpReceiveHttpRequest; ; ; Argument[*3]; remote; manual |
+| 10 | Source: ; ; false; HttpReceiveRequestEntityBody; ; ; Argument[*3]; remote; manual |
+| 11 | Source: ; ; false; MapViewOfFile2; ; ; ReturnValue[*]; local; manual |
+| 12 | Source: ; ; false; MapViewOfFile3; ; ; ReturnValue[*]; local; manual |
+| 13 | Source: ; ; false; MapViewOfFile3FromApp; ; ; ReturnValue[*]; local; manual |
+| 14 | Source: ; ; false; MapViewOfFile; ; ; ReturnValue[*]; local; manual |
+| 15 | Source: ; ; false; MapViewOfFileEx; ; ; ReturnValue[*]; local; manual |
+| 16 | Source: ; ; false; MapViewOfFileFromApp; ; ; ReturnValue[*]; local; manual |
+| 17 | Source: ; ; false; MapViewOfFileNuma2; ; ; ReturnValue[*]; local; manual |
+| 18 | Source: ; ; false; NtReadFile; ; ; Argument[*5]; local; manual |
+| 19 | Source: ; ; false; ReadFile; ; ; Argument[*1]; local; manual |
+| 20 | Source: ; ; false; ReadFileEx; ; ; Argument[*1]; local; manual |
+| 21 | Source: ; ; false; RegEnumValueA; ; ; Argument[*2,*6]; windows-registry; manual |
+| 22 | Source: ; ; false; RegEnumValueW; ; ; Argument[*2,*6]; windows-registry; manual |
+| 23 | Source: ; ; false; RegGetValueA; ; ; Argument[*5]; windows-registry; manual |
+| 24 | Source: ; ; false; RegGetValueW; ; ; Argument[*5]; windows-registry; manual |
+| 25 | Source: ; ; false; RegQueryMultipleValuesA; ; ; Argument[*3]; windows-registry; manual |
+| 26 | Source: ; ; false; RegQueryMultipleValuesW; ; ; Argument[*3]; windows-registry; manual |
+| 27 | Source: ; ; false; RegQueryValueA; ; ; Argument[*2]; windows-registry; manual |
+| 28 | Source: ; ; false; RegQueryValueExA; ; ; Argument[*4]; windows-registry; manual |
+| 29 | Source: ; ; false; RegQueryValueExW; ; ; Argument[*4]; windows-registry; manual |
+| 30 | Source: ; ; false; RegQueryValueW; ; ; Argument[*2]; windows-registry; manual |
+| 31 | Source: ; ; false; WinHttpQueryHeaders; ; ; Argument[*3]; remote; manual |
+| 32 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[**8]; remote; manual |
+| 33 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*5]; remote; manual |
+| 34 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*6]; remote; manual |
+| 35 | Source: ; ; false; WinHttpReadData; ; ; Argument[*1]; remote; manual |
+| 36 | Source: ; ; false; WinHttpReadDataEx; ; ; Argument[*1]; remote; manual |
+| 37 | Source: ; ; false; source_from_callback_ptr; ; ; Argument[0].Parameter[*0].Field[SourceWrapper::value]; local; manual |
+| 38 | Source: ; ; false; source_from_callback_return_ptr; ; ; Argument[0].ReturnValue; local; manual |
+| 39 | Source: ; ; false; source_from_callback_return_template; ; ; Argument[0].ReturnValue; local; manual |
+| 40 | Source: ; ; false; source_from_callback_template; ; ; Argument[0].Parameter[*0].Field[SourceWrapper::value]; local; manual |
+| 41 | Source: ; ; false; source_ptr_from_callback_return_ptr; ; ; Argument[0].ReturnValue[*]; local; manual |
+| 42 | Source: ; ; false; test_parameter; ; ; Parameter[*0].Field[*SourceWrapper::pointer]; local; manual |
+| 43 | Source: ; ; false; test_parameter; ; ; Parameter[*0].Field[SourceWrapper::value]; local; manual |
+| 44 | Source: ; ; false; test_parameter; ; ; Parameter[*2]; local; manual |
+| 45 | Source: ; ; false; test_parameter; ; ; Parameter[1].Field[*SourceWrapper::pointer]; local; manual |
+| 46 | Source: ; ; false; test_parameter; ; ; Parameter[1].Field[SourceWrapper::value]; local; manual |
+| 47 | Source: ; ; false; ymlFieldSource; ; ; ReturnValue.Field[SourceWrapper::value]; local; manual |
+| 48 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
+| 49 | Source: ; ; false; ymlSourcePtr; ; ; ReturnValue[*]; local; manual |
+| 50 | Source: Azure::Core::Http; RawResponse; true; ExtractBodyStream; ; ; ReturnValue[*]; remote; manual |
+| 51 | Source: Azure::Core::Http; RawResponse; true; GetBody; ; ; ReturnValue[*]; remote; manual |
+| 52 | Source: Azure::Core::Http; RawResponse; true; GetHeaders; ; ; ReturnValue[*]; remote; manual |
+| 53 | Source: Azure::Core::Http; Request; true; GetBodyStream; ; ; ReturnValue[*]; remote; manual |
+| 54 | Source: Azure::Core::Http; Request; true; GetHeader; ; ; ReturnValue; remote; manual |
+| 55 | Source: Azure::Core::Http; Request; true; GetHeaders; ; ; ReturnValue; remote; manual |
+| 56 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
+| 57 | Summary: ; ; false; CLSIDFromProgID; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 58 | Summary: ; ; false; CLSIDFromString; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 59 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
+| 60 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
+| 61 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
+| 62 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
+| 63 | Summary: ; ; false; GUIDFromString; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 64 | Summary: ; ; false; IIDFromString; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 65 | Summary: ; ; false; ProgIDFromCLSID; ; ; Argument[*0]; Argument[**1]; taint; manual |
+| 66 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
+| 67 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 68 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 69 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 70 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
+| 71 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 72 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
+| 73 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 74 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
+| 75 | Summary: ; ; false; StringFromCLSID; ; ; Argument[*0]; Argument[**1]; taint; manual |
+| 76 | Summary: ; ; false; StringFromGUID2; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 77 | Summary: ; ; false; StringFromIID; ; ; Argument[*0]; Argument[**1]; taint; manual |
+| 78 | Summary: ; ; false; WinHttpCrackUrl; ; ; Argument[*0]; Argument[*3]; taint; manual |
+| 79 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
+| 80 | Summary: ; ; false; callWithNonTypeTemplate; (const T &); ; Argument[*0]; ReturnValue; value; manual |
+| 81 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
+| 82 | Summary: ; ; false; read_field_from_struct; ; ; Argument[*0].Field[MyNamespace::MyStructInNamespace::myField]; ReturnValue; value; manual |
+| 83 | Summary: ; ; false; read_field_from_struct_2; ; ; Argument[*0].Field[MyGlobalStruct::myField]; ReturnValue; value; manual |
+| 84 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
+| 85 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
+| 86 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
+| 87 | Summary: ; Container; true; get; ; ; Argument[-1].Element; ReturnValue[*]; value; manual |
+| 88 | Summary: ; Forwarder; true; get; ; ; Argument[-1]; ReturnValue; value; manual |
+| 89 | Summary: ; MyString; true; operator[]; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 90 | Summary: ; MyString; true; operator[]; ; ; ReturnValue[*]; Argument[-1]; taint; manual |
+| 91 | Summary: ; ReverseFlow; true; get_ptr; ; ; ReturnValue[*]; Argument[-1].Field[ReverseFlow::value]; value; manual |
+| 92 | Summary: ; TemplateClass1; true; templateFunction2; (U,V); ; Argument[1]; ReturnValue; value; manual |
+| 93 | Summary: ; TemplateClass1; false; templateFunction; (T,U); ; Argument[0]; ReturnValue; value; manual |
+| 94 | Summary: ; TemplateClass2; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual |
+| 95 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 96 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 97 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
+| 98 | Summary: Azure::Core; Url; true; GetQueryParameters; ; ; Argument[-1]; ReturnValue; taint; manual |
+| 99 | Summary: Azure::Core; Url; true; SetQueryParameters; ; ; Argument[0]; Argument[-1]; taint; manual |
+| 100 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 101 | Summary: BloombergLP::balber; BerDecoder; true; decode; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 102 | Summary: BloombergLP::balber; BerDecoder; true; decodeAny; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 103 | Summary: BloombergLP::balber; BerEncoder; true; encode; ; ; Argument[*1]; Argument[*0]; taint; manual |
+| 104 | Summary: BloombergLP::balber; BerEncoder; true; encodeAny; ; ; Argument[*1]; Argument[*0]; taint; manual |
+| 105 | Summary: BloombergLP::baljsn; Decoder; true; decode; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 106 | Summary: BloombergLP::baljsn; Decoder; true; decodeAny; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 107 | Summary: BloombergLP::baljsn; Encoder; true; encode; ; ; Argument[*1]; Argument[*0]; taint; manual |
+| 108 | Summary: BloombergLP::baljsn; Encoder; true; encodeAny; ; ; Argument[*1]; Argument[*0]; taint; manual |
+| 109 | Summary: BloombergLP::balxml; Decoder; true; decode; (const char *,size_t,TYPE *,const char *); ; Argument[*0]; Argument[*2]; taint; manual |
+| 110 | Summary: BloombergLP::balxml; Decoder; true; decode; (istream &,TYPE *,const char *); ; Argument[*0]; Argument[*1]; taint; manual |
+| 111 | Summary: BloombergLP::balxml; Decoder; true; decode; (istream &,TYPE *,const char *); ; Argument[*0]; ReturnValue[*]; taint; manual |
+| 112 | Summary: BloombergLP::balxml; Decoder; true; decode; (streambuf *,TYPE *,const char *); ; Argument[*0]; Argument[*1]; taint; manual |
+| 113 | Summary: BloombergLP::balxml; Decoder; true; decodeAny; (istream &,AnyRef *,const char *); ; Argument[*0]; Argument[*1]; taint; manual |
+| 114 | Summary: BloombergLP::balxml; Decoder; true; decodeAny; (istream &,AnyRef *,const char *); ; Argument[*0]; ReturnValue[*]; taint; manual |
+| 115 | Summary: BloombergLP::balxml; Decoder; true; decodeAny; (streambuf *,AnyRef *,const char *); ; Argument[*0]; Argument[*1]; taint; manual |
+| 116 | Summary: BloombergLP::balxml; Decoder; true; decodeAny; (istream &,TYPE *,const char *); ; Argument[*0]; Argument[*1]; taint; manual |
+| 117 | Summary: BloombergLP::balxml; Decoder; true; decodeAny; (istream &,TYPE *,const char *); ; Argument[*0]; ReturnValue[*]; taint; manual |
+| 118 | Summary: BloombergLP::balxml; Decoder; true; decodeAny; (streambuf *,TYPE *,const char *); ; Argument[*0]; Argument[*1]; taint; manual |
+| 119 | Summary: BloombergLP::balxml; Encoder; true; encode; (ostream &,const TYPE &); ; Argument[*0..1]; ReturnValue[*]; taint; manual |
+| 120 | Summary: BloombergLP::balxml; Encoder; true; encode; (ostream &,const TYPE &); ; Argument[*1]; Argument[*0]; taint; manual |
+| 121 | Summary: BloombergLP::balxml; Encoder; true; encode; (streambuf *,const TYPE &); ; Argument[*1]; Argument[*0]; taint; manual |
+| 122 | Summary: BloombergLP::balxml; Encoder; true; encodeAny; (ostream &,const AnyConstRef &); ; Argument[*0..1]; ReturnValue[*]; taint; manual |
+| 123 | Summary: BloombergLP::balxml; Encoder; true; encodeAny; (ostream &,const AnyConstRef &); ; Argument[*1]; Argument[*0]; taint; manual |
+| 124 | Summary: BloombergLP::balxml; Encoder; true; encodeAny; (streambuf *,const AnyConstRef &); ; Argument[*1]; Argument[*0]; taint; manual |
+| 125 | Summary: BloombergLP::balxml; Encoder; true; encodeAny; (ostream &,const TYPE &); ; Argument[*0..1]; ReturnValue[*]; taint; manual |
+| 126 | Summary: BloombergLP::balxml; Encoder; true; encodeAny; (ostream &,const TYPE &); ; Argument[*1]; Argument[*0]; taint; manual |
+| 127 | Summary: BloombergLP::balxml; Encoder; true; encodeAny; (streambuf *,const TYPE &); ; Argument[*1]; Argument[*0]; taint; manual |
+| 128 | Summary: BloombergLP::balxml; Encoder; true; encodeAnyToStream; ; ; Argument[*1]; Argument[*0]; taint; manual |
+| 129 | Summary: BloombergLP::balxml; Encoder; true; encodeToStream; ; ; Argument[*1]; Argument[*0]; taint; manual |
+| 130 | Summary: BloombergLP::bdlbb; Blob; true; buffer; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 131 | Summary: BloombergLP::bdlbb; BlobBuffer; true; buffer; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 132 | Summary: BloombergLP::bdlbb; BlobBuffer; true; data; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 133 | Summary: BloombergLP::bdlbb; BlobUtil; true; copy; (Blob *,int,const Blob &,int,int); ; Argument[*2]; Argument[*0]; taint; manual |
+| 134 | Summary: BloombergLP::bdlbb; BlobUtil; true; copy; (Blob *,int,const char *,int); ; Argument[*2]; Argument[*0]; taint; manual |
+| 135 | Summary: BloombergLP::bdlbb; BlobUtil; true; copy; (char *,const Blob &,int,int); ; Argument[*1]; Argument[*0]; taint; manual |
+| 136 | Summary: BloombergLP::bdlbb; BlobUtil; true; getContiguousRangeOrCopy; ; ; Argument[*1]; ReturnValue[*]; taint; manual |
+| 137 | Summary: BloombergLP::bmqa; Message; true; clone; ; ; Argument[-1]; ReturnValue; taint; manual |
+| 138 | Summary: BloombergLP::bmqa; Message; true; getData; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 139 | Summary: BloombergLP::bmqa; Message; true; loadProperties; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 140 | Summary: BloombergLP::bmqa; Message; true; setData; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 141 | Summary: BloombergLP::bmqa; Message; true; setDataRef; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 142 | Summary: BloombergLP::bmqa; Message; true; setPropertiesRef; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 143 | Summary: BloombergLP::bmqa; MessageEvent; true; messageIterator; ; ; Argument[-1]; ReturnValue; taint; manual |
+| 144 | Summary: BloombergLP::bmqa; MessageIterator; true; message; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 145 | Summary: BloombergLP::bmqa; MessageProperties; true; MessageProperties; (const MessageProperties &,Allocator *); ; Argument[*0]; Argument[-1]; value; manual |
+| 146 | Summary: BloombergLP::bmqa; MessageProperties; true; getPropertyAsBinary; ; ; Argument[-1]; ReturnValue[*].Element; taint; manual |
+| 147 | Summary: BloombergLP::bmqa; MessageProperties; true; getPropertyAsBinaryOr; ; ; Argument[*1].Element[@]; ReturnValue[*].Element[@]; value; manual |
+| 148 | Summary: BloombergLP::bmqa; MessageProperties; true; getPropertyAsBinaryOr; ; ; Argument[-1]; ReturnValue[*].Element; taint; manual |
+| 149 | Summary: BloombergLP::bmqa; MessageProperties; true; getPropertyAsString; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 150 | Summary: BloombergLP::bmqa; MessageProperties; true; getPropertyAsStringOr; ; ; Argument[*1]; ReturnValue[*]; value; manual |
+| 151 | Summary: BloombergLP::bmqa; MessageProperties; true; getPropertyAsStringOr; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 152 | Summary: BloombergLP::bmqa; MessageProperties; true; operator=; ; ; Argument[*0]; Argument[-1]; value; manual |
+| 153 | Summary: BloombergLP::bmqa; MessageProperties; true; operator=; ; ; Argument[*0]; ReturnValue[*]; value; manual |
+| 154 | Summary: BloombergLP::bmqa; MessageProperties; true; setPropertyAsBinary; ; ; Argument[0]; Argument[-1]; taint; manual |
+| 155 | Summary: BloombergLP::bmqa; MessageProperties; true; setPropertyAsBinary; ; ; Argument[1]; Argument[-1]; taint; manual |
+| 156 | Summary: BloombergLP::bmqa; MessageProperties; true; setPropertyAsBool; ; ; Argument[0]; Argument[-1]; taint; manual |
+| 157 | Summary: BloombergLP::bmqa; MessageProperties; true; setPropertyAsChar; ; ; Argument[0]; Argument[-1]; taint; manual |
+| 158 | Summary: BloombergLP::bmqa; MessageProperties; true; setPropertyAsInt32; ; ; Argument[0]; Argument[-1]; taint; manual |
+| 159 | Summary: BloombergLP::bmqa; MessageProperties; true; setPropertyAsInt64; ; ; Argument[0]; Argument[-1]; taint; manual |
+| 160 | Summary: BloombergLP::bmqa; MessageProperties; true; setPropertyAsShort; ; ; Argument[0]; Argument[-1]; taint; manual |
+| 161 | Summary: BloombergLP::bmqa; MessageProperties; true; setPropertyAsString; ; ; Argument[0]; Argument[-1]; taint; manual |
+| 162 | Summary: BloombergLP::bmqa; MessageProperties; true; setPropertyAsString; ; ; Argument[1]; Argument[-1]; taint; manual |
+| 163 | Summary: BloombergLP::bmqa; MessageProperties; true; streamIn; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 164 | Summary: BloombergLP::bmqa; MessageProperties; true; streamOut; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 165 | Summary: BloombergLP::bmqa; MessagePropertiesIterator; true; MessagePropertiesIterator; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 166 | Summary: BloombergLP::bmqa; MessagePropertiesIterator; true; getAsBinary; ; ; Argument[-1]; ReturnValue[*].Element; taint; manual |
+| 167 | Summary: BloombergLP::bmqa; MessagePropertiesIterator; true; getAsString; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 168 | Summary: BloombergLP::bmqa; MessagePropertiesIterator; true; name; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 169 | Summary: BloombergLP::bmqa; MessagePropertiesIterator; true; operator=; ; ; Argument[*0]; Argument[-1]; value; manual |
+| 170 | Summary: BloombergLP::bmqa; MessagePropertiesIterator; true; operator=; ; ; Argument[*0]; ReturnValue[*]; value; manual |
+| 171 | Summary: BloombergLP::bslx::InStreamFunctions; ; false; bdexStreamIn; ; ; Argument[*0]; Argument[*1]; taint; manual |
+| 172 | Summary: BloombergLP::bslx::InStreamFunctions; ; false; bdexStreamIn; ; ; Argument[*0]; ReturnValue[*]; taint; manual |
+| 173 | Summary: BloombergLP::bslx; ByteInStream; true; ByteInStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 174 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayFloat32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 175 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayFloat64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 176 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayInt16; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 177 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayInt24; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 178 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayInt32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 179 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayInt40; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 180 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayInt48; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 181 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayInt56; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 182 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayInt64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 183 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayInt8; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 184 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayInt8; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 185 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayUint16; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 186 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayUint24; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 187 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayUint32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 188 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayUint40; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 189 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayUint48; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 190 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayUint56; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 191 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayUint64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 192 | Summary: BloombergLP::bslx; ByteInStream; true; getArrayUint8; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 193 | Summary: BloombergLP::bslx; ByteInStream; true; getFloat32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 194 | Summary: BloombergLP::bslx; ByteInStream; true; getFloat64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 195 | Summary: BloombergLP::bslx; ByteInStream; true; getInt16; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 196 | Summary: BloombergLP::bslx; ByteInStream; true; getInt24; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 197 | Summary: BloombergLP::bslx; ByteInStream; true; getInt32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 198 | Summary: BloombergLP::bslx; ByteInStream; true; getInt40; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 199 | Summary: BloombergLP::bslx; ByteInStream; true; getInt48; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 200 | Summary: BloombergLP::bslx; ByteInStream; true; getInt56; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 201 | Summary: BloombergLP::bslx; ByteInStream; true; getInt64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 202 | Summary: BloombergLP::bslx; ByteInStream; true; getInt8; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 203 | Summary: BloombergLP::bslx; ByteInStream; true; getLength; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 204 | Summary: BloombergLP::bslx; ByteInStream; true; getString; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 205 | Summary: BloombergLP::bslx; ByteInStream; true; getString; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 206 | Summary: BloombergLP::bslx; ByteInStream; true; getUint16; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 207 | Summary: BloombergLP::bslx; ByteInStream; true; getUint24; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 208 | Summary: BloombergLP::bslx; ByteInStream; true; getUint32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 209 | Summary: BloombergLP::bslx; ByteInStream; true; getUint40; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 210 | Summary: BloombergLP::bslx; ByteInStream; true; getUint48; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 211 | Summary: BloombergLP::bslx; ByteInStream; true; getUint56; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 212 | Summary: BloombergLP::bslx; ByteInStream; true; getUint64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 213 | Summary: BloombergLP::bslx; ByteInStream; true; getUint8; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 214 | Summary: BloombergLP::bslx; ByteInStream; true; getVersion; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 215 | Summary: BloombergLP::bslx; ByteInStream; true; reset; (const StringRef &); ; Argument[*0]; Argument[-1]; taint; manual |
+| 216 | Summary: BloombergLP::bslx; ByteInStream; true; reset; (const char *,size_t); ; Argument[*0]; Argument[-1]; taint; manual |
+| 217 | Summary: BloombergLP::bslx; GenericInStream; true; GenericInStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 218 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayFloat32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 219 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayFloat64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 220 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayInt16; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 221 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayInt24; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 222 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayInt32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 223 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayInt40; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 224 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayInt48; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 225 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayInt56; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 226 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayInt64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 227 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayInt8; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 228 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayUint16; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 229 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayUint24; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 230 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayUint32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 231 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayUint40; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 232 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayUint48; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 233 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayUint56; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 234 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayUint64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 235 | Summary: BloombergLP::bslx; GenericInStream; true; getArrayUint8; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 236 | Summary: BloombergLP::bslx; GenericInStream; true; getFloat32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 237 | Summary: BloombergLP::bslx; GenericInStream; true; getFloat64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 238 | Summary: BloombergLP::bslx; GenericInStream; true; getInt16; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 239 | Summary: BloombergLP::bslx; GenericInStream; true; getInt24; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 240 | Summary: BloombergLP::bslx; GenericInStream; true; getInt32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 241 | Summary: BloombergLP::bslx; GenericInStream; true; getInt40; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 242 | Summary: BloombergLP::bslx; GenericInStream; true; getInt48; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 243 | Summary: BloombergLP::bslx; GenericInStream; true; getInt56; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 244 | Summary: BloombergLP::bslx; GenericInStream; true; getInt64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 245 | Summary: BloombergLP::bslx; GenericInStream; true; getInt8; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 246 | Summary: BloombergLP::bslx; GenericInStream; true; getLength; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 247 | Summary: BloombergLP::bslx; GenericInStream; true; getString; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 248 | Summary: BloombergLP::bslx; GenericInStream; true; getString; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 249 | Summary: BloombergLP::bslx; GenericInStream; true; getUint16; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 250 | Summary: BloombergLP::bslx; GenericInStream; true; getUint24; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 251 | Summary: BloombergLP::bslx; GenericInStream; true; getUint32; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 252 | Summary: BloombergLP::bslx; GenericInStream; true; getUint40; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 253 | Summary: BloombergLP::bslx; GenericInStream; true; getUint48; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 254 | Summary: BloombergLP::bslx; GenericInStream; true; getUint56; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 255 | Summary: BloombergLP::bslx; GenericInStream; true; getUint64; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 256 | Summary: BloombergLP::bslx; GenericInStream; true; getUint8; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 257 | Summary: BloombergLP::bslx; GenericInStream; true; getVersion; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
+| 258 | Summary: boost::asio::ip; basic_resolver; false; resolve; (const InternetProtocol &,const string &,const string &); ; Argument[*1..2]; ReturnValue; taint; manual |
+| 259 | Summary: boost::asio::ip; basic_resolver; false; resolve; (const InternetProtocol &,const string &,const string &,error_code &); ; Argument[*1..2]; ReturnValue; taint; manual |
+| 260 | Summary: boost::asio::ip; basic_resolver; false; resolve; (const InternetProtocol &,const string &,const string &,flags); ; Argument[*1..2]; ReturnValue; taint; manual |
+| 261 | Summary: boost::asio::ip; basic_resolver; false; resolve; (const InternetProtocol &,const string &,const string &,flags,error_code &); ; Argument[*1..2]; ReturnValue; taint; manual |
+| 262 | Summary: boost::asio::ip; basic_resolver; false; resolve; (const string &,const string &); ; Argument[*0..1]; ReturnValue; taint; manual |
+| 263 | Summary: boost::asio::ip; basic_resolver; false; resolve; (const string &,const string &,error_code &); ; Argument[*0..1]; ReturnValue; taint; manual |
+| 264 | Summary: boost::asio::ip; basic_resolver; false; resolve; (const string &,const string &,flags); ; Argument[*0..1]; ReturnValue; taint; manual |
+| 265 | Summary: boost::asio::ip; basic_resolver; false; resolve; (const string &,const string &,flags,error_code &); ; Argument[*0..1]; ReturnValue; taint; manual |
+| 266 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
+| 267 | Summary: bsl; vector; true; data; ; ; Argument[-1].Element[@]; ReturnValue[*@]; value; manual |
+| 268 | Summary: bsl; vector; true; operator[]; ; ; Argument[-1].Element[@]; ReturnValue[*@]; value; manual |
+| 269 | Summary: bsl; vector; true; push_back; ; ; Argument[*@0]; Argument[-1].Element[@]; value; manual |
+| 270 | Summary: google::protobuf; MessageLite; true; AppendPartialToCord; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 271 | Summary: google::protobuf; MessageLite; true; AppendPartialToString; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 272 | Summary: google::protobuf; MessageLite; true; AppendToCord; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 273 | Summary: google::protobuf; MessageLite; true; AppendToString; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 274 | Summary: google::protobuf; MessageLite; true; MergeFromBoundedZeroCopyStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 275 | Summary: google::protobuf; MessageLite; true; MergeFromCodedStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 276 | Summary: google::protobuf; MessageLite; true; MergeFromCord; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 277 | Summary: google::protobuf; MessageLite; true; MergeFromString; (const Cord &); ; Argument[*0]; Argument[-1]; taint; manual |
+| 278 | Summary: google::protobuf; MessageLite; true; MergeFromString; (string_view); ; Argument[0]; Argument[-1]; taint; manual |
+| 279 | Summary: google::protobuf; MessageLite; true; MergePartialFromBoundedZeroCopyStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 280 | Summary: google::protobuf; MessageLite; true; MergePartialFromCodedStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 281 | Summary: google::protobuf; MessageLite; true; MergePartialFromCord; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 282 | Summary: google::protobuf; MessageLite; true; MergePartialFromString; (const Cord &); ; Argument[*0]; Argument[-1]; taint; manual |
+| 283 | Summary: google::protobuf; MessageLite; true; MergePartialFromString; (string_view); ; Argument[0]; Argument[-1]; taint; manual |
+| 284 | Summary: google::protobuf; MessageLite; true; ParseFromArray; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 285 | Summary: google::protobuf; MessageLite; true; ParseFromBoundedZeroCopyStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 286 | Summary: google::protobuf; MessageLite; true; ParseFromCodedStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 287 | Summary: google::protobuf; MessageLite; true; ParseFromCord; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 288 | Summary: google::protobuf; MessageLite; true; ParseFromIstream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 289 | Summary: google::protobuf; MessageLite; true; ParseFromString; (const Cord &); ; Argument[*0]; Argument[-1]; taint; manual |
+| 290 | Summary: google::protobuf; MessageLite; true; ParseFromString; (string_view); ; Argument[0]; Argument[-1]; taint; manual |
+| 291 | Summary: google::protobuf; MessageLite; true; ParseFromZeroCopyStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 292 | Summary: google::protobuf; MessageLite; true; ParsePartialFromArray; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 293 | Summary: google::protobuf; MessageLite; true; ParsePartialFromBoundedZeroCopyStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 294 | Summary: google::protobuf; MessageLite; true; ParsePartialFromCodedStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 295 | Summary: google::protobuf; MessageLite; true; ParsePartialFromCord; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 296 | Summary: google::protobuf; MessageLite; true; ParsePartialFromIstream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 297 | Summary: google::protobuf; MessageLite; true; ParsePartialFromString; (const Cord &); ; Argument[*0]; Argument[-1]; taint; manual |
+| 298 | Summary: google::protobuf; MessageLite; true; ParsePartialFromString; (string_view); ; Argument[0]; Argument[-1]; taint; manual |
+| 299 | Summary: google::protobuf; MessageLite; true; ParsePartialFromZeroCopyStream; ; ; Argument[*0]; Argument[-1]; taint; manual |
+| 300 | Summary: google::protobuf; MessageLite; true; SerializeAsCord; ; ; Argument[-1]; ReturnValue; taint; manual |
+| 301 | Summary: google::protobuf; MessageLite; true; SerializeAsString; ; ; Argument[-1]; ReturnValue; taint; manual |
+| 302 | Summary: google::protobuf; MessageLite; true; SerializePartialAsCord; ; ; Argument[-1]; ReturnValue; taint; manual |
+| 303 | Summary: google::protobuf; MessageLite; true; SerializePartialAsString; ; ; Argument[-1]; ReturnValue; taint; manual |
+| 304 | Summary: google::protobuf; MessageLite; true; SerializePartialToArray; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 305 | Summary: google::protobuf; MessageLite; true; SerializePartialToCodedStream; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 306 | Summary: google::protobuf; MessageLite; true; SerializePartialToCord; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 307 | Summary: google::protobuf; MessageLite; true; SerializePartialToOstream; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 308 | Summary: google::protobuf; MessageLite; true; SerializePartialToString; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 309 | Summary: google::protobuf; MessageLite; true; SerializePartialToZeroCopyStream; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 310 | Summary: google::protobuf; MessageLite; true; SerializeToArray; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 311 | Summary: google::protobuf; MessageLite; true; SerializeToCodedStream; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 312 | Summary: google::protobuf; MessageLite; true; SerializeToCord; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 313 | Summary: google::protobuf; MessageLite; true; SerializeToOstream; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 314 | Summary: google::protobuf; MessageLite; true; SerializeToString; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 315 | Summary: google::protobuf; MessageLite; true; SerializeToZeroCopyStream; ; ; Argument[-1]; Argument[*0]; taint; manual |
+| 316 | Summary: std; vector; true; vector; (const vector &); ; Argument[*0].Element[@]; Argument[-1].Element[@]; value; manual |
edges
-| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:42 |
-| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:42 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:100:44:100:62 | call to buffer | provenance | MaD:83 |
-| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:39 |
-| 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:257:16:257:21 | Read output argument | provenance | MaD:79 |
-| 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:262:23:262:28 | ReadToCount output argument | provenance | MaD:80 |
-| 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:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:81 |
-| 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:38 |
-| 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:37 |
-| 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:36 |
-| 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:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:81 |
-| 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:289:63:289:65 | call to Value | provenance | MaD:82 |
-| 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:40 |
-| 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:41 |
-| 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 | |
+| asio_streams.cpp:109:34:109:44 | read_until output argument | asio_streams.cpp:113:7:113:17 | recv_buffer | provenance | Src:MaD:56 |
+| asio_streams.cpp:109:34:109:44 | read_until output argument | asio_streams.cpp:115:29:115:39 | recv_buffer | provenance | Src:MaD:56 Sink:MaD:4 |
+| asio_streams.cpp:119:37:119:44 | call to source | asio_streams.cpp:120:7:120:14 | send_str | provenance | TaintFunction |
+| asio_streams.cpp:119:37:119:44 | call to source | asio_streams.cpp:122:64:122:71 | *send_str | provenance | TaintFunction |
+| asio_streams.cpp:122:44:122:62 | call to buffer | asio_streams.cpp:122:44:122:62 | call to buffer | provenance | |
+| asio_streams.cpp:122:44:122:62 | call to buffer | asio_streams.cpp:123:7:123:17 | send_buffer | provenance | |
+| asio_streams.cpp:122:44:122:62 | call to buffer | asio_streams.cpp:125:29:125:39 | send_buffer | provenance | Sink:MaD:4 |
+| asio_streams.cpp:122:64:122:71 | *send_str | asio_streams.cpp:122:44:122:62 | call to buffer | provenance | MaD:266 |
+| asio_streams.cpp:136:19:136:26 | call to source | asio_streams.cpp:141:24:141:27 | *host | provenance | TaintFunction |
+| asio_streams.cpp:136:19:136:26 | call to source | asio_streams.cpp:142:24:142:27 | *host | provenance | TaintFunction |
+| asio_streams.cpp:136:19:136:26 | call to source | asio_streams.cpp:143:24:143:27 | *host | provenance | TaintFunction |
+| asio_streams.cpp:136:19:136:26 | call to source | asio_streams.cpp:144:24:144:27 | *host | provenance | TaintFunction |
+| asio_streams.cpp:136:19:136:26 | call to source | asio_streams.cpp:151:34:151:37 | *host | provenance | TaintFunction |
+| asio_streams.cpp:136:19:136:26 | call to source | asio_streams.cpp:152:34:152:37 | *host | provenance | TaintFunction |
+| asio_streams.cpp:136:19:136:26 | call to source | asio_streams.cpp:153:34:153:37 | *host | provenance | TaintFunction |
+| asio_streams.cpp:136:19:136:26 | call to source | asio_streams.cpp:154:34:154:37 | *host | provenance | TaintFunction |
+| asio_streams.cpp:141:24:141:27 | *host | asio_streams.cpp:141:16:141:22 | call to resolve | provenance | MaD:262 |
+| asio_streams.cpp:142:24:142:27 | *host | asio_streams.cpp:142:16:142:22 | call to resolve | provenance | MaD:263 |
+| asio_streams.cpp:143:24:143:27 | *host | asio_streams.cpp:143:16:143:22 | call to resolve | provenance | MaD:264 |
+| asio_streams.cpp:144:24:144:27 | *host | asio_streams.cpp:144:16:144:22 | call to resolve | provenance | MaD:265 |
+| asio_streams.cpp:151:34:151:37 | *host | asio_streams.cpp:151:16:151:22 | call to resolve | provenance | MaD:258 |
+| asio_streams.cpp:152:34:152:37 | *host | asio_streams.cpp:152:16:152:22 | call to resolve | provenance | MaD:259 |
+| asio_streams.cpp:153:34:153:37 | *host | asio_streams.cpp:153:16:153:22 | call to resolve | provenance | MaD:260 |
+| asio_streams.cpp:154:34:154:37 | *host | asio_streams.cpp:154:16:154:22 | call to resolve | provenance | MaD:261 |
+| asio_streams.cpp:168:22:168:29 | call to source | asio_streams.cpp:172:30:172:36 | *service | provenance | TaintFunction |
+| asio_streams.cpp:168:22:168:29 | call to source | asio_streams.cpp:173:30:173:36 | *service | provenance | TaintFunction |
+| asio_streams.cpp:168:22:168:29 | call to source | asio_streams.cpp:174:30:174:36 | *service | provenance | TaintFunction |
+| asio_streams.cpp:168:22:168:29 | call to source | asio_streams.cpp:175:30:175:36 | *service | provenance | TaintFunction |
+| asio_streams.cpp:168:22:168:29 | call to source | asio_streams.cpp:182:40:182:46 | *service | provenance | TaintFunction |
+| asio_streams.cpp:168:22:168:29 | call to source | asio_streams.cpp:183:40:183:46 | *service | provenance | TaintFunction |
+| asio_streams.cpp:168:22:168:29 | call to source | asio_streams.cpp:184:40:184:46 | *service | provenance | TaintFunction |
+| asio_streams.cpp:168:22:168:29 | call to source | asio_streams.cpp:185:40:185:46 | *service | provenance | TaintFunction |
+| asio_streams.cpp:172:30:172:36 | *service | asio_streams.cpp:172:16:172:22 | call to resolve | provenance | MaD:262 |
+| asio_streams.cpp:173:30:173:36 | *service | asio_streams.cpp:173:16:173:22 | call to resolve | provenance | MaD:263 |
+| asio_streams.cpp:174:30:174:36 | *service | asio_streams.cpp:174:16:174:22 | call to resolve | provenance | MaD:264 |
+| asio_streams.cpp:175:30:175:36 | *service | asio_streams.cpp:175:16:175:22 | call to resolve | provenance | MaD:265 |
+| asio_streams.cpp:182:40:182:46 | *service | asio_streams.cpp:182:16:182:22 | call to resolve | provenance | MaD:258 |
+| asio_streams.cpp:183:40:183:46 | *service | asio_streams.cpp:183:16:183:22 | call to resolve | provenance | MaD:259 |
+| asio_streams.cpp:184:40:184:46 | *service | asio_streams.cpp:184:16:184:22 | call to resolve | provenance | MaD:260 |
+| asio_streams.cpp:185:40:185:46 | *service | asio_streams.cpp:185:16:185:22 | call to resolve | provenance | MaD:261 |
+| azure.cpp:216:48:216:60 | *call to GetBodyStream | azure.cpp:220:5:220:8 | *resp | provenance | |
+| azure.cpp:216:48:216:60 | *call to GetBodyStream | azure.cpp:225:5:225:8 | *resp | provenance | |
+| azure.cpp:216:48:216:60 | *call to GetBodyStream | azure.cpp:229:38:229:41 | *resp | provenance | |
+| azure.cpp:216:48:216:60 | call to GetBodyStream | azure.cpp:216:48:216:60 | *call to GetBodyStream | provenance | Src:MaD:53 |
+| azure.cpp:220:5:220:8 | *resp | azure.cpp:220:16:220:21 | Read output argument | provenance | MaD:95 |
+| azure.cpp:220:16:220:21 | Read output argument | azure.cpp:221:10:221:16 | * ... | provenance | |
+| azure.cpp:225:5:225:8 | *resp | azure.cpp:225:23:225:28 | ReadToCount output argument | provenance | MaD:96 |
+| azure.cpp:225:23:225:28 | ReadToCount output argument | azure.cpp:226:10:226:16 | * ... | provenance | |
+| azure.cpp:229:38:229:41 | *resp | azure.cpp:229:44:229:52 | call to ReadToEnd [element] | provenance | MaD:97 |
+| azure.cpp:229:44:229:52 | call to ReadToEnd [element] | azure.cpp:229:44:229:52 | call to ReadToEnd [element] | provenance | |
+| azure.cpp:229:44:229:52 | call to ReadToEnd [element] | azure.cpp:230:10:230:12 | *vec [element] | provenance | |
+| azure.cpp:229:44:229:52 | call to ReadToEnd [element] | azure.cpp:230:10:230:12 | call to vector | provenance | DataFlowFunction |
+| azure.cpp:230:10:230:12 | *vec [element] | azure.cpp:230:10:230:12 | call to vector [element] | provenance | MaD:316 |
+| azure.cpp:230:10:230:12 | call to vector [element] | azure.cpp:230:10:230:12 | call to vector | provenance | |
+| azure.cpp:236:52:236:61 | call to GetHeaders | azure.cpp:237:14:237:29 | call to operator[] | provenance | Src:MaD:52 DataFlowFunction |
+| azure.cpp:236:52:236:61 | call to GetHeaders | azure.cpp:237:14:237:29 | call to operator[] | provenance | Src:MaD:52 TaintFunction |
+| azure.cpp:240:38:240:44 | call to GetBody | azure.cpp:241:10:241:13 | call to vector | provenance | Src:MaD:51 DataFlowFunction |
+| azure.cpp:240:38:240:44 | call to GetBody | azure.cpp:241:10:241:13 | call to vector | provenance | Src:MaD:51 DataFlowFunction |
+| azure.cpp:240:38:240:44 | call to GetBody | azure.cpp:241:10:241:13 | call to vector | provenance | Src:MaD:51 DataFlowFunction |
+| azure.cpp:240:38:240:44 | call to GetBody | azure.cpp:241:10:241:13 | call to vector | provenance | Src:MaD:51 TaintFunction |
+| azure.cpp:240:38:240:44 | call to GetBody | azure.cpp:241:10:241:13 | call to vector | provenance | Src:MaD:51 TaintFunction |
+| azure.cpp:240:38:240:44 | call to GetBody | azure.cpp:241:10:241:13 | call to vector | provenance | Src:MaD:51 TaintFunction |
+| azure.cpp:241:10:241:13 | call to vector | azure.cpp:241:10:241:13 | call to vector | provenance | |
+| azure.cpp:244:68:244:84 | *call to ExtractBodyStream | azure.cpp:245:21:245:23 | *call to get | provenance | |
+| azure.cpp:244:68:244:84 | call to ExtractBodyStream | azure.cpp:244:68:244:84 | *call to ExtractBodyStream | provenance | Src:MaD:50 |
+| azure.cpp:245:21:245:23 | *call to get | azure.cpp:245:28:245:36 | call to ReadToEnd [element] | provenance | MaD:97 |
+| azure.cpp:245:28:245:36 | call to ReadToEnd [element] | azure.cpp:245:10:245:38 | call to ReadToEnd | provenance | |
+| azure.cpp:245:28:245:36 | call to ReadToEnd [element] | azure.cpp:245:28:245:36 | call to ReadToEnd [element] | provenance | |
+| azure.cpp:255:24:255:56 | call to GetHeader | azure.cpp:255:63:255:65 | call to Value | provenance | MaD:100 |
+| azure.cpp:255:32:255:40 | call to GetHeader | azure.cpp:255:24:255:56 | call to GetHeader | provenance | |
+| azure.cpp:255:32:255:40 | call to GetHeader | azure.cpp:255:32:255:40 | call to GetHeader | provenance | Src:MaD:54 |
+| azure.cpp:255:63:255:65 | call to Value | azure.cpp:255:63:255:65 | call to Value | provenance | |
+| azure.cpp:255:63:255:65 | call to Value | azure.cpp:256:10:256:20 | headerValue | provenance | |
+| azure.cpp:259:58:259:67 | call to GetHeaders | azure.cpp:259:58:259:67 | call to GetHeaders | provenance | Src:MaD:55 |
+| azure.cpp:259:58:259:67 | call to GetHeaders | azure.cpp:260:38:260:53 | call to operator[] | provenance | TaintFunction |
+| azure.cpp:260:38:260:53 | call to operator[] | azure.cpp:261:10:261:20 | contentType | provenance | |
+| azure.cpp:268:3:268:5 | SetQueryParameters output argument | azure.cpp:269:8:269:10 | *url | provenance | |
+| azure.cpp:268:26:268:45 | call to GetHeaders | azure.cpp:268:3:268:5 | SetQueryParameters output argument | provenance | MaD:99 |
+| azure.cpp:268:34:268:43 | call to GetHeaders | azure.cpp:268:26:268:45 | call to GetHeaders | provenance | |
+| azure.cpp:268:34:268:43 | call to GetHeaders | azure.cpp:268:34:268:43 | call to GetHeaders | provenance | Src:MaD:55 |
+| azure.cpp:269:8:269:10 | *url | azure.cpp:269:12:269:29 | call to GetQueryParameters | provenance | MaD:98 |
+| azure.cpp:269:12:269:29 | call to GetQueryParameters | azure.cpp:269:12:269:29 | call to GetQueryParameters | provenance | |
+| azure.cpp:269:12:269:29 | call to GetQueryParameters | azure.cpp:269:32:269:40 | call to operator[] | provenance | TaintFunction |
+| bal.cpp:128:19:128:26 | call to source | bal.cpp:129:23:129:51 | *call to data | provenance | TaintFunction |
+| bal.cpp:129:23:129:51 | *call to data | bal.cpp:132:17:132:18 | *sb | provenance | |
+| bal.cpp:132:17:132:18 | *sb | bal.cpp:132:21:132:24 | decode output argument | provenance | MaD:101 |
+| bal.cpp:132:21:132:24 | decode output argument | bal.cpp:133:7:133:17 | * ... | provenance | TaintFunction |
+| bal.cpp:137:19:137:26 | call to source | bal.cpp:138:21:138:47 | *call to data | provenance | TaintFunction |
+| bal.cpp:138:21:138:47 | *call to data | bal.cpp:141:17:141:19 | ** ... | provenance | |
+| bal.cpp:141:17:141:19 | ** ... | bal.cpp:141:22:141:25 | decode output argument | provenance | MaD:101 |
+| bal.cpp:141:22:141:25 | decode output argument | bal.cpp:142:7:142:17 | * ... | provenance | TaintFunction |
+| bal.cpp:146:19:146:26 | call to source | bal.cpp:147:23:147:51 | *call to data | provenance | TaintFunction |
+| bal.cpp:147:23:147:51 | *call to data | bal.cpp:150:20:150:21 | *sb | provenance | |
+| bal.cpp:150:20:150:21 | *sb | bal.cpp:150:24:150:27 | decodeAny output argument | provenance | MaD:102 |
+| bal.cpp:150:24:150:27 | decodeAny output argument | bal.cpp:151:7:151:17 | * ... | provenance | TaintFunction |
+| bal.cpp:156:18:156:25 | call to source | bal.cpp:159:40:159:42 | *obj | provenance | TaintFunction |
+| bal.cpp:159:17:159:37 | encode output argument | bal.cpp:160:7:160:12 | access to array | provenance | |
+| bal.cpp:159:40:159:42 | *obj | bal.cpp:159:17:159:37 | encode output argument | provenance | MaD:103 |
+| bal.cpp:164:18:164:25 | call to source | bal.cpp:167:43:167:45 | *obj | provenance | TaintFunction |
+| bal.cpp:167:20:167:40 | encodeAny output argument | bal.cpp:168:7:168:12 | access to array | provenance | |
+| bal.cpp:167:43:167:45 | *obj | bal.cpp:167:20:167:40 | encodeAny output argument | provenance | MaD:104 |
+| bal.cpp:175:19:175:26 | call to source | bal.cpp:176:23:176:51 | *call to data | provenance | TaintFunction |
+| bal.cpp:176:23:176:51 | *call to data | bal.cpp:180:17:180:18 | *sb | provenance | |
+| bal.cpp:180:17:180:18 | *sb | bal.cpp:180:21:180:24 | decode output argument | provenance | MaD:105 |
+| bal.cpp:180:21:180:24 | decode output argument | bal.cpp:181:7:181:17 | * ... | provenance | TaintFunction |
+| bal.cpp:185:19:185:26 | call to source | bal.cpp:186:21:186:47 | *call to data | provenance | TaintFunction |
+| bal.cpp:186:21:186:47 | *call to data | bal.cpp:190:17:190:19 | ** ... | provenance | |
+| bal.cpp:190:17:190:19 | ** ... | bal.cpp:190:22:190:25 | decode output argument | provenance | MaD:105 |
+| bal.cpp:190:22:190:25 | decode output argument | bal.cpp:191:7:191:17 | * ... | provenance | TaintFunction |
+| bal.cpp:195:19:195:26 | call to source | bal.cpp:196:23:196:51 | *call to data | provenance | TaintFunction |
+| bal.cpp:196:23:196:51 | *call to data | bal.cpp:199:20:199:21 | *sb | provenance | |
+| bal.cpp:199:20:199:21 | *sb | bal.cpp:199:24:199:27 | decodeAny output argument | provenance | MaD:106 |
+| bal.cpp:199:24:199:27 | decodeAny output argument | bal.cpp:200:7:200:17 | * ... | provenance | TaintFunction |
+| bal.cpp:204:18:204:25 | call to source | bal.cpp:208:40:208:42 | *obj | provenance | TaintFunction |
+| bal.cpp:208:17:208:37 | encode output argument | bal.cpp:209:7:209:12 | access to array | provenance | |
+| bal.cpp:208:40:208:42 | *obj | bal.cpp:208:17:208:37 | encode output argument | provenance | MaD:107 |
+| bal.cpp:213:18:213:25 | call to source | bal.cpp:216:43:216:45 | *obj | provenance | TaintFunction |
+| bal.cpp:216:20:216:40 | encodeAny output argument | bal.cpp:217:7:217:12 | access to array | provenance | |
+| bal.cpp:216:43:216:45 | *obj | bal.cpp:216:20:216:40 | encodeAny output argument | provenance | MaD:108 |
+| bal.cpp:222:19:222:26 | call to source | bal.cpp:223:23:223:51 | *call to data | provenance | TaintFunction |
+| bal.cpp:223:23:223:51 | *call to data | bal.cpp:226:17:226:18 | *sb | provenance | |
+| bal.cpp:226:17:226:18 | *sb | bal.cpp:226:21:226:24 | decode output argument | provenance | MaD:105 |
+| bal.cpp:226:21:226:24 | decode output argument | bal.cpp:229:40:229:42 | *rec | provenance | |
+| bal.cpp:229:17:229:37 | encode output argument | bal.cpp:230:7:230:12 | access to array | provenance | |
+| bal.cpp:229:40:229:42 | *rec | bal.cpp:229:17:229:37 | encode output argument | provenance | MaD:107 |
+| bal.cpp:245:19:245:26 | call to source | bal.cpp:246:21:246:47 | *call to data | provenance | TaintFunction |
+| bal.cpp:246:21:246:47 | *call to data | bal.cpp:249:17:249:19 | ** ... | provenance | |
+| bal.cpp:249:17:249:19 | ** ... | bal.cpp:249:22:249:25 | decode output argument | provenance | MaD:110 |
+| bal.cpp:249:22:249:25 | decode output argument | bal.cpp:250:7:250:17 | * ... | provenance | TaintFunction |
+| bal.cpp:254:19:254:26 | call to source | bal.cpp:255:21:255:47 | *call to data | provenance | TaintFunction |
+| bal.cpp:255:21:255:47 | *call to data | bal.cpp:258:35:258:37 | ** ... | provenance | |
+| bal.cpp:258:34:258:52 | *call to decode | bal.cpp:258:34:258:52 | *call to decode | provenance | |
+| bal.cpp:258:34:258:52 | *call to decode | bal.cpp:259:7:259:17 | * ... | provenance | |
+| bal.cpp:258:35:258:37 | ** ... | bal.cpp:258:34:258:52 | *call to decode | provenance | MaD:111 |
+| bal.cpp:258:35:258:37 | ** ... | bal.cpp:258:40:258:43 | decode output argument | provenance | MaD:110 |
+| bal.cpp:258:40:258:43 | decode output argument | bal.cpp:260:7:260:9 | out | provenance | |
+| bal.cpp:264:19:264:26 | call to source | bal.cpp:265:23:265:51 | *call to data | provenance | TaintFunction |
+| bal.cpp:265:23:265:51 | *call to data | bal.cpp:268:17:268:18 | *sb | provenance | |
+| bal.cpp:268:17:268:18 | *sb | bal.cpp:268:21:268:24 | decode output argument | provenance | MaD:112 |
+| bal.cpp:268:21:268:24 | decode output argument | bal.cpp:269:7:269:17 | * ... | provenance | TaintFunction |
+| bal.cpp:273:19:273:26 | call to source | bal.cpp:276:22:276:25 | *call to data | provenance | TaintFunction |
+| bal.cpp:276:22:276:25 | *call to data | bal.cpp:276:43:276:46 | decode output argument | provenance | MaD:109 |
+| bal.cpp:276:43:276:46 | decode output argument | bal.cpp:277:7:277:17 | * ... | provenance | TaintFunction |
+| bal.cpp:301:19:301:26 | call to source | bal.cpp:302:21:302:47 | *call to data | provenance | TaintFunction |
+| bal.cpp:302:21:302:47 | *call to data | bal.cpp:305:20:305:22 | ** ... | provenance | |
+| bal.cpp:305:20:305:22 | ** ... | bal.cpp:305:25:305:28 | decodeAny output argument | provenance | MaD:116 |
+| bal.cpp:305:25:305:28 | decodeAny output argument | bal.cpp:306:7:306:17 | * ... | provenance | TaintFunction |
+| bal.cpp:310:19:310:26 | call to source | bal.cpp:311:21:311:47 | *call to data | provenance | TaintFunction |
+| bal.cpp:311:21:311:47 | *call to data | bal.cpp:314:38:314:40 | ** ... | provenance | |
+| bal.cpp:314:37:314:48 | *call to decodeAny | bal.cpp:314:37:314:48 | *call to decodeAny | provenance | |
+| bal.cpp:314:37:314:48 | *call to decodeAny | bal.cpp:315:7:315:17 | * ... | provenance | |
+| bal.cpp:314:38:314:40 | ** ... | bal.cpp:314:37:314:48 | *call to decodeAny | provenance | MaD:117 |
+| bal.cpp:314:38:314:40 | ** ... | bal.cpp:314:43:314:46 | decodeAny output argument | provenance | MaD:116 |
+| bal.cpp:314:43:314:46 | decodeAny output argument | bal.cpp:316:7:316:9 | out | provenance | |
+| bal.cpp:320:19:320:26 | call to source | bal.cpp:321:23:321:51 | *call to data | provenance | TaintFunction |
+| bal.cpp:321:23:321:51 | *call to data | bal.cpp:324:20:324:21 | *sb | provenance | |
+| bal.cpp:324:20:324:21 | *sb | bal.cpp:324:24:324:27 | decodeAny output argument | provenance | MaD:118 |
+| bal.cpp:324:24:324:27 | decodeAny output argument | bal.cpp:325:7:325:17 | * ... | provenance | TaintFunction |
+| bal.cpp:329:19:329:26 | call to source | bal.cpp:330:21:330:47 | *call to data | provenance | TaintFunction |
+| bal.cpp:330:21:330:47 | *call to data | bal.cpp:333:20:333:22 | ** ... | provenance | |
+| bal.cpp:333:20:333:22 | ** ... | bal.cpp:333:25:333:28 | decodeAny output argument | provenance | MaD:113 |
+| bal.cpp:333:25:333:28 | decodeAny output argument | bal.cpp:334:7:334:19 | * ... | provenance | |
+| bal.cpp:338:19:338:26 | call to source | bal.cpp:339:21:339:47 | *call to data | provenance | TaintFunction |
+| bal.cpp:339:21:339:47 | *call to data | bal.cpp:342:38:342:40 | ** ... | provenance | |
+| bal.cpp:342:37:342:48 | *call to decodeAny | bal.cpp:342:37:342:48 | *call to decodeAny | provenance | |
+| bal.cpp:342:37:342:48 | *call to decodeAny | bal.cpp:343:7:343:17 | * ... | provenance | |
+| bal.cpp:342:38:342:40 | ** ... | bal.cpp:342:37:342:48 | *call to decodeAny | provenance | MaD:114 |
+| bal.cpp:342:38:342:40 | ** ... | bal.cpp:342:43:342:46 | decodeAny output argument | provenance | MaD:113 |
+| bal.cpp:342:43:342:46 | decodeAny output argument | bal.cpp:344:7:344:19 | * ... | provenance | |
+| bal.cpp:348:19:348:26 | call to source | bal.cpp:349:23:349:51 | *call to data | provenance | TaintFunction |
+| bal.cpp:349:23:349:51 | *call to data | bal.cpp:352:20:352:21 | *sb | provenance | |
+| bal.cpp:352:20:352:21 | *sb | bal.cpp:352:24:352:27 | decodeAny output argument | provenance | MaD:115 |
+| bal.cpp:352:24:352:27 | decodeAny output argument | bal.cpp:353:7:353:19 | * ... | provenance | |
+| bal.cpp:357:18:357:25 | call to source | bal.cpp:360:40:360:42 | *obj | provenance | TaintFunction |
+| bal.cpp:360:17:360:37 | encode output argument | bal.cpp:361:7:361:12 | access to array | provenance | |
+| bal.cpp:360:40:360:42 | *obj | bal.cpp:360:17:360:37 | encode output argument | provenance | MaD:121 |
+| bal.cpp:365:18:365:25 | call to source | bal.cpp:368:39:368:41 | *obj | provenance | TaintFunction |
+| bal.cpp:368:17:368:36 | encode output argument | bal.cpp:369:7:369:12 | access to array | provenance | |
+| bal.cpp:368:39:368:41 | *obj | bal.cpp:368:17:368:36 | encode output argument | provenance | MaD:120 |
+| bal.cpp:373:18:373:25 | call to source | bal.cpp:376:57:376:59 | *obj | provenance | TaintFunction |
+| bal.cpp:376:34:376:61 | *call to encode | bal.cpp:376:34:376:61 | *call to encode | provenance | |
+| bal.cpp:376:34:376:61 | *call to encode | bal.cpp:377:7:377:17 | * ... | provenance | |
+| bal.cpp:376:35:376:54 | encode output argument | bal.cpp:378:7:378:12 | access to array | provenance | |
+| bal.cpp:376:57:376:59 | *obj | bal.cpp:376:34:376:61 | *call to encode | provenance | MaD:119 |
+| bal.cpp:376:57:376:59 | *obj | bal.cpp:376:35:376:54 | encode output argument | provenance | MaD:120 |
+| bal.cpp:382:19:382:26 | call to source | bal.cpp:383:21:383:47 | *call to data | provenance | TaintFunction |
+| bal.cpp:383:21:383:47 | *call to data | bal.cpp:386:35:386:37 | ** ... | provenance | |
+| bal.cpp:386:34:386:44 | *call to encode | bal.cpp:386:34:386:44 | *call to encode | provenance | |
+| bal.cpp:386:34:386:44 | *call to encode | bal.cpp:387:7:387:17 | * ... | provenance | |
+| bal.cpp:386:35:386:37 | ** ... | bal.cpp:386:34:386:44 | *call to encode | provenance | MaD:119 |
+| bal.cpp:391:18:391:25 | call to source | bal.cpp:394:47:394:49 | *obj | provenance | TaintFunction |
+| bal.cpp:394:25:394:44 | encodeToStream output argument | bal.cpp:395:7:395:12 | access to array | provenance | |
+| bal.cpp:394:47:394:49 | *obj | bal.cpp:394:25:394:44 | encodeToStream output argument | provenance | MaD:129 |
+| bal.cpp:409:18:409:25 | call to source | bal.cpp:412:43:412:45 | *obj | provenance | TaintFunction |
+| bal.cpp:412:20:412:40 | encodeAny output argument | bal.cpp:413:7:413:12 | access to array | provenance | |
+| bal.cpp:412:43:412:45 | *obj | bal.cpp:412:20:412:40 | encodeAny output argument | provenance | MaD:127 |
+| bal.cpp:417:18:417:25 | call to source | bal.cpp:420:42:420:44 | *obj | provenance | TaintFunction |
+| bal.cpp:420:20:420:39 | encodeAny output argument | bal.cpp:421:7:421:12 | access to array | provenance | |
+| bal.cpp:420:42:420:44 | *obj | bal.cpp:420:20:420:39 | encodeAny output argument | provenance | MaD:126 |
+| bal.cpp:425:18:425:25 | call to source | bal.cpp:428:60:428:62 | *obj | provenance | TaintFunction |
+| bal.cpp:428:37:428:64 | *call to encodeAny | bal.cpp:428:37:428:64 | *call to encodeAny | provenance | |
+| bal.cpp:428:37:428:64 | *call to encodeAny | bal.cpp:429:7:429:17 | * ... | provenance | |
+| bal.cpp:428:38:428:57 | encodeAny output argument | bal.cpp:430:7:430:12 | access to array | provenance | |
+| bal.cpp:428:60:428:62 | *obj | bal.cpp:428:37:428:64 | *call to encodeAny | provenance | MaD:125 |
+| bal.cpp:428:60:428:62 | *obj | bal.cpp:428:38:428:57 | encodeAny output argument | provenance | MaD:126 |
+| bal.cpp:434:18:434:25 | call to source | bal.cpp:437:50:437:52 | *obj | provenance | TaintFunction |
+| bal.cpp:437:28:437:47 | encodeAnyToStream output argument | bal.cpp:438:7:438:12 | access to array | provenance | |
+| bal.cpp:437:50:437:52 | *obj | bal.cpp:437:28:437:47 | encodeAnyToStream output argument | provenance | MaD:128 |
+| bal.cpp:442:19:442:26 | call to source | bal.cpp:443:41:443:86 | *call to data | provenance | TaintFunction |
+| bal.cpp:443:41:443:86 | *call to data | bal.cpp:446:43:446:46 | ** ... | provenance | |
+| bal.cpp:446:20:446:40 | encodeAny output argument | bal.cpp:447:7:447:12 | access to array | provenance | |
+| bal.cpp:446:43:446:46 | ** ... | bal.cpp:446:20:446:40 | encodeAny output argument | provenance | MaD:124 |
+| bal.cpp:451:19:451:26 | call to source | bal.cpp:452:41:452:86 | *call to data | provenance | TaintFunction |
+| bal.cpp:452:41:452:86 | *call to data | bal.cpp:455:42:455:45 | ** ... | provenance | |
+| bal.cpp:455:20:455:39 | encodeAny output argument | bal.cpp:456:7:456:12 | access to array | provenance | |
+| bal.cpp:455:42:455:45 | ** ... | bal.cpp:455:20:455:39 | encodeAny output argument | provenance | MaD:123 |
+| bal.cpp:460:19:460:26 | call to source | bal.cpp:461:41:461:86 | *call to data | provenance | TaintFunction |
+| bal.cpp:461:41:461:86 | *call to data | bal.cpp:464:60:464:63 | ** ... | provenance | |
+| bal.cpp:464:37:464:65 | *call to encodeAny | bal.cpp:464:37:464:65 | *call to encodeAny | provenance | |
+| bal.cpp:464:37:464:65 | *call to encodeAny | bal.cpp:465:7:465:17 | * ... | provenance | |
+| bal.cpp:464:38:464:57 | encodeAny output argument | bal.cpp:466:7:466:12 | access to array | provenance | |
+| bal.cpp:464:60:464:63 | ** ... | bal.cpp:464:37:464:65 | *call to encodeAny | provenance | MaD:122 |
+| bal.cpp:464:60:464:63 | ** ... | bal.cpp:464:38:464:57 | encodeAny output argument | provenance | MaD:123 |
+| bdlbb.cpp:37:16:37:23 | call to source | bdlbb.cpp:39:49:39:52 | *call to data | provenance | TaintFunction |
+| bdlbb.cpp:39:37:39:41 | copy output argument | bdlbb.cpp:41:42:41:45 | *blob | provenance | |
+| bdlbb.cpp:39:49:39:52 | *call to data | bdlbb.cpp:39:37:39:41 | copy output argument | provenance | MaD:134 |
+| bdlbb.cpp:41:37:41:39 | copy output argument | bdlbb.cpp:42:7:42:10 | * ... | provenance | |
+| bdlbb.cpp:41:42:41:45 | *blob | bdlbb.cpp:41:37:41:39 | copy output argument | provenance | MaD:135 |
+| bdlbb.cpp:46:16:46:23 | call to source | bdlbb.cpp:48:49:48:52 | *call to data | provenance | TaintFunction |
+| bdlbb.cpp:48:37:48:41 | copy output argument | bdlbb.cpp:49:18:49:21 | *blob | provenance | |
+| bdlbb.cpp:48:49:48:52 | *call to data | bdlbb.cpp:48:37:48:41 | copy output argument | provenance | MaD:134 |
+| bdlbb.cpp:49:18:49:21 | *blob | bdlbb.cpp:49:29:49:32 | *call to buffer | provenance | MaD:130 |
+| bdlbb.cpp:49:18:49:38 | *call to data | bdlbb.cpp:49:18:49:38 | *call to data | provenance | |
+| bdlbb.cpp:49:18:49:38 | *call to data | bdlbb.cpp:50:7:50:8 | * ... | provenance | |
+| bdlbb.cpp:49:29:49:32 | *call to buffer | bdlbb.cpp:49:18:49:38 | *call to data | provenance | MaD:132 |
+| bdlbb.cpp:55:16:55:23 | call to source | bdlbb.cpp:57:49:57:52 | *call to data | provenance | TaintFunction |
+| bdlbb.cpp:57:37:57:41 | copy output argument | bdlbb.cpp:58:18:58:21 | *blob | provenance | |
+| bdlbb.cpp:57:49:57:52 | *call to data | bdlbb.cpp:57:37:57:41 | copy output argument | provenance | MaD:134 |
+| bdlbb.cpp:58:18:58:21 | *blob | bdlbb.cpp:58:29:58:32 | *call to buffer | provenance | MaD:130 |
+| bdlbb.cpp:58:18:58:46 | call to get | bdlbb.cpp:59:7:59:8 | * ... | provenance | |
+| bdlbb.cpp:58:29:58:32 | *call to buffer | bdlbb.cpp:58:39:58:41 | *call to buffer | provenance | MaD:131 |
+| bdlbb.cpp:58:39:58:41 | *call to buffer | bdlbb.cpp:58:18:58:46 | call to get | provenance | DataFlowFunction |
+| bdlbb.cpp:63:16:63:23 | call to source | bdlbb.cpp:65:49:65:52 | *call to data | provenance | TaintFunction |
+| bdlbb.cpp:65:37:65:41 | copy output argument | bdlbb.cpp:67:72:67:75 | *blob | provenance | |
+| bdlbb.cpp:65:49:65:52 | *call to data | bdlbb.cpp:65:37:65:41 | copy output argument | provenance | MaD:134 |
+| bdlbb.cpp:67:12:67:65 | *call to getContiguousRangeOrCopy | bdlbb.cpp:67:12:67:65 | *call to getContiguousRangeOrCopy | provenance | |
+| bdlbb.cpp:67:12:67:65 | *call to getContiguousRangeOrCopy | bdlbb.cpp:68:7:68:8 | * ... | provenance | |
+| bdlbb.cpp:67:72:67:75 | *blob | bdlbb.cpp:67:12:67:65 | *call to getContiguousRangeOrCopy | provenance | MaD:136 |
+| bdlbb.cpp:73:16:73:23 | call to source | bdlbb.cpp:75:48:75:51 | *call to data | provenance | TaintFunction |
+| bdlbb.cpp:75:37:75:40 | copy output argument | bdlbb.cpp:77:46:77:48 | *src | provenance | |
+| bdlbb.cpp:75:48:75:51 | *call to data | bdlbb.cpp:75:37:75:40 | copy output argument | provenance | MaD:134 |
+| bdlbb.cpp:77:37:77:40 | copy output argument | bdlbb.cpp:79:42:79:44 | *dst | provenance | |
+| bdlbb.cpp:77:46:77:48 | *src | bdlbb.cpp:77:37:77:40 | copy output argument | provenance | MaD:133 |
+| bdlbb.cpp:79:37:79:39 | copy output argument | bdlbb.cpp:80:7:80:10 | * ... | provenance | |
+| bdlbb.cpp:79:42:79:44 | *dst | bdlbb.cpp:79:37:79:39 | copy output argument | provenance | MaD:135 |
+| bmqa.cpp:87:19:87:26 | call to source | bmqa.cpp:88:36:88:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:88:36:88:76 | *call to data | bmqa.cpp:90:2:90:4 | *msg | provenance | |
+| bmqa.cpp:90:2:90:4 | *msg | bmqa.cpp:90:15:90:19 | getData output argument | provenance | MaD:138 |
+| bmqa.cpp:90:15:90:19 | getData output argument | bmqa.cpp:92:42:92:45 | *blob | provenance | |
+| bmqa.cpp:92:37:92:39 | copy output argument | bmqa.cpp:93:7:93:10 | * ... | provenance | |
+| bmqa.cpp:92:42:92:45 | *blob | bmqa.cpp:92:37:92:39 | copy output argument | provenance | MaD:135 |
+| bmqa.cpp:97:19:97:26 | call to source | bmqa.cpp:98:43:98:88 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:98:43:98:88 | *call to data | bmqa.cpp:99:42:99:46 | *event | provenance | |
+| bmqa.cpp:99:42:99:46 | *event | bmqa.cpp:99:49:99:63 | call to messageIterator | provenance | MaD:143 |
+| bmqa.cpp:99:49:99:63 | call to messageIterator | bmqa.cpp:99:49:99:63 | call to messageIterator | provenance | |
+| bmqa.cpp:99:49:99:63 | call to messageIterator | bmqa.cpp:101:43:101:44 | *it | provenance | |
+| bmqa.cpp:101:43:101:44 | *it | bmqa.cpp:101:53:101:55 | *call to message | provenance | MaD:144 |
+| bmqa.cpp:101:53:101:55 | *call to message | bmqa.cpp:101:53:101:55 | *call to message | provenance | |
+| bmqa.cpp:101:53:101:55 | *call to message | bmqa.cpp:103:3:103:5 | *msg | provenance | |
+| bmqa.cpp:103:3:103:5 | *msg | bmqa.cpp:103:15:103:19 | getData output argument | provenance | MaD:138 |
+| bmqa.cpp:103:15:103:19 | getData output argument | bmqa.cpp:105:43:105:46 | *blob | provenance | |
+| bmqa.cpp:105:38:105:40 | copy output argument | bmqa.cpp:106:8:106:11 | * ... | provenance | |
+| bmqa.cpp:105:43:105:46 | *blob | bmqa.cpp:105:38:105:40 | copy output argument | provenance | MaD:135 |
+| bmqa.cpp:111:16:111:23 | call to source | bmqa.cpp:113:47:113:50 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:113:37:113:39 | copy output argument | bmqa.cpp:115:17:115:19 | *& ... | provenance | |
+| bmqa.cpp:113:47:113:50 | *call to data | bmqa.cpp:113:37:113:39 | copy output argument | provenance | MaD:134 |
+| bmqa.cpp:115:2:115:4 | setDataRef output argument | bmqa.cpp:117:2:117:4 | *msg | provenance | |
+| bmqa.cpp:115:17:115:19 | *& ... | bmqa.cpp:115:2:115:4 | setDataRef output argument | provenance | MaD:141 |
+| bmqa.cpp:117:2:117:4 | *msg | bmqa.cpp:117:14:117:17 | getData output argument | provenance | MaD:138 |
+| bmqa.cpp:117:14:117:17 | getData output argument | bmqa.cpp:119:42:119:44 | *out | provenance | |
+| bmqa.cpp:119:37:119:39 | copy output argument | bmqa.cpp:120:7:120:10 | * ... | provenance | |
+| bmqa.cpp:119:42:119:44 | *out | bmqa.cpp:119:37:119:39 | copy output argument | provenance | MaD:135 |
+| bmqa.cpp:124:16:124:23 | call to source | bmqa.cpp:126:19:126:22 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:126:2:126:4 | setDataRef output argument | bmqa.cpp:128:2:128:4 | *msg | provenance | |
+| bmqa.cpp:126:19:126:22 | *call to data | bmqa.cpp:126:2:126:4 | setDataRef output argument | provenance | MaD:141 |
+| bmqa.cpp:128:2:128:4 | *msg | bmqa.cpp:128:14:128:17 | getData output argument | provenance | MaD:138 |
+| bmqa.cpp:128:14:128:17 | getData output argument | bmqa.cpp:130:42:130:44 | *out | provenance | |
+| bmqa.cpp:130:37:130:39 | copy output argument | bmqa.cpp:131:7:131:10 | * ... | provenance | |
+| bmqa.cpp:130:42:130:44 | *out | bmqa.cpp:130:37:130:39 | copy output argument | provenance | MaD:135 |
+| bmqa.cpp:135:16:135:23 | call to source | bmqa.cpp:137:16:137:19 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:137:2:137:4 | setData output argument | bmqa.cpp:139:2:139:4 | *msg | provenance | |
+| bmqa.cpp:137:16:137:19 | *call to data | bmqa.cpp:137:2:137:4 | setData output argument | provenance | MaD:140 |
+| bmqa.cpp:139:2:139:4 | *msg | bmqa.cpp:139:14:139:17 | getData output argument | provenance | MaD:138 |
+| bmqa.cpp:139:14:139:17 | getData output argument | bmqa.cpp:141:42:141:44 | *out | provenance | |
+| bmqa.cpp:141:37:141:39 | copy output argument | bmqa.cpp:142:7:142:10 | * ... | provenance | |
+| bmqa.cpp:141:42:141:44 | *out | bmqa.cpp:141:37:141:39 | copy output argument | provenance | MaD:135 |
+| bmqa.cpp:146:19:146:26 | call to source | bmqa.cpp:147:36:147:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:147:36:147:76 | *call to data | bmqa.cpp:148:36:148:38 | *msg | provenance | |
+| bmqa.cpp:148:36:148:38 | *msg | bmqa.cpp:148:41:148:45 | call to clone | provenance | MaD:137 |
+| bmqa.cpp:148:41:148:45 | call to clone | bmqa.cpp:148:41:148:45 | call to clone | provenance | |
+| bmqa.cpp:148:41:148:45 | call to clone | bmqa.cpp:150:2:150:5 | *copy | provenance | |
+| bmqa.cpp:150:2:150:5 | *copy | bmqa.cpp:150:15:150:19 | getData output argument | provenance | MaD:138 |
+| bmqa.cpp:150:15:150:19 | getData output argument | bmqa.cpp:152:42:152:45 | *blob | provenance | |
+| bmqa.cpp:152:37:152:39 | copy output argument | bmqa.cpp:153:7:153:10 | * ... | provenance | |
+| bmqa.cpp:152:42:152:45 | *blob | bmqa.cpp:152:37:152:39 | copy output argument | provenance | MaD:135 |
+| bmqa.cpp:157:19:157:26 | call to source | bmqa.cpp:158:36:158:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:158:36:158:76 | *call to data | bmqa.cpp:160:2:160:4 | *msg | provenance | |
+| bmqa.cpp:160:2:160:4 | *msg | bmqa.cpp:160:22:160:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:160:22:160:27 | loadProperties output argument | bmqa.cpp:161:29:161:33 | *props | provenance | |
+| bmqa.cpp:161:29:161:33 | *props | bmqa.cpp:161:54:161:61 | *call to getPropertyAsString | provenance | MaD:149 |
+| bmqa.cpp:161:54:161:61 | *call to getPropertyAsString | bmqa.cpp:161:54:161:61 | *call to getPropertyAsString | provenance | |
+| bmqa.cpp:161:54:161:61 | *call to getPropertyAsString | bmqa.cpp:162:7:162:21 | access to array | provenance | TaintFunction |
+| bmqa.cpp:166:19:166:26 | call to source | bmqa.cpp:167:36:167:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:167:36:167:76 | *call to data | bmqa.cpp:169:2:169:4 | *msg | provenance | |
+| bmqa.cpp:169:2:169:4 | *msg | bmqa.cpp:169:22:169:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:169:22:169:27 | loadProperties output argument | bmqa.cpp:170:35:170:39 | *props | provenance | |
+| bmqa.cpp:170:35:170:39 | *props | bmqa.cpp:170:60:170:67 | *call to getPropertyAsBinary [element] | provenance | MaD:146 |
+| bmqa.cpp:170:60:170:67 | *call to getPropertyAsBinary [element] | bmqa.cpp:170:60:170:67 | *call to getPropertyAsBinary [element] | provenance | |
+| bmqa.cpp:170:60:170:67 | *call to getPropertyAsBinary [element] | bmqa.cpp:171:7:171:11 | *value [element] | provenance | |
+| bmqa.cpp:171:7:171:11 | *value [element] | bmqa.cpp:171:7:171:21 | access to array | provenance | MaD:267 |
+| bmqa.cpp:175:19:175:26 | call to source | bmqa.cpp:176:36:176:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:176:36:176:76 | *call to data | bmqa.cpp:178:2:178:4 | *msg | provenance | |
+| bmqa.cpp:178:2:178:4 | *msg | bmqa.cpp:178:22:178:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:178:22:178:27 | loadProperties output argument | bmqa.cpp:179:35:179:39 | *props | provenance | |
+| bmqa.cpp:179:35:179:39 | *props | bmqa.cpp:179:60:179:67 | *call to getPropertyAsBinary [element] | provenance | MaD:146 |
+| bmqa.cpp:179:60:179:67 | *call to getPropertyAsBinary [element] | bmqa.cpp:179:60:179:67 | *call to getPropertyAsBinary [element] | provenance | |
+| bmqa.cpp:179:60:179:67 | *call to getPropertyAsBinary [element] | bmqa.cpp:180:7:180:11 | *value [element] | provenance | |
+| bmqa.cpp:180:7:180:11 | *value [element] | bmqa.cpp:180:12:180:14 | call to operator[] | provenance | MaD:268 |
+| bmqa.cpp:184:19:184:26 | call to source | bmqa.cpp:185:36:185:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:185:36:185:76 | *call to data | bmqa.cpp:187:2:187:4 | *msg | provenance | |
+| bmqa.cpp:187:2:187:4 | *msg | bmqa.cpp:187:22:187:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:187:22:187:27 | loadProperties output argument | bmqa.cpp:189:29:189:33 | *props | provenance | |
+| bmqa.cpp:189:29:189:33 | *props | bmqa.cpp:189:56:189:69 | *call to getPropertyAsStringOr | provenance | MaD:151 |
+| bmqa.cpp:189:56:189:69 | *call to getPropertyAsStringOr | bmqa.cpp:189:56:189:69 | *call to getPropertyAsStringOr | provenance | |
+| bmqa.cpp:189:56:189:69 | *call to getPropertyAsStringOr | bmqa.cpp:190:7:190:19 | * ... | provenance | TaintFunction |
+| bmqa.cpp:195:19:195:26 | call to source | bmqa.cpp:197:64:197:67 | *dflt | provenance | TaintFunction |
+| bmqa.cpp:197:56:197:69 | *call to getPropertyAsStringOr | bmqa.cpp:197:56:197:69 | *call to getPropertyAsStringOr | provenance | |
+| bmqa.cpp:197:56:197:69 | *call to getPropertyAsStringOr | bmqa.cpp:198:7:198:19 | * ... | provenance | TaintFunction |
+| bmqa.cpp:197:64:197:67 | *dflt | bmqa.cpp:197:56:197:69 | *call to getPropertyAsStringOr | provenance | MaD:150 |
+| bmqa.cpp:202:19:202:26 | call to source | bmqa.cpp:203:36:203:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:203:36:203:76 | *call to data | bmqa.cpp:205:2:205:4 | *msg | provenance | |
+| bmqa.cpp:205:2:205:4 | *msg | bmqa.cpp:205:22:205:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:205:22:205:27 | loadProperties output argument | bmqa.cpp:207:35:207:39 | *props | provenance | |
+| bmqa.cpp:207:35:207:39 | *props | bmqa.cpp:207:62:207:75 | *call to getPropertyAsBinaryOr [element] | provenance | MaD:148 |
+| bmqa.cpp:207:62:207:75 | *call to getPropertyAsBinaryOr [element] | bmqa.cpp:207:62:207:75 | *call to getPropertyAsBinaryOr [element] | provenance | |
+| bmqa.cpp:207:62:207:75 | *call to getPropertyAsBinaryOr [element] | bmqa.cpp:208:8:208:12 | *value [element] | provenance | |
+| bmqa.cpp:208:8:208:12 | *value [element] | bmqa.cpp:208:7:208:19 | * ... | provenance | MaD:267 |
+| bmqa.cpp:212:11:212:19 | * ... | bmqa.cpp:214:17:214:17 | *c | provenance | |
+| bmqa.cpp:212:12:212:17 | call to source | bmqa.cpp:212:11:212:19 | * ... | provenance | |
+| bmqa.cpp:214:2:214:5 | push_back output argument [element] | bmqa.cpp:216:70:216:73 | *dflt [element] | provenance | |
+| bmqa.cpp:214:17:214:17 | *c | bmqa.cpp:214:2:214:5 | push_back output argument [element] | provenance | MaD:269 |
+| bmqa.cpp:216:62:216:75 | *call to getPropertyAsBinaryOr [element] | bmqa.cpp:216:62:216:75 | *call to getPropertyAsBinaryOr [element] | provenance | |
+| bmqa.cpp:216:62:216:75 | *call to getPropertyAsBinaryOr [element] | bmqa.cpp:217:8:217:12 | *value [element] | provenance | |
+| bmqa.cpp:216:70:216:73 | *dflt [element] | bmqa.cpp:216:62:216:75 | *call to getPropertyAsBinaryOr [element] | provenance | MaD:147 |
+| bmqa.cpp:217:8:217:12 | *value [element] | bmqa.cpp:217:7:217:19 | * ... | provenance | MaD:267 |
+| bmqa.cpp:229:16:229:23 | call to source | bmqa.cpp:231:49:231:52 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:231:37:231:41 | copy output argument | bmqa.cpp:233:17:233:20 | *blob | provenance | |
+| bmqa.cpp:231:49:231:52 | *call to data | bmqa.cpp:231:37:231:41 | copy output argument | provenance | MaD:134 |
+| bmqa.cpp:233:2:233:6 | streamIn output argument | bmqa.cpp:234:8:234:12 | *props | provenance | |
+| bmqa.cpp:233:17:233:20 | *blob | bmqa.cpp:233:2:233:6 | streamIn output argument | provenance | MaD:163 |
+| bmqa.cpp:234:8:234:12 | *props | bmqa.cpp:234:33:234:40 | *call to getPropertyAsString | provenance | MaD:149 |
+| bmqa.cpp:234:33:234:40 | *call to getPropertyAsString | bmqa.cpp:234:7:234:46 | * ... | provenance | TaintFunction |
+| bmqa.cpp:238:16:238:23 | call to source | bmqa.cpp:240:49:240:52 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:240:37:240:41 | copy output argument | bmqa.cpp:242:14:242:17 | *blob | provenance | |
+| bmqa.cpp:240:49:240:52 | *call to data | bmqa.cpp:240:37:240:41 | copy output argument | provenance | MaD:134 |
+| bmqa.cpp:242:2:242:3 | streamIn output argument | bmqa.cpp:244:23:244:25 | *& ... | provenance | |
+| bmqa.cpp:242:14:242:17 | *blob | bmqa.cpp:242:2:242:3 | streamIn output argument | provenance | MaD:163 |
+| bmqa.cpp:244:2:244:4 | setPropertiesRef output argument | bmqa.cpp:246:2:246:4 | *msg | provenance | |
+| bmqa.cpp:244:23:244:25 | *& ... | bmqa.cpp:244:2:244:4 | setPropertiesRef output argument | provenance | MaD:142 |
+| bmqa.cpp:246:2:246:4 | *msg | bmqa.cpp:246:21:246:24 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:246:21:246:24 | loadProperties output argument | bmqa.cpp:247:8:247:10 | *out | provenance | |
+| bmqa.cpp:247:8:247:10 | *out | bmqa.cpp:247:31:247:38 | *call to getPropertyAsString | provenance | MaD:149 |
+| bmqa.cpp:247:31:247:38 | *call to getPropertyAsString | bmqa.cpp:247:7:247:44 | * ... | provenance | TaintFunction |
+| bmqa.cpp:251:19:251:26 | call to source | bmqa.cpp:252:36:252:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:252:36:252:76 | *call to data | bmqa.cpp:254:2:254:4 | *msg | provenance | |
+| bmqa.cpp:254:2:254:4 | *msg | bmqa.cpp:254:22:254:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:254:22:254:27 | loadProperties output argument | bmqa.cpp:256:41:256:45 | *props | provenance | |
+| bmqa.cpp:256:41:256:45 | *props | bmqa.cpp:256:56:256:66 | *call to streamOut | provenance | MaD:164 |
+| bmqa.cpp:256:56:256:66 | *call to streamOut | bmqa.cpp:256:56:256:66 | *call to streamOut | provenance | |
+| bmqa.cpp:256:56:256:66 | *call to streamOut | bmqa.cpp:258:42:258:45 | *blob | provenance | |
+| bmqa.cpp:258:37:258:39 | copy output argument | bmqa.cpp:259:7:259:10 | * ... | provenance | |
+| bmqa.cpp:258:42:258:45 | *blob | bmqa.cpp:258:37:258:39 | copy output argument | provenance | MaD:135 |
+| bmqa.cpp:263:19:263:26 | call to source | bmqa.cpp:264:36:264:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:264:36:264:76 | *call to data | bmqa.cpp:266:2:266:4 | *msg | provenance | |
+| bmqa.cpp:266:2:266:4 | *msg | bmqa.cpp:266:22:266:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:266:22:266:27 | loadProperties output argument | bmqa.cpp:267:44:267:48 | *props | provenance | |
+| bmqa.cpp:266:22:266:27 | loadProperties output argument | bmqa.cpp:268:8:268:11 | *copy | provenance | DataFlowFunction |
+| bmqa.cpp:266:22:266:27 | loadProperties output argument | bmqa.cpp:268:8:268:11 | *copy | provenance | TaintFunction |
+| bmqa.cpp:267:39:267:42 | call to MessageProperties | bmqa.cpp:268:8:268:11 | *copy | provenance | |
+| bmqa.cpp:267:44:267:48 | *props | bmqa.cpp:267:39:267:42 | call to MessageProperties | provenance | MaD:145 |
+| bmqa.cpp:268:8:268:11 | *copy | bmqa.cpp:268:32:268:39 | *call to getPropertyAsString | provenance | MaD:149 |
+| bmqa.cpp:268:32:268:39 | *call to getPropertyAsString | bmqa.cpp:268:7:268:45 | * ... | provenance | TaintFunction |
+| bmqa.cpp:272:19:272:26 | call to source | bmqa.cpp:273:36:273:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:273:36:273:76 | *call to data | bmqa.cpp:275:2:275:4 | *msg | provenance | |
+| bmqa.cpp:275:2:275:4 | *msg | bmqa.cpp:275:22:275:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:275:22:275:27 | loadProperties output argument | bmqa.cpp:277:9:277:13 | *props | provenance | |
+| bmqa.cpp:275:22:275:27 | loadProperties output argument | bmqa.cpp:278:8:278:11 | *copy | provenance | TaintFunction |
+| bmqa.cpp:277:2:277:5 | operator= output argument | bmqa.cpp:278:8:278:11 | *copy | provenance | |
+| bmqa.cpp:277:9:277:13 | *props | bmqa.cpp:277:2:277:5 | operator= output argument | provenance | MaD:152 |
+| bmqa.cpp:278:8:278:11 | *copy | bmqa.cpp:278:32:278:39 | *call to getPropertyAsString | provenance | MaD:149 |
+| bmqa.cpp:278:32:278:39 | *call to getPropertyAsString | bmqa.cpp:278:7:278:45 | * ... | provenance | TaintFunction |
+| bmqa.cpp:282:19:282:26 | call to source | bmqa.cpp:283:36:283:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:283:36:283:76 | *call to data | bmqa.cpp:285:2:285:4 | *msg | provenance | |
+| bmqa.cpp:285:2:285:4 | *msg | bmqa.cpp:285:22:285:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:285:22:285:27 | loadProperties output argument | bmqa.cpp:287:8:287:21 | *call to operator= | provenance | TaintFunction |
+| bmqa.cpp:285:22:285:27 | loadProperties output argument | bmqa.cpp:287:16:287:20 | *props | provenance | |
+| bmqa.cpp:287:8:287:21 | *call to operator= | bmqa.cpp:287:42:287:49 | *call to getPropertyAsString | provenance | MaD:149 |
+| bmqa.cpp:287:16:287:20 | *props | bmqa.cpp:287:8:287:21 | *call to operator= | provenance | MaD:153 |
+| bmqa.cpp:287:42:287:49 | *call to getPropertyAsString | bmqa.cpp:287:7:287:55 | * ... | provenance | TaintFunction |
+| bmqa.cpp:291:19:291:26 | call to source | bmqa.cpp:292:28:292:58 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:292:28:292:58 | *call to data | bmqa.cpp:294:35:294:40 | * ... | provenance | |
+| bmqa.cpp:294:2:294:6 | setPropertyAsString output argument | bmqa.cpp:295:8:295:12 | *props | provenance | |
+| bmqa.cpp:294:35:294:40 | * ... | bmqa.cpp:294:2:294:6 | setPropertyAsString output argument | provenance | MaD:162 |
+| bmqa.cpp:295:8:295:12 | *props | bmqa.cpp:295:33:295:40 | *call to getPropertyAsString | provenance | MaD:149 |
+| bmqa.cpp:295:33:295:40 | *call to getPropertyAsString | bmqa.cpp:295:7:295:46 | * ... | provenance | TaintFunction |
+| bmqa.cpp:299:25:299:32 | call to source | bmqa.cpp:301:35:301:39 | value | provenance | TaintFunction |
+| bmqa.cpp:301:2:301:6 | setPropertyAsString output argument | bmqa.cpp:302:8:302:12 | *props | provenance | |
+| bmqa.cpp:301:35:301:39 | value | bmqa.cpp:301:2:301:6 | setPropertyAsString output argument | provenance | MaD:162 |
+| bmqa.cpp:302:8:302:12 | *props | bmqa.cpp:302:33:302:40 | *call to getPropertyAsString | provenance | MaD:149 |
+| bmqa.cpp:302:33:302:40 | *call to getPropertyAsString | bmqa.cpp:302:7:302:46 | * ... | provenance | TaintFunction |
+| bmqa.cpp:306:19:306:26 | call to source | bmqa.cpp:307:33:307:68 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:307:33:307:68 | *call to data | bmqa.cpp:309:35:309:40 | * ... | provenance | |
+| bmqa.cpp:309:2:309:6 | setPropertyAsBinary output argument | bmqa.cpp:310:8:310:12 | *props | provenance | |
+| bmqa.cpp:309:35:309:40 | * ... | bmqa.cpp:309:2:309:6 | setPropertyAsBinary output argument | provenance | MaD:155 |
+| bmqa.cpp:310:8:310:12 | *props | bmqa.cpp:310:33:310:40 | *call to getPropertyAsBinary [element] | provenance | MaD:146 |
+| bmqa.cpp:310:33:310:40 | *call to getPropertyAsBinary [element] | bmqa.cpp:310:7:310:46 | * ... | provenance | MaD:267 |
+| bmqa.cpp:315:24:315:31 | call to source | bmqa.cpp:317:26:317:29 | name | provenance | TaintFunction |
+| bmqa.cpp:317:2:317:6 | setPropertyAsBool output argument | bmqa.cpp:318:50:318:55 | *& ... | provenance | |
+| bmqa.cpp:317:26:317:29 | name | bmqa.cpp:317:2:317:6 | setPropertyAsBool output argument | provenance | MaD:156 |
+| bmqa.cpp:318:47:318:48 | call to MessagePropertiesIterator | bmqa.cpp:319:8:319:9 | *it | provenance | |
+| bmqa.cpp:318:50:318:55 | *& ... | bmqa.cpp:318:47:318:48 | call to MessagePropertiesIterator | provenance | MaD:165 |
+| bmqa.cpp:319:8:319:9 | *it | bmqa.cpp:319:15:319:17 | *call to name | provenance | MaD:168 |
+| bmqa.cpp:319:15:319:17 | *call to name | bmqa.cpp:319:7:319:23 | * ... | provenance | TaintFunction |
+| bmqa.cpp:323:24:323:31 | call to source | bmqa.cpp:325:26:325:29 | name | provenance | TaintFunction |
+| bmqa.cpp:325:2:325:6 | setPropertyAsChar output argument | bmqa.cpp:326:50:326:55 | *& ... | provenance | |
+| bmqa.cpp:325:26:325:29 | name | bmqa.cpp:325:2:325:6 | setPropertyAsChar output argument | provenance | MaD:157 |
+| bmqa.cpp:326:47:326:48 | call to MessagePropertiesIterator | bmqa.cpp:327:8:327:9 | *it | provenance | |
+| bmqa.cpp:326:50:326:55 | *& ... | bmqa.cpp:326:47:326:48 | call to MessagePropertiesIterator | provenance | MaD:165 |
+| bmqa.cpp:327:8:327:9 | *it | bmqa.cpp:327:15:327:17 | *call to name | provenance | MaD:168 |
+| bmqa.cpp:327:15:327:17 | *call to name | bmqa.cpp:327:7:327:23 | * ... | provenance | TaintFunction |
+| bmqa.cpp:331:24:331:31 | call to source | bmqa.cpp:333:27:333:30 | name | provenance | TaintFunction |
+| bmqa.cpp:333:2:333:6 | setPropertyAsShort output argument | bmqa.cpp:334:50:334:55 | *& ... | provenance | |
+| bmqa.cpp:333:27:333:30 | name | bmqa.cpp:333:2:333:6 | setPropertyAsShort output argument | provenance | MaD:160 |
+| bmqa.cpp:334:47:334:48 | call to MessagePropertiesIterator | bmqa.cpp:335:8:335:9 | *it | provenance | |
+| bmqa.cpp:334:50:334:55 | *& ... | bmqa.cpp:334:47:334:48 | call to MessagePropertiesIterator | provenance | MaD:165 |
+| bmqa.cpp:335:8:335:9 | *it | bmqa.cpp:335:15:335:17 | *call to name | provenance | MaD:168 |
+| bmqa.cpp:335:15:335:17 | *call to name | bmqa.cpp:335:7:335:23 | * ... | provenance | TaintFunction |
+| bmqa.cpp:339:24:339:31 | call to source | bmqa.cpp:341:27:341:30 | name | provenance | TaintFunction |
+| bmqa.cpp:341:2:341:6 | setPropertyAsInt32 output argument | bmqa.cpp:342:50:342:55 | *& ... | provenance | |
+| bmqa.cpp:341:27:341:30 | name | bmqa.cpp:341:2:341:6 | setPropertyAsInt32 output argument | provenance | MaD:158 |
+| bmqa.cpp:342:47:342:48 | call to MessagePropertiesIterator | bmqa.cpp:343:8:343:9 | *it | provenance | |
+| bmqa.cpp:342:50:342:55 | *& ... | bmqa.cpp:342:47:342:48 | call to MessagePropertiesIterator | provenance | MaD:165 |
+| bmqa.cpp:343:8:343:9 | *it | bmqa.cpp:343:15:343:17 | *call to name | provenance | MaD:168 |
+| bmqa.cpp:343:15:343:17 | *call to name | bmqa.cpp:343:7:343:23 | * ... | provenance | TaintFunction |
+| bmqa.cpp:347:24:347:31 | call to source | bmqa.cpp:349:27:349:30 | name | provenance | TaintFunction |
+| bmqa.cpp:349:2:349:6 | setPropertyAsInt64 output argument | bmqa.cpp:350:50:350:55 | *& ... | provenance | |
+| bmqa.cpp:349:27:349:30 | name | bmqa.cpp:349:2:349:6 | setPropertyAsInt64 output argument | provenance | MaD:159 |
+| bmqa.cpp:350:47:350:48 | call to MessagePropertiesIterator | bmqa.cpp:351:8:351:9 | *it | provenance | |
+| bmqa.cpp:350:50:350:55 | *& ... | bmqa.cpp:350:47:350:48 | call to MessagePropertiesIterator | provenance | MaD:165 |
+| bmqa.cpp:351:8:351:9 | *it | bmqa.cpp:351:15:351:17 | *call to name | provenance | MaD:168 |
+| bmqa.cpp:351:15:351:17 | *call to name | bmqa.cpp:351:7:351:23 | * ... | provenance | TaintFunction |
+| bmqa.cpp:355:24:355:31 | call to source | bmqa.cpp:357:28:357:31 | name | provenance | TaintFunction |
+| bmqa.cpp:357:2:357:6 | setPropertyAsString output argument | bmqa.cpp:358:50:358:55 | *& ... | provenance | |
+| bmqa.cpp:357:28:357:31 | name | bmqa.cpp:357:2:357:6 | setPropertyAsString output argument | provenance | MaD:161 |
+| bmqa.cpp:358:47:358:48 | call to MessagePropertiesIterator | bmqa.cpp:359:8:359:9 | *it | provenance | |
+| bmqa.cpp:358:50:358:55 | *& ... | bmqa.cpp:358:47:358:48 | call to MessagePropertiesIterator | provenance | MaD:165 |
+| bmqa.cpp:359:8:359:9 | *it | bmqa.cpp:359:15:359:17 | *call to name | provenance | MaD:168 |
+| bmqa.cpp:359:15:359:17 | *call to name | bmqa.cpp:359:7:359:23 | * ... | provenance | TaintFunction |
+| bmqa.cpp:363:24:363:31 | call to source | bmqa.cpp:365:28:365:31 | name | provenance | TaintFunction |
+| bmqa.cpp:365:2:365:6 | setPropertyAsBinary output argument | bmqa.cpp:366:50:366:55 | *& ... | provenance | |
+| bmqa.cpp:365:28:365:31 | name | bmqa.cpp:365:2:365:6 | setPropertyAsBinary output argument | provenance | MaD:154 |
+| bmqa.cpp:366:47:366:48 | call to MessagePropertiesIterator | bmqa.cpp:367:8:367:9 | *it | provenance | |
+| bmqa.cpp:366:50:366:55 | *& ... | bmqa.cpp:366:47:366:48 | call to MessagePropertiesIterator | provenance | MaD:165 |
+| bmqa.cpp:367:8:367:9 | *it | bmqa.cpp:367:15:367:17 | *call to name | provenance | MaD:168 |
+| bmqa.cpp:367:15:367:17 | *call to name | bmqa.cpp:367:7:367:23 | * ... | provenance | TaintFunction |
+| bmqa.cpp:371:19:371:26 | call to source | bmqa.cpp:372:36:372:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:372:36:372:76 | *call to data | bmqa.cpp:374:2:374:4 | *msg | provenance | |
+| bmqa.cpp:374:2:374:4 | *msg | bmqa.cpp:374:22:374:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:374:22:374:27 | loadProperties output argument | bmqa.cpp:375:50:375:55 | *& ... | provenance | |
+| bmqa.cpp:375:47:375:48 | call to MessagePropertiesIterator | bmqa.cpp:377:9:377:10 | *it | provenance | |
+| bmqa.cpp:375:47:375:48 | call to MessagePropertiesIterator | bmqa.cpp:378:9:378:10 | *it | provenance | |
+| bmqa.cpp:375:47:375:48 | call to MessagePropertiesIterator | bmqa.cpp:379:9:379:10 | *it | provenance | |
+| bmqa.cpp:375:50:375:55 | *& ... | bmqa.cpp:375:47:375:48 | call to MessagePropertiesIterator | provenance | MaD:165 |
+| bmqa.cpp:377:9:377:10 | *it | bmqa.cpp:377:16:377:18 | *call to name | provenance | MaD:168 |
+| bmqa.cpp:377:16:377:18 | *call to name | bmqa.cpp:377:8:377:24 | * ... | provenance | TaintFunction |
+| bmqa.cpp:378:9:378:10 | *it | bmqa.cpp:378:23:378:25 | *call to getAsString | provenance | MaD:167 |
+| bmqa.cpp:378:23:378:25 | *call to getAsString | bmqa.cpp:378:8:378:31 | * ... | provenance | TaintFunction |
+| bmqa.cpp:379:9:379:10 | *it | bmqa.cpp:379:23:379:25 | *call to getAsBinary [element] | provenance | MaD:166 |
+| bmqa.cpp:379:23:379:25 | *call to getAsBinary [element] | bmqa.cpp:379:8:379:31 | * ... | provenance | MaD:267 |
+| bmqa.cpp:385:19:385:26 | call to source | bmqa.cpp:386:36:386:76 | *call to data | provenance | TaintFunction |
+| bmqa.cpp:386:36:386:76 | *call to data | bmqa.cpp:388:2:388:4 | *msg | provenance | |
+| bmqa.cpp:388:2:388:4 | *msg | bmqa.cpp:388:22:388:27 | loadProperties output argument | provenance | MaD:139 |
+| bmqa.cpp:388:22:388:27 | loadProperties output argument | bmqa.cpp:389:50:389:55 | *& ... | provenance | |
+| bmqa.cpp:389:47:389:48 | call to MessagePropertiesIterator | bmqa.cpp:391:9:391:10 | *it | provenance | |
+| bmqa.cpp:389:47:389:48 | call to MessagePropertiesIterator | bmqa.cpp:392:8:392:11 | *copy | provenance | TaintFunction |
+| bmqa.cpp:389:47:389:48 | call to MessagePropertiesIterator | bmqa.cpp:393:8:393:18 | *call to operator= | provenance | TaintFunction |
+| bmqa.cpp:389:47:389:48 | call to MessagePropertiesIterator | bmqa.cpp:393:16:393:17 | *it | provenance | |
+| bmqa.cpp:389:50:389:55 | *& ... | bmqa.cpp:389:47:389:48 | call to MessagePropertiesIterator | provenance | MaD:165 |
+| bmqa.cpp:391:2:391:5 | operator= output argument | bmqa.cpp:392:8:392:11 | *copy | provenance | |
+| bmqa.cpp:391:9:391:10 | *it | bmqa.cpp:391:2:391:5 | operator= output argument | provenance | MaD:169 |
+| bmqa.cpp:392:8:392:11 | *copy | bmqa.cpp:392:24:392:26 | *call to getAsString | provenance | MaD:167 |
+| bmqa.cpp:392:24:392:26 | *call to getAsString | bmqa.cpp:392:7:392:32 | * ... | provenance | TaintFunction |
+| bmqa.cpp:393:8:393:18 | *call to operator= | bmqa.cpp:393:24:393:26 | *call to name | provenance | MaD:168 |
+| bmqa.cpp:393:16:393:17 | *it | bmqa.cpp:393:8:393:18 | *call to operator= | provenance | MaD:170 |
+| bmqa.cpp:393:24:393:26 | *call to name | bmqa.cpp:393:7:393:32 | * ... | provenance | TaintFunction |
+| bslx.cpp:145:33:145:40 | call to source | bslx.cpp:146:41:146:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:146:34:146:39 | call to ByteInStream | bslx.cpp:148:2:148:7 | *stream | provenance | |
+| bslx.cpp:146:41:146:51 | *call to data | bslx.cpp:146:34:146:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:148:2:148:7 | *stream | bslx.cpp:148:22:148:24 | getArrayInt8 output argument | provenance | MaD:183 |
+| bslx.cpp:148:22:148:24 | getArrayInt8 output argument | bslx.cpp:149:7:149:10 | * ... | provenance | |
+| bslx.cpp:153:33:153:40 | call to source | bslx.cpp:154:41:154:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:154:34:154:39 | call to ByteInStream | bslx.cpp:156:2:156:7 | *stream | provenance | |
+| bslx.cpp:154:41:154:51 | *call to data | bslx.cpp:154:34:154:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:156:2:156:7 | *stream | bslx.cpp:156:19:156:21 | getString output argument | provenance | MaD:204 |
+| bslx.cpp:156:19:156:21 | getString output argument | bslx.cpp:157:7:157:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:161:33:161:40 | call to source | bslx.cpp:162:41:162:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:162:34:162:39 | call to ByteInStream | bslx.cpp:165:2:165:7 | *stream | provenance | |
+| bslx.cpp:162:41:162:51 | *call to data | bslx.cpp:162:34:162:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:165:2:165:7 | *stream | bslx.cpp:165:17:165:20 | *call to getInt32 | provenance | MaD:197 |
+| bslx.cpp:165:17:165:20 | *call to getInt32 | bslx.cpp:165:31:165:33 | getString output argument | provenance | MaD:204 |
+| bslx.cpp:165:31:165:33 | getString output argument | bslx.cpp:166:7:166:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:171:33:171:40 | call to source | bslx.cpp:172:15:172:25 | *call to data | provenance | TaintFunction |
+| bslx.cpp:172:2:172:7 | reset output argument | bslx.cpp:174:2:174:7 | *stream | provenance | |
+| bslx.cpp:172:15:172:25 | *call to data | bslx.cpp:172:2:172:7 | reset output argument | provenance | MaD:216 |
+| bslx.cpp:174:2:174:7 | *stream | bslx.cpp:174:19:174:21 | getString output argument | provenance | MaD:204 |
+| bslx.cpp:174:19:174:21 | getString output argument | bslx.cpp:175:7:175:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:179:33:179:40 | call to source | bslx.cpp:180:20:180:45 | *call to data | provenance | TaintFunction |
+| bslx.cpp:180:20:180:45 | *call to data | bslx.cpp:181:57:181:58 | *sb | provenance | |
+| bslx.cpp:180:20:180:45 | *call to data | bslx.cpp:183:2:183:7 | *stream | provenance | TaintFunction |
+| bslx.cpp:181:50:181:55 | call to GenericInStream | bslx.cpp:183:2:183:7 | *stream | provenance | |
+| bslx.cpp:181:57:181:58 | *sb | bslx.cpp:181:50:181:55 | call to GenericInStream | provenance | MaD:217 |
+| bslx.cpp:183:2:183:7 | *stream | bslx.cpp:183:19:183:21 | getString output argument | provenance | MaD:247 |
+| bslx.cpp:183:19:183:21 | getString output argument | bslx.cpp:184:7:184:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:197:33:197:40 | call to source | bslx.cpp:198:41:198:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:198:34:198:39 | call to ByteInStream | bslx.cpp:200:53:200:58 | *stream | provenance | |
+| bslx.cpp:198:41:198:51 | *call to data | bslx.cpp:198:34:198:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:200:53:200:58 | *stream | bslx.cpp:200:61:200:63 | bdexStreamIn output argument | provenance | MaD:171 |
+| bslx.cpp:200:61:200:63 | bdexStreamIn output argument | bslx.cpp:201:7:201:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:207:33:207:40 | call to source | bslx.cpp:208:41:208:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:208:34:208:39 | call to ByteInStream | bslx.cpp:231:2:231:7 | *stream | provenance | |
+| bslx.cpp:208:41:208:51 | *call to data | bslx.cpp:208:34:208:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:231:2:231:7 | *stream | bslx.cpp:231:18:231:21 | *call to getLength | provenance | MaD:203 |
+| bslx.cpp:231:18:231:21 | *call to getLength | bslx.cpp:231:32:231:35 | *call to getVersion | provenance | MaD:214 |
+| bslx.cpp:231:32:231:35 | *call to getVersion | bslx.cpp:231:43:231:46 | *call to getInt8 | provenance | MaD:202 |
+| bslx.cpp:231:43:231:46 | *call to getInt8 | bslx.cpp:231:55:231:59 | *call to getUint8 | provenance | MaD:213 |
+| bslx.cpp:231:55:231:59 | *call to getUint8 | bslx.cpp:231:68:231:71 | *call to getInt16 | provenance | MaD:195 |
+| bslx.cpp:231:68:231:71 | *call to getInt16 | bslx.cpp:231:81:231:85 | *call to getUint16 | provenance | MaD:206 |
+| bslx.cpp:231:81:231:85 | *call to getUint16 | bslx.cpp:231:94:231:97 | *call to getInt24 | provenance | MaD:196 |
+| bslx.cpp:231:94:231:97 | *call to getInt24 | bslx.cpp:231:107:231:111 | *call to getUint24 | provenance | MaD:207 |
+| bslx.cpp:231:107:231:111 | *call to getUint24 | bslx.cpp:231:120:231:123 | *call to getInt32 | provenance | MaD:197 |
+| bslx.cpp:231:120:231:123 | *call to getInt32 | bslx.cpp:231:133:231:137 | *call to getUint32 | provenance | MaD:208 |
+| bslx.cpp:231:133:231:137 | *call to getUint32 | bslx.cpp:231:146:231:150 | *call to getInt40 | provenance | MaD:198 |
+| bslx.cpp:231:146:231:150 | *call to getInt40 | bslx.cpp:231:160:231:165 | *call to getUint40 | provenance | MaD:209 |
+| bslx.cpp:231:160:231:165 | *call to getUint40 | bslx.cpp:231:174:231:178 | *call to getInt48 | provenance | MaD:199 |
+| bslx.cpp:231:174:231:178 | *call to getInt48 | bslx.cpp:231:188:231:193 | *call to getUint48 | provenance | MaD:210 |
+| bslx.cpp:231:188:231:193 | *call to getUint48 | bslx.cpp:231:202:231:206 | *call to getInt56 | provenance | MaD:200 |
+| bslx.cpp:231:202:231:206 | *call to getInt56 | bslx.cpp:231:216:231:221 | *call to getUint56 | provenance | MaD:211 |
+| bslx.cpp:231:216:231:221 | *call to getUint56 | bslx.cpp:231:230:231:234 | *call to getInt64 | provenance | MaD:201 |
+| bslx.cpp:231:230:231:234 | *call to getInt64 | bslx.cpp:231:244:231:249 | *call to getUint64 | provenance | MaD:212 |
+| bslx.cpp:231:244:231:249 | *call to getUint64 | bslx.cpp:231:260:231:263 | *call to getFloat32 | provenance | MaD:193 |
+| bslx.cpp:231:260:231:263 | *call to getFloat32 | bslx.cpp:231:274:231:277 | *call to getFloat64 | provenance | MaD:194 |
+| bslx.cpp:231:274:231:277 | *call to getFloat64 | bslx.cpp:231:287:231:292 | *call to getString | provenance | MaD:205 |
+| bslx.cpp:231:287:231:292 | *call to getString | bslx.cpp:231:305:231:315 | *call to getArrayInt8 | provenance | MaD:184 |
+| bslx.cpp:231:305:231:315 | *call to getArrayInt8 | bslx.cpp:231:329:231:340 | *call to getArrayUint8 | provenance | MaD:192 |
+| bslx.cpp:231:329:231:340 | *call to getArrayUint8 | bslx.cpp:231:354:231:364 | *call to getArrayInt16 | provenance | MaD:176 |
+| bslx.cpp:231:354:231:364 | *call to getArrayInt16 | bslx.cpp:231:379:231:390 | *call to getArrayUint16 | provenance | MaD:185 |
+| bslx.cpp:231:379:231:390 | *call to getArrayUint16 | bslx.cpp:231:404:231:414 | *call to getArrayInt24 | provenance | MaD:177 |
+| bslx.cpp:231:404:231:414 | *call to getArrayInt24 | bslx.cpp:231:429:231:440 | *call to getArrayUint24 | provenance | MaD:186 |
+| bslx.cpp:231:429:231:440 | *call to getArrayUint24 | bslx.cpp:231:454:231:464 | *call to getArrayInt32 | provenance | MaD:178 |
+| bslx.cpp:231:454:231:464 | *call to getArrayInt32 | bslx.cpp:231:479:231:490 | *call to getArrayUint32 | provenance | MaD:187 |
+| bslx.cpp:231:479:231:490 | *call to getArrayUint32 | bslx.cpp:231:504:231:515 | *call to getArrayInt40 | provenance | MaD:179 |
+| bslx.cpp:231:504:231:515 | *call to getArrayInt40 | bslx.cpp:231:530:231:542 | *call to getArrayUint40 | provenance | MaD:188 |
+| bslx.cpp:231:530:231:542 | *call to getArrayUint40 | bslx.cpp:231:556:231:567 | *call to getArrayInt48 | provenance | MaD:180 |
+| bslx.cpp:231:556:231:567 | *call to getArrayInt48 | bslx.cpp:231:582:231:594 | *call to getArrayUint48 | provenance | MaD:189 |
+| bslx.cpp:231:582:231:594 | *call to getArrayUint48 | bslx.cpp:231:608:231:619 | *call to getArrayInt56 | provenance | MaD:181 |
+| bslx.cpp:231:608:231:619 | *call to getArrayInt56 | bslx.cpp:231:634:231:646 | *call to getArrayUint56 | provenance | MaD:190 |
+| bslx.cpp:231:634:231:646 | *call to getArrayUint56 | bslx.cpp:231:660:231:671 | *call to getArrayInt64 | provenance | MaD:182 |
+| bslx.cpp:231:660:231:671 | *call to getArrayInt64 | bslx.cpp:231:686:231:698 | *call to getArrayUint64 | provenance | MaD:191 |
+| bslx.cpp:231:686:231:698 | *call to getArrayUint64 | bslx.cpp:231:714:231:724 | *call to getArrayFloat32 | provenance | MaD:174 |
+| bslx.cpp:231:714:231:724 | *call to getArrayFloat32 | bslx.cpp:231:740:231:750 | *call to getArrayFloat64 | provenance | MaD:175 |
+| bslx.cpp:231:740:231:750 | *call to getArrayFloat64 | bslx.cpp:231:761:231:763 | getString output argument | provenance | MaD:204 |
+| bslx.cpp:231:761:231:763 | getString output argument | bslx.cpp:232:7:232:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:236:33:236:40 | call to source | bslx.cpp:237:20:237:45 | *call to data | provenance | TaintFunction |
+| bslx.cpp:237:20:237:45 | *call to data | bslx.cpp:238:57:238:58 | *sb | provenance | |
+| bslx.cpp:237:20:237:45 | *call to data | bslx.cpp:261:2:261:7 | *stream | provenance | TaintFunction |
+| bslx.cpp:238:50:238:55 | call to GenericInStream | bslx.cpp:261:2:261:7 | *stream | provenance | |
+| bslx.cpp:238:57:238:58 | *sb | bslx.cpp:238:50:238:55 | call to GenericInStream | provenance | MaD:217 |
+| bslx.cpp:261:2:261:7 | *stream | bslx.cpp:261:18:261:21 | *call to getLength | provenance | MaD:246 |
+| bslx.cpp:261:18:261:21 | *call to getLength | bslx.cpp:261:32:261:35 | *call to getVersion | provenance | MaD:257 |
+| bslx.cpp:261:32:261:35 | *call to getVersion | bslx.cpp:261:43:261:46 | *call to getInt8 | provenance | MaD:245 |
+| bslx.cpp:261:43:261:46 | *call to getInt8 | bslx.cpp:261:55:261:59 | *call to getUint8 | provenance | MaD:256 |
+| bslx.cpp:261:55:261:59 | *call to getUint8 | bslx.cpp:261:68:261:71 | *call to getInt16 | provenance | MaD:238 |
+| bslx.cpp:261:68:261:71 | *call to getInt16 | bslx.cpp:261:81:261:85 | *call to getUint16 | provenance | MaD:249 |
+| bslx.cpp:261:81:261:85 | *call to getUint16 | bslx.cpp:261:94:261:97 | *call to getInt24 | provenance | MaD:239 |
+| bslx.cpp:261:94:261:97 | *call to getInt24 | bslx.cpp:261:107:261:111 | *call to getUint24 | provenance | MaD:250 |
+| bslx.cpp:261:107:261:111 | *call to getUint24 | bslx.cpp:261:120:261:123 | *call to getInt32 | provenance | MaD:240 |
+| bslx.cpp:261:120:261:123 | *call to getInt32 | bslx.cpp:261:133:261:137 | *call to getUint32 | provenance | MaD:251 |
+| bslx.cpp:261:133:261:137 | *call to getUint32 | bslx.cpp:261:146:261:150 | *call to getInt40 | provenance | MaD:241 |
+| bslx.cpp:261:146:261:150 | *call to getInt40 | bslx.cpp:261:160:261:165 | *call to getUint40 | provenance | MaD:252 |
+| bslx.cpp:261:160:261:165 | *call to getUint40 | bslx.cpp:261:174:261:178 | *call to getInt48 | provenance | MaD:242 |
+| bslx.cpp:261:174:261:178 | *call to getInt48 | bslx.cpp:261:188:261:193 | *call to getUint48 | provenance | MaD:253 |
+| bslx.cpp:261:188:261:193 | *call to getUint48 | bslx.cpp:261:202:261:206 | *call to getInt56 | provenance | MaD:243 |
+| bslx.cpp:261:202:261:206 | *call to getInt56 | bslx.cpp:261:216:261:221 | *call to getUint56 | provenance | MaD:254 |
+| bslx.cpp:261:216:261:221 | *call to getUint56 | bslx.cpp:261:230:261:234 | *call to getInt64 | provenance | MaD:244 |
+| bslx.cpp:261:230:261:234 | *call to getInt64 | bslx.cpp:261:244:261:249 | *call to getUint64 | provenance | MaD:255 |
+| bslx.cpp:261:244:261:249 | *call to getUint64 | bslx.cpp:261:260:261:263 | *call to getFloat32 | provenance | MaD:236 |
+| bslx.cpp:261:260:261:263 | *call to getFloat32 | bslx.cpp:261:274:261:277 | *call to getFloat64 | provenance | MaD:237 |
+| bslx.cpp:261:274:261:277 | *call to getFloat64 | bslx.cpp:261:287:261:292 | *call to getString | provenance | MaD:248 |
+| bslx.cpp:261:287:261:292 | *call to getString | bslx.cpp:261:305:261:315 | *call to getArrayInt8 | provenance | MaD:227 |
+| bslx.cpp:261:305:261:315 | *call to getArrayInt8 | bslx.cpp:261:329:261:340 | *call to getArrayUint8 | provenance | MaD:235 |
+| bslx.cpp:261:329:261:340 | *call to getArrayUint8 | bslx.cpp:261:354:261:364 | *call to getArrayInt16 | provenance | MaD:220 |
+| bslx.cpp:261:354:261:364 | *call to getArrayInt16 | bslx.cpp:261:379:261:390 | *call to getArrayUint16 | provenance | MaD:228 |
+| bslx.cpp:261:379:261:390 | *call to getArrayUint16 | bslx.cpp:261:404:261:414 | *call to getArrayInt24 | provenance | MaD:221 |
+| bslx.cpp:261:404:261:414 | *call to getArrayInt24 | bslx.cpp:261:429:261:440 | *call to getArrayUint24 | provenance | MaD:229 |
+| bslx.cpp:261:429:261:440 | *call to getArrayUint24 | bslx.cpp:261:454:261:464 | *call to getArrayInt32 | provenance | MaD:222 |
+| bslx.cpp:261:454:261:464 | *call to getArrayInt32 | bslx.cpp:261:479:261:490 | *call to getArrayUint32 | provenance | MaD:230 |
+| bslx.cpp:261:479:261:490 | *call to getArrayUint32 | bslx.cpp:261:504:261:515 | *call to getArrayInt40 | provenance | MaD:223 |
+| bslx.cpp:261:504:261:515 | *call to getArrayInt40 | bslx.cpp:261:530:261:542 | *call to getArrayUint40 | provenance | MaD:231 |
+| bslx.cpp:261:530:261:542 | *call to getArrayUint40 | bslx.cpp:261:556:261:567 | *call to getArrayInt48 | provenance | MaD:224 |
+| bslx.cpp:261:556:261:567 | *call to getArrayInt48 | bslx.cpp:261:582:261:594 | *call to getArrayUint48 | provenance | MaD:232 |
+| bslx.cpp:261:582:261:594 | *call to getArrayUint48 | bslx.cpp:261:608:261:619 | *call to getArrayInt56 | provenance | MaD:225 |
+| bslx.cpp:261:608:261:619 | *call to getArrayInt56 | bslx.cpp:261:634:261:646 | *call to getArrayUint56 | provenance | MaD:233 |
+| bslx.cpp:261:634:261:646 | *call to getArrayUint56 | bslx.cpp:261:660:261:671 | *call to getArrayInt64 | provenance | MaD:226 |
+| bslx.cpp:261:660:261:671 | *call to getArrayInt64 | bslx.cpp:261:686:261:698 | *call to getArrayUint64 | provenance | MaD:234 |
+| bslx.cpp:261:686:261:698 | *call to getArrayUint64 | bslx.cpp:261:714:261:724 | *call to getArrayFloat32 | provenance | MaD:218 |
+| bslx.cpp:261:714:261:724 | *call to getArrayFloat32 | bslx.cpp:261:740:261:750 | *call to getArrayFloat64 | provenance | MaD:219 |
+| bslx.cpp:261:740:261:750 | *call to getArrayFloat64 | bslx.cpp:261:761:261:763 | getString output argument | provenance | MaD:247 |
+| bslx.cpp:261:761:261:763 | getString output argument | bslx.cpp:262:7:262:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:266:33:266:40 | call to source | bslx.cpp:267:41:267:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:267:34:267:39 | call to ByteInStream | bslx.cpp:269:53:269:58 | *stream | provenance | |
+| bslx.cpp:267:34:267:39 | call to ByteInStream | bslx.cpp:271:53:271:58 | *stream | provenance | |
+| bslx.cpp:267:34:267:39 | call to ByteInStream | bslx.cpp:274:53:274:58 | *stream | provenance | |
+| bslx.cpp:267:41:267:51 | *call to data | bslx.cpp:267:34:267:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:269:53:269:58 | *stream | bslx.cpp:269:61:269:61 | bdexStreamIn output argument | provenance | MaD:171 |
+| bslx.cpp:269:61:269:61 | bdexStreamIn output argument | bslx.cpp:270:7:270:7 | x | provenance | |
+| bslx.cpp:269:61:269:61 | bdexStreamIn output argument | bslx.cpp:272:7:272:7 | x | provenance | |
+| bslx.cpp:271:53:271:58 | *stream | bslx.cpp:271:61:271:61 | bdexStreamIn output argument | provenance | MaD:171 |
+| bslx.cpp:271:61:271:61 | bdexStreamIn output argument | bslx.cpp:272:7:272:7 | x | provenance | |
+| bslx.cpp:274:52:274:66 | *call to bdexStreamIn | bslx.cpp:274:77:274:79 | getString output argument | provenance | MaD:204 |
+| bslx.cpp:274:53:274:58 | *stream | bslx.cpp:274:52:274:66 | *call to bdexStreamIn | provenance | MaD:172 |
+| bslx.cpp:274:77:274:79 | getString output argument | bslx.cpp:275:7:275:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:279:33:279:40 | call to source | bslx.cpp:280:41:280:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:280:34:280:39 | call to ByteInStream | bslx.cpp:282:53:282:58 | *stream | provenance | |
+| bslx.cpp:280:41:280:51 | *call to data | bslx.cpp:280:34:280:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:282:53:282:58 | *stream | bslx.cpp:282:61:282:63 | bdexStreamIn output argument | provenance | MaD:171 |
+| bslx.cpp:282:61:282:63 | bdexStreamIn output argument | bslx.cpp:283:7:283:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:293:33:293:40 | call to source | bslx.cpp:294:41:294:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:294:34:294:39 | call to ByteInStream | bslx.cpp:296:53:296:58 | *stream | provenance | |
+| bslx.cpp:294:41:294:51 | *call to data | bslx.cpp:294:34:294:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:296:53:296:58 | *stream | bslx.cpp:296:61:296:63 | bdexStreamIn output argument | provenance | MaD:171 |
+| bslx.cpp:296:61:296:63 | bdexStreamIn output argument | bslx.cpp:297:7:297:9 | out | provenance | |
+| bslx.cpp:306:40:306:60 | call to source | bslx.cpp:306:40:306:60 | call to source | provenance | |
+| bslx.cpp:306:40:306:60 | call to source | bslx.cpp:307:15:307:18 | *data | provenance | |
+| bslx.cpp:307:2:307:7 | reset output argument | bslx.cpp:309:2:309:7 | *stream | provenance | |
+| bslx.cpp:307:15:307:18 | *data | bslx.cpp:307:2:307:7 | reset output argument | provenance | MaD:215 |
+| bslx.cpp:309:2:309:7 | *stream | bslx.cpp:309:19:309:21 | getString output argument | provenance | MaD:204 |
+| bslx.cpp:309:19:309:21 | getString output argument | bslx.cpp:310:7:310:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:314:33:314:40 | call to source | bslx.cpp:315:41:315:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:315:34:315:39 | call to ByteInStream | bslx.cpp:318:2:318:7 | *stream | provenance | |
+| bslx.cpp:315:41:315:51 | *call to data | bslx.cpp:315:34:315:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:318:2:318:7 | *stream | bslx.cpp:318:19:318:21 | getString output argument | provenance | MaD:204 |
+| bslx.cpp:318:19:318:21 | getString output argument | bslx.cpp:319:7:319:17 | * ... | provenance | TaintFunction |
+| bslx.cpp:333:33:333:40 | call to source | bslx.cpp:334:41:334:51 | *call to data | provenance | TaintFunction |
+| bslx.cpp:334:34:334:39 | call to ByteInStream | bslx.cpp:338:2:338:7 | *stream | provenance | |
+| bslx.cpp:334:41:334:51 | *call to data | bslx.cpp:334:34:334:39 | call to ByteInStream | provenance | MaD:173 |
+| bslx.cpp:338:2:338:7 | *stream | bslx.cpp:338:19:338:21 | getString output argument | provenance | MaD:204 |
+| bslx.cpp:338:19:338:21 | getString output argument | bslx.cpp:340:7:340:17 | * ... | provenance | TaintFunction |
+| protobuf.cpp:105:27:105:51 | call to source | protobuf.cpp:105:27:105:51 | call to source | provenance | |
+| protobuf.cpp:105:27:105:51 | call to source | protobuf.cpp:106:22:106:25 | data | provenance | |
+| protobuf.cpp:106:2:106:4 | ParseFromString output argument | protobuf.cpp:107:7:107:9 | msg | provenance | |
+| protobuf.cpp:106:22:106:25 | data | protobuf.cpp:106:2:106:4 | ParseFromString output argument | provenance | MaD:290 |
+| protobuf.cpp:112:20:112:37 | call to source | protobuf.cpp:112:20:112:37 | call to source | provenance | |
+| protobuf.cpp:112:20:112:37 | call to source | protobuf.cpp:113:22:113:25 | *data | provenance | |
+| protobuf.cpp:113:2:113:4 | ParseFromString output argument | protobuf.cpp:114:7:114:9 | msg | provenance | |
+| protobuf.cpp:113:22:113:25 | *data | protobuf.cpp:113:2:113:4 | ParseFromString output argument | provenance | MaD:289 |
+| protobuf.cpp:119:27:119:51 | call to source | protobuf.cpp:119:27:119:51 | call to source | provenance | |
+| protobuf.cpp:119:27:119:51 | call to source | protobuf.cpp:120:29:120:32 | data | provenance | |
+| protobuf.cpp:120:2:120:4 | ParsePartialFromString output argument | protobuf.cpp:121:7:121:9 | msg | provenance | |
+| protobuf.cpp:120:29:120:32 | data | protobuf.cpp:120:2:120:4 | ParsePartialFromString output argument | provenance | MaD:298 |
+| protobuf.cpp:126:20:126:37 | call to source | protobuf.cpp:126:20:126:37 | call to source | provenance | |
+| protobuf.cpp:126:20:126:37 | call to source | protobuf.cpp:127:29:127:32 | *data | provenance | |
+| protobuf.cpp:127:2:127:4 | ParsePartialFromString output argument | protobuf.cpp:128:7:128:9 | msg | provenance | |
+| protobuf.cpp:127:29:127:32 | *data | protobuf.cpp:127:2:127:4 | ParsePartialFromString output argument | provenance | MaD:297 |
+| protobuf.cpp:133:27:133:51 | call to source | protobuf.cpp:133:27:133:51 | call to source | provenance | |
+| protobuf.cpp:133:27:133:51 | call to source | protobuf.cpp:134:22:134:25 | data | provenance | |
+| protobuf.cpp:134:2:134:4 | MergeFromString output argument | protobuf.cpp:135:7:135:9 | msg | provenance | |
+| protobuf.cpp:134:22:134:25 | data | protobuf.cpp:134:2:134:4 | MergeFromString output argument | provenance | MaD:278 |
+| protobuf.cpp:140:20:140:37 | call to source | protobuf.cpp:140:20:140:37 | call to source | provenance | |
+| protobuf.cpp:140:20:140:37 | call to source | protobuf.cpp:141:22:141:25 | *data | provenance | |
+| protobuf.cpp:141:2:141:4 | MergeFromString output argument | protobuf.cpp:142:7:142:9 | msg | provenance | |
+| protobuf.cpp:141:22:141:25 | *data | protobuf.cpp:141:2:141:4 | MergeFromString output argument | provenance | MaD:277 |
+| protobuf.cpp:147:27:147:51 | call to source | protobuf.cpp:147:27:147:51 | call to source | provenance | |
+| protobuf.cpp:147:27:147:51 | call to source | protobuf.cpp:148:29:148:32 | data | provenance | |
+| protobuf.cpp:148:2:148:4 | MergePartialFromString output argument | protobuf.cpp:149:7:149:9 | msg | provenance | |
+| protobuf.cpp:148:29:148:32 | data | protobuf.cpp:148:2:148:4 | MergePartialFromString output argument | provenance | MaD:283 |
+| protobuf.cpp:154:20:154:37 | call to source | protobuf.cpp:154:20:154:37 | call to source | provenance | |
+| protobuf.cpp:154:20:154:37 | call to source | protobuf.cpp:155:29:155:32 | *data | provenance | |
+| protobuf.cpp:155:2:155:4 | MergePartialFromString output argument | protobuf.cpp:156:7:156:9 | msg | provenance | |
+| protobuf.cpp:155:29:155:32 | *data | protobuf.cpp:155:2:155:4 | MergePartialFromString output argument | provenance | MaD:282 |
+| protobuf.cpp:161:19:161:38 | call to source | protobuf.cpp:162:21:162:31 | *call to data | provenance | TaintFunction |
+| protobuf.cpp:162:2:162:4 | ParseFromArray output argument | protobuf.cpp:163:7:163:9 | msg | provenance | |
+| protobuf.cpp:162:21:162:31 | *call to data | protobuf.cpp:162:2:162:4 | ParseFromArray output argument | provenance | MaD:284 |
+| protobuf.cpp:168:19:168:38 | call to source | protobuf.cpp:169:28:169:38 | *call to data | provenance | TaintFunction |
+| protobuf.cpp:169:2:169:4 | ParsePartialFromArray output argument | protobuf.cpp:170:7:170:9 | msg | provenance | |
+| protobuf.cpp:169:28:169:38 | *call to data | protobuf.cpp:169:2:169:4 | ParsePartialFromArray output argument | provenance | MaD:292 |
+| protobuf.cpp:175:20:175:37 | call to source | protobuf.cpp:175:20:175:37 | call to source | provenance | |
+| protobuf.cpp:175:20:175:37 | call to source | protobuf.cpp:176:20:176:23 | *data | provenance | |
+| protobuf.cpp:176:2:176:4 | ParseFromCord output argument | protobuf.cpp:177:7:177:9 | msg | provenance | |
+| protobuf.cpp:176:20:176:23 | *data | protobuf.cpp:176:2:176:4 | ParseFromCord output argument | provenance | MaD:287 |
+| protobuf.cpp:182:20:182:37 | call to source | protobuf.cpp:182:20:182:37 | call to source | provenance | |
+| protobuf.cpp:182:20:182:37 | call to source | protobuf.cpp:183:27:183:30 | *data | provenance | |
+| protobuf.cpp:183:2:183:4 | ParsePartialFromCord output argument | protobuf.cpp:184:7:184:9 | msg | provenance | |
+| protobuf.cpp:183:27:183:30 | *data | protobuf.cpp:183:2:183:4 | ParsePartialFromCord output argument | provenance | MaD:295 |
+| protobuf.cpp:189:20:189:37 | call to source | protobuf.cpp:189:20:189:37 | call to source | provenance | |
+| protobuf.cpp:189:20:189:37 | call to source | protobuf.cpp:190:20:190:23 | *data | provenance | |
+| protobuf.cpp:190:2:190:4 | MergeFromCord output argument | protobuf.cpp:191:7:191:9 | msg | provenance | |
+| protobuf.cpp:190:20:190:23 | *data | protobuf.cpp:190:2:190:4 | MergeFromCord output argument | provenance | MaD:276 |
+| protobuf.cpp:196:20:196:37 | call to source | protobuf.cpp:196:20:196:37 | call to source | provenance | |
+| protobuf.cpp:196:20:196:37 | call to source | protobuf.cpp:197:27:197:30 | *data | provenance | |
+| protobuf.cpp:197:2:197:4 | MergePartialFromCord output argument | protobuf.cpp:198:7:198:9 | msg | provenance | |
+| protobuf.cpp:197:27:197:30 | *data | protobuf.cpp:197:2:197:4 | MergePartialFromCord output argument | provenance | MaD:281 |
+| protobuf.cpp:203:20:203:39 | call to source | protobuf.cpp:203:20:203:39 | call to source | provenance | |
+| protobuf.cpp:203:20:203:39 | call to source | protobuf.cpp:204:23:204:25 | *& ... | provenance | |
+| protobuf.cpp:204:2:204:4 | ParseFromIstream output argument | protobuf.cpp:205:7:205:9 | msg | provenance | |
+| protobuf.cpp:204:23:204:25 | *& ... | protobuf.cpp:204:2:204:4 | ParseFromIstream output argument | provenance | MaD:288 |
+| protobuf.cpp:210:20:210:39 | call to source | protobuf.cpp:210:20:210:39 | call to source | provenance | |
+| protobuf.cpp:210:20:210:39 | call to source | protobuf.cpp:211:30:211:32 | *& ... | provenance | |
+| protobuf.cpp:211:2:211:4 | ParsePartialFromIstream output argument | protobuf.cpp:212:7:212:9 | msg | provenance | |
+| protobuf.cpp:211:30:211:32 | *& ... | protobuf.cpp:211:2:211:4 | ParsePartialFromIstream output argument | provenance | MaD:296 |
+| protobuf.cpp:217:27:217:53 | call to source | protobuf.cpp:217:27:217:53 | call to source | provenance | |
+| protobuf.cpp:217:27:217:53 | call to source | protobuf.cpp:218:30:218:32 | *& ... | provenance | |
+| protobuf.cpp:218:2:218:4 | ParseFromZeroCopyStream output argument | protobuf.cpp:219:7:219:9 | msg | provenance | |
+| protobuf.cpp:218:30:218:32 | *& ... | protobuf.cpp:218:2:218:4 | ParseFromZeroCopyStream output argument | provenance | MaD:291 |
+| protobuf.cpp:224:27:224:53 | call to source | protobuf.cpp:224:27:224:53 | call to source | provenance | |
+| protobuf.cpp:224:27:224:53 | call to source | protobuf.cpp:225:37:225:39 | *& ... | provenance | |
+| protobuf.cpp:225:2:225:4 | ParsePartialFromZeroCopyStream output argument | protobuf.cpp:226:7:226:9 | msg | provenance | |
+| protobuf.cpp:225:37:225:39 | *& ... | protobuf.cpp:225:2:225:4 | ParsePartialFromZeroCopyStream output argument | provenance | MaD:299 |
+| protobuf.cpp:231:27:231:53 | call to source | protobuf.cpp:231:27:231:53 | call to source | provenance | |
+| protobuf.cpp:231:27:231:53 | call to source | protobuf.cpp:232:37:232:39 | *& ... | provenance | |
+| protobuf.cpp:232:2:232:4 | ParseFromBoundedZeroCopyStream output argument | protobuf.cpp:233:7:233:9 | msg | provenance | |
+| protobuf.cpp:232:37:232:39 | *& ... | protobuf.cpp:232:2:232:4 | ParseFromBoundedZeroCopyStream output argument | provenance | MaD:285 |
+| protobuf.cpp:238:27:238:53 | call to source | protobuf.cpp:238:27:238:53 | call to source | provenance | |
+| protobuf.cpp:238:27:238:53 | call to source | protobuf.cpp:239:44:239:46 | *& ... | provenance | |
+| protobuf.cpp:239:2:239:4 | ParsePartialFromBoundedZeroCopyStream output argument | protobuf.cpp:240:7:240:9 | msg | provenance | |
+| protobuf.cpp:239:44:239:46 | *& ... | protobuf.cpp:239:2:239:4 | ParsePartialFromBoundedZeroCopyStream output argument | provenance | MaD:293 |
+| protobuf.cpp:245:27:245:53 | call to source | protobuf.cpp:245:27:245:53 | call to source | provenance | |
+| protobuf.cpp:245:27:245:53 | call to source | protobuf.cpp:246:37:246:39 | *& ... | provenance | |
+| protobuf.cpp:246:2:246:4 | MergeFromBoundedZeroCopyStream output argument | protobuf.cpp:247:7:247:9 | msg | provenance | |
+| protobuf.cpp:246:37:246:39 | *& ... | protobuf.cpp:246:2:246:4 | MergeFromBoundedZeroCopyStream output argument | provenance | MaD:274 |
+| protobuf.cpp:252:27:252:53 | call to source | protobuf.cpp:252:27:252:53 | call to source | provenance | |
+| protobuf.cpp:252:27:252:53 | call to source | protobuf.cpp:253:44:253:46 | *& ... | provenance | |
+| protobuf.cpp:253:2:253:4 | MergePartialFromBoundedZeroCopyStream output argument | protobuf.cpp:254:7:254:9 | msg | provenance | |
+| protobuf.cpp:253:44:253:46 | *& ... | protobuf.cpp:253:2:253:4 | MergePartialFromBoundedZeroCopyStream output argument | provenance | MaD:279 |
+| protobuf.cpp:259:24:259:47 | call to source | protobuf.cpp:259:24:259:47 | call to source | provenance | |
+| protobuf.cpp:259:24:259:47 | call to source | protobuf.cpp:260:27:260:29 | *& ... | provenance | |
+| protobuf.cpp:260:2:260:4 | ParseFromCodedStream output argument | protobuf.cpp:261:7:261:9 | msg | provenance | |
+| protobuf.cpp:260:27:260:29 | *& ... | protobuf.cpp:260:2:260:4 | ParseFromCodedStream output argument | provenance | MaD:286 |
+| protobuf.cpp:266:24:266:47 | call to source | protobuf.cpp:266:24:266:47 | call to source | provenance | |
+| protobuf.cpp:266:24:266:47 | call to source | protobuf.cpp:267:34:267:36 | *& ... | provenance | |
+| protobuf.cpp:267:2:267:4 | ParsePartialFromCodedStream output argument | protobuf.cpp:268:7:268:9 | msg | provenance | |
+| protobuf.cpp:267:34:267:36 | *& ... | protobuf.cpp:267:2:267:4 | ParsePartialFromCodedStream output argument | provenance | MaD:294 |
+| protobuf.cpp:273:24:273:47 | call to source | protobuf.cpp:273:24:273:47 | call to source | provenance | |
+| protobuf.cpp:273:24:273:47 | call to source | protobuf.cpp:274:27:274:29 | *& ... | provenance | |
+| protobuf.cpp:274:2:274:4 | MergeFromCodedStream output argument | protobuf.cpp:275:7:275:9 | msg | provenance | |
+| protobuf.cpp:274:27:274:29 | *& ... | protobuf.cpp:274:2:274:4 | MergeFromCodedStream output argument | provenance | MaD:275 |
+| protobuf.cpp:280:24:280:47 | call to source | protobuf.cpp:280:24:280:47 | call to source | provenance | |
+| protobuf.cpp:280:24:280:47 | call to source | protobuf.cpp:281:34:281:36 | *& ... | provenance | |
+| protobuf.cpp:281:2:281:4 | MergePartialFromCodedStream output argument | protobuf.cpp:282:7:282:9 | msg | provenance | |
+| protobuf.cpp:281:34:281:36 | *& ... | protobuf.cpp:281:2:281:4 | MergePartialFromCodedStream output argument | provenance | MaD:280 |
+| protobuf.cpp:295:15:295:28 | call to source | protobuf.cpp:295:15:295:28 | call to source | provenance | |
+| protobuf.cpp:295:15:295:28 | call to source | protobuf.cpp:297:2:297:4 | *msg | provenance | |
+| protobuf.cpp:297:2:297:4 | *msg | protobuf.cpp:297:24:297:27 | SerializeToString output argument | provenance | MaD:314 |
+| protobuf.cpp:297:24:297:27 | SerializeToString output argument | protobuf.cpp:298:7:298:9 | out | provenance | |
+| protobuf.cpp:302:15:302:28 | call to source | protobuf.cpp:302:15:302:28 | call to source | provenance | |
+| protobuf.cpp:302:15:302:28 | call to source | protobuf.cpp:304:2:304:4 | *msg | provenance | |
+| protobuf.cpp:304:2:304:4 | *msg | protobuf.cpp:304:31:304:34 | SerializePartialToString output argument | provenance | MaD:308 |
+| protobuf.cpp:304:31:304:34 | SerializePartialToString output argument | protobuf.cpp:305:7:305:9 | out | provenance | |
+| protobuf.cpp:309:15:309:28 | call to source | protobuf.cpp:309:15:309:28 | call to source | provenance | |
+| protobuf.cpp:309:15:309:28 | call to source | protobuf.cpp:311:2:311:4 | *msg | provenance | |
+| protobuf.cpp:311:2:311:4 | *msg | protobuf.cpp:311:21:311:24 | AppendToString output argument | provenance | MaD:273 |
+| protobuf.cpp:311:21:311:24 | AppendToString output argument | protobuf.cpp:312:7:312:9 | out | provenance | |
+| protobuf.cpp:316:15:316:28 | call to source | protobuf.cpp:316:15:316:28 | call to source | provenance | |
+| protobuf.cpp:316:15:316:28 | call to source | protobuf.cpp:318:2:318:4 | *msg | provenance | |
+| protobuf.cpp:318:2:318:4 | *msg | protobuf.cpp:318:28:318:31 | AppendPartialToString output argument | provenance | MaD:271 |
+| protobuf.cpp:318:28:318:31 | AppendPartialToString output argument | protobuf.cpp:319:7:319:9 | out | provenance | |
+| protobuf.cpp:323:15:323:28 | call to source | protobuf.cpp:323:15:323:28 | call to source | provenance | |
+| protobuf.cpp:323:15:323:28 | call to source | protobuf.cpp:325:2:325:4 | *msg | provenance | |
+| protobuf.cpp:325:2:325:4 | *msg | protobuf.cpp:325:24:325:27 | SerializeToString output argument | provenance | MaD:314 |
+| protobuf.cpp:325:24:325:27 | SerializeToString output argument | protobuf.cpp:326:7:326:9 | out | provenance | |
+| protobuf.cpp:330:15:330:28 | call to source | protobuf.cpp:330:15:330:28 | call to source | provenance | |
+| protobuf.cpp:330:15:330:28 | call to source | protobuf.cpp:332:2:332:4 | *msg | provenance | |
+| protobuf.cpp:332:2:332:4 | *msg | protobuf.cpp:332:31:332:34 | SerializePartialToString output argument | provenance | MaD:308 |
+| protobuf.cpp:332:31:332:34 | SerializePartialToString output argument | protobuf.cpp:333:7:333:9 | out | provenance | |
+| protobuf.cpp:337:15:337:28 | call to source | protobuf.cpp:337:15:337:28 | call to source | provenance | |
+| protobuf.cpp:337:15:337:28 | call to source | protobuf.cpp:339:2:339:4 | *msg | provenance | |
+| protobuf.cpp:339:2:339:4 | *msg | protobuf.cpp:339:21:339:24 | AppendToString output argument | provenance | MaD:273 |
+| protobuf.cpp:339:21:339:24 | AppendToString output argument | protobuf.cpp:340:7:340:9 | out | provenance | |
+| protobuf.cpp:344:15:344:28 | call to source | protobuf.cpp:344:15:344:28 | call to source | provenance | |
+| protobuf.cpp:344:15:344:28 | call to source | protobuf.cpp:346:2:346:4 | *msg | provenance | |
+| protobuf.cpp:346:2:346:4 | *msg | protobuf.cpp:346:28:346:31 | AppendPartialToString output argument | provenance | MaD:271 |
+| protobuf.cpp:346:28:346:31 | AppendPartialToString output argument | protobuf.cpp:347:7:347:9 | out | provenance | |
+| protobuf.cpp:351:15:351:28 | call to source | protobuf.cpp:351:15:351:28 | call to source | provenance | |
+| protobuf.cpp:351:15:351:28 | call to source | protobuf.cpp:353:2:353:4 | *msg | provenance | |
+| protobuf.cpp:353:2:353:4 | *msg | protobuf.cpp:353:23:353:25 | SerializeToArray output argument | provenance | MaD:310 |
+| protobuf.cpp:353:23:353:25 | SerializeToArray output argument | protobuf.cpp:354:7:354:10 | * ... | provenance | |
+| protobuf.cpp:358:15:358:28 | call to source | protobuf.cpp:358:15:358:28 | call to source | provenance | |
+| protobuf.cpp:358:15:358:28 | call to source | protobuf.cpp:360:2:360:4 | *msg | provenance | |
+| protobuf.cpp:360:2:360:4 | *msg | protobuf.cpp:360:30:360:32 | SerializePartialToArray output argument | provenance | MaD:304 |
+| protobuf.cpp:360:30:360:32 | SerializePartialToArray output argument | protobuf.cpp:361:7:361:10 | * ... | provenance | |
+| protobuf.cpp:365:15:365:28 | call to source | protobuf.cpp:365:15:365:28 | call to source | provenance | |
+| protobuf.cpp:365:15:365:28 | call to source | protobuf.cpp:367:2:367:4 | *msg | provenance | |
+| protobuf.cpp:367:2:367:4 | *msg | protobuf.cpp:367:22:367:25 | SerializeToCord output argument | provenance | MaD:312 |
+| protobuf.cpp:367:22:367:25 | SerializeToCord output argument | protobuf.cpp:368:7:368:9 | out | provenance | |
+| protobuf.cpp:372:15:372:28 | call to source | protobuf.cpp:372:15:372:28 | call to source | provenance | |
+| protobuf.cpp:372:15:372:28 | call to source | protobuf.cpp:374:2:374:4 | *msg | provenance | |
+| protobuf.cpp:374:2:374:4 | *msg | protobuf.cpp:374:29:374:32 | SerializePartialToCord output argument | provenance | MaD:306 |
+| protobuf.cpp:374:29:374:32 | SerializePartialToCord output argument | protobuf.cpp:375:7:375:9 | out | provenance | |
+| protobuf.cpp:379:15:379:28 | call to source | protobuf.cpp:379:15:379:28 | call to source | provenance | |
+| protobuf.cpp:379:15:379:28 | call to source | protobuf.cpp:381:2:381:4 | *msg | provenance | |
+| protobuf.cpp:381:2:381:4 | *msg | protobuf.cpp:381:19:381:22 | AppendToCord output argument | provenance | MaD:272 |
+| protobuf.cpp:381:19:381:22 | AppendToCord output argument | protobuf.cpp:382:7:382:9 | out | provenance | |
+| protobuf.cpp:386:15:386:28 | call to source | protobuf.cpp:386:15:386:28 | call to source | provenance | |
+| protobuf.cpp:386:15:386:28 | call to source | protobuf.cpp:388:2:388:4 | *msg | provenance | |
+| protobuf.cpp:388:2:388:4 | *msg | protobuf.cpp:388:26:388:29 | AppendPartialToCord output argument | provenance | MaD:270 |
+| protobuf.cpp:388:26:388:29 | AppendPartialToCord output argument | protobuf.cpp:389:7:389:9 | out | provenance | |
+| protobuf.cpp:393:15:393:28 | call to source | protobuf.cpp:393:15:393:28 | call to source | provenance | |
+| protobuf.cpp:393:15:393:28 | call to source | protobuf.cpp:395:2:395:4 | *msg | provenance | |
+| protobuf.cpp:395:2:395:4 | *msg | protobuf.cpp:395:25:395:28 | SerializeToOstream output argument | provenance | MaD:313 |
+| protobuf.cpp:395:25:395:28 | SerializeToOstream output argument | protobuf.cpp:396:7:396:9 | out | provenance | |
+| protobuf.cpp:400:15:400:28 | call to source | protobuf.cpp:400:15:400:28 | call to source | provenance | |
+| protobuf.cpp:400:15:400:28 | call to source | protobuf.cpp:402:2:402:4 | *msg | provenance | |
+| protobuf.cpp:402:2:402:4 | *msg | protobuf.cpp:402:32:402:35 | SerializePartialToOstream output argument | provenance | MaD:307 |
+| protobuf.cpp:402:32:402:35 | SerializePartialToOstream output argument | protobuf.cpp:403:7:403:9 | out | provenance | |
+| protobuf.cpp:407:15:407:28 | call to source | protobuf.cpp:407:15:407:28 | call to source | provenance | |
+| protobuf.cpp:407:15:407:28 | call to source | protobuf.cpp:409:2:409:4 | *msg | provenance | |
+| protobuf.cpp:409:2:409:4 | *msg | protobuf.cpp:409:32:409:35 | SerializeToZeroCopyStream output argument | provenance | MaD:315 |
+| protobuf.cpp:409:32:409:35 | SerializeToZeroCopyStream output argument | protobuf.cpp:410:7:410:9 | out | provenance | |
+| protobuf.cpp:414:15:414:28 | call to source | protobuf.cpp:414:15:414:28 | call to source | provenance | |
+| protobuf.cpp:414:15:414:28 | call to source | protobuf.cpp:416:2:416:4 | *msg | provenance | |
+| protobuf.cpp:416:2:416:4 | *msg | protobuf.cpp:416:39:416:42 | SerializePartialToZeroCopyStream output argument | provenance | MaD:309 |
+| protobuf.cpp:416:39:416:42 | SerializePartialToZeroCopyStream output argument | protobuf.cpp:417:7:417:9 | out | provenance | |
+| protobuf.cpp:421:15:421:28 | call to source | protobuf.cpp:421:15:421:28 | call to source | provenance | |
+| protobuf.cpp:421:15:421:28 | call to source | protobuf.cpp:423:2:423:4 | *msg | provenance | |
+| protobuf.cpp:423:2:423:4 | *msg | protobuf.cpp:423:29:423:32 | SerializeToCodedStream output argument | provenance | MaD:311 |
+| protobuf.cpp:423:29:423:32 | SerializeToCodedStream output argument | protobuf.cpp:424:7:424:9 | out | provenance | |
+| protobuf.cpp:428:15:428:28 | call to source | protobuf.cpp:428:15:428:28 | call to source | provenance | |
+| protobuf.cpp:428:15:428:28 | call to source | protobuf.cpp:430:2:430:4 | *msg | provenance | |
+| protobuf.cpp:430:2:430:4 | *msg | protobuf.cpp:430:36:430:39 | SerializePartialToCodedStream output argument | provenance | MaD:305 |
+| protobuf.cpp:430:36:430:39 | SerializePartialToCodedStream output argument | protobuf.cpp:431:7:431:9 | out | provenance | |
+| protobuf.cpp:437:15:437:28 | call to source | protobuf.cpp:437:15:437:28 | call to source | provenance | |
+| protobuf.cpp:437:15:437:28 | call to source | protobuf.cpp:438:7:438:9 | *msg | provenance | |
+| protobuf.cpp:438:7:438:9 | *msg | protobuf.cpp:438:11:438:27 | call to SerializeAsString | provenance | MaD:301 |
+| protobuf.cpp:442:15:442:28 | call to source | protobuf.cpp:442:15:442:28 | call to source | provenance | |
+| protobuf.cpp:442:15:442:28 | call to source | protobuf.cpp:443:7:443:9 | *msg | provenance | |
+| protobuf.cpp:443:7:443:9 | *msg | protobuf.cpp:443:11:443:34 | call to SerializePartialAsString | provenance | MaD:303 |
+| protobuf.cpp:447:15:447:28 | call to source | protobuf.cpp:447:15:447:28 | call to source | provenance | |
+| protobuf.cpp:447:15:447:28 | call to source | protobuf.cpp:448:7:448:9 | *msg | provenance | |
+| protobuf.cpp:448:7:448:9 | *msg | protobuf.cpp:448:11:448:25 | call to SerializeAsCord | provenance | MaD:300 |
+| protobuf.cpp:452:15:452:28 | call to source | protobuf.cpp:452:15:452:28 | call to source | provenance | |
+| protobuf.cpp:452:15:452:28 | call to source | protobuf.cpp:453:7:453:9 | *msg | provenance | |
+| protobuf.cpp:453:7:453:9 | *msg | protobuf.cpp:453:11:453:32 | call to SerializePartialAsCord | provenance | MaD:302 |
| 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:35 |
-| 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:10:10:10:18 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:3 |
| 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 | |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:25:35:25:35 | x | provenance | |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:32:41:32:41 | x | provenance | |
| 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:17:10:17:22 | call to ymlStepManual | provenance | MaD:71 |
+| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:3 |
+| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:85 |
| 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:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:70 |
+| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:3 |
+| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:84 |
| 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:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:72 |
+| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:3 |
+| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:86 |
| 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:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:3 |
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | |
| test.cpp:32:41:32:41 | x | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
| 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:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | |
+| test.cpp:48:16:48:16 | x | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:3 |
| 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:35 |
-| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | MaD:67 |
-| test.cpp:68:22:68:22 | y | test.cpp:69:11:69:11 | y | provenance | Sink:MaD:1 |
-| 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:35 |
+| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:48 |
+| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | MaD:81 |
+| test.cpp:68:22:68:22 | y | test.cpp:69:11:69:11 | y | provenance | Sink:MaD:3 |
+| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:3 |
+| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:3 |
+| test.cpp:88:22:88:22 | y | test.cpp:89:11:89:11 | y | provenance | Sink:MaD:3 |
+| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:48 |
| 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 | |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:104:62:104:62 | x | provenance | |
-| test.cpp:97:26:97:26 | x | test.cpp:68:22:68:22 | y | provenance | MaD:65 |
-| test.cpp:101:26:101:26 | x | test.cpp:74:22:74:22 | y | provenance | MaD:65 |
-| test.cpp:103:63:103:63 | x | test.cpp:82:22:82:22 | y | provenance | MaD:65 |
-| test.cpp:104:62:104:62 | x | test.cpp:88:22:88:22 | y | provenance | MaD:65 |
-| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:35 |
+| test.cpp:97:26:97:26 | x | test.cpp:68:22:68:22 | y | provenance | MaD:79 |
+| test.cpp:101:26:101:26 | x | test.cpp:74:22:74:22 | y | provenance | MaD:79 |
+| test.cpp:103:63:103:63 | x | test.cpp:82:22:82:22 | y | provenance | MaD:79 |
+| test.cpp:104:62:104:62 | x | test.cpp:88:22:88:22 | y | provenance | MaD:79 |
+| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:48 |
| 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:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:66 |
-| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:133:10:133:18 | call to ymlSource | provenance | Src:MaD:35 |
+| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:3 |
+| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:80 |
+| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:133:10:133:18 | call to ymlSource | provenance | Src:MaD:48 |
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:134:45:134:45 | x | provenance | |
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:134:13:134:43 | call to templateFunction | provenance | |
-| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:135:10:135:10 | y | provenance | Sink:MaD:1 |
-| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:77 |
-| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:146:10:146:18 | call to ymlSource | provenance | Src:MaD:35 |
+| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:135:10:135:10 | y | provenance | Sink:MaD:3 |
+| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:93 |
+| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:146:10:146:18 | call to ymlSource | provenance | Src:MaD:48 |
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:148:26:148:26 | x | provenance | |
| test.cpp:148:10:148:27 | call to function | test.cpp:148:10:148:27 | call to function | provenance | |
-| test.cpp:148:10:148:27 | call to function | test.cpp:149:10:149:10 | z | provenance | Sink:MaD:1 |
-| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:78 |
-| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:155:10:155:18 | call to ymlSource | provenance | Src:MaD:35 |
+| test.cpp:148:10:148:27 | call to function | test.cpp:149:10:149:10 | z | provenance | Sink:MaD:3 |
+| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:94 |
+| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:155:10:155:18 | call to ymlSource | provenance | Src:MaD:48 |
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:157:26:157:26 | x | provenance | |
| test.cpp:157:13:157:20 | call to function | test.cpp:157:13:157:20 | call to function | provenance | |
-| test.cpp:157:13:157:20 | call to function | test.cpp:158:10:158:10 | z | provenance | Sink:MaD:1 |
-| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:78 |
+| test.cpp:157:13:157:20 | call to function | test.cpp:158:10:158:10 | z | provenance | Sink:MaD:3 |
+| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:94 |
| test.cpp:164:34:164:34 | x | test.cpp:165:69:165:69 | x | provenance | |
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:164:7:164:7 | *templateFunction3 | provenance | |
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | |
-| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:76 |
-| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:170:10:170:18 | call to ymlSource | provenance | Src:MaD:35 |
+| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:92 |
+| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:170:10:170:18 | call to ymlSource | provenance | Src:MaD:48 |
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:172:51:172:51 | x | provenance | |
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | |
-| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:173:10:173:10 | y | provenance | Sink:MaD:1 |
+| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:173:10:173:10 | y | provenance | Sink:MaD:3 |
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | provenance | |
-| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:76 |
+| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:92 |
| test.cpp:186:2:186:2 | *s [post update] [myField] | test.cpp:187:33:187:34 | *& ... [myField] | provenance | |
| test.cpp:186:2:186:24 | ... = ... | test.cpp:186:2:186:2 | *s [post update] [myField] | provenance | |
-| test.cpp:186:14:186:22 | call to ymlSource | test.cpp:186:2:186:24 | ... = ... | provenance | Src:MaD:35 |
+| test.cpp:186:14:186:22 | call to ymlSource | test.cpp:186:2:186:24 | ... = ... | provenance | Src:MaD:48 |
| test.cpp:187:10:187:31 | call to read_field_from_struct | test.cpp:187:10:187:31 | call to read_field_from_struct | provenance | |
-| test.cpp:187:10:187:31 | call to read_field_from_struct | test.cpp:188:10:188:10 | x | provenance | Sink:MaD:1 |
-| test.cpp:187:33:187:34 | *& ... [myField] | test.cpp:187:10:187:31 | call to read_field_from_struct | provenance | MaD:68 |
+| test.cpp:187:10:187:31 | call to read_field_from_struct | test.cpp:188:10:188:10 | x | provenance | Sink:MaD:3 |
+| test.cpp:187:33:187:34 | *& ... [myField] | test.cpp:187:10:187:31 | call to read_field_from_struct | provenance | MaD:82 |
| test.cpp:199:2:199:2 | *s [post update] [myField] | test.cpp:200:35:200:36 | *& ... [myField] | provenance | |
| test.cpp:199:2:199:24 | ... = ... | test.cpp:199:2:199:2 | *s [post update] [myField] | provenance | |
-| test.cpp:199:14:199:22 | call to ymlSource | test.cpp:199:2:199:24 | ... = ... | provenance | Src:MaD:35 |
+| test.cpp:199:14:199:22 | call to ymlSource | test.cpp:199:2:199:24 | ... = ... | provenance | Src:MaD:48 |
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | test.cpp:200:10:200:33 | call to read_field_from_struct_2 | provenance | |
-| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | test.cpp:201:10:201:10 | x | provenance | Sink:MaD:1 |
-| test.cpp:200:35:200:36 | *& ... [myField] | test.cpp:200:10:200:33 | call to read_field_from_struct_2 | provenance | MaD:69 |
+| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | test.cpp:201:10:201:10 | x | provenance | Sink:MaD:3 |
+| test.cpp:200:35:200:36 | *& ... [myField] | test.cpp:200:10:200:33 | call to read_field_from_struct_2 | provenance | MaD:83 |
| test.cpp:216:3:216:4 | get_ptr output argument [value] | test.cpp:217:11:217:12 | *rf [value] | provenance | |
-| test.cpp:216:3:216:28 | ... = ... | test.cpp:216:3:216:4 | get_ptr output argument [value] | provenance | MaD:75 |
-| test.cpp:216:18:216:26 | call to ymlSource | test.cpp:216:3:216:28 | ... = ... | provenance | Src:MaD:35 |
+| test.cpp:216:3:216:28 | ... = ... | test.cpp:216:3:216:4 | get_ptr output argument [value] | provenance | MaD:91 |
+| test.cpp:216:18:216:26 | call to ymlSource | test.cpp:216:3:216:28 | ... = ... | provenance | Src:MaD:48 |
| test.cpp:217:11:217:12 | *rf [value] | test.cpp:217:14:217:18 | value | provenance | |
| test.cpp:217:14:217:18 | value | test.cpp:217:14:217:18 | value | provenance | |
-| test.cpp:217:14:217:18 | value | test.cpp:218:11:218:11 | x | provenance | Sink:MaD:1 |
+| test.cpp:217:14:217:18 | value | test.cpp:218:11:218:11 | x | provenance | Sink:MaD:3 |
| test.cpp:222:3:222:3 | operator[] output argument | test.cpp:223:12:223:12 | *s | provenance | |
-| test.cpp:222:3:222:20 | ... = ... | test.cpp:222:3:222:3 | operator[] output argument | provenance | MaD:74 |
-| test.cpp:222:10:222:20 | call to ymlSource | test.cpp:222:3:222:20 | ... = ... | provenance | Src:MaD:35 |
-| test.cpp:223:12:223:12 | *s | test.cpp:223:13:223:15 | call to operator[] | provenance | MaD:73 |
+| test.cpp:222:3:222:20 | ... = ... | test.cpp:222:3:222:3 | operator[] output argument | provenance | MaD:90 |
+| test.cpp:222:10:222:18 | call to ymlSource | test.cpp:222:3:222:20 | ... = ... | provenance | Src:MaD:48 |
+| test.cpp:223:12:223:12 | *s | test.cpp:223:13:223:15 | call to operator[] | provenance | MaD:89 |
| test.cpp:223:13:223:15 | call to operator[] | test.cpp:223:13:223:15 | call to operator[] | provenance | |
-| test.cpp:223:13:223:15 | call to operator[] | test.cpp:224:11:224:11 | c | provenance | Sink:MaD:1 |
-| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
+| test.cpp:223:13:223:15 | call to operator[] | test.cpp:224:11:224:11 | c | provenance | Sink:MaD:3 |
+| test.cpp:242:29:242:29 | *s [value] | test.cpp:243:10:243:10 | *s [value] | provenance | |
+| test.cpp:243:10:243:10 | *s [value] | test.cpp:243:13:243:17 | value | provenance | |
+| test.cpp:243:13:243:17 | value | test.cpp:243:13:243:17 | value | provenance | Sink:MaD:3 |
+| test.cpp:247:26:247:39 | call to ymlFieldSource | test.cpp:247:26:247:39 | call to ymlFieldSource [value] | provenance | Src:MaD:47 |
+| test.cpp:247:26:247:39 | call to ymlFieldSource [value] | test.cpp:248:10:248:16 | *wrapper [value] | provenance | |
+| test.cpp:248:10:248:16 | *wrapper [value] | test.cpp:248:18:248:22 | value | provenance | |
+| test.cpp:248:18:248:22 | value | test.cpp:248:18:248:22 | value | provenance | Sink:MaD:3 |
+| test.cpp:250:32:250:32 | source_from_callback_template output argument | test.cpp:250:32:250:32 | source_from_callback_template output argument [value] | provenance | Src:MaD:40 |
+| test.cpp:250:32:250:32 | source_from_callback_template output argument [value] | test.cpp:242:29:242:29 | *s [value] | provenance | |
+| test.cpp:251:27:251:27 | source_from_callback_ptr output argument | test.cpp:251:27:251:27 | source_from_callback_ptr output argument [value] | provenance | Src:MaD:37 |
+| test.cpp:251:27:251:27 | source_from_callback_ptr output argument [value] | test.cpp:242:29:242:29 | *s [value] | provenance | |
+| test.cpp:257:35:257:35 | *s [value] | test.cpp:258:12:258:12 | *s [value] | provenance | |
+| test.cpp:258:12:258:12 | *s [value] | test.cpp:258:15:258:19 | value | provenance | |
+| test.cpp:258:15:258:19 | value | test.cpp:258:15:258:19 | value | provenance | Sink:MaD:3 |
+| test.cpp:262:27:262:31 | source_from_callback_ptr output argument | test.cpp:262:27:262:31 | source_from_callback_ptr output argument [value] | provenance | Src:MaD:37 |
+| test.cpp:262:27:262:31 | source_from_callback_ptr output argument [value] | test.cpp:242:29:242:29 | *s [value] | provenance | |
+| test.cpp:262:27:262:31 | source_from_callback_ptr output argument [value] | test.cpp:257:35:257:35 | *s [value] | provenance | |
+| test.cpp:264:32:266:2 | source_from_callback_template output argument | test.cpp:264:32:266:2 | source_from_callback_template output argument [value] | provenance | Src:MaD:40 |
+| test.cpp:264:32:266:2 | source_from_callback_template output argument [value] | test.cpp:264:56:264:56 | *s [value] | provenance | |
+| test.cpp:264:56:264:56 | *s [value] | test.cpp:265:11:265:11 | *s [value] | provenance | |
+| test.cpp:265:11:265:11 | *s [value] | test.cpp:265:14:265:18 | value | provenance | |
+| test.cpp:265:14:265:18 | value | test.cpp:265:14:265:18 | value | provenance | Sink:MaD:3 |
+| test.cpp:268:27:268:27 | source_from_callback_ptr output argument | test.cpp:268:27:268:27 | source_from_callback_ptr output argument [value] | provenance | Src:MaD:37 |
+| test.cpp:268:27:268:27 | source_from_callback_ptr output argument [value] | test.cpp:268:51:268:51 | *s [value] | provenance | |
+| test.cpp:268:51:268:51 | *s [value] | test.cpp:269:11:269:11 | *s [value] | provenance | |
+| test.cpp:269:11:269:11 | *s [value] | test.cpp:269:14:269:18 | value | provenance | |
+| test.cpp:269:14:269:18 | value | test.cpp:269:14:269:18 | value | provenance | Sink:MaD:3 |
+| test.cpp:273:40:273:40 | *s [value] | test.cpp:274:12:274:12 | *s [value] | provenance | |
+| test.cpp:274:12:274:12 | *s [value] | test.cpp:274:15:274:19 | value | provenance | |
+| test.cpp:274:15:274:19 | value | test.cpp:274:15:274:19 | value | provenance | Sink:MaD:3 |
+| test.cpp:278:32:278:34 | source_from_callback_template output argument | test.cpp:278:32:278:34 | source_from_callback_template output argument [value] | provenance | Src:MaD:40 |
+| test.cpp:278:32:278:34 | source_from_callback_template output argument [value] | test.cpp:273:40:273:40 | *s [value] | provenance | |
+| test.cpp:293:5:293:26 | *callback_returning_int | test.cpp:307:10:307:31 | call to callback_returning_int | provenance | |
+| test.cpp:294:5:294:28 | *callback_returning_int_2 | test.cpp:310:10:310:33 | call to callback_returning_int_2 | provenance | |
+| test.cpp:295:6:295:31 | **callback_returning_ptr_int | test.cpp:313:13:313:38 | *call to callback_returning_ptr_int | provenance | |
+| test.cpp:297:5:297:20 | *return_ymlSource | test.cpp:318:37:318:52 | return_ymlSource | provenance | Sink:MaD:1 |
+| test.cpp:297:33:297:41 | call to ymlSource | test.cpp:297:5:297:20 | *return_ymlSource | provenance | |
+| test.cpp:297:33:297:41 | call to ymlSource | test.cpp:297:5:297:20 | *return_ymlSource | provenance | Src:MaD:48 |
+| test.cpp:297:33:297:41 | call to ymlSource | test.cpp:297:33:297:41 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:299:6:299:28 | **return_ptr_to_ymlSource | test.cpp:321:36:321:58 | return_ptr_to_ymlSource | provenance | Sink:MaD:2 |
+| test.cpp:299:41:299:52 | *call to ymlSourcePtr | test.cpp:299:6:299:28 | **return_ptr_to_ymlSource | provenance | |
+| test.cpp:299:41:299:52 | call to ymlSourcePtr | test.cpp:299:6:299:28 | **return_ptr_to_ymlSource | provenance | Src:MaD:49 |
+| test.cpp:299:41:299:52 | call to ymlSourcePtr | test.cpp:299:41:299:52 | *call to ymlSourcePtr | provenance | Src:MaD:49 |
+| test.cpp:304:11:304:22 | call to ymlSourcePtr | test.cpp:304:10:304:24 | * ... | provenance | Src:MaD:49 Sink:MaD:3 |
+| test.cpp:306:39:306:60 | source_from_callback_return_template output argument | test.cpp:293:5:293:26 | *callback_returning_int | provenance | Src:MaD:39 |
+| test.cpp:307:10:307:31 | call to callback_returning_int | test.cpp:307:10:307:31 | call to callback_returning_int | provenance | Sink:MaD:3 |
+| test.cpp:309:34:309:57 | source_from_callback_return_ptr output argument | test.cpp:294:5:294:28 | *callback_returning_int_2 | provenance | Src:MaD:38 |
+| test.cpp:310:10:310:33 | call to callback_returning_int_2 | test.cpp:310:10:310:33 | call to callback_returning_int_2 | provenance | Sink:MaD:3 |
+| test.cpp:312:38:312:63 | source_ptr_from_callback_return_ptr output argument | test.cpp:295:6:295:31 | **callback_returning_ptr_int | provenance | Src:MaD:41 |
+| test.cpp:313:13:313:38 | *call to callback_returning_ptr_int | test.cpp:313:13:313:38 | *call to callback_returning_ptr_int | provenance | |
+| test.cpp:313:13:313:38 | *call to callback_returning_ptr_int | test.cpp:315:10:315:13 | * ... | provenance | Sink:MaD:3 |
+| test.cpp:317:39:317:39 | *operator() | test.cpp:317:37:317:64 | [...](...){...} | provenance | Sink:MaD:1 |
+| test.cpp:317:51:317:59 | call to ymlSource | test.cpp:317:39:317:39 | *operator() | provenance | |
+| test.cpp:317:51:317:59 | call to ymlSource | test.cpp:317:39:317:39 | *operator() | provenance | Src:MaD:48 |
+| test.cpp:317:51:317:59 | call to ymlSource | test.cpp:317:51:317:59 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:320:38:320:38 | **operator() | test.cpp:320:36:320:36 | call to operator int *(*)() | provenance | Sink:MaD:2 |
+| test.cpp:320:50:320:61 | *call to ymlSourcePtr | test.cpp:320:38:320:38 | **operator() | provenance | |
+| test.cpp:320:50:320:61 | call to ymlSourcePtr | test.cpp:320:38:320:38 | **operator() | provenance | Src:MaD:49 |
+| test.cpp:320:50:320:61 | call to ymlSourcePtr | test.cpp:320:50:320:61 | *call to ymlSourcePtr | provenance | Src:MaD:49 |
+| test.cpp:324:36:324:36 | p | test.cpp:325:10:325:10 | *p [value] | provenance | Src:MaD:43 |
+| test.cpp:324:36:324:36 | p | test.cpp:327:11:327:11 | *p [*pointer] | provenance | Src:MaD:42 |
+| test.cpp:324:53:324:53 | s | test.cpp:329:10:329:10 | *s [value] | provenance | Src:MaD:46 |
+| test.cpp:324:53:324:53 | s | test.cpp:331:11:331:11 | *s [*pointer] | provenance | Src:MaD:45 |
+| test.cpp:324:61:324:66 | source | test.cpp:334:10:334:16 | * ... | provenance | Src:MaD:44 Sink:MaD:3 |
+| test.cpp:325:10:325:10 | *p [value] | test.cpp:325:13:325:17 | value | provenance | |
+| test.cpp:325:13:325:17 | value | test.cpp:325:13:325:17 | value | provenance | Sink:MaD:3 |
+| test.cpp:327:10:327:20 | * ... | test.cpp:327:10:327:20 | * ... | provenance | Sink:MaD:3 |
+| test.cpp:327:11:327:11 | *p [*pointer] | test.cpp:327:10:327:20 | * ... | provenance | |
+| test.cpp:329:10:329:10 | *s [value] | test.cpp:329:12:329:16 | value | provenance | |
+| test.cpp:329:12:329:16 | value | test.cpp:329:12:329:16 | value | provenance | Sink:MaD:3 |
+| test.cpp:331:10:331:19 | * ... | test.cpp:331:10:331:19 | * ... | provenance | Sink:MaD:3 |
+| test.cpp:331:11:331:11 | *s [*pointer] | test.cpp:331:10:331:19 | * ... | provenance | |
+| test.cpp:341:30:341:32 | arg | test.cpp:342:5:342:17 | ... = ... | provenance | |
+| test.cpp:342:5:342:8 | *this [post update] [s] | test.cpp:341:3:341:22 | *this [Return] [s] | provenance | |
+| test.cpp:342:5:342:17 | ... = ... | test.cpp:342:5:342:8 | *this [post update] [s] | provenance | |
+| test.cpp:345:38:345:40 | arg | test.cpp:346:5:346:18 | ... = ... | provenance | |
+| test.cpp:346:5:346:8 | *this [post update] [ul] | test.cpp:345:3:345:22 | *this [Return] [ul] | provenance | |
+| test.cpp:346:5:346:18 | ... = ... | test.cpp:346:5:346:8 | *this [post update] [ul] | provenance | |
+| test.cpp:362:15:362:23 | call to ymlSource | test.cpp:362:15:362:25 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:362:15:362:25 | call to ymlSource | test.cpp:363:15:363:15 | *x | provenance | |
+| test.cpp:363:5:363:5 | forward output argument [s] | test.cpp:365:30:365:30 | *f [s] | provenance | |
+| test.cpp:363:5:363:5 | forward output argument [ul] | test.cpp:365:30:365:30 | *f [ul] | provenance | |
+| test.cpp:363:15:363:15 | *x | test.cpp:341:30:341:32 | arg | provenance | |
+| test.cpp:363:15:363:15 | *x | test.cpp:345:38:345:40 | arg | provenance | |
+| test.cpp:363:15:363:15 | *x | test.cpp:363:5:363:5 | forward output argument [s] | provenance | |
+| test.cpp:363:15:363:15 | *x | test.cpp:363:5:363:5 | forward output argument [ul] | provenance | |
+| test.cpp:365:30:365:30 | *f [s] | test.cpp:365:32:365:34 | call to get [s] | provenance | MaD:88 |
+| test.cpp:365:30:365:30 | *f [ul] | test.cpp:365:32:365:34 | call to get [ul] | provenance | MaD:88 |
+| test.cpp:365:32:365:34 | call to get [s] | test.cpp:365:32:365:34 | call to get [s] | provenance | |
+| test.cpp:365:32:365:34 | call to get [s] | test.cpp:366:13:366:13 | *c [s] | provenance | |
+| test.cpp:365:32:365:34 | call to get [ul] | test.cpp:365:32:365:34 | call to get [ul] | provenance | |
+| test.cpp:365:32:365:34 | call to get [ul] | test.cpp:367:13:367:13 | *c [ul] | provenance | |
+| test.cpp:366:13:366:13 | *c [s] | test.cpp:366:13:366:15 | s | provenance | |
+| test.cpp:366:13:366:13 | *c [s] | test.cpp:366:15:366:15 | s | provenance | Sink:MaD:3 |
+| test.cpp:366:13:366:15 | s | test.cpp:366:15:366:15 | s | provenance | Sink:MaD:3 |
+| test.cpp:367:13:367:13 | *c [ul] | test.cpp:367:13:367:16 | ul | provenance | |
+| test.cpp:367:13:367:13 | *c [ul] | test.cpp:367:15:367:16 | ul | provenance | Sink:MaD:3 |
+| test.cpp:367:13:367:16 | ul | test.cpp:367:15:367:16 | ul | provenance | Sink:MaD:3 |
+| test.cpp:371:24:371:32 | call to ymlSource | test.cpp:371:24:371:34 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:371:24:371:34 | call to ymlSource | test.cpp:372:15:372:16 | *ul | provenance | |
+| test.cpp:372:5:372:5 | forward output argument [s] | test.cpp:374:30:374:30 | *f [s] | provenance | |
+| test.cpp:372:5:372:5 | forward output argument [ul] | test.cpp:374:30:374:30 | *f [ul] | provenance | |
+| test.cpp:372:15:372:16 | *ul | test.cpp:341:30:341:32 | arg | provenance | |
+| test.cpp:372:15:372:16 | *ul | test.cpp:345:38:345:40 | arg | provenance | |
+| test.cpp:372:15:372:16 | *ul | test.cpp:372:5:372:5 | forward output argument [s] | provenance | |
+| test.cpp:372:15:372:16 | *ul | test.cpp:372:5:372:5 | forward output argument [ul] | provenance | |
+| test.cpp:374:30:374:30 | *f [s] | test.cpp:374:32:374:34 | call to get [s] | provenance | MaD:88 |
+| test.cpp:374:30:374:30 | *f [ul] | test.cpp:374:32:374:34 | call to get [ul] | provenance | MaD:88 |
+| test.cpp:374:32:374:34 | call to get [s] | test.cpp:374:32:374:34 | call to get [s] | provenance | |
+| test.cpp:374:32:374:34 | call to get [s] | test.cpp:375:13:375:13 | *c [s] | provenance | |
+| test.cpp:374:32:374:34 | call to get [ul] | test.cpp:374:32:374:34 | call to get [ul] | provenance | |
+| test.cpp:374:32:374:34 | call to get [ul] | test.cpp:376:13:376:13 | *c [ul] | provenance | |
+| test.cpp:375:13:375:13 | *c [s] | test.cpp:375:13:375:15 | s | provenance | |
+| test.cpp:375:13:375:13 | *c [s] | test.cpp:375:15:375:15 | s | provenance | Sink:MaD:3 |
+| test.cpp:375:13:375:15 | s | test.cpp:375:15:375:15 | s | provenance | Sink:MaD:3 |
+| test.cpp:376:13:376:13 | *c [ul] | test.cpp:376:13:376:16 | ul | provenance | |
+| test.cpp:376:13:376:13 | *c [ul] | test.cpp:376:15:376:16 | ul | provenance | Sink:MaD:3 |
+| test.cpp:376:13:376:16 | ul | test.cpp:376:15:376:16 | ul | provenance | Sink:MaD:3 |
+| test.cpp:398:11:398:19 | call to ymlSource | test.cpp:398:11:398:19 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:398:11:398:19 | call to ymlSource | test.cpp:399:38:399:38 | x | provenance | |
+| test.cpp:399:15:399:36 | call to makeForwarded [x] | test.cpp:399:15:399:36 | call to makeForwarded [x] | provenance | |
+| test.cpp:399:15:399:36 | call to makeForwarded [x] | test.cpp:400:11:400:11 | *e [x] | provenance | |
+| test.cpp:399:38:399:38 | x | test.cpp:399:15:399:36 | call to makeForwarded [x] | provenance | |
+| test.cpp:400:11:400:11 | *e [x] | test.cpp:400:13:400:13 | x | provenance | |
+| test.cpp:400:13:400:13 | x | test.cpp:400:13:400:13 | x | provenance | Sink:MaD:3 |
+| test.cpp:405:11:405:19 | call to ymlSource | test.cpp:405:11:405:19 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:405:11:405:19 | call to ymlSource | test.cpp:406:22:406:22 | x | provenance | |
+| test.cpp:406:3:406:3 | forwardToElement output argument [x] | test.cpp:407:15:407:15 | *f [x] | provenance | |
+| test.cpp:406:22:406:22 | x | test.cpp:406:3:406:3 | forwardToElement output argument [x] | provenance | |
+| test.cpp:407:15:407:15 | *f [x] | test.cpp:407:17:407:19 | call to get [x] | provenance | MaD:88 |
+| test.cpp:407:17:407:19 | call to get [x] | test.cpp:407:17:407:19 | call to get [x] | provenance | |
+| test.cpp:407:17:407:19 | call to get [x] | test.cpp:408:11:408:11 | *e [x] | provenance | |
+| test.cpp:408:11:408:11 | *e [x] | test.cpp:408:13:408:13 | x | provenance | |
+| test.cpp:408:13:408:13 | x | test.cpp:408:13:408:13 | x | provenance | Sink:MaD:3 |
+| test.cpp:413:11:413:19 | call to ymlSource | test.cpp:413:11:413:19 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:413:11:413:19 | call to ymlSource | test.cpp:414:16:414:16 | *x | provenance | |
+| test.cpp:414:3:414:3 | emplace output argument [element, x] | test.cpp:416:15:416:15 | *c [element, x] | provenance | |
+| test.cpp:414:16:414:16 | *x | test.cpp:414:3:414:3 | emplace output argument [element, x] | provenance | |
+| test.cpp:416:15:416:15 | *c [element, x] | test.cpp:416:20:416:22 | call to get [x] | provenance | MaD:87 |
+| test.cpp:416:20:416:22 | call to get [x] | test.cpp:416:20:416:22 | call to get [x] | provenance | |
+| test.cpp:416:20:416:22 | call to get [x] | test.cpp:417:11:417:11 | *e [x] | provenance | |
+| test.cpp:417:11:417:11 | *e [x] | test.cpp:417:13:417:13 | x | provenance | |
+| test.cpp:417:13:417:13 | x | test.cpp:417:13:417:13 | x | provenance | Sink:MaD:3 |
+| test.cpp:422:3:422:8 | emplace output argument [element] | test.cpp:423:11:423:16 | *scalar [element] | provenance | |
+| test.cpp:422:21:422:29 | call to ymlSource | test.cpp:422:21:422:29 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:422:21:422:29 | call to ymlSource | test.cpp:422:21:422:31 | call to ymlSource | provenance | |
+| test.cpp:422:21:422:31 | call to ymlSource | test.cpp:422:3:422:8 | emplace output argument [element] | provenance | |
+| test.cpp:423:11:423:16 | *scalar [element] | test.cpp:423:21:423:23 | call to get | provenance | MaD:87 |
+| test.cpp:423:21:423:23 | call to get | test.cpp:423:18:423:20 | call to get | provenance | Sink:MaD:3 |
+| test.cpp:426:3:426:9 | emplace output argument [element] | test.cpp:427:12:427:18 | *pointer [element] | provenance | |
+| test.cpp:426:22:426:33 | *call to ymlSourcePtr | test.cpp:426:22:426:35 | **call to ymlSourcePtr | provenance | |
+| test.cpp:426:22:426:33 | call to ymlSourcePtr | test.cpp:426:22:426:33 | *call to ymlSourcePtr | provenance | Src:MaD:49 |
+| test.cpp:426:22:426:35 | **call to ymlSourcePtr | test.cpp:426:3:426:9 | emplace output argument [element] | provenance | |
+| test.cpp:427:12:427:18 | *pointer [element] | test.cpp:427:11:427:24 | * ... | provenance | MaD:87 Sink:MaD:3 |
+| test.cpp:437:11:437:19 | call to ymlSource | test.cpp:437:11:437:19 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:437:11:437:19 | call to ymlSource | test.cpp:438:16:438:16 | *x | provenance | |
+| test.cpp:438:3:438:3 | emplace output argument [element, x] | test.cpp:440:34:440:34 | *c [element, x] | provenance | |
+| test.cpp:438:16:438:16 | *x | test.cpp:438:3:438:3 | emplace output argument [element, x] | provenance | |
+| test.cpp:440:34:440:34 | *c [element, x] | test.cpp:440:39:440:41 | call to get [x] | provenance | MaD:87 |
+| test.cpp:440:39:440:41 | call to get [x] | test.cpp:440:39:440:41 | call to get [x] | provenance | |
+| test.cpp:440:39:440:41 | call to get [x] | test.cpp:441:11:441:11 | *e [x] | provenance | |
+| test.cpp:441:11:441:11 | *e [x] | test.cpp:441:13:441:13 | x | provenance | |
+| test.cpp:441:13:441:13 | x | test.cpp:441:13:441:13 | x | provenance | Sink:MaD:3 |
+| test.cpp:446:3:446:28 | *ElementWithOverloadedArity [post update] [x] | test.cpp:446:3:446:28 | *this [Return] [x] | provenance | |
+| test.cpp:446:34:446:38 | first | test.cpp:446:45:446:49 | first | provenance | |
+| test.cpp:446:45:446:49 | first | test.cpp:446:3:446:28 | *ElementWithOverloadedArity [post update] [x] | provenance | |
+| test.cpp:447:3:447:28 | *ElementWithOverloadedArity [post update] [x] | test.cpp:447:3:447:28 | *this [Return] [x] | provenance | |
+| test.cpp:447:39:447:44 | second | test.cpp:447:51:447:56 | second | provenance | |
+| test.cpp:447:51:447:56 | second | test.cpp:447:3:447:28 | *ElementWithOverloadedArity [post update] [x] | provenance | |
+| test.cpp:451:11:451:19 | call to ymlSource | test.cpp:451:11:451:19 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:451:11:451:19 | call to ymlSource | test.cpp:454:18:454:18 | *x | provenance | |
+| test.cpp:451:11:451:19 | call to ymlSource | test.cpp:464:21:464:21 | *x | provenance | |
+| test.cpp:454:5:454:5 | emplace output argument [element, x] | test.cpp:455:13:455:13 | *c [element, x] | provenance | |
+| test.cpp:454:18:454:18 | *x | test.cpp:446:34:446:38 | first | provenance | |
+| test.cpp:454:18:454:18 | *x | test.cpp:454:5:454:5 | emplace output argument [element, x] | provenance | |
+| test.cpp:455:13:455:13 | *c [element, x] | test.cpp:455:18:455:20 | *call to get [x] | provenance | MaD:87 |
+| test.cpp:455:18:455:20 | *call to get [x] | test.cpp:455:21:455:21 | x | provenance | |
+| test.cpp:455:21:455:21 | x | test.cpp:455:21:455:21 | x | provenance | Sink:MaD:3 |
+| test.cpp:464:5:464:5 | emplace output argument [element, x] | test.cpp:465:13:465:13 | *c [element, x] | provenance | |
+| test.cpp:464:21:464:21 | *x | test.cpp:447:39:447:44 | second | provenance | |
+| test.cpp:464:21:464:21 | *x | test.cpp:464:5:464:5 | emplace output argument [element, x] | provenance | |
+| test.cpp:465:13:465:13 | *c [element, x] | test.cpp:465:18:465:20 | *call to get [x] | provenance | MaD:87 |
+| test.cpp:465:18:465:20 | *call to get [x] | test.cpp:465:21:465:21 | x | provenance | |
+| test.cpp:465:21:465:21 | x | test.cpp:465:21:465:21 | x | provenance | Sink:MaD:3 |
+| test.cpp:472:5:472:5 | forward output argument | test.cpp:473:13:473:13 | *f | provenance | |
+| test.cpp:472:15:472:23 | call to ymlSource | test.cpp:472:15:472:23 | call to ymlSource | provenance | Src:MaD:48 |
+| test.cpp:472:15:472:23 | call to ymlSource | test.cpp:472:15:472:25 | call to ymlSource | provenance | |
+| test.cpp:472:15:472:25 | call to ymlSource | test.cpp:472:5:472:5 | forward output argument | provenance | |
+| test.cpp:473:13:473:13 | *f | test.cpp:473:15:473:17 | call to get | provenance | MaD:88 |
+| test.cpp:473:15:473:17 | call to get | test.cpp:473:15:473:17 | call to get | provenance | Sink:MaD:3 |
+| test.cpp:477:5:477:5 | forward output argument | test.cpp:478:14:478:14 | *f | provenance | |
+| test.cpp:477:15:477:26 | *call to ymlSourcePtr | test.cpp:477:15:477:28 | **call to ymlSourcePtr | provenance | |
+| test.cpp:477:15:477:26 | call to ymlSourcePtr | test.cpp:477:15:477:26 | *call to ymlSourcePtr | provenance | Src:MaD:49 |
+| test.cpp:477:15:477:28 | **call to ymlSourcePtr | test.cpp:477:5:477:5 | forward output argument | provenance | |
+| test.cpp:478:14:478:14 | *f | test.cpp:478:13:478:20 | * ... | provenance | MaD:88 Sink: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:22:15:22:29 | call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:5 |
| 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:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:45 |
-| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:4 |
+| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:59 |
| 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:34:17:34:38 | call to GetEnvironmentStringsA | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:6 |
+| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | windows.cpp:41:10:41:13 | * ... | provenance | Src:MaD:7 |
| windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | windows.cpp:149:42:149:53 | *lpOverlapped [*hEvent] | provenance | |
| windows.cpp:149:18:149:62 | *hEvent | windows.cpp:149:18:149:62 | *hEvent | provenance | |
| windows.cpp:149:18:149:62 | *hEvent | windows.cpp:151:8:151:14 | * ... | provenance | |
@@ -245,37 +1488,37 @@ 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: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:168:35:168:40 | ReadFile output argument | windows.cpp:170:10:170:16 | * ... | provenance | Src:MaD:19 |
+| windows.cpp:177:23:177:28 | ReadFileEx output argument | windows.cpp:179:10:179:16 | * ... | provenance | Src:MaD:20 |
+| windows.cpp:189:21:189:26 | ReadFile output argument | windows.cpp:190:5:190:56 | *... = ... | provenance | Src:MaD:19 |
| 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:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | MaD:52 |
-| windows.cpp:198:21:198:26 | ReadFile output argument | windows.cpp:199:5:199:57 | ... = ... | provenance | Src:MaD:17 |
+| windows.cpp:192:53:192:63 | *& ... [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | MaD:66 |
+| windows.cpp:198:21:198:26 | ReadFile output argument | windows.cpp:199:5:199:57 | ... = ... | provenance | Src:MaD:19 |
| 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:157:16:157:27 | *lpOverlapped [hEvent] | provenance | MaD:52 |
-| 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:201:53:201:63 | *& ... [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | MaD:66 |
+| windows.cpp:209:84:209:89 | NtReadFile output argument | windows.cpp:211:10:211:16 | * ... | provenance | Src:MaD:18 |
| windows.cpp:286:23:286:35 | *call to MapViewOfFile | windows.cpp:287:20:287:52 | *pMapView | provenance | |
+| windows.cpp:286:23:286:35 | call to MapViewOfFile | windows.cpp:286:23:286:35 | *call to MapViewOfFile | provenance | Src:MaD:14 |
| 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:9 |
| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | windows.cpp:294:20:294:52 | *pMapView | provenance | |
+| windows.cpp:293:23:293:36 | call to MapViewOfFile2 | windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | provenance | Src:MaD:11 |
| 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:10 |
| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | windows.cpp:303:20:303:52 | *pMapView | provenance | |
+| windows.cpp:302:23:302:36 | call to MapViewOfFile3 | windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | provenance | Src:MaD:12 |
| 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:11 |
| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | windows.cpp:312:20:312:52 | *pMapView | provenance | |
+| windows.cpp:311:23:311:43 | call to MapViewOfFile3FromApp | windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | provenance | Src:MaD:13 |
| 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:13 |
| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | windows.cpp:319:20:319:52 | *pMapView | provenance | |
+| windows.cpp:318:23:318:37 | call to MapViewOfFileEx | windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | provenance | Src:MaD:15 |
| 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:14 |
| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | windows.cpp:326:20:326:52 | *pMapView | provenance | |
+| windows.cpp:325:23:325:42 | call to MapViewOfFileFromApp | windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | provenance | Src:MaD:16 |
| 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:15 |
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:333:20:333:52 | *pMapView | provenance | |
+| windows.cpp:332:23:332:40 | call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:17 |
| windows.cpp:333:20:333:52 | *pMapView | windows.cpp:335:10:335:16 | * ... | 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 | |
@@ -291,9 +1534,9 @@ edges
| windows.cpp:431:3:431:3 | *s [post update] [x] | windows.cpp:464:7:464:8 | *& ... [x] | provenance | |
| windows.cpp:431:3:431:16 | ... = ... | windows.cpp:431:3:431:3 | *s [post update] [x] | provenance | |
| windows.cpp:431:9:431:14 | call to source | windows.cpp:431:3:431:16 | ... = ... | provenance | |
-| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | MaD:48 |
-| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | MaD:46 |
-| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | MaD:47 |
+| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | MaD:62 |
+| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | MaD:60 |
+| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | MaD:61 |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:533:11:533:16 | call to source | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:537:40:537:41 | *& ... | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:542:38:542:39 | *& ... | provenance | |
@@ -302,158 +1545,1094 @@ edges
| windows.cpp:533:11:533:16 | call to source | windows.cpp:568:32:568:33 | *& ... | provenance | |
| 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:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:57 |
+| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:71 |
| 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:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:53 |
+| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:67 |
| 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:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:54 |
+| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:68 |
| 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:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:55 |
+| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:69 |
| 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:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:58 |
+| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:72 |
| 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:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:56 |
+| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:70 |
| 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:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:59 |
+| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:73 |
| 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:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:60 |
-| windows.cpp:645:45:645:50 | WinHttpReadData output argument | windows.cpp:647:10:647:16 | * ... | provenance | Src:MaD:33 |
-| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | windows.cpp:654:10:654:16 | * ... | provenance | Src:MaD:34 |
-| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | windows.cpp:661:10:661:16 | * ... | provenance | Src:MaD:29 |
-| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | windows.cpp:673:10:673:29 | * ... | provenance | Src:MaD:31 |
-| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | windows.cpp:671:10:671:16 | * ... | provenance | Src:MaD:32 |
-| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | windows.cpp:675:10:675:27 | * ... | provenance | Src:MaD:30 |
+| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:74 |
+| windows.cpp:645:45:645:50 | WinHttpReadData output argument | windows.cpp:647:10:647:16 | * ... | provenance | Src:MaD:35 |
+| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | windows.cpp:654:10:654:16 | * ... | provenance | Src:MaD:36 |
+| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | windows.cpp:661:10:661:16 | * ... | provenance | Src:MaD:31 |
+| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | windows.cpp:673:10:673:29 | * ... | provenance | Src:MaD:33 |
+| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | windows.cpp:671:10:671:16 | * ... | provenance | Src:MaD:34 |
+| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | windows.cpp:675:10:675:27 | * ... | provenance | Src:MaD:32 |
| 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:729:44:729:57 | WinHttpCrackUrl output argument | provenance | MaD:64 |
+| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | provenance | MaD:78 |
| 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:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:901:15:901:53 | *& ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:905:10:905:31 | * ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:907:10:907:42 | * ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:909:10:909:57 | * ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:911:10:911:60 | * ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:912:54:912:63 | FileHandle | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:914:10:914:70 | * ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:916:10:916:72 | * ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:918:10:918:64 | * ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:920:10:920:51 | * ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:922:10:922:52 | * ... | provenance | Src:MaD:9 |
+| windows.cpp:900:64:900:77 | HttpReceiveHttpRequest output argument | windows.cpp:924:10:924:63 | * ... | provenance | Src:MaD:9 |
| 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:929:70:929:75 | HttpReceiveRequestEntityBody output argument | windows.cpp:931:10:931:16 | * ... | provenance | Src:MaD:10 |
+| windows.cpp:936:70:936:78 | HttpReceiveClientCertificate output argument | windows.cpp:937:15:937:48 | *& ... | provenance | Src:MaD:8 |
+| windows.cpp:936:70:936:78 | HttpReceiveClientCertificate output argument | windows.cpp:941:10:941:31 | * ... | provenance | Src:MaD:8 |
| windows.cpp:937:15:937:48 | *& ... | windows.cpp:939:10:939:11 | * ... | provenance | |
-| windows.cpp:1009:35:1009:38 | RegQueryValueA output argument | windows.cpp:1011:10:1011:14 | * ... | provenance | Src:MaD:25 |
-| windows.cpp:1016:36:1016:39 | RegQueryValueW output argument | windows.cpp:1018:10:1018:14 | * ... | provenance | Src:MaD:28 |
-| windows.cpp:1024:53:1024:56 | RegQueryValueExA output argument | windows.cpp:1026:10:1026:14 | * ... | provenance | Src:MaD:26 |
-| windows.cpp:1032:54:1032:57 | RegQueryValueExW output argument | windows.cpp:1034:10:1034:14 | * ... | provenance | Src:MaD:27 |
-| windows.cpp:1040:46:1040:49 | RegQueryMultipleValuesA output argument | windows.cpp:1042:10:1042:14 | * ... | provenance | Src:MaD:23 |
-| windows.cpp:1048:46:1048:49 | RegQueryMultipleValuesW output argument | windows.cpp:1050:10:1050:14 | * ... | provenance | Src:MaD:24 |
-| windows.cpp:1056:53:1056:56 | RegGetValueA output argument | windows.cpp:1058:10:1058:14 | * ... | provenance | Src:MaD:21 |
-| windows.cpp:1065:55:1065:58 | RegGetValueW output argument | windows.cpp:1067:10:1067:14 | * ... | provenance | Src:MaD:22 |
-| windows.cpp:1075:28:1075:36 | RegEnumValueA output argument | windows.cpp:1079:10:1079:19 | * ... | provenance | Src:MaD:19 |
-| windows.cpp:1075:71:1075:74 | RegEnumValueA output argument | windows.cpp:1077:10:1077:14 | * ... | provenance | Src:MaD:19 |
-| windows.cpp:1087:28:1087:36 | RegEnumValueW output argument | windows.cpp:1091:10:1091:19 | * ... | provenance | Src:MaD:20 |
-| windows.cpp:1087:71:1087:74 | RegEnumValueW output argument | windows.cpp:1089:10:1089:14 | * ... | provenance | Src:MaD:20 |
+| windows.cpp:1009:35:1009:38 | RegQueryValueA output argument | windows.cpp:1011:10:1011:14 | * ... | provenance | Src:MaD:27 |
+| windows.cpp:1016:36:1016:39 | RegQueryValueW output argument | windows.cpp:1018:10:1018:14 | * ... | provenance | Src:MaD:30 |
+| windows.cpp:1024:53:1024:56 | RegQueryValueExA output argument | windows.cpp:1026:10:1026:14 | * ... | provenance | Src:MaD:28 |
+| windows.cpp:1032:54:1032:57 | RegQueryValueExW output argument | windows.cpp:1034:10:1034:14 | * ... | provenance | Src:MaD:29 |
+| windows.cpp:1040:46:1040:49 | RegQueryMultipleValuesA output argument | windows.cpp:1042:10:1042:14 | * ... | provenance | Src:MaD:25 |
+| windows.cpp:1048:46:1048:49 | RegQueryMultipleValuesW output argument | windows.cpp:1050:10:1050:14 | * ... | provenance | Src:MaD:26 |
+| windows.cpp:1056:53:1056:56 | RegGetValueA output argument | windows.cpp:1058:10:1058:14 | * ... | provenance | Src:MaD:23 |
+| windows.cpp:1065:55:1065:58 | RegGetValueW output argument | windows.cpp:1067:10:1067:14 | * ... | provenance | Src:MaD:24 |
+| windows.cpp:1075:28:1075:36 | RegEnumValueA output argument | windows.cpp:1079:10:1079:19 | * ... | provenance | Src:MaD:21 |
+| windows.cpp:1075:71:1075:74 | RegEnumValueA output argument | windows.cpp:1077:10:1077:14 | * ... | provenance | Src:MaD:21 |
+| windows.cpp:1087:28:1087:36 | RegEnumValueW output argument | windows.cpp:1091:10:1091:19 | * ... | provenance | Src:MaD:22 |
+| windows.cpp:1087:71:1087:74 | RegEnumValueW output argument | windows.cpp:1089:10:1089:14 | * ... | provenance | Src:MaD:22 |
| windows.cpp:1122:5:1122:27 | ... = ... | windows.cpp:1124:19:1124:21 | *str | provenance | |
| windows.cpp:1122:14:1122:27 | call to source | windows.cpp:1122:5:1122:27 | ... = ... | provenance | |
-| windows.cpp:1124:19:1124:21 | *str | windows.cpp:1124:24:1124:27 | IIDFromString output argument | provenance | MaD:50 |
+| windows.cpp:1124:19:1124:21 | *str | windows.cpp:1124:24:1124:27 | IIDFromString output argument | provenance | MaD:64 |
| windows.cpp:1124:24:1124:27 | IIDFromString output argument | windows.cpp:1125:10:1125:12 | iid | provenance | |
| windows.cpp:1128:15:1128:20 | call to source | windows.cpp:1128:15:1128:20 | call to source | provenance | |
| windows.cpp:1128:15:1128:20 | call to source | windows.cpp:1130:19:1130:21 | *iid | provenance | |
-| windows.cpp:1130:19:1130:21 | *iid | windows.cpp:1130:24:1130:27 | StringFromIID output argument | provenance | MaD:63 |
+| windows.cpp:1130:19:1130:21 | *iid | windows.cpp:1130:24:1130:27 | StringFromIID output argument | provenance | MaD:77 |
| windows.cpp:1130:24:1130:27 | StringFromIID output argument | windows.cpp:1132:10:1132:13 | * ... | provenance | |
| windows.cpp:1135:19:1135:24 | call to source | windows.cpp:1135:19:1135:24 | call to source | provenance | |
| windows.cpp:1135:19:1135:24 | call to source | windows.cpp:1137:21:1137:25 | *clsid | provenance | |
-| windows.cpp:1137:21:1137:25 | *clsid | windows.cpp:1137:28:1137:31 | ProgIDFromCLSID output argument | provenance | MaD:51 |
+| windows.cpp:1137:21:1137:25 | *clsid | windows.cpp:1137:28:1137:31 | ProgIDFromCLSID output argument | provenance | MaD:65 |
| windows.cpp:1137:28:1137:31 | ProgIDFromCLSID output argument | windows.cpp:1139:10:1139:13 | * ... | provenance | |
| windows.cpp:1143:5:1143:30 | ... = ... | windows.cpp:1145:21:1145:26 | *progID | provenance | |
| windows.cpp:1143:17:1143:30 | call to source | windows.cpp:1143:5:1143:30 | ... = ... | provenance | |
-| windows.cpp:1145:21:1145:26 | *progID | windows.cpp:1145:29:1145:34 | CLSIDFromProgID output argument | provenance | MaD:43 |
+| windows.cpp:1145:21:1145:26 | *progID | windows.cpp:1145:29:1145:34 | CLSIDFromProgID output argument | provenance | MaD:57 |
| windows.cpp:1145:29:1145:34 | CLSIDFromProgID output argument | windows.cpp:1146:10:1146:14 | clsid | provenance | |
| windows.cpp:1150:5:1150:27 | ... = ... | windows.cpp:1152:21:1152:23 | *str | provenance | |
| windows.cpp:1150:14:1150:27 | call to source | windows.cpp:1150:5:1150:27 | ... = ... | provenance | |
-| windows.cpp:1152:21:1152:23 | *str | windows.cpp:1152:26:1152:31 | CLSIDFromString output argument | provenance | MaD:44 |
+| windows.cpp:1152:21:1152:23 | *str | windows.cpp:1152:26:1152:31 | CLSIDFromString output argument | provenance | MaD:58 |
| windows.cpp:1152:26:1152:31 | CLSIDFromString output argument | windows.cpp:1153:10:1153:14 | clsid | provenance | |
| windows.cpp:1156:19:1156:24 | call to source | windows.cpp:1156:19:1156:24 | call to source | provenance | |
| windows.cpp:1156:19:1156:24 | call to source | windows.cpp:1158:21:1158:25 | *clsid | provenance | |
-| windows.cpp:1158:21:1158:25 | *clsid | windows.cpp:1158:28:1158:31 | StringFromCLSID output argument | provenance | MaD:61 |
+| windows.cpp:1158:21:1158:25 | *clsid | windows.cpp:1158:28:1158:31 | StringFromCLSID output argument | provenance | MaD:75 |
| windows.cpp:1158:28:1158:31 | StringFromCLSID output argument | windows.cpp:1160:10:1160:13 | * ... | provenance | |
| windows.cpp:1164:5:1164:27 | ... = ... | windows.cpp:1166:20:1166:22 | *str | provenance | |
| windows.cpp:1164:14:1164:27 | call to source | windows.cpp:1164:5:1164:27 | ... = ... | provenance | |
-| windows.cpp:1166:20:1166:22 | *str | windows.cpp:1166:25:1166:29 | GUIDFromString output argument | provenance | MaD:49 |
+| windows.cpp:1166:20:1166:22 | *str | windows.cpp:1166:25:1166:29 | GUIDFromString output argument | provenance | MaD:63 |
| windows.cpp:1166:25:1166:29 | GUIDFromString output argument | windows.cpp:1167:10:1167:13 | guid | provenance | |
| windows.cpp:1170:17:1170:22 | call to source | windows.cpp:1170:17:1170:22 | call to source | provenance | |
| windows.cpp:1170:17:1170:22 | call to source | windows.cpp:1172:21:1172:24 | *guid | provenance | |
-| windows.cpp:1172:21:1172:24 | *guid | windows.cpp:1172:27:1172:29 | StringFromGUID2 output argument | provenance | MaD:62 |
+| windows.cpp:1172:21:1172:24 | *guid | windows.cpp:1172:27:1172:29 | StringFromGUID2 output argument | provenance | MaD:76 |
| windows.cpp:1172:27:1172:29 | StringFromGUID2 output argument | windows.cpp:1174:10:1174:13 | * ... | provenance | |
nodes
-| asio_streams.cpp:87:34:87:44 | read_until output argument | semmle.label | read_until output argument |
-| asio_streams.cpp:91:7:91:17 | recv_buffer | semmle.label | recv_buffer |
-| asio_streams.cpp:93:29:93:39 | *recv_buffer | semmle.label | *recv_buffer |
-| asio_streams.cpp:97:37:97:44 | call to source | semmle.label | call to source |
-| asio_streams.cpp:98:7:98:14 | send_str | semmle.label | send_str |
-| asio_streams.cpp:100:44:100:62 | call to buffer | semmle.label | call to buffer |
-| asio_streams.cpp:100:44:100:62 | call to buffer | semmle.label | call to buffer |
-| asio_streams.cpp:100:64:100:71 | *send_str | semmle.label | *send_str |
-| asio_streams.cpp:101:7:101:17 | send_buffer | semmle.label | send_buffer |
-| asio_streams.cpp:103:29:103:39 | *send_buffer | semmle.label | *send_buffer |
-| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
-| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
-| azure.cpp:257:5:257:8 | *resp | semmle.label | *resp |
-| azure.cpp:257:16:257:21 | Read output argument | semmle.label | Read output argument |
-| azure.cpp:258:10:258:16 | * ... | semmle.label | * ... |
-| azure.cpp:262:5:262:8 | *resp | semmle.label | *resp |
-| azure.cpp:262:23:262:28 | ReadToCount output argument | semmle.label | ReadToCount output argument |
-| azure.cpp:263:10:263:16 | * ... | semmle.label | * ... |
-| azure.cpp:266:38:266:41 | *resp | semmle.label | *resp |
-| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
-| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
-| azure.cpp:267:10:267:12 | vec | semmle.label | vec |
-| azure.cpp:267:10:267:12 | vec [element] | semmle.label | vec [element] |
-| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
-| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
-| azure.cpp:274:10:274:29 | call to operator[] | semmle.label | call to operator[] |
-| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
-| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
-| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
-| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
-| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
-| azure.cpp:278:10:278:13 | body | semmle.label | body |
-| azure.cpp:278:10:278:13 | body | semmle.label | body |
-| azure.cpp:278:10:278:13 | body | semmle.label | body |
-| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
-| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
-| azure.cpp:282:10:282:38 | call to ReadToEnd | semmle.label | call to ReadToEnd |
-| azure.cpp:282:21:282:23 | *call to get | semmle.label | *call to get |
-| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
-| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
-| azure.cpp:289:24:289:56 | call to GetHeader | semmle.label | call to GetHeader |
-| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
-| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
-| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
-| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
-| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
-| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
-| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
-| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
-| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
-| azure.cpp:294:38:294:53 | call to operator[] | semmle.label | call to operator[] |
-| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
-| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
-| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
+| asio_streams.cpp:109:34:109:44 | read_until output argument | semmle.label | read_until output argument |
+| asio_streams.cpp:113:7:113:17 | recv_buffer | semmle.label | recv_buffer |
+| asio_streams.cpp:115:29:115:39 | recv_buffer | semmle.label | recv_buffer |
+| asio_streams.cpp:119:37:119:44 | call to source | semmle.label | call to source |
+| asio_streams.cpp:120:7:120:14 | send_str | semmle.label | send_str |
+| asio_streams.cpp:122:44:122:62 | call to buffer | semmle.label | call to buffer |
+| asio_streams.cpp:122:44:122:62 | call to buffer | semmle.label | call to buffer |
+| asio_streams.cpp:122:64:122:71 | *send_str | semmle.label | *send_str |
+| asio_streams.cpp:123:7:123:17 | send_buffer | semmle.label | send_buffer |
+| asio_streams.cpp:125:29:125:39 | send_buffer | semmle.label | send_buffer |
+| asio_streams.cpp:136:19:136:26 | call to source | semmle.label | call to source |
+| asio_streams.cpp:141:16:141:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:141:24:141:27 | *host | semmle.label | *host |
+| asio_streams.cpp:142:16:142:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:142:24:142:27 | *host | semmle.label | *host |
+| asio_streams.cpp:143:16:143:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:143:24:143:27 | *host | semmle.label | *host |
+| asio_streams.cpp:144:16:144:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:144:24:144:27 | *host | semmle.label | *host |
+| asio_streams.cpp:151:16:151:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:151:34:151:37 | *host | semmle.label | *host |
+| asio_streams.cpp:152:16:152:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:152:34:152:37 | *host | semmle.label | *host |
+| asio_streams.cpp:153:16:153:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:153:34:153:37 | *host | semmle.label | *host |
+| asio_streams.cpp:154:16:154:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:154:34:154:37 | *host | semmle.label | *host |
+| asio_streams.cpp:168:22:168:29 | call to source | semmle.label | call to source |
+| asio_streams.cpp:172:16:172:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:172:30:172:36 | *service | semmle.label | *service |
+| asio_streams.cpp:173:16:173:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:173:30:173:36 | *service | semmle.label | *service |
+| asio_streams.cpp:174:16:174:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:174:30:174:36 | *service | semmle.label | *service |
+| asio_streams.cpp:175:16:175:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:175:30:175:36 | *service | semmle.label | *service |
+| asio_streams.cpp:182:16:182:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:182:40:182:46 | *service | semmle.label | *service |
+| asio_streams.cpp:183:16:183:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:183:40:183:46 | *service | semmle.label | *service |
+| asio_streams.cpp:184:16:184:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:184:40:184:46 | *service | semmle.label | *service |
+| asio_streams.cpp:185:16:185:22 | call to resolve | semmle.label | call to resolve |
+| asio_streams.cpp:185:40:185:46 | *service | semmle.label | *service |
+| azure.cpp:216:48:216:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
+| azure.cpp:216:48:216:60 | call to GetBodyStream | semmle.label | call to GetBodyStream |
+| azure.cpp:220:5:220:8 | *resp | semmle.label | *resp |
+| azure.cpp:220:16:220:21 | Read output argument | semmle.label | Read output argument |
+| azure.cpp:221:10:221:16 | * ... | semmle.label | * ... |
+| azure.cpp:225:5:225:8 | *resp | semmle.label | *resp |
+| azure.cpp:225:23:225:28 | ReadToCount output argument | semmle.label | ReadToCount output argument |
+| azure.cpp:226:10:226:16 | * ... | semmle.label | * ... |
+| azure.cpp:229:38:229:41 | *resp | semmle.label | *resp |
+| azure.cpp:229:44:229:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
+| azure.cpp:229:44:229:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
+| azure.cpp:230:10:230:12 | *vec [element] | semmle.label | *vec [element] |
+| azure.cpp:230:10:230:12 | call to vector | semmle.label | call to vector |
+| azure.cpp:230:10:230:12 | call to vector [element] | semmle.label | call to vector [element] |
+| azure.cpp:236:52:236:61 | call to GetHeaders | semmle.label | call to GetHeaders |
+| azure.cpp:237:14:237:29 | call to operator[] | semmle.label | call to operator[] |
+| azure.cpp:240:38:240:44 | call to GetBody | semmle.label | call to GetBody |
+| azure.cpp:241:10:241:13 | call to vector | semmle.label | call to vector |
+| azure.cpp:241:10:241:13 | call to vector | semmle.label | call to vector |
+| azure.cpp:241:10:241:13 | call to vector | semmle.label | call to vector |
+| azure.cpp:244:68:244:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
+| azure.cpp:244:68:244:84 | call to ExtractBodyStream | semmle.label | call to ExtractBodyStream |
+| azure.cpp:245:10:245:38 | call to ReadToEnd | semmle.label | call to ReadToEnd |
+| azure.cpp:245:21:245:23 | *call to get | semmle.label | *call to get |
+| azure.cpp:245:28:245:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
+| azure.cpp:245:28:245:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
+| azure.cpp:255:24:255:56 | call to GetHeader | semmle.label | call to GetHeader |
+| azure.cpp:255:32:255:40 | call to GetHeader | semmle.label | call to GetHeader |
+| azure.cpp:255:32:255:40 | call to GetHeader | semmle.label | call to GetHeader |
+| azure.cpp:255:63:255:65 | call to Value | semmle.label | call to Value |
+| azure.cpp:255:63:255:65 | call to Value | semmle.label | call to Value |
+| azure.cpp:256:10:256:20 | headerValue | semmle.label | headerValue |
+| azure.cpp:259:58:259:67 | call to GetHeaders | semmle.label | call to GetHeaders |
+| azure.cpp:259:58:259:67 | call to GetHeaders | semmle.label | call to GetHeaders |
+| azure.cpp:260:38:260:53 | call to operator[] | semmle.label | call to operator[] |
+| azure.cpp:261:10:261:20 | contentType | semmle.label | contentType |
+| azure.cpp:268:3:268:5 | SetQueryParameters output argument | semmle.label | SetQueryParameters output argument |
+| azure.cpp:268:26:268:45 | call to GetHeaders | semmle.label | call to GetHeaders |
+| azure.cpp:268:34:268:43 | call to GetHeaders | semmle.label | call to GetHeaders |
+| azure.cpp:268:34:268:43 | call to GetHeaders | semmle.label | call to GetHeaders |
+| azure.cpp:269:8:269:10 | *url | semmle.label | *url |
+| azure.cpp:269:12:269:29 | call to GetQueryParameters | semmle.label | call to GetQueryParameters |
+| azure.cpp:269:12:269:29 | call to GetQueryParameters | semmle.label | call to GetQueryParameters |
+| azure.cpp:269:32:269:40 | call to operator[] | semmle.label | call to operator[] |
+| bal.cpp:128:19:128:26 | call to source | semmle.label | call to source |
+| bal.cpp:129:23:129:51 | *call to data | semmle.label | *call to data |
+| bal.cpp:132:17:132:18 | *sb | semmle.label | *sb |
+| bal.cpp:132:21:132:24 | decode output argument | semmle.label | decode output argument |
+| bal.cpp:133:7:133:17 | * ... | semmle.label | * ... |
+| bal.cpp:137:19:137:26 | call to source | semmle.label | call to source |
+| bal.cpp:138:21:138:47 | *call to data | semmle.label | *call to data |
+| bal.cpp:141:17:141:19 | ** ... | semmle.label | ** ... |
+| bal.cpp:141:22:141:25 | decode output argument | semmle.label | decode output argument |
+| bal.cpp:142:7:142:17 | * ... | semmle.label | * ... |
+| bal.cpp:146:19:146:26 | call to source | semmle.label | call to source |
+| bal.cpp:147:23:147:51 | *call to data | semmle.label | *call to data |
+| bal.cpp:150:20:150:21 | *sb | semmle.label | *sb |
+| bal.cpp:150:24:150:27 | decodeAny output argument | semmle.label | decodeAny output argument |
+| bal.cpp:151:7:151:17 | * ... | semmle.label | * ... |
+| bal.cpp:156:18:156:25 | call to source | semmle.label | call to source |
+| bal.cpp:159:17:159:37 | encode output argument | semmle.label | encode output argument |
+| bal.cpp:159:40:159:42 | *obj | semmle.label | *obj |
+| bal.cpp:160:7:160:12 | access to array | semmle.label | access to array |
+| bal.cpp:164:18:164:25 | call to source | semmle.label | call to source |
+| bal.cpp:167:20:167:40 | encodeAny output argument | semmle.label | encodeAny output argument |
+| bal.cpp:167:43:167:45 | *obj | semmle.label | *obj |
+| bal.cpp:168:7:168:12 | access to array | semmle.label | access to array |
+| bal.cpp:175:19:175:26 | call to source | semmle.label | call to source |
+| bal.cpp:176:23:176:51 | *call to data | semmle.label | *call to data |
+| bal.cpp:180:17:180:18 | *sb | semmle.label | *sb |
+| bal.cpp:180:21:180:24 | decode output argument | semmle.label | decode output argument |
+| bal.cpp:181:7:181:17 | * ... | semmle.label | * ... |
+| bal.cpp:185:19:185:26 | call to source | semmle.label | call to source |
+| bal.cpp:186:21:186:47 | *call to data | semmle.label | *call to data |
+| bal.cpp:190:17:190:19 | ** ... | semmle.label | ** ... |
+| bal.cpp:190:22:190:25 | decode output argument | semmle.label | decode output argument |
+| bal.cpp:191:7:191:17 | * ... | semmle.label | * ... |
+| bal.cpp:195:19:195:26 | call to source | semmle.label | call to source |
+| bal.cpp:196:23:196:51 | *call to data | semmle.label | *call to data |
+| bal.cpp:199:20:199:21 | *sb | semmle.label | *sb |
+| bal.cpp:199:24:199:27 | decodeAny output argument | semmle.label | decodeAny output argument |
+| bal.cpp:200:7:200:17 | * ... | semmle.label | * ... |
+| bal.cpp:204:18:204:25 | call to source | semmle.label | call to source |
+| bal.cpp:208:17:208:37 | encode output argument | semmle.label | encode output argument |
+| bal.cpp:208:40:208:42 | *obj | semmle.label | *obj |
+| bal.cpp:209:7:209:12 | access to array | semmle.label | access to array |
+| bal.cpp:213:18:213:25 | call to source | semmle.label | call to source |
+| bal.cpp:216:20:216:40 | encodeAny output argument | semmle.label | encodeAny output argument |
+| bal.cpp:216:43:216:45 | *obj | semmle.label | *obj |
+| bal.cpp:217:7:217:12 | access to array | semmle.label | access to array |
+| bal.cpp:222:19:222:26 | call to source | semmle.label | call to source |
+| bal.cpp:223:23:223:51 | *call to data | semmle.label | *call to data |
+| bal.cpp:226:17:226:18 | *sb | semmle.label | *sb |
+| bal.cpp:226:21:226:24 | decode output argument | semmle.label | decode output argument |
+| bal.cpp:229:17:229:37 | encode output argument | semmle.label | encode output argument |
+| bal.cpp:229:40:229:42 | *rec | semmle.label | *rec |
+| bal.cpp:230:7:230:12 | access to array | semmle.label | access to array |
+| bal.cpp:245:19:245:26 | call to source | semmle.label | call to source |
+| bal.cpp:246:21:246:47 | *call to data | semmle.label | *call to data |
+| bal.cpp:249:17:249:19 | ** ... | semmle.label | ** ... |
+| bal.cpp:249:22:249:25 | decode output argument | semmle.label | decode output argument |
+| bal.cpp:250:7:250:17 | * ... | semmle.label | * ... |
+| bal.cpp:254:19:254:26 | call to source | semmle.label | call to source |
+| bal.cpp:255:21:255:47 | *call to data | semmle.label | *call to data |
+| bal.cpp:258:34:258:52 | *call to decode | semmle.label | *call to decode |
+| bal.cpp:258:34:258:52 | *call to decode | semmle.label | *call to decode |
+| bal.cpp:258:35:258:37 | ** ... | semmle.label | ** ... |
+| bal.cpp:258:40:258:43 | decode output argument | semmle.label | decode output argument |
+| bal.cpp:259:7:259:17 | * ... | semmle.label | * ... |
+| bal.cpp:260:7:260:9 | out | semmle.label | out |
+| bal.cpp:264:19:264:26 | call to source | semmle.label | call to source |
+| bal.cpp:265:23:265:51 | *call to data | semmle.label | *call to data |
+| bal.cpp:268:17:268:18 | *sb | semmle.label | *sb |
+| bal.cpp:268:21:268:24 | decode output argument | semmle.label | decode output argument |
+| bal.cpp:269:7:269:17 | * ... | semmle.label | * ... |
+| bal.cpp:273:19:273:26 | call to source | semmle.label | call to source |
+| bal.cpp:276:22:276:25 | *call to data | semmle.label | *call to data |
+| bal.cpp:276:43:276:46 | decode output argument | semmle.label | decode output argument |
+| bal.cpp:277:7:277:17 | * ... | semmle.label | * ... |
+| bal.cpp:301:19:301:26 | call to source | semmle.label | call to source |
+| bal.cpp:302:21:302:47 | *call to data | semmle.label | *call to data |
+| bal.cpp:305:20:305:22 | ** ... | semmle.label | ** ... |
+| bal.cpp:305:25:305:28 | decodeAny output argument | semmle.label | decodeAny output argument |
+| bal.cpp:306:7:306:17 | * ... | semmle.label | * ... |
+| bal.cpp:310:19:310:26 | call to source | semmle.label | call to source |
+| bal.cpp:311:21:311:47 | *call to data | semmle.label | *call to data |
+| bal.cpp:314:37:314:48 | *call to decodeAny | semmle.label | *call to decodeAny |
+| bal.cpp:314:37:314:48 | *call to decodeAny | semmle.label | *call to decodeAny |
+| bal.cpp:314:38:314:40 | ** ... | semmle.label | ** ... |
+| bal.cpp:314:43:314:46 | decodeAny output argument | semmle.label | decodeAny output argument |
+| bal.cpp:315:7:315:17 | * ... | semmle.label | * ... |
+| bal.cpp:316:7:316:9 | out | semmle.label | out |
+| bal.cpp:320:19:320:26 | call to source | semmle.label | call to source |
+| bal.cpp:321:23:321:51 | *call to data | semmle.label | *call to data |
+| bal.cpp:324:20:324:21 | *sb | semmle.label | *sb |
+| bal.cpp:324:24:324:27 | decodeAny output argument | semmle.label | decodeAny output argument |
+| bal.cpp:325:7:325:17 | * ... | semmle.label | * ... |
+| bal.cpp:329:19:329:26 | call to source | semmle.label | call to source |
+| bal.cpp:330:21:330:47 | *call to data | semmle.label | *call to data |
+| bal.cpp:333:20:333:22 | ** ... | semmle.label | ** ... |
+| bal.cpp:333:25:333:28 | decodeAny output argument | semmle.label | decodeAny output argument |
+| bal.cpp:334:7:334:19 | * ... | semmle.label | * ... |
+| bal.cpp:338:19:338:26 | call to source | semmle.label | call to source |
+| bal.cpp:339:21:339:47 | *call to data | semmle.label | *call to data |
+| bal.cpp:342:37:342:48 | *call to decodeAny | semmle.label | *call to decodeAny |
+| bal.cpp:342:37:342:48 | *call to decodeAny | semmle.label | *call to decodeAny |
+| bal.cpp:342:38:342:40 | ** ... | semmle.label | ** ... |
+| bal.cpp:342:43:342:46 | decodeAny output argument | semmle.label | decodeAny output argument |
+| bal.cpp:343:7:343:17 | * ... | semmle.label | * ... |
+| bal.cpp:344:7:344:19 | * ... | semmle.label | * ... |
+| bal.cpp:348:19:348:26 | call to source | semmle.label | call to source |
+| bal.cpp:349:23:349:51 | *call to data | semmle.label | *call to data |
+| bal.cpp:352:20:352:21 | *sb | semmle.label | *sb |
+| bal.cpp:352:24:352:27 | decodeAny output argument | semmle.label | decodeAny output argument |
+| bal.cpp:353:7:353:19 | * ... | semmle.label | * ... |
+| bal.cpp:357:18:357:25 | call to source | semmle.label | call to source |
+| bal.cpp:360:17:360:37 | encode output argument | semmle.label | encode output argument |
+| bal.cpp:360:40:360:42 | *obj | semmle.label | *obj |
+| bal.cpp:361:7:361:12 | access to array | semmle.label | access to array |
+| bal.cpp:365:18:365:25 | call to source | semmle.label | call to source |
+| bal.cpp:368:17:368:36 | encode output argument | semmle.label | encode output argument |
+| bal.cpp:368:39:368:41 | *obj | semmle.label | *obj |
+| bal.cpp:369:7:369:12 | access to array | semmle.label | access to array |
+| bal.cpp:373:18:373:25 | call to source | semmle.label | call to source |
+| bal.cpp:376:34:376:61 | *call to encode | semmle.label | *call to encode |
+| bal.cpp:376:34:376:61 | *call to encode | semmle.label | *call to encode |
+| bal.cpp:376:35:376:54 | encode output argument | semmle.label | encode output argument |
+| bal.cpp:376:57:376:59 | *obj | semmle.label | *obj |
+| bal.cpp:377:7:377:17 | * ... | semmle.label | * ... |
+| bal.cpp:378:7:378:12 | access to array | semmle.label | access to array |
+| bal.cpp:382:19:382:26 | call to source | semmle.label | call to source |
+| bal.cpp:383:21:383:47 | *call to data | semmle.label | *call to data |
+| bal.cpp:386:34:386:44 | *call to encode | semmle.label | *call to encode |
+| bal.cpp:386:34:386:44 | *call to encode | semmle.label | *call to encode |
+| bal.cpp:386:35:386:37 | ** ... | semmle.label | ** ... |
+| bal.cpp:387:7:387:17 | * ... | semmle.label | * ... |
+| bal.cpp:391:18:391:25 | call to source | semmle.label | call to source |
+| bal.cpp:394:25:394:44 | encodeToStream output argument | semmle.label | encodeToStream output argument |
+| bal.cpp:394:47:394:49 | *obj | semmle.label | *obj |
+| bal.cpp:395:7:395:12 | access to array | semmle.label | access to array |
+| bal.cpp:409:18:409:25 | call to source | semmle.label | call to source |
+| bal.cpp:412:20:412:40 | encodeAny output argument | semmle.label | encodeAny output argument |
+| bal.cpp:412:43:412:45 | *obj | semmle.label | *obj |
+| bal.cpp:413:7:413:12 | access to array | semmle.label | access to array |
+| bal.cpp:417:18:417:25 | call to source | semmle.label | call to source |
+| bal.cpp:420:20:420:39 | encodeAny output argument | semmle.label | encodeAny output argument |
+| bal.cpp:420:42:420:44 | *obj | semmle.label | *obj |
+| bal.cpp:421:7:421:12 | access to array | semmle.label | access to array |
+| bal.cpp:425:18:425:25 | call to source | semmle.label | call to source |
+| bal.cpp:428:37:428:64 | *call to encodeAny | semmle.label | *call to encodeAny |
+| bal.cpp:428:37:428:64 | *call to encodeAny | semmle.label | *call to encodeAny |
+| bal.cpp:428:38:428:57 | encodeAny output argument | semmle.label | encodeAny output argument |
+| bal.cpp:428:60:428:62 | *obj | semmle.label | *obj |
+| bal.cpp:429:7:429:17 | * ... | semmle.label | * ... |
+| bal.cpp:430:7:430:12 | access to array | semmle.label | access to array |
+| bal.cpp:434:18:434:25 | call to source | semmle.label | call to source |
+| bal.cpp:437:28:437:47 | encodeAnyToStream output argument | semmle.label | encodeAnyToStream output argument |
+| bal.cpp:437:50:437:52 | *obj | semmle.label | *obj |
+| bal.cpp:438:7:438:12 | access to array | semmle.label | access to array |
+| bal.cpp:442:19:442:26 | call to source | semmle.label | call to source |
+| bal.cpp:443:41:443:86 | *call to data | semmle.label | *call to data |
+| bal.cpp:446:20:446:40 | encodeAny output argument | semmle.label | encodeAny output argument |
+| bal.cpp:446:43:446:46 | ** ... | semmle.label | ** ... |
+| bal.cpp:447:7:447:12 | access to array | semmle.label | access to array |
+| bal.cpp:451:19:451:26 | call to source | semmle.label | call to source |
+| bal.cpp:452:41:452:86 | *call to data | semmle.label | *call to data |
+| bal.cpp:455:20:455:39 | encodeAny output argument | semmle.label | encodeAny output argument |
+| bal.cpp:455:42:455:45 | ** ... | semmle.label | ** ... |
+| bal.cpp:456:7:456:12 | access to array | semmle.label | access to array |
+| bal.cpp:460:19:460:26 | call to source | semmle.label | call to source |
+| bal.cpp:461:41:461:86 | *call to data | semmle.label | *call to data |
+| bal.cpp:464:37:464:65 | *call to encodeAny | semmle.label | *call to encodeAny |
+| bal.cpp:464:37:464:65 | *call to encodeAny | semmle.label | *call to encodeAny |
+| bal.cpp:464:38:464:57 | encodeAny output argument | semmle.label | encodeAny output argument |
+| bal.cpp:464:60:464:63 | ** ... | semmle.label | ** ... |
+| bal.cpp:465:7:465:17 | * ... | semmle.label | * ... |
+| bal.cpp:466:7:466:12 | access to array | semmle.label | access to array |
+| bdlbb.cpp:37:16:37:23 | call to source | semmle.label | call to source |
+| bdlbb.cpp:39:37:39:41 | copy output argument | semmle.label | copy output argument |
+| bdlbb.cpp:39:49:39:52 | *call to data | semmle.label | *call to data |
+| bdlbb.cpp:41:37:41:39 | copy output argument | semmle.label | copy output argument |
+| bdlbb.cpp:41:42:41:45 | *blob | semmle.label | *blob |
+| bdlbb.cpp:42:7:42:10 | * ... | semmle.label | * ... |
+| bdlbb.cpp:46:16:46:23 | call to source | semmle.label | call to source |
+| bdlbb.cpp:48:37:48:41 | copy output argument | semmle.label | copy output argument |
+| bdlbb.cpp:48:49:48:52 | *call to data | semmle.label | *call to data |
+| bdlbb.cpp:49:18:49:21 | *blob | semmle.label | *blob |
+| bdlbb.cpp:49:18:49:38 | *call to data | semmle.label | *call to data |
+| bdlbb.cpp:49:18:49:38 | *call to data | semmle.label | *call to data |
+| bdlbb.cpp:49:29:49:32 | *call to buffer | semmle.label | *call to buffer |
+| bdlbb.cpp:50:7:50:8 | * ... | semmle.label | * ... |
+| bdlbb.cpp:55:16:55:23 | call to source | semmle.label | call to source |
+| bdlbb.cpp:57:37:57:41 | copy output argument | semmle.label | copy output argument |
+| bdlbb.cpp:57:49:57:52 | *call to data | semmle.label | *call to data |
+| bdlbb.cpp:58:18:58:21 | *blob | semmle.label | *blob |
+| bdlbb.cpp:58:18:58:46 | call to get | semmle.label | call to get |
+| bdlbb.cpp:58:29:58:32 | *call to buffer | semmle.label | *call to buffer |
+| bdlbb.cpp:58:39:58:41 | *call to buffer | semmle.label | *call to buffer |
+| bdlbb.cpp:59:7:59:8 | * ... | semmle.label | * ... |
+| bdlbb.cpp:63:16:63:23 | call to source | semmle.label | call to source |
+| bdlbb.cpp:65:37:65:41 | copy output argument | semmle.label | copy output argument |
+| bdlbb.cpp:65:49:65:52 | *call to data | semmle.label | *call to data |
+| bdlbb.cpp:67:12:67:65 | *call to getContiguousRangeOrCopy | semmle.label | *call to getContiguousRangeOrCopy |
+| bdlbb.cpp:67:12:67:65 | *call to getContiguousRangeOrCopy | semmle.label | *call to getContiguousRangeOrCopy |
+| bdlbb.cpp:67:72:67:75 | *blob | semmle.label | *blob |
+| bdlbb.cpp:68:7:68:8 | * ... | semmle.label | * ... |
+| bdlbb.cpp:73:16:73:23 | call to source | semmle.label | call to source |
+| bdlbb.cpp:75:37:75:40 | copy output argument | semmle.label | copy output argument |
+| bdlbb.cpp:75:48:75:51 | *call to data | semmle.label | *call to data |
+| bdlbb.cpp:77:37:77:40 | copy output argument | semmle.label | copy output argument |
+| bdlbb.cpp:77:46:77:48 | *src | semmle.label | *src |
+| bdlbb.cpp:79:37:79:39 | copy output argument | semmle.label | copy output argument |
+| bdlbb.cpp:79:42:79:44 | *dst | semmle.label | *dst |
+| bdlbb.cpp:80:7:80:10 | * ... | semmle.label | * ... |
+| bmqa.cpp:87:19:87:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:88:36:88:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:90:2:90:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:90:15:90:19 | getData output argument | semmle.label | getData output argument |
+| bmqa.cpp:92:37:92:39 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:92:42:92:45 | *blob | semmle.label | *blob |
+| bmqa.cpp:93:7:93:10 | * ... | semmle.label | * ... |
+| bmqa.cpp:97:19:97:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:98:43:98:88 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:99:42:99:46 | *event | semmle.label | *event |
+| bmqa.cpp:99:49:99:63 | call to messageIterator | semmle.label | call to messageIterator |
+| bmqa.cpp:99:49:99:63 | call to messageIterator | semmle.label | call to messageIterator |
+| bmqa.cpp:101:43:101:44 | *it | semmle.label | *it |
+| bmqa.cpp:101:53:101:55 | *call to message | semmle.label | *call to message |
+| bmqa.cpp:101:53:101:55 | *call to message | semmle.label | *call to message |
+| bmqa.cpp:103:3:103:5 | *msg | semmle.label | *msg |
+| bmqa.cpp:103:15:103:19 | getData output argument | semmle.label | getData output argument |
+| bmqa.cpp:105:38:105:40 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:105:43:105:46 | *blob | semmle.label | *blob |
+| bmqa.cpp:106:8:106:11 | * ... | semmle.label | * ... |
+| bmqa.cpp:111:16:111:23 | call to source | semmle.label | call to source |
+| bmqa.cpp:113:37:113:39 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:113:47:113:50 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:115:2:115:4 | setDataRef output argument | semmle.label | setDataRef output argument |
+| bmqa.cpp:115:17:115:19 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:117:2:117:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:117:14:117:17 | getData output argument | semmle.label | getData output argument |
+| bmqa.cpp:119:37:119:39 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:119:42:119:44 | *out | semmle.label | *out |
+| bmqa.cpp:120:7:120:10 | * ... | semmle.label | * ... |
+| bmqa.cpp:124:16:124:23 | call to source | semmle.label | call to source |
+| bmqa.cpp:126:2:126:4 | setDataRef output argument | semmle.label | setDataRef output argument |
+| bmqa.cpp:126:19:126:22 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:128:2:128:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:128:14:128:17 | getData output argument | semmle.label | getData output argument |
+| bmqa.cpp:130:37:130:39 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:130:42:130:44 | *out | semmle.label | *out |
+| bmqa.cpp:131:7:131:10 | * ... | semmle.label | * ... |
+| bmqa.cpp:135:16:135:23 | call to source | semmle.label | call to source |
+| bmqa.cpp:137:2:137:4 | setData output argument | semmle.label | setData output argument |
+| bmqa.cpp:137:16:137:19 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:139:2:139:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:139:14:139:17 | getData output argument | semmle.label | getData output argument |
+| bmqa.cpp:141:37:141:39 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:141:42:141:44 | *out | semmle.label | *out |
+| bmqa.cpp:142:7:142:10 | * ... | semmle.label | * ... |
+| bmqa.cpp:146:19:146:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:147:36:147:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:148:36:148:38 | *msg | semmle.label | *msg |
+| bmqa.cpp:148:41:148:45 | call to clone | semmle.label | call to clone |
+| bmqa.cpp:148:41:148:45 | call to clone | semmle.label | call to clone |
+| bmqa.cpp:150:2:150:5 | *copy | semmle.label | *copy |
+| bmqa.cpp:150:15:150:19 | getData output argument | semmle.label | getData output argument |
+| bmqa.cpp:152:37:152:39 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:152:42:152:45 | *blob | semmle.label | *blob |
+| bmqa.cpp:153:7:153:10 | * ... | semmle.label | * ... |
+| bmqa.cpp:157:19:157:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:158:36:158:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:160:2:160:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:160:22:160:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:161:29:161:33 | *props | semmle.label | *props |
+| bmqa.cpp:161:54:161:61 | *call to getPropertyAsString | semmle.label | *call to getPropertyAsString |
+| bmqa.cpp:161:54:161:61 | *call to getPropertyAsString | semmle.label | *call to getPropertyAsString |
+| bmqa.cpp:162:7:162:21 | access to array | semmle.label | access to array |
+| bmqa.cpp:166:19:166:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:167:36:167:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:169:2:169:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:169:22:169:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:170:35:170:39 | *props | semmle.label | *props |
+| bmqa.cpp:170:60:170:67 | *call to getPropertyAsBinary [element] | semmle.label | *call to getPropertyAsBinary [element] |
+| bmqa.cpp:170:60:170:67 | *call to getPropertyAsBinary [element] | semmle.label | *call to getPropertyAsBinary [element] |
+| bmqa.cpp:171:7:171:11 | *value [element] | semmle.label | *value [element] |
+| bmqa.cpp:171:7:171:21 | access to array | semmle.label | access to array |
+| bmqa.cpp:175:19:175:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:176:36:176:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:178:2:178:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:178:22:178:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:179:35:179:39 | *props | semmle.label | *props |
+| bmqa.cpp:179:60:179:67 | *call to getPropertyAsBinary [element] | semmle.label | *call to getPropertyAsBinary [element] |
+| bmqa.cpp:179:60:179:67 | *call to getPropertyAsBinary [element] | semmle.label | *call to getPropertyAsBinary [element] |
+| bmqa.cpp:180:7:180:11 | *value [element] | semmle.label | *value [element] |
+| bmqa.cpp:180:12:180:14 | call to operator[] | semmle.label | call to operator[] |
+| bmqa.cpp:184:19:184:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:185:36:185:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:187:2:187:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:187:22:187:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:189:29:189:33 | *props | semmle.label | *props |
+| bmqa.cpp:189:56:189:69 | *call to getPropertyAsStringOr | semmle.label | *call to getPropertyAsStringOr |
+| bmqa.cpp:189:56:189:69 | *call to getPropertyAsStringOr | semmle.label | *call to getPropertyAsStringOr |
+| bmqa.cpp:190:7:190:19 | * ... | semmle.label | * ... |
+| bmqa.cpp:195:19:195:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:197:56:197:69 | *call to getPropertyAsStringOr | semmle.label | *call to getPropertyAsStringOr |
+| bmqa.cpp:197:56:197:69 | *call to getPropertyAsStringOr | semmle.label | *call to getPropertyAsStringOr |
+| bmqa.cpp:197:64:197:67 | *dflt | semmle.label | *dflt |
+| bmqa.cpp:198:7:198:19 | * ... | semmle.label | * ... |
+| bmqa.cpp:202:19:202:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:203:36:203:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:205:2:205:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:205:22:205:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:207:35:207:39 | *props | semmle.label | *props |
+| bmqa.cpp:207:62:207:75 | *call to getPropertyAsBinaryOr [element] | semmle.label | *call to getPropertyAsBinaryOr [element] |
+| bmqa.cpp:207:62:207:75 | *call to getPropertyAsBinaryOr [element] | semmle.label | *call to getPropertyAsBinaryOr [element] |
+| bmqa.cpp:208:7:208:19 | * ... | semmle.label | * ... |
+| bmqa.cpp:208:8:208:12 | *value [element] | semmle.label | *value [element] |
+| bmqa.cpp:212:11:212:19 | * ... | semmle.label | * ... |
+| bmqa.cpp:212:12:212:17 | call to source | semmle.label | call to source |
+| bmqa.cpp:214:2:214:5 | push_back output argument [element] | semmle.label | push_back output argument [element] |
+| bmqa.cpp:214:17:214:17 | *c | semmle.label | *c |
+| bmqa.cpp:216:62:216:75 | *call to getPropertyAsBinaryOr [element] | semmle.label | *call to getPropertyAsBinaryOr [element] |
+| bmqa.cpp:216:62:216:75 | *call to getPropertyAsBinaryOr [element] | semmle.label | *call to getPropertyAsBinaryOr [element] |
+| bmqa.cpp:216:70:216:73 | *dflt [element] | semmle.label | *dflt [element] |
+| bmqa.cpp:217:7:217:19 | * ... | semmle.label | * ... |
+| bmqa.cpp:217:8:217:12 | *value [element] | semmle.label | *value [element] |
+| bmqa.cpp:229:16:229:23 | call to source | semmle.label | call to source |
+| bmqa.cpp:231:37:231:41 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:231:49:231:52 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:233:2:233:6 | streamIn output argument | semmle.label | streamIn output argument |
+| bmqa.cpp:233:17:233:20 | *blob | semmle.label | *blob |
+| bmqa.cpp:234:7:234:46 | * ... | semmle.label | * ... |
+| bmqa.cpp:234:8:234:12 | *props | semmle.label | *props |
+| bmqa.cpp:234:33:234:40 | *call to getPropertyAsString | semmle.label | *call to getPropertyAsString |
+| bmqa.cpp:238:16:238:23 | call to source | semmle.label | call to source |
+| bmqa.cpp:240:37:240:41 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:240:49:240:52 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:242:2:242:3 | streamIn output argument | semmle.label | streamIn output argument |
+| bmqa.cpp:242:14:242:17 | *blob | semmle.label | *blob |
+| bmqa.cpp:244:2:244:4 | setPropertiesRef output argument | semmle.label | setPropertiesRef output argument |
+| bmqa.cpp:244:23:244:25 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:246:2:246:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:246:21:246:24 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:247:7:247:44 | * ... | semmle.label | * ... |
+| bmqa.cpp:247:8:247:10 | *out | semmle.label | *out |
+| bmqa.cpp:247:31:247:38 | *call to getPropertyAsString | semmle.label | *call to getPropertyAsString |
+| bmqa.cpp:251:19:251:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:252:36:252:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:254:2:254:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:254:22:254:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:256:41:256:45 | *props | semmle.label | *props |
+| bmqa.cpp:256:56:256:66 | *call to streamOut | semmle.label | *call to streamOut |
+| bmqa.cpp:256:56:256:66 | *call to streamOut | semmle.label | *call to streamOut |
+| bmqa.cpp:258:37:258:39 | copy output argument | semmle.label | copy output argument |
+| bmqa.cpp:258:42:258:45 | *blob | semmle.label | *blob |
+| bmqa.cpp:259:7:259:10 | * ... | semmle.label | * ... |
+| bmqa.cpp:263:19:263:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:264:36:264:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:266:2:266:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:266:22:266:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:267:39:267:42 | call to MessageProperties | semmle.label | call to MessageProperties |
+| bmqa.cpp:267:44:267:48 | *props | semmle.label | *props |
+| bmqa.cpp:268:7:268:45 | * ... | semmle.label | * ... |
+| bmqa.cpp:268:8:268:11 | *copy | semmle.label | *copy |
+| bmqa.cpp:268:32:268:39 | *call to getPropertyAsString | semmle.label | *call to getPropertyAsString |
+| bmqa.cpp:272:19:272:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:273:36:273:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:275:2:275:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:275:22:275:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:277:2:277:5 | operator= output argument | semmle.label | operator= output argument |
+| bmqa.cpp:277:9:277:13 | *props | semmle.label | *props |
+| bmqa.cpp:278:7:278:45 | * ... | semmle.label | * ... |
+| bmqa.cpp:278:8:278:11 | *copy | semmle.label | *copy |
+| bmqa.cpp:278:32:278:39 | *call to getPropertyAsString | semmle.label | *call to getPropertyAsString |
+| bmqa.cpp:282:19:282:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:283:36:283:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:285:2:285:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:285:22:285:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:287:7:287:55 | * ... | semmle.label | * ... |
+| bmqa.cpp:287:8:287:21 | *call to operator= | semmle.label | *call to operator= |
+| bmqa.cpp:287:16:287:20 | *props | semmle.label | *props |
+| bmqa.cpp:287:42:287:49 | *call to getPropertyAsString | semmle.label | *call to getPropertyAsString |
+| bmqa.cpp:291:19:291:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:292:28:292:58 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:294:2:294:6 | setPropertyAsString output argument | semmle.label | setPropertyAsString output argument |
+| bmqa.cpp:294:35:294:40 | * ... | semmle.label | * ... |
+| bmqa.cpp:295:7:295:46 | * ... | semmle.label | * ... |
+| bmqa.cpp:295:8:295:12 | *props | semmle.label | *props |
+| bmqa.cpp:295:33:295:40 | *call to getPropertyAsString | semmle.label | *call to getPropertyAsString |
+| bmqa.cpp:299:25:299:32 | call to source | semmle.label | call to source |
+| bmqa.cpp:301:2:301:6 | setPropertyAsString output argument | semmle.label | setPropertyAsString output argument |
+| bmqa.cpp:301:35:301:39 | value | semmle.label | value |
+| bmqa.cpp:302:7:302:46 | * ... | semmle.label | * ... |
+| bmqa.cpp:302:8:302:12 | *props | semmle.label | *props |
+| bmqa.cpp:302:33:302:40 | *call to getPropertyAsString | semmle.label | *call to getPropertyAsString |
+| bmqa.cpp:306:19:306:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:307:33:307:68 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:309:2:309:6 | setPropertyAsBinary output argument | semmle.label | setPropertyAsBinary output argument |
+| bmqa.cpp:309:35:309:40 | * ... | semmle.label | * ... |
+| bmqa.cpp:310:7:310:46 | * ... | semmle.label | * ... |
+| bmqa.cpp:310:8:310:12 | *props | semmle.label | *props |
+| bmqa.cpp:310:33:310:40 | *call to getPropertyAsBinary [element] | semmle.label | *call to getPropertyAsBinary [element] |
+| bmqa.cpp:315:24:315:31 | call to source | semmle.label | call to source |
+| bmqa.cpp:317:2:317:6 | setPropertyAsBool output argument | semmle.label | setPropertyAsBool output argument |
+| bmqa.cpp:317:26:317:29 | name | semmle.label | name |
+| bmqa.cpp:318:47:318:48 | call to MessagePropertiesIterator | semmle.label | call to MessagePropertiesIterator |
+| bmqa.cpp:318:50:318:55 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:319:7:319:23 | * ... | semmle.label | * ... |
+| bmqa.cpp:319:8:319:9 | *it | semmle.label | *it |
+| bmqa.cpp:319:15:319:17 | *call to name | semmle.label | *call to name |
+| bmqa.cpp:323:24:323:31 | call to source | semmle.label | call to source |
+| bmqa.cpp:325:2:325:6 | setPropertyAsChar output argument | semmle.label | setPropertyAsChar output argument |
+| bmqa.cpp:325:26:325:29 | name | semmle.label | name |
+| bmqa.cpp:326:47:326:48 | call to MessagePropertiesIterator | semmle.label | call to MessagePropertiesIterator |
+| bmqa.cpp:326:50:326:55 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:327:7:327:23 | * ... | semmle.label | * ... |
+| bmqa.cpp:327:8:327:9 | *it | semmle.label | *it |
+| bmqa.cpp:327:15:327:17 | *call to name | semmle.label | *call to name |
+| bmqa.cpp:331:24:331:31 | call to source | semmle.label | call to source |
+| bmqa.cpp:333:2:333:6 | setPropertyAsShort output argument | semmle.label | setPropertyAsShort output argument |
+| bmqa.cpp:333:27:333:30 | name | semmle.label | name |
+| bmqa.cpp:334:47:334:48 | call to MessagePropertiesIterator | semmle.label | call to MessagePropertiesIterator |
+| bmqa.cpp:334:50:334:55 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:335:7:335:23 | * ... | semmle.label | * ... |
+| bmqa.cpp:335:8:335:9 | *it | semmle.label | *it |
+| bmqa.cpp:335:15:335:17 | *call to name | semmle.label | *call to name |
+| bmqa.cpp:339:24:339:31 | call to source | semmle.label | call to source |
+| bmqa.cpp:341:2:341:6 | setPropertyAsInt32 output argument | semmle.label | setPropertyAsInt32 output argument |
+| bmqa.cpp:341:27:341:30 | name | semmle.label | name |
+| bmqa.cpp:342:47:342:48 | call to MessagePropertiesIterator | semmle.label | call to MessagePropertiesIterator |
+| bmqa.cpp:342:50:342:55 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:343:7:343:23 | * ... | semmle.label | * ... |
+| bmqa.cpp:343:8:343:9 | *it | semmle.label | *it |
+| bmqa.cpp:343:15:343:17 | *call to name | semmle.label | *call to name |
+| bmqa.cpp:347:24:347:31 | call to source | semmle.label | call to source |
+| bmqa.cpp:349:2:349:6 | setPropertyAsInt64 output argument | semmle.label | setPropertyAsInt64 output argument |
+| bmqa.cpp:349:27:349:30 | name | semmle.label | name |
+| bmqa.cpp:350:47:350:48 | call to MessagePropertiesIterator | semmle.label | call to MessagePropertiesIterator |
+| bmqa.cpp:350:50:350:55 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:351:7:351:23 | * ... | semmle.label | * ... |
+| bmqa.cpp:351:8:351:9 | *it | semmle.label | *it |
+| bmqa.cpp:351:15:351:17 | *call to name | semmle.label | *call to name |
+| bmqa.cpp:355:24:355:31 | call to source | semmle.label | call to source |
+| bmqa.cpp:357:2:357:6 | setPropertyAsString output argument | semmle.label | setPropertyAsString output argument |
+| bmqa.cpp:357:28:357:31 | name | semmle.label | name |
+| bmqa.cpp:358:47:358:48 | call to MessagePropertiesIterator | semmle.label | call to MessagePropertiesIterator |
+| bmqa.cpp:358:50:358:55 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:359:7:359:23 | * ... | semmle.label | * ... |
+| bmqa.cpp:359:8:359:9 | *it | semmle.label | *it |
+| bmqa.cpp:359:15:359:17 | *call to name | semmle.label | *call to name |
+| bmqa.cpp:363:24:363:31 | call to source | semmle.label | call to source |
+| bmqa.cpp:365:2:365:6 | setPropertyAsBinary output argument | semmle.label | setPropertyAsBinary output argument |
+| bmqa.cpp:365:28:365:31 | name | semmle.label | name |
+| bmqa.cpp:366:47:366:48 | call to MessagePropertiesIterator | semmle.label | call to MessagePropertiesIterator |
+| bmqa.cpp:366:50:366:55 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:367:7:367:23 | * ... | semmle.label | * ... |
+| bmqa.cpp:367:8:367:9 | *it | semmle.label | *it |
+| bmqa.cpp:367:15:367:17 | *call to name | semmle.label | *call to name |
+| bmqa.cpp:371:19:371:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:372:36:372:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:374:2:374:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:374:22:374:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:375:47:375:48 | call to MessagePropertiesIterator | semmle.label | call to MessagePropertiesIterator |
+| bmqa.cpp:375:50:375:55 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:377:8:377:24 | * ... | semmle.label | * ... |
+| bmqa.cpp:377:9:377:10 | *it | semmle.label | *it |
+| bmqa.cpp:377:16:377:18 | *call to name | semmle.label | *call to name |
+| bmqa.cpp:378:8:378:31 | * ... | semmle.label | * ... |
+| bmqa.cpp:378:9:378:10 | *it | semmle.label | *it |
+| bmqa.cpp:378:23:378:25 | *call to getAsString | semmle.label | *call to getAsString |
+| bmqa.cpp:379:8:379:31 | * ... | semmle.label | * ... |
+| bmqa.cpp:379:9:379:10 | *it | semmle.label | *it |
+| bmqa.cpp:379:23:379:25 | *call to getAsBinary [element] | semmle.label | *call to getAsBinary [element] |
+| bmqa.cpp:385:19:385:26 | call to source | semmle.label | call to source |
+| bmqa.cpp:386:36:386:76 | *call to data | semmle.label | *call to data |
+| bmqa.cpp:388:2:388:4 | *msg | semmle.label | *msg |
+| bmqa.cpp:388:22:388:27 | loadProperties output argument | semmle.label | loadProperties output argument |
+| bmqa.cpp:389:47:389:48 | call to MessagePropertiesIterator | semmle.label | call to MessagePropertiesIterator |
+| bmqa.cpp:389:50:389:55 | *& ... | semmle.label | *& ... |
+| bmqa.cpp:391:2:391:5 | operator= output argument | semmle.label | operator= output argument |
+| bmqa.cpp:391:9:391:10 | *it | semmle.label | *it |
+| bmqa.cpp:392:7:392:32 | * ... | semmle.label | * ... |
+| bmqa.cpp:392:8:392:11 | *copy | semmle.label | *copy |
+| bmqa.cpp:392:24:392:26 | *call to getAsString | semmle.label | *call to getAsString |
+| bmqa.cpp:393:7:393:32 | * ... | semmle.label | * ... |
+| bmqa.cpp:393:8:393:18 | *call to operator= | semmle.label | *call to operator= |
+| bmqa.cpp:393:16:393:17 | *it | semmle.label | *it |
+| bmqa.cpp:393:24:393:26 | *call to name | semmle.label | *call to name |
+| bslx.cpp:145:33:145:40 | call to source | semmle.label | call to source |
+| bslx.cpp:146:34:146:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:146:41:146:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:148:2:148:7 | *stream | semmle.label | *stream |
+| bslx.cpp:148:22:148:24 | getArrayInt8 output argument | semmle.label | getArrayInt8 output argument |
+| bslx.cpp:149:7:149:10 | * ... | semmle.label | * ... |
+| bslx.cpp:153:33:153:40 | call to source | semmle.label | call to source |
+| bslx.cpp:154:34:154:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:154:41:154:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:156:2:156:7 | *stream | semmle.label | *stream |
+| bslx.cpp:156:19:156:21 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:157:7:157:17 | * ... | semmle.label | * ... |
+| bslx.cpp:161:33:161:40 | call to source | semmle.label | call to source |
+| bslx.cpp:162:34:162:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:162:41:162:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:165:2:165:7 | *stream | semmle.label | *stream |
+| bslx.cpp:165:17:165:20 | *call to getInt32 | semmle.label | *call to getInt32 |
+| bslx.cpp:165:31:165:33 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:166:7:166:17 | * ... | semmle.label | * ... |
+| bslx.cpp:171:33:171:40 | call to source | semmle.label | call to source |
+| bslx.cpp:172:2:172:7 | reset output argument | semmle.label | reset output argument |
+| bslx.cpp:172:15:172:25 | *call to data | semmle.label | *call to data |
+| bslx.cpp:174:2:174:7 | *stream | semmle.label | *stream |
+| bslx.cpp:174:19:174:21 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:175:7:175:17 | * ... | semmle.label | * ... |
+| bslx.cpp:179:33:179:40 | call to source | semmle.label | call to source |
+| bslx.cpp:180:20:180:45 | *call to data | semmle.label | *call to data |
+| bslx.cpp:181:50:181:55 | call to GenericInStream | semmle.label | call to GenericInStream |
+| bslx.cpp:181:57:181:58 | *sb | semmle.label | *sb |
+| bslx.cpp:183:2:183:7 | *stream | semmle.label | *stream |
+| bslx.cpp:183:19:183:21 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:184:7:184:17 | * ... | semmle.label | * ... |
+| bslx.cpp:197:33:197:40 | call to source | semmle.label | call to source |
+| bslx.cpp:198:34:198:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:198:41:198:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:200:53:200:58 | *stream | semmle.label | *stream |
+| bslx.cpp:200:61:200:63 | bdexStreamIn output argument | semmle.label | bdexStreamIn output argument |
+| bslx.cpp:201:7:201:17 | * ... | semmle.label | * ... |
+| bslx.cpp:207:33:207:40 | call to source | semmle.label | call to source |
+| bslx.cpp:208:34:208:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:208:41:208:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:231:2:231:7 | *stream | semmle.label | *stream |
+| bslx.cpp:231:18:231:21 | *call to getLength | semmle.label | *call to getLength |
+| bslx.cpp:231:32:231:35 | *call to getVersion | semmle.label | *call to getVersion |
+| bslx.cpp:231:43:231:46 | *call to getInt8 | semmle.label | *call to getInt8 |
+| bslx.cpp:231:55:231:59 | *call to getUint8 | semmle.label | *call to getUint8 |
+| bslx.cpp:231:68:231:71 | *call to getInt16 | semmle.label | *call to getInt16 |
+| bslx.cpp:231:81:231:85 | *call to getUint16 | semmle.label | *call to getUint16 |
+| bslx.cpp:231:94:231:97 | *call to getInt24 | semmle.label | *call to getInt24 |
+| bslx.cpp:231:107:231:111 | *call to getUint24 | semmle.label | *call to getUint24 |
+| bslx.cpp:231:120:231:123 | *call to getInt32 | semmle.label | *call to getInt32 |
+| bslx.cpp:231:133:231:137 | *call to getUint32 | semmle.label | *call to getUint32 |
+| bslx.cpp:231:146:231:150 | *call to getInt40 | semmle.label | *call to getInt40 |
+| bslx.cpp:231:160:231:165 | *call to getUint40 | semmle.label | *call to getUint40 |
+| bslx.cpp:231:174:231:178 | *call to getInt48 | semmle.label | *call to getInt48 |
+| bslx.cpp:231:188:231:193 | *call to getUint48 | semmle.label | *call to getUint48 |
+| bslx.cpp:231:202:231:206 | *call to getInt56 | semmle.label | *call to getInt56 |
+| bslx.cpp:231:216:231:221 | *call to getUint56 | semmle.label | *call to getUint56 |
+| bslx.cpp:231:230:231:234 | *call to getInt64 | semmle.label | *call to getInt64 |
+| bslx.cpp:231:244:231:249 | *call to getUint64 | semmle.label | *call to getUint64 |
+| bslx.cpp:231:260:231:263 | *call to getFloat32 | semmle.label | *call to getFloat32 |
+| bslx.cpp:231:274:231:277 | *call to getFloat64 | semmle.label | *call to getFloat64 |
+| bslx.cpp:231:287:231:292 | *call to getString | semmle.label | *call to getString |
+| bslx.cpp:231:305:231:315 | *call to getArrayInt8 | semmle.label | *call to getArrayInt8 |
+| bslx.cpp:231:329:231:340 | *call to getArrayUint8 | semmle.label | *call to getArrayUint8 |
+| bslx.cpp:231:354:231:364 | *call to getArrayInt16 | semmle.label | *call to getArrayInt16 |
+| bslx.cpp:231:379:231:390 | *call to getArrayUint16 | semmle.label | *call to getArrayUint16 |
+| bslx.cpp:231:404:231:414 | *call to getArrayInt24 | semmle.label | *call to getArrayInt24 |
+| bslx.cpp:231:429:231:440 | *call to getArrayUint24 | semmle.label | *call to getArrayUint24 |
+| bslx.cpp:231:454:231:464 | *call to getArrayInt32 | semmle.label | *call to getArrayInt32 |
+| bslx.cpp:231:479:231:490 | *call to getArrayUint32 | semmle.label | *call to getArrayUint32 |
+| bslx.cpp:231:504:231:515 | *call to getArrayInt40 | semmle.label | *call to getArrayInt40 |
+| bslx.cpp:231:530:231:542 | *call to getArrayUint40 | semmle.label | *call to getArrayUint40 |
+| bslx.cpp:231:556:231:567 | *call to getArrayInt48 | semmle.label | *call to getArrayInt48 |
+| bslx.cpp:231:582:231:594 | *call to getArrayUint48 | semmle.label | *call to getArrayUint48 |
+| bslx.cpp:231:608:231:619 | *call to getArrayInt56 | semmle.label | *call to getArrayInt56 |
+| bslx.cpp:231:634:231:646 | *call to getArrayUint56 | semmle.label | *call to getArrayUint56 |
+| bslx.cpp:231:660:231:671 | *call to getArrayInt64 | semmle.label | *call to getArrayInt64 |
+| bslx.cpp:231:686:231:698 | *call to getArrayUint64 | semmle.label | *call to getArrayUint64 |
+| bslx.cpp:231:714:231:724 | *call to getArrayFloat32 | semmle.label | *call to getArrayFloat32 |
+| bslx.cpp:231:740:231:750 | *call to getArrayFloat64 | semmle.label | *call to getArrayFloat64 |
+| bslx.cpp:231:761:231:763 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:232:7:232:17 | * ... | semmle.label | * ... |
+| bslx.cpp:236:33:236:40 | call to source | semmle.label | call to source |
+| bslx.cpp:237:20:237:45 | *call to data | semmle.label | *call to data |
+| bslx.cpp:238:50:238:55 | call to GenericInStream | semmle.label | call to GenericInStream |
+| bslx.cpp:238:57:238:58 | *sb | semmle.label | *sb |
+| bslx.cpp:261:2:261:7 | *stream | semmle.label | *stream |
+| bslx.cpp:261:18:261:21 | *call to getLength | semmle.label | *call to getLength |
+| bslx.cpp:261:32:261:35 | *call to getVersion | semmle.label | *call to getVersion |
+| bslx.cpp:261:43:261:46 | *call to getInt8 | semmle.label | *call to getInt8 |
+| bslx.cpp:261:55:261:59 | *call to getUint8 | semmle.label | *call to getUint8 |
+| bslx.cpp:261:68:261:71 | *call to getInt16 | semmle.label | *call to getInt16 |
+| bslx.cpp:261:81:261:85 | *call to getUint16 | semmle.label | *call to getUint16 |
+| bslx.cpp:261:94:261:97 | *call to getInt24 | semmle.label | *call to getInt24 |
+| bslx.cpp:261:107:261:111 | *call to getUint24 | semmle.label | *call to getUint24 |
+| bslx.cpp:261:120:261:123 | *call to getInt32 | semmle.label | *call to getInt32 |
+| bslx.cpp:261:133:261:137 | *call to getUint32 | semmle.label | *call to getUint32 |
+| bslx.cpp:261:146:261:150 | *call to getInt40 | semmle.label | *call to getInt40 |
+| bslx.cpp:261:160:261:165 | *call to getUint40 | semmle.label | *call to getUint40 |
+| bslx.cpp:261:174:261:178 | *call to getInt48 | semmle.label | *call to getInt48 |
+| bslx.cpp:261:188:261:193 | *call to getUint48 | semmle.label | *call to getUint48 |
+| bslx.cpp:261:202:261:206 | *call to getInt56 | semmle.label | *call to getInt56 |
+| bslx.cpp:261:216:261:221 | *call to getUint56 | semmle.label | *call to getUint56 |
+| bslx.cpp:261:230:261:234 | *call to getInt64 | semmle.label | *call to getInt64 |
+| bslx.cpp:261:244:261:249 | *call to getUint64 | semmle.label | *call to getUint64 |
+| bslx.cpp:261:260:261:263 | *call to getFloat32 | semmle.label | *call to getFloat32 |
+| bslx.cpp:261:274:261:277 | *call to getFloat64 | semmle.label | *call to getFloat64 |
+| bslx.cpp:261:287:261:292 | *call to getString | semmle.label | *call to getString |
+| bslx.cpp:261:305:261:315 | *call to getArrayInt8 | semmle.label | *call to getArrayInt8 |
+| bslx.cpp:261:329:261:340 | *call to getArrayUint8 | semmle.label | *call to getArrayUint8 |
+| bslx.cpp:261:354:261:364 | *call to getArrayInt16 | semmle.label | *call to getArrayInt16 |
+| bslx.cpp:261:379:261:390 | *call to getArrayUint16 | semmle.label | *call to getArrayUint16 |
+| bslx.cpp:261:404:261:414 | *call to getArrayInt24 | semmle.label | *call to getArrayInt24 |
+| bslx.cpp:261:429:261:440 | *call to getArrayUint24 | semmle.label | *call to getArrayUint24 |
+| bslx.cpp:261:454:261:464 | *call to getArrayInt32 | semmle.label | *call to getArrayInt32 |
+| bslx.cpp:261:479:261:490 | *call to getArrayUint32 | semmle.label | *call to getArrayUint32 |
+| bslx.cpp:261:504:261:515 | *call to getArrayInt40 | semmle.label | *call to getArrayInt40 |
+| bslx.cpp:261:530:261:542 | *call to getArrayUint40 | semmle.label | *call to getArrayUint40 |
+| bslx.cpp:261:556:261:567 | *call to getArrayInt48 | semmle.label | *call to getArrayInt48 |
+| bslx.cpp:261:582:261:594 | *call to getArrayUint48 | semmle.label | *call to getArrayUint48 |
+| bslx.cpp:261:608:261:619 | *call to getArrayInt56 | semmle.label | *call to getArrayInt56 |
+| bslx.cpp:261:634:261:646 | *call to getArrayUint56 | semmle.label | *call to getArrayUint56 |
+| bslx.cpp:261:660:261:671 | *call to getArrayInt64 | semmle.label | *call to getArrayInt64 |
+| bslx.cpp:261:686:261:698 | *call to getArrayUint64 | semmle.label | *call to getArrayUint64 |
+| bslx.cpp:261:714:261:724 | *call to getArrayFloat32 | semmle.label | *call to getArrayFloat32 |
+| bslx.cpp:261:740:261:750 | *call to getArrayFloat64 | semmle.label | *call to getArrayFloat64 |
+| bslx.cpp:261:761:261:763 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:262:7:262:17 | * ... | semmle.label | * ... |
+| bslx.cpp:266:33:266:40 | call to source | semmle.label | call to source |
+| bslx.cpp:267:34:267:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:267:41:267:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:269:53:269:58 | *stream | semmle.label | *stream |
+| bslx.cpp:269:61:269:61 | bdexStreamIn output argument | semmle.label | bdexStreamIn output argument |
+| bslx.cpp:270:7:270:7 | x | semmle.label | x |
+| bslx.cpp:271:53:271:58 | *stream | semmle.label | *stream |
+| bslx.cpp:271:61:271:61 | bdexStreamIn output argument | semmle.label | bdexStreamIn output argument |
+| bslx.cpp:272:7:272:7 | x | semmle.label | x |
+| bslx.cpp:274:52:274:66 | *call to bdexStreamIn | semmle.label | *call to bdexStreamIn |
+| bslx.cpp:274:53:274:58 | *stream | semmle.label | *stream |
+| bslx.cpp:274:77:274:79 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:275:7:275:17 | * ... | semmle.label | * ... |
+| bslx.cpp:279:33:279:40 | call to source | semmle.label | call to source |
+| bslx.cpp:280:34:280:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:280:41:280:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:282:53:282:58 | *stream | semmle.label | *stream |
+| bslx.cpp:282:61:282:63 | bdexStreamIn output argument | semmle.label | bdexStreamIn output argument |
+| bslx.cpp:283:7:283:17 | * ... | semmle.label | * ... |
+| bslx.cpp:293:33:293:40 | call to source | semmle.label | call to source |
+| bslx.cpp:294:34:294:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:294:41:294:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:296:53:296:58 | *stream | semmle.label | *stream |
+| bslx.cpp:296:61:296:63 | bdexStreamIn output argument | semmle.label | bdexStreamIn output argument |
+| bslx.cpp:297:7:297:9 | out | semmle.label | out |
+| bslx.cpp:306:40:306:60 | call to source | semmle.label | call to source |
+| bslx.cpp:306:40:306:60 | call to source | semmle.label | call to source |
+| bslx.cpp:307:2:307:7 | reset output argument | semmle.label | reset output argument |
+| bslx.cpp:307:15:307:18 | *data | semmle.label | *data |
+| bslx.cpp:309:2:309:7 | *stream | semmle.label | *stream |
+| bslx.cpp:309:19:309:21 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:310:7:310:17 | * ... | semmle.label | * ... |
+| bslx.cpp:314:33:314:40 | call to source | semmle.label | call to source |
+| bslx.cpp:315:34:315:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:315:41:315:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:318:2:318:7 | *stream | semmle.label | *stream |
+| bslx.cpp:318:19:318:21 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:319:7:319:17 | * ... | semmle.label | * ... |
+| bslx.cpp:333:33:333:40 | call to source | semmle.label | call to source |
+| bslx.cpp:334:34:334:39 | call to ByteInStream | semmle.label | call to ByteInStream |
+| bslx.cpp:334:41:334:51 | *call to data | semmle.label | *call to data |
+| bslx.cpp:338:2:338:7 | *stream | semmle.label | *stream |
+| bslx.cpp:338:19:338:21 | getString output argument | semmle.label | getString output argument |
+| bslx.cpp:340:7:340:17 | * ... | semmle.label | * ... |
+| protobuf.cpp:105:27:105:51 | call to source | semmle.label | call to source |
+| protobuf.cpp:105:27:105:51 | call to source | semmle.label | call to source |
+| protobuf.cpp:106:2:106:4 | ParseFromString output argument | semmle.label | ParseFromString output argument |
+| protobuf.cpp:106:22:106:25 | data | semmle.label | data |
+| protobuf.cpp:107:7:107:9 | msg | semmle.label | msg |
+| protobuf.cpp:112:20:112:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:112:20:112:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:113:2:113:4 | ParseFromString output argument | semmle.label | ParseFromString output argument |
+| protobuf.cpp:113:22:113:25 | *data | semmle.label | *data |
+| protobuf.cpp:114:7:114:9 | msg | semmle.label | msg |
+| protobuf.cpp:119:27:119:51 | call to source | semmle.label | call to source |
+| protobuf.cpp:119:27:119:51 | call to source | semmle.label | call to source |
+| protobuf.cpp:120:2:120:4 | ParsePartialFromString output argument | semmle.label | ParsePartialFromString output argument |
+| protobuf.cpp:120:29:120:32 | data | semmle.label | data |
+| protobuf.cpp:121:7:121:9 | msg | semmle.label | msg |
+| protobuf.cpp:126:20:126:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:126:20:126:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:127:2:127:4 | ParsePartialFromString output argument | semmle.label | ParsePartialFromString output argument |
+| protobuf.cpp:127:29:127:32 | *data | semmle.label | *data |
+| protobuf.cpp:128:7:128:9 | msg | semmle.label | msg |
+| protobuf.cpp:133:27:133:51 | call to source | semmle.label | call to source |
+| protobuf.cpp:133:27:133:51 | call to source | semmle.label | call to source |
+| protobuf.cpp:134:2:134:4 | MergeFromString output argument | semmle.label | MergeFromString output argument |
+| protobuf.cpp:134:22:134:25 | data | semmle.label | data |
+| protobuf.cpp:135:7:135:9 | msg | semmle.label | msg |
+| protobuf.cpp:140:20:140:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:140:20:140:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:141:2:141:4 | MergeFromString output argument | semmle.label | MergeFromString output argument |
+| protobuf.cpp:141:22:141:25 | *data | semmle.label | *data |
+| protobuf.cpp:142:7:142:9 | msg | semmle.label | msg |
+| protobuf.cpp:147:27:147:51 | call to source | semmle.label | call to source |
+| protobuf.cpp:147:27:147:51 | call to source | semmle.label | call to source |
+| protobuf.cpp:148:2:148:4 | MergePartialFromString output argument | semmle.label | MergePartialFromString output argument |
+| protobuf.cpp:148:29:148:32 | data | semmle.label | data |
+| protobuf.cpp:149:7:149:9 | msg | semmle.label | msg |
+| protobuf.cpp:154:20:154:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:154:20:154:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:155:2:155:4 | MergePartialFromString output argument | semmle.label | MergePartialFromString output argument |
+| protobuf.cpp:155:29:155:32 | *data | semmle.label | *data |
+| protobuf.cpp:156:7:156:9 | msg | semmle.label | msg |
+| protobuf.cpp:161:19:161:38 | call to source | semmle.label | call to source |
+| protobuf.cpp:162:2:162:4 | ParseFromArray output argument | semmle.label | ParseFromArray output argument |
+| protobuf.cpp:162:21:162:31 | *call to data | semmle.label | *call to data |
+| protobuf.cpp:163:7:163:9 | msg | semmle.label | msg |
+| protobuf.cpp:168:19:168:38 | call to source | semmle.label | call to source |
+| protobuf.cpp:169:2:169:4 | ParsePartialFromArray output argument | semmle.label | ParsePartialFromArray output argument |
+| protobuf.cpp:169:28:169:38 | *call to data | semmle.label | *call to data |
+| protobuf.cpp:170:7:170:9 | msg | semmle.label | msg |
+| protobuf.cpp:175:20:175:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:175:20:175:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:176:2:176:4 | ParseFromCord output argument | semmle.label | ParseFromCord output argument |
+| protobuf.cpp:176:20:176:23 | *data | semmle.label | *data |
+| protobuf.cpp:177:7:177:9 | msg | semmle.label | msg |
+| protobuf.cpp:182:20:182:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:182:20:182:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:183:2:183:4 | ParsePartialFromCord output argument | semmle.label | ParsePartialFromCord output argument |
+| protobuf.cpp:183:27:183:30 | *data | semmle.label | *data |
+| protobuf.cpp:184:7:184:9 | msg | semmle.label | msg |
+| protobuf.cpp:189:20:189:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:189:20:189:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:190:2:190:4 | MergeFromCord output argument | semmle.label | MergeFromCord output argument |
+| protobuf.cpp:190:20:190:23 | *data | semmle.label | *data |
+| protobuf.cpp:191:7:191:9 | msg | semmle.label | msg |
+| protobuf.cpp:196:20:196:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:196:20:196:37 | call to source | semmle.label | call to source |
+| protobuf.cpp:197:2:197:4 | MergePartialFromCord output argument | semmle.label | MergePartialFromCord output argument |
+| protobuf.cpp:197:27:197:30 | *data | semmle.label | *data |
+| protobuf.cpp:198:7:198:9 | msg | semmle.label | msg |
+| protobuf.cpp:203:20:203:39 | call to source | semmle.label | call to source |
+| protobuf.cpp:203:20:203:39 | call to source | semmle.label | call to source |
+| protobuf.cpp:204:2:204:4 | ParseFromIstream output argument | semmle.label | ParseFromIstream output argument |
+| protobuf.cpp:204:23:204:25 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:205:7:205:9 | msg | semmle.label | msg |
+| protobuf.cpp:210:20:210:39 | call to source | semmle.label | call to source |
+| protobuf.cpp:210:20:210:39 | call to source | semmle.label | call to source |
+| protobuf.cpp:211:2:211:4 | ParsePartialFromIstream output argument | semmle.label | ParsePartialFromIstream output argument |
+| protobuf.cpp:211:30:211:32 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:212:7:212:9 | msg | semmle.label | msg |
+| protobuf.cpp:217:27:217:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:217:27:217:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:218:2:218:4 | ParseFromZeroCopyStream output argument | semmle.label | ParseFromZeroCopyStream output argument |
+| protobuf.cpp:218:30:218:32 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:219:7:219:9 | msg | semmle.label | msg |
+| protobuf.cpp:224:27:224:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:224:27:224:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:225:2:225:4 | ParsePartialFromZeroCopyStream output argument | semmle.label | ParsePartialFromZeroCopyStream output argument |
+| protobuf.cpp:225:37:225:39 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:226:7:226:9 | msg | semmle.label | msg |
+| protobuf.cpp:231:27:231:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:231:27:231:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:232:2:232:4 | ParseFromBoundedZeroCopyStream output argument | semmle.label | ParseFromBoundedZeroCopyStream output argument |
+| protobuf.cpp:232:37:232:39 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:233:7:233:9 | msg | semmle.label | msg |
+| protobuf.cpp:238:27:238:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:238:27:238:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:239:2:239:4 | ParsePartialFromBoundedZeroCopyStream output argument | semmle.label | ParsePartialFromBoundedZeroCopyStream output argument |
+| protobuf.cpp:239:44:239:46 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:240:7:240:9 | msg | semmle.label | msg |
+| protobuf.cpp:245:27:245:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:245:27:245:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:246:2:246:4 | MergeFromBoundedZeroCopyStream output argument | semmle.label | MergeFromBoundedZeroCopyStream output argument |
+| protobuf.cpp:246:37:246:39 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:247:7:247:9 | msg | semmle.label | msg |
+| protobuf.cpp:252:27:252:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:252:27:252:53 | call to source | semmle.label | call to source |
+| protobuf.cpp:253:2:253:4 | MergePartialFromBoundedZeroCopyStream output argument | semmle.label | MergePartialFromBoundedZeroCopyStream output argument |
+| protobuf.cpp:253:44:253:46 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:254:7:254:9 | msg | semmle.label | msg |
+| protobuf.cpp:259:24:259:47 | call to source | semmle.label | call to source |
+| protobuf.cpp:259:24:259:47 | call to source | semmle.label | call to source |
+| protobuf.cpp:260:2:260:4 | ParseFromCodedStream output argument | semmle.label | ParseFromCodedStream output argument |
+| protobuf.cpp:260:27:260:29 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:261:7:261:9 | msg | semmle.label | msg |
+| protobuf.cpp:266:24:266:47 | call to source | semmle.label | call to source |
+| protobuf.cpp:266:24:266:47 | call to source | semmle.label | call to source |
+| protobuf.cpp:267:2:267:4 | ParsePartialFromCodedStream output argument | semmle.label | ParsePartialFromCodedStream output argument |
+| protobuf.cpp:267:34:267:36 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:268:7:268:9 | msg | semmle.label | msg |
+| protobuf.cpp:273:24:273:47 | call to source | semmle.label | call to source |
+| protobuf.cpp:273:24:273:47 | call to source | semmle.label | call to source |
+| protobuf.cpp:274:2:274:4 | MergeFromCodedStream output argument | semmle.label | MergeFromCodedStream output argument |
+| protobuf.cpp:274:27:274:29 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:275:7:275:9 | msg | semmle.label | msg |
+| protobuf.cpp:280:24:280:47 | call to source | semmle.label | call to source |
+| protobuf.cpp:280:24:280:47 | call to source | semmle.label | call to source |
+| protobuf.cpp:281:2:281:4 | MergePartialFromCodedStream output argument | semmle.label | MergePartialFromCodedStream output argument |
+| protobuf.cpp:281:34:281:36 | *& ... | semmle.label | *& ... |
+| protobuf.cpp:282:7:282:9 | msg | semmle.label | msg |
+| protobuf.cpp:295:15:295:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:295:15:295:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:297:2:297:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:297:24:297:27 | SerializeToString output argument | semmle.label | SerializeToString output argument |
+| protobuf.cpp:298:7:298:9 | out | semmle.label | out |
+| protobuf.cpp:302:15:302:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:302:15:302:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:304:2:304:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:304:31:304:34 | SerializePartialToString output argument | semmle.label | SerializePartialToString output argument |
+| protobuf.cpp:305:7:305:9 | out | semmle.label | out |
+| protobuf.cpp:309:15:309:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:309:15:309:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:311:2:311:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:311:21:311:24 | AppendToString output argument | semmle.label | AppendToString output argument |
+| protobuf.cpp:312:7:312:9 | out | semmle.label | out |
+| protobuf.cpp:316:15:316:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:316:15:316:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:318:2:318:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:318:28:318:31 | AppendPartialToString output argument | semmle.label | AppendPartialToString output argument |
+| protobuf.cpp:319:7:319:9 | out | semmle.label | out |
+| protobuf.cpp:323:15:323:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:323:15:323:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:325:2:325:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:325:24:325:27 | SerializeToString output argument | semmle.label | SerializeToString output argument |
+| protobuf.cpp:326:7:326:9 | out | semmle.label | out |
+| protobuf.cpp:330:15:330:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:330:15:330:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:332:2:332:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:332:31:332:34 | SerializePartialToString output argument | semmle.label | SerializePartialToString output argument |
+| protobuf.cpp:333:7:333:9 | out | semmle.label | out |
+| protobuf.cpp:337:15:337:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:337:15:337:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:339:2:339:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:339:21:339:24 | AppendToString output argument | semmle.label | AppendToString output argument |
+| protobuf.cpp:340:7:340:9 | out | semmle.label | out |
+| protobuf.cpp:344:15:344:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:344:15:344:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:346:2:346:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:346:28:346:31 | AppendPartialToString output argument | semmle.label | AppendPartialToString output argument |
+| protobuf.cpp:347:7:347:9 | out | semmle.label | out |
+| protobuf.cpp:351:15:351:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:351:15:351:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:353:2:353:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:353:23:353:25 | SerializeToArray output argument | semmle.label | SerializeToArray output argument |
+| protobuf.cpp:354:7:354:10 | * ... | semmle.label | * ... |
+| protobuf.cpp:358:15:358:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:358:15:358:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:360:2:360:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:360:30:360:32 | SerializePartialToArray output argument | semmle.label | SerializePartialToArray output argument |
+| protobuf.cpp:361:7:361:10 | * ... | semmle.label | * ... |
+| protobuf.cpp:365:15:365:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:365:15:365:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:367:2:367:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:367:22:367:25 | SerializeToCord output argument | semmle.label | SerializeToCord output argument |
+| protobuf.cpp:368:7:368:9 | out | semmle.label | out |
+| protobuf.cpp:372:15:372:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:372:15:372:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:374:2:374:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:374:29:374:32 | SerializePartialToCord output argument | semmle.label | SerializePartialToCord output argument |
+| protobuf.cpp:375:7:375:9 | out | semmle.label | out |
+| protobuf.cpp:379:15:379:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:379:15:379:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:381:2:381:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:381:19:381:22 | AppendToCord output argument | semmle.label | AppendToCord output argument |
+| protobuf.cpp:382:7:382:9 | out | semmle.label | out |
+| protobuf.cpp:386:15:386:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:386:15:386:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:388:2:388:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:388:26:388:29 | AppendPartialToCord output argument | semmle.label | AppendPartialToCord output argument |
+| protobuf.cpp:389:7:389:9 | out | semmle.label | out |
+| protobuf.cpp:393:15:393:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:393:15:393:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:395:2:395:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:395:25:395:28 | SerializeToOstream output argument | semmle.label | SerializeToOstream output argument |
+| protobuf.cpp:396:7:396:9 | out | semmle.label | out |
+| protobuf.cpp:400:15:400:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:400:15:400:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:402:2:402:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:402:32:402:35 | SerializePartialToOstream output argument | semmle.label | SerializePartialToOstream output argument |
+| protobuf.cpp:403:7:403:9 | out | semmle.label | out |
+| protobuf.cpp:407:15:407:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:407:15:407:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:409:2:409:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:409:32:409:35 | SerializeToZeroCopyStream output argument | semmle.label | SerializeToZeroCopyStream output argument |
+| protobuf.cpp:410:7:410:9 | out | semmle.label | out |
+| protobuf.cpp:414:15:414:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:414:15:414:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:416:2:416:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:416:39:416:42 | SerializePartialToZeroCopyStream output argument | semmle.label | SerializePartialToZeroCopyStream output argument |
+| protobuf.cpp:417:7:417:9 | out | semmle.label | out |
+| protobuf.cpp:421:15:421:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:421:15:421:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:423:2:423:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:423:29:423:32 | SerializeToCodedStream output argument | semmle.label | SerializeToCodedStream output argument |
+| protobuf.cpp:424:7:424:9 | out | semmle.label | out |
+| protobuf.cpp:428:15:428:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:428:15:428:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:430:2:430:4 | *msg | semmle.label | *msg |
+| protobuf.cpp:430:36:430:39 | SerializePartialToCodedStream output argument | semmle.label | SerializePartialToCodedStream output argument |
+| protobuf.cpp:431:7:431:9 | out | semmle.label | out |
+| protobuf.cpp:437:15:437:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:437:15:437:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:438:7:438:9 | *msg | semmle.label | *msg |
+| protobuf.cpp:438:11:438:27 | call to SerializeAsString | semmle.label | call to SerializeAsString |
+| protobuf.cpp:442:15:442:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:442:15:442:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:443:7:443:9 | *msg | semmle.label | *msg |
+| protobuf.cpp:443:11:443:34 | call to SerializePartialAsString | semmle.label | call to SerializePartialAsString |
+| protobuf.cpp:447:15:447:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:447:15:447:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:448:7:448:9 | *msg | semmle.label | *msg |
+| protobuf.cpp:448:11:448:25 | call to SerializeAsCord | semmle.label | call to SerializeAsCord |
+| protobuf.cpp:452:15:452:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:452:15:452:28 | call to source | semmle.label | call to source |
+| protobuf.cpp:453:7:453:9 | *msg | semmle.label | *msg |
+| protobuf.cpp:453:11:453:32 | call to SerializePartialAsCord | semmle.label | call to SerializePartialAsCord |
| test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | semmle.label | *ymlStepGenerated_with_body |
| test.cpp:7:47:7:52 | value2 | semmle.label | value2 |
| test.cpp:7:64:7:69 | value2 | semmle.label | value2 |
@@ -480,6 +2659,7 @@ nodes
| test.cpp:47:12:47:19 | *arg [x] | semmle.label | *arg [x] |
| test.cpp:48:13:48:13 | *s [x] | semmle.label | *s [x] |
| test.cpp:48:16:48:16 | x | semmle.label | x |
+| test.cpp:48:16:48:16 | x | semmle.label | x |
| test.cpp:56:2:56:2 | *s [post update] [x] | semmle.label | *s [post update] [x] |
| test.cpp:56:2:56:18 | ... = ... | semmle.label | ... = ... |
| test.cpp:56:8:56:16 | call to ymlSource | semmle.label | call to ymlSource |
@@ -556,20 +2736,234 @@ nodes
| test.cpp:218:11:218:11 | x | semmle.label | x |
| test.cpp:222:3:222:3 | operator[] output argument | semmle.label | operator[] output argument |
| test.cpp:222:3:222:20 | ... = ... | semmle.label | ... = ... |
-| test.cpp:222:10:222:20 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:222:10:222:18 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:223:12:223:12 | *s | semmle.label | *s |
| test.cpp:223:13:223:15 | call to operator[] | semmle.label | call to operator[] |
| test.cpp:223:13:223:15 | call to operator[] | semmle.label | call to operator[] |
| test.cpp:224:11:224:11 | c | semmle.label | c |
+| test.cpp:242:29:242:29 | *s [value] | semmle.label | *s [value] |
+| test.cpp:243:10:243:10 | *s [value] | semmle.label | *s [value] |
+| test.cpp:243:13:243:17 | value | semmle.label | value |
+| test.cpp:243:13:243:17 | value | semmle.label | value |
+| test.cpp:247:26:247:39 | call to ymlFieldSource | semmle.label | call to ymlFieldSource |
+| test.cpp:247:26:247:39 | call to ymlFieldSource [value] | semmle.label | call to ymlFieldSource [value] |
+| test.cpp:248:10:248:16 | *wrapper [value] | semmle.label | *wrapper [value] |
+| test.cpp:248:18:248:22 | value | semmle.label | value |
+| test.cpp:248:18:248:22 | value | semmle.label | value |
+| test.cpp:250:32:250:32 | source_from_callback_template output argument | semmle.label | source_from_callback_template output argument |
+| test.cpp:250:32:250:32 | source_from_callback_template output argument [value] | semmle.label | source_from_callback_template output argument [value] |
+| test.cpp:251:27:251:27 | source_from_callback_ptr output argument | semmle.label | source_from_callback_ptr output argument |
+| test.cpp:251:27:251:27 | source_from_callback_ptr output argument [value] | semmle.label | source_from_callback_ptr output argument [value] |
+| test.cpp:257:35:257:35 | *s [value] | semmle.label | *s [value] |
+| test.cpp:258:12:258:12 | *s [value] | semmle.label | *s [value] |
+| test.cpp:258:15:258:19 | value | semmle.label | value |
+| test.cpp:258:15:258:19 | value | semmle.label | value |
+| test.cpp:262:27:262:31 | source_from_callback_ptr output argument | semmle.label | source_from_callback_ptr output argument |
+| test.cpp:262:27:262:31 | source_from_callback_ptr output argument [value] | semmle.label | source_from_callback_ptr output argument [value] |
+| test.cpp:264:32:266:2 | source_from_callback_template output argument | semmle.label | source_from_callback_template output argument |
+| test.cpp:264:32:266:2 | source_from_callback_template output argument [value] | semmle.label | source_from_callback_template output argument [value] |
+| test.cpp:264:56:264:56 | *s [value] | semmle.label | *s [value] |
+| test.cpp:265:11:265:11 | *s [value] | semmle.label | *s [value] |
+| test.cpp:265:14:265:18 | value | semmle.label | value |
+| test.cpp:265:14:265:18 | value | semmle.label | value |
+| test.cpp:268:27:268:27 | source_from_callback_ptr output argument | semmle.label | source_from_callback_ptr output argument |
+| test.cpp:268:27:268:27 | source_from_callback_ptr output argument [value] | semmle.label | source_from_callback_ptr output argument [value] |
+| test.cpp:268:51:268:51 | *s [value] | semmle.label | *s [value] |
+| test.cpp:269:11:269:11 | *s [value] | semmle.label | *s [value] |
+| test.cpp:269:14:269:18 | value | semmle.label | value |
+| test.cpp:269:14:269:18 | value | semmle.label | value |
+| test.cpp:273:40:273:40 | *s [value] | semmle.label | *s [value] |
+| test.cpp:274:12:274:12 | *s [value] | semmle.label | *s [value] |
+| test.cpp:274:15:274:19 | value | semmle.label | value |
+| test.cpp:274:15:274:19 | value | semmle.label | value |
+| test.cpp:278:32:278:34 | source_from_callback_template output argument | semmle.label | source_from_callback_template output argument |
+| test.cpp:278:32:278:34 | source_from_callback_template output argument [value] | semmle.label | source_from_callback_template output argument [value] |
+| test.cpp:293:5:293:26 | *callback_returning_int | semmle.label | *callback_returning_int |
+| test.cpp:294:5:294:28 | *callback_returning_int_2 | semmle.label | *callback_returning_int_2 |
+| test.cpp:295:6:295:31 | **callback_returning_ptr_int | semmle.label | **callback_returning_ptr_int |
+| test.cpp:297:5:297:20 | *return_ymlSource | semmle.label | *return_ymlSource |
+| test.cpp:297:33:297:41 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:297:33:297:41 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:299:6:299:28 | **return_ptr_to_ymlSource | semmle.label | **return_ptr_to_ymlSource |
+| test.cpp:299:41:299:52 | *call to ymlSourcePtr | semmle.label | *call to ymlSourcePtr |
+| test.cpp:299:41:299:52 | call to ymlSourcePtr | semmle.label | call to ymlSourcePtr |
+| test.cpp:304:10:304:24 | * ... | semmle.label | * ... |
+| test.cpp:304:11:304:22 | call to ymlSourcePtr | semmle.label | call to ymlSourcePtr |
+| test.cpp:306:39:306:60 | source_from_callback_return_template output argument | semmle.label | source_from_callback_return_template output argument |
+| test.cpp:307:10:307:31 | call to callback_returning_int | semmle.label | call to callback_returning_int |
+| test.cpp:307:10:307:31 | call to callback_returning_int | semmle.label | call to callback_returning_int |
+| test.cpp:309:34:309:57 | source_from_callback_return_ptr output argument | semmle.label | source_from_callback_return_ptr output argument |
+| test.cpp:310:10:310:33 | call to callback_returning_int_2 | semmle.label | call to callback_returning_int_2 |
+| test.cpp:310:10:310:33 | call to callback_returning_int_2 | semmle.label | call to callback_returning_int_2 |
+| test.cpp:312:38:312:63 | source_ptr_from_callback_return_ptr output argument | semmle.label | source_ptr_from_callback_return_ptr output argument |
+| test.cpp:313:13:313:38 | *call to callback_returning_ptr_int | semmle.label | *call to callback_returning_ptr_int |
+| test.cpp:313:13:313:38 | *call to callback_returning_ptr_int | semmle.label | *call to callback_returning_ptr_int |
+| test.cpp:315:10:315:13 | * ... | semmle.label | * ... |
+| test.cpp:317:37:317:64 | [...](...){...} | semmle.label | [...](...){...} |
+| test.cpp:317:39:317:39 | *operator() | semmle.label | *operator() |
+| test.cpp:317:51:317:59 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:317:51:317:59 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:318:37:318:52 | return_ymlSource | semmle.label | return_ymlSource |
+| test.cpp:320:36:320:36 | call to operator int *(*)() | semmle.label | call to operator int *(*)() |
+| test.cpp:320:38:320:38 | **operator() | semmle.label | **operator() |
+| test.cpp:320:50:320:61 | *call to ymlSourcePtr | semmle.label | *call to ymlSourcePtr |
+| test.cpp:320:50:320:61 | call to ymlSourcePtr | semmle.label | call to ymlSourcePtr |
+| test.cpp:321:36:321:58 | return_ptr_to_ymlSource | semmle.label | return_ptr_to_ymlSource |
+| test.cpp:324:36:324:36 | p | semmle.label | p |
+| test.cpp:324:36:324:36 | p | semmle.label | p |
+| test.cpp:324:53:324:53 | s | semmle.label | s |
+| test.cpp:324:53:324:53 | s | semmle.label | s |
+| test.cpp:324:61:324:66 | source | semmle.label | source |
+| test.cpp:325:10:325:10 | *p [value] | semmle.label | *p [value] |
+| test.cpp:325:13:325:17 | value | semmle.label | value |
+| test.cpp:325:13:325:17 | value | semmle.label | value |
+| test.cpp:327:10:327:20 | * ... | semmle.label | * ... |
+| test.cpp:327:10:327:20 | * ... | semmle.label | * ... |
+| test.cpp:327:11:327:11 | *p [*pointer] | semmle.label | *p [*pointer] |
+| test.cpp:329:10:329:10 | *s [value] | semmle.label | *s [value] |
+| test.cpp:329:12:329:16 | value | semmle.label | value |
+| test.cpp:329:12:329:16 | value | semmle.label | value |
+| test.cpp:331:10:331:19 | * ... | semmle.label | * ... |
+| test.cpp:331:10:331:19 | * ... | semmle.label | * ... |
+| test.cpp:331:11:331:11 | *s [*pointer] | semmle.label | *s [*pointer] |
+| test.cpp:334:10:334:16 | * ... | semmle.label | * ... |
+| test.cpp:341:3:341:22 | *this [Return] [s] | semmle.label | *this [Return] [s] |
+| test.cpp:341:30:341:32 | arg | semmle.label | arg |
+| test.cpp:342:5:342:8 | *this [post update] [s] | semmle.label | *this [post update] [s] |
+| test.cpp:342:5:342:17 | ... = ... | semmle.label | ... = ... |
+| test.cpp:345:3:345:22 | *this [Return] [ul] | semmle.label | *this [Return] [ul] |
+| test.cpp:345:38:345:40 | arg | semmle.label | arg |
+| test.cpp:346:5:346:8 | *this [post update] [ul] | semmle.label | *this [post update] [ul] |
+| test.cpp:346:5:346:18 | ... = ... | semmle.label | ... = ... |
+| test.cpp:362:15:362:23 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:362:15:362:25 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:363:5:363:5 | forward output argument [s] | semmle.label | forward output argument [s] |
+| test.cpp:363:5:363:5 | forward output argument [ul] | semmle.label | forward output argument [ul] |
+| test.cpp:363:15:363:15 | *x | semmle.label | *x |
+| test.cpp:365:30:365:30 | *f [s] | semmle.label | *f [s] |
+| test.cpp:365:30:365:30 | *f [ul] | semmle.label | *f [ul] |
+| test.cpp:365:32:365:34 | call to get [s] | semmle.label | call to get [s] |
+| test.cpp:365:32:365:34 | call to get [s] | semmle.label | call to get [s] |
+| test.cpp:365:32:365:34 | call to get [ul] | semmle.label | call to get [ul] |
+| test.cpp:365:32:365:34 | call to get [ul] | semmle.label | call to get [ul] |
+| test.cpp:366:13:366:13 | *c [s] | semmle.label | *c [s] |
+| test.cpp:366:13:366:15 | s | semmle.label | s |
+| test.cpp:366:15:366:15 | s | semmle.label | s |
+| test.cpp:367:13:367:13 | *c [ul] | semmle.label | *c [ul] |
+| test.cpp:367:13:367:16 | ul | semmle.label | ul |
+| test.cpp:367:15:367:16 | ul | semmle.label | ul |
+| test.cpp:371:24:371:32 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:371:24:371:34 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:372:5:372:5 | forward output argument [s] | semmle.label | forward output argument [s] |
+| test.cpp:372:5:372:5 | forward output argument [ul] | semmle.label | forward output argument [ul] |
+| test.cpp:372:15:372:16 | *ul | semmle.label | *ul |
+| test.cpp:374:30:374:30 | *f [s] | semmle.label | *f [s] |
+| test.cpp:374:30:374:30 | *f [ul] | semmle.label | *f [ul] |
+| test.cpp:374:32:374:34 | call to get [s] | semmle.label | call to get [s] |
+| test.cpp:374:32:374:34 | call to get [s] | semmle.label | call to get [s] |
+| test.cpp:374:32:374:34 | call to get [ul] | semmle.label | call to get [ul] |
+| test.cpp:374:32:374:34 | call to get [ul] | semmle.label | call to get [ul] |
+| test.cpp:375:13:375:13 | *c [s] | semmle.label | *c [s] |
+| test.cpp:375:13:375:15 | s | semmle.label | s |
+| test.cpp:375:15:375:15 | s | semmle.label | s |
+| test.cpp:376:13:376:13 | *c [ul] | semmle.label | *c [ul] |
+| test.cpp:376:13:376:16 | ul | semmle.label | ul |
+| test.cpp:376:15:376:16 | ul | semmle.label | ul |
+| test.cpp:398:11:398:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:398:11:398:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:399:15:399:36 | call to makeForwarded [x] | semmle.label | call to makeForwarded [x] |
+| test.cpp:399:15:399:36 | call to makeForwarded [x] | semmle.label | call to makeForwarded [x] |
+| test.cpp:399:38:399:38 | x | semmle.label | x |
+| test.cpp:400:11:400:11 | *e [x] | semmle.label | *e [x] |
+| test.cpp:400:13:400:13 | x | semmle.label | x |
+| test.cpp:400:13:400:13 | x | semmle.label | x |
+| test.cpp:405:11:405:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:405:11:405:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:406:3:406:3 | forwardToElement output argument [x] | semmle.label | forwardToElement output argument [x] |
+| test.cpp:406:22:406:22 | x | semmle.label | x |
+| test.cpp:407:15:407:15 | *f [x] | semmle.label | *f [x] |
+| test.cpp:407:17:407:19 | call to get [x] | semmle.label | call to get [x] |
+| test.cpp:407:17:407:19 | call to get [x] | semmle.label | call to get [x] |
+| test.cpp:408:11:408:11 | *e [x] | semmle.label | *e [x] |
+| test.cpp:408:13:408:13 | x | semmle.label | x |
+| test.cpp:408:13:408:13 | x | semmle.label | x |
+| test.cpp:413:11:413:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:413:11:413:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:414:3:414:3 | emplace output argument [element, x] | semmle.label | emplace output argument [element, x] |
+| test.cpp:414:16:414:16 | *x | semmle.label | *x |
+| test.cpp:416:15:416:15 | *c [element, x] | semmle.label | *c [element, x] |
+| test.cpp:416:20:416:22 | call to get [x] | semmle.label | call to get [x] |
+| test.cpp:416:20:416:22 | call to get [x] | semmle.label | call to get [x] |
+| test.cpp:417:11:417:11 | *e [x] | semmle.label | *e [x] |
+| test.cpp:417:13:417:13 | x | semmle.label | x |
+| test.cpp:417:13:417:13 | x | semmle.label | x |
+| test.cpp:422:3:422:8 | emplace output argument [element] | semmle.label | emplace output argument [element] |
+| test.cpp:422:21:422:29 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:422:21:422:29 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:422:21:422:31 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:423:11:423:16 | *scalar [element] | semmle.label | *scalar [element] |
+| test.cpp:423:18:423:20 | call to get | semmle.label | call to get |
+| test.cpp:423:21:423:23 | call to get | semmle.label | call to get |
+| test.cpp:426:3:426:9 | emplace output argument [element] | semmle.label | emplace output argument [element] |
+| test.cpp:426:22:426:33 | *call to ymlSourcePtr | semmle.label | *call to ymlSourcePtr |
+| test.cpp:426:22:426:33 | call to ymlSourcePtr | semmle.label | call to ymlSourcePtr |
+| test.cpp:426:22:426:35 | **call to ymlSourcePtr | semmle.label | **call to ymlSourcePtr |
+| test.cpp:427:11:427:24 | * ... | semmle.label | * ... |
+| test.cpp:427:12:427:18 | *pointer [element] | semmle.label | *pointer [element] |
+| test.cpp:437:11:437:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:437:11:437:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:438:3:438:3 | emplace output argument [element, x] | semmle.label | emplace output argument [element, x] |
+| test.cpp:438:16:438:16 | *x | semmle.label | *x |
+| test.cpp:440:34:440:34 | *c [element, x] | semmle.label | *c [element, x] |
+| test.cpp:440:39:440:41 | call to get [x] | semmle.label | call to get [x] |
+| test.cpp:440:39:440:41 | call to get [x] | semmle.label | call to get [x] |
+| test.cpp:441:11:441:11 | *e [x] | semmle.label | *e [x] |
+| test.cpp:441:13:441:13 | x | semmle.label | x |
+| test.cpp:441:13:441:13 | x | semmle.label | x |
+| test.cpp:446:3:446:28 | *ElementWithOverloadedArity [post update] [x] | semmle.label | *ElementWithOverloadedArity [post update] [x] |
+| test.cpp:446:3:446:28 | *this [Return] [x] | semmle.label | *this [Return] [x] |
+| test.cpp:446:34:446:38 | first | semmle.label | first |
+| test.cpp:446:45:446:49 | first | semmle.label | first |
+| test.cpp:447:3:447:28 | *ElementWithOverloadedArity [post update] [x] | semmle.label | *ElementWithOverloadedArity [post update] [x] |
+| test.cpp:447:3:447:28 | *this [Return] [x] | semmle.label | *this [Return] [x] |
+| test.cpp:447:39:447:44 | second | semmle.label | second |
+| test.cpp:447:51:447:56 | second | semmle.label | second |
+| test.cpp:451:11:451:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:451:11:451:19 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:454:5:454:5 | emplace output argument [element, x] | semmle.label | emplace output argument [element, x] |
+| test.cpp:454:18:454:18 | *x | semmle.label | *x |
+| test.cpp:455:13:455:13 | *c [element, x] | semmle.label | *c [element, x] |
+| test.cpp:455:18:455:20 | *call to get [x] | semmle.label | *call to get [x] |
+| test.cpp:455:21:455:21 | x | semmle.label | x |
+| test.cpp:455:21:455:21 | x | semmle.label | x |
+| test.cpp:464:5:464:5 | emplace output argument [element, x] | semmle.label | emplace output argument [element, x] |
+| test.cpp:464:21:464:21 | *x | semmle.label | *x |
+| test.cpp:465:13:465:13 | *c [element, x] | semmle.label | *c [element, x] |
+| test.cpp:465:18:465:20 | *call to get [x] | semmle.label | *call to get [x] |
+| test.cpp:465:21:465:21 | x | semmle.label | x |
+| test.cpp:465:21:465:21 | x | semmle.label | x |
+| test.cpp:472:5:472:5 | forward output argument | semmle.label | forward output argument |
+| test.cpp:472:15:472:23 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:472:15:472:23 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:472:15:472:25 | call to ymlSource | semmle.label | call to ymlSource |
+| test.cpp:473:13:473:13 | *f | semmle.label | *f |
+| test.cpp:473:15:473:17 | call to get | semmle.label | call to get |
+| test.cpp:473:15:473:17 | call to get | semmle.label | call to get |
+| test.cpp:477:5:477:5 | forward output argument | semmle.label | forward output argument |
+| test.cpp:477:15:477:26 | *call to ymlSourcePtr | semmle.label | *call to ymlSourcePtr |
+| test.cpp:477:15:477:26 | call to ymlSourcePtr | semmle.label | call to ymlSourcePtr |
+| test.cpp:477:15:477:28 | **call to ymlSourcePtr | semmle.label | **call to ymlSourcePtr |
+| test.cpp:478:13:478:20 | * ... | semmle.label | * ... |
+| test.cpp:478:14:478:14 | *f | semmle.label | *f |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
-| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
+| windows.cpp:22:15:22:29 | call to GetCommandLineA | semmle.label | call to GetCommandLineA |
| windows.cpp:24:8:24:11 | * ... | semmle.label | * ... |
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | semmle.label | **call to CommandLineToArgvA |
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | semmle.label | **call to CommandLineToArgvA |
| windows.cpp:27:36:27:38 | *cmd | semmle.label | *cmd |
| windows.cpp:30:8:30:15 | * ... | semmle.label | * ... |
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | semmle.label | *call to GetEnvironmentStringsA |
-| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | semmle.label | *call to GetEnvironmentStringsA |
+| windows.cpp:34:17:34:38 | call to GetEnvironmentStringsA | semmle.label | call to GetEnvironmentStringsA |
| windows.cpp:36:10:36:13 | * ... | semmle.label | * ... |
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | semmle.label | GetEnvironmentVariableA output argument |
| windows.cpp:41:10:41:13 | * ... | semmle.label | * ... |
@@ -599,31 +2993,31 @@ nodes
| windows.cpp:209:84:209:89 | NtReadFile output argument | semmle.label | NtReadFile output argument |
| windows.cpp:211:10:211:16 | * ... | semmle.label | * ... |
| windows.cpp:286:23:286:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile |
-| windows.cpp:286:23:286:35 | *call to MapViewOfFile | semmle.label | *call to MapViewOfFile |
+| windows.cpp:286:23:286:35 | call to MapViewOfFile | semmle.label | call to MapViewOfFile |
| windows.cpp:287:20:287:52 | *pMapView | semmle.label | *pMapView |
| windows.cpp:289:10:289:16 | * ... | semmle.label | * ... |
| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 |
-| windows.cpp:293:23:293:36 | *call to MapViewOfFile2 | semmle.label | *call to MapViewOfFile2 |
+| windows.cpp:293:23:293:36 | call to MapViewOfFile2 | semmle.label | call to MapViewOfFile2 |
| windows.cpp:294:20:294:52 | *pMapView | semmle.label | *pMapView |
| windows.cpp:296:10:296:16 | * ... | semmle.label | * ... |
| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 |
-| windows.cpp:302:23:302:36 | *call to MapViewOfFile3 | semmle.label | *call to MapViewOfFile3 |
+| windows.cpp:302:23:302:36 | call to MapViewOfFile3 | semmle.label | call to MapViewOfFile3 |
| windows.cpp:303:20:303:52 | *pMapView | semmle.label | *pMapView |
| windows.cpp:305:10:305:16 | * ... | semmle.label | * ... |
| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp |
-| windows.cpp:311:23:311:43 | *call to MapViewOfFile3FromApp | semmle.label | *call to MapViewOfFile3FromApp |
+| windows.cpp:311:23:311:43 | call to MapViewOfFile3FromApp | semmle.label | call to MapViewOfFile3FromApp |
| windows.cpp:312:20:312:52 | *pMapView | semmle.label | *pMapView |
| windows.cpp:314:10:314:16 | * ... | semmle.label | * ... |
| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx |
-| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | semmle.label | *call to MapViewOfFileEx |
+| windows.cpp:318:23:318:37 | call to MapViewOfFileEx | semmle.label | call to MapViewOfFileEx |
| windows.cpp:319:20:319:52 | *pMapView | semmle.label | *pMapView |
| windows.cpp:321:10:321:16 | * ... | semmle.label | * ... |
| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp |
-| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | semmle.label | *call to MapViewOfFileFromApp |
+| windows.cpp:325:23:325:42 | call to MapViewOfFileFromApp | semmle.label | call to MapViewOfFileFromApp |
| windows.cpp:326:20:326:52 | *pMapView | semmle.label | *pMapView |
| windows.cpp:328:10:328:16 | * ... | semmle.label | * ... |
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 |
-| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 |
+| windows.cpp:332:23:332:40 | call to MapViewOfFileNuma2 | semmle.label | call to MapViewOfFileNuma2 |
| windows.cpp:333:20:333:52 | *pMapView | semmle.label | *pMapView |
| windows.cpp:335:10:335:16 | * ... | semmle.label | * ... |
| windows.cpp:403:26:403:36 | *lpParameter [x] | semmle.label | *lpParameter [x] |
@@ -782,4 +3176,10 @@ nodes
subpaths
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | test.cpp:164:7:164:7 | *templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 |
+| test.cpp:363:15:363:15 | *x | test.cpp:341:30:341:32 | arg | test.cpp:341:3:341:22 | *this [Return] [s] | test.cpp:363:5:363:5 | forward output argument [s] |
+| test.cpp:363:15:363:15 | *x | test.cpp:345:38:345:40 | arg | test.cpp:345:3:345:22 | *this [Return] [ul] | test.cpp:363:5:363:5 | forward output argument [ul] |
+| test.cpp:372:15:372:16 | *ul | test.cpp:341:30:341:32 | arg | test.cpp:341:3:341:22 | *this [Return] [s] | test.cpp:372:5:372:5 | forward output argument [s] |
+| test.cpp:372:15:372:16 | *ul | test.cpp:345:38:345:40 | arg | test.cpp:345:3:345:22 | *this [Return] [ul] | test.cpp:372:5:372:5 | forward output argument [ul] |
+| test.cpp:454:18:454:18 | *x | test.cpp:446:34:446:38 | first | test.cpp:446:3:446:28 | *this [Return] [x] | test.cpp:454:5:454:5 | emplace output argument [element, x] |
+| test.cpp:464:21:464:21 | *x | test.cpp:447:39:447:44 | second | test.cpp:447:3:447:28 | *this [Return] [x] | test.cpp:464:5:464:5 | emplace output argument [element, x] |
testFailures
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml b/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml
index 130e13a92571..77f168112bb5 100644
--- a/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml
+++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.ext.yml
@@ -4,11 +4,26 @@ extensions:
extensible: sourceModel
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
- ["", "", False, "ymlSource", "", "", "ReturnValue", "local", "manual"]
+ - ["", "", False, "ymlSourcePtr", "", "", "ReturnValue[*]", "local", "manual"]
+ - ["", "", False, "ymlFieldSource", "", "", "ReturnValue.Field[SourceWrapper::value]", "local", "manual"]
+ - ["", "", False, "source_from_callback_template", "", "", "Argument[0].Parameter[*0].Field[SourceWrapper::value]", "local", "manual"]
+ - ["", "", False, "source_from_callback_ptr", "", "", "Argument[0].Parameter[*0].Field[SourceWrapper::value]", "local", "manual"]
+ - ["", "", False, "source_from_callback_return_template", "", "", "Argument[0].ReturnValue", "local", "manual"]
+ - ["", "", False, "source_from_callback_return_ptr", "", "", "Argument[0].ReturnValue", "local", "manual"]
+ - ["", "", False, "source_ptr_from_callback_return_ptr", "", "", "Argument[0].ReturnValue[*]", "local", "manual"]
+ - ["", "", False, "test_parameter", "", "", "Parameter[*0].Field[SourceWrapper::value]", "local", "manual"]
+ - ["", "", False, "test_parameter", "", "", "Parameter[*0].Field[*SourceWrapper::pointer]", "local", "manual"]
+ - ["", "", False, "test_parameter", "", "", "Parameter[1].Field[*SourceWrapper::pointer]", "local", "manual"]
+ - ["", "", False, "test_parameter", "", "", "Parameter[1].Field[SourceWrapper::value]", "local", "manual"]
+ - ["", "", False, "test_parameter", "", "", "Parameter[*2]", "local", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: sinkModel
data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
- ["", "", False, "ymlSink", "", "", "Argument[0]", "test-sink", "manual"]
+ - ["", "", False, "sink_from_callback_return_template", "", "", "Argument[0].ReturnValue", "test-sink", "manual"]
+ - ["", "", False, "sink_from_callback_return_ptr", "", "", "Argument[0].ReturnValue", "test-sink", "manual"]
+ - ["", "", False, "sink_ptr_from_callback_return_ptr", "", "", "Argument[0].ReturnValue[*]", "test-sink", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
@@ -27,3 +42,15 @@ extensions:
- ["", "ReverseFlow", True, "get_ptr", "", "", "ReturnValue[*]", "Argument[-1].Field[ReverseFlow::value]", "value", "manual"]
- ["", "MyString", True, "operator[]", "", "", "ReturnValue[*]", "Argument[-1]", "taint", "manual"]
- ["", "MyString", True, "operator[]", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
+ - ["", "Forwarder", True, "get", "", "", "Argument[-1]", "ReturnValue", "value", "manual"]
+ - ["", "Container", True, "get", "", "", "Argument[-1].Element", "ReturnValue[*]", "value", "manual"]
+ - ["", "Element", True, "Element", "", "", "Argument[0]", "Argument[-1].Field[Element::x]", "value", "manual"]
+ - ["", "ElementWithDefaultArgument", True, "ElementWithDefaultArgument", "", "", "Argument[0]", "Argument[-1].Field[ElementWithDefaultArgument::x]", "value", "manual"]
+ - addsTo:
+ pack: codeql/cpp-all
+ extensible: forwardsModel
+ data: # namespace, type, subtypes, name, signature, ext, start, constructor, output, provenance
+ - ["", "Forwarder", True, "forward", "(Args &&)", "", "0", "T", "Argument[-1]", "manual"]
+ - ["", "", False, "makeForwarded", "(int)", "", "0", "T", "ReturnValue", "manual"]
+ - ["", "Forwarder", True, "forwardToElement", "(int)", "", "0", "Element", "Argument[-1]", "manual"]
+ - ["", "Container", True, "emplace", "(int,Args &&)", "", "1", "value_type", "Argument[-1].Element", "manual"]
diff --git a/cpp/ql/test/library-tests/dataflow/external-models/protobuf.cpp b/cpp/ql/test/library-tests/dataflow/external-models/protobuf.cpp
new file mode 100644
index 000000000000..ec8043218255
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/external-models/protobuf.cpp
@@ -0,0 +1,459 @@
+
+// --- stub library headers ---
+
+#include "../taint-tests/stl.h"
+
+namespace absl {
+ class string_view {
+ public:
+ string_view();
+ string_view(const char *s);
+ string_view(const std::string &s);
+ };
+
+ class Cord {
+ public:
+ Cord();
+ };
+}
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class ZeroCopyInputStream {};
+ class ZeroCopyOutputStream {};
+ class CodedInputStream {};
+ class CodedOutputStream {};
+ }
+
+ class MessageLite {
+ public:
+ bool ParseFromString(absl::string_view data);
+ bool ParseFromString(const absl::Cord &data);
+ bool ParsePartialFromString(absl::string_view data);
+ bool ParsePartialFromString(const absl::Cord &data);
+ bool MergeFromString(absl::string_view data);
+ bool MergeFromString(const absl::Cord &data);
+ bool MergePartialFromString(absl::string_view data);
+ bool MergePartialFromString(const absl::Cord &data);
+ bool ParseFromArray(const void *data, int size);
+ bool ParsePartialFromArray(const void *data, int size);
+ bool ParseFromCord(const absl::Cord &data);
+ bool ParsePartialFromCord(const absl::Cord &data);
+ bool MergeFromCord(const absl::Cord &data);
+ bool MergePartialFromCord(const absl::Cord &data);
+ bool ParseFromIstream(std::istream *input);
+ bool ParsePartialFromIstream(std::istream *input);
+ bool ParseFromZeroCopyStream(io::ZeroCopyInputStream *input);
+ bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream *input);
+ bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream *input, int size);
+ bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream *input, int size);
+ bool MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream *input, int size);
+ bool MergePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream *input, int size);
+ bool ParseFromCodedStream(io::CodedInputStream *input);
+ bool ParsePartialFromCodedStream(io::CodedInputStream *input);
+ bool MergeFromCodedStream(io::CodedInputStream *input);
+ bool MergePartialFromCodedStream(io::CodedInputStream *input);
+
+ bool SerializeToString(std::string *output) const;
+ bool SerializePartialToString(std::string *output) const;
+ bool AppendToString(std::string *output) const;
+ bool AppendPartialToString(std::string *output) const;
+ bool SerializeToString(absl::Cord *output) const;
+ bool SerializePartialToString(absl::Cord *output) const;
+ bool AppendToString(absl::Cord *output) const;
+ bool AppendPartialToString(absl::Cord *output) const;
+ bool SerializeToArray(void *data, int size) const;
+ bool SerializePartialToArray(void *data, int size) const;
+ bool SerializeToCord(absl::Cord *output) const;
+ bool SerializePartialToCord(absl::Cord *output) const;
+ bool AppendToCord(absl::Cord *output) const;
+ bool AppendPartialToCord(absl::Cord *output) const;
+ bool SerializeToOstream(std::ostream *output) const;
+ bool SerializePartialToOstream(std::ostream *output) const;
+ bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream *output) const;
+ bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream *output) const;
+ bool SerializeToCodedStream(io::CodedOutputStream *output) const;
+ bool SerializePartialToCodedStream(io::CodedOutputStream *output) const;
+
+ std::string SerializeAsString() const;
+ std::string SerializePartialAsString() const;
+ absl::Cord SerializeAsCord() const;
+ absl::Cord SerializePartialAsCord() const;
+ };
+
+ class Message : public MessageLite {
+ };
+}
+}
+
+// A generated message type derives from `Message`.
+class Person : public google::protobuf::Message {
+};
+
+// --- test code ---
+
+template T source();
+void sink(...);
+
+using namespace google::protobuf::io;
+
+// Deserialization: the input taints the message.
+
+void test_ParseFromString_string_view() {
+ Person msg;
+ absl::string_view data = source();
+ msg.ParseFromString(data);
+ sink(msg); // $ ir
+}
+
+void test_ParseFromString_Cord() {
+ Person msg;
+ absl::Cord data = source();
+ msg.ParseFromString(data);
+ sink(msg); // $ ir
+}
+
+void test_ParsePartialFromString_string_view() {
+ Person msg;
+ absl::string_view data = source();
+ msg.ParsePartialFromString(data);
+ sink(msg); // $ ir
+}
+
+void test_ParsePartialFromString_Cord() {
+ Person msg;
+ absl::Cord data = source();
+ msg.ParsePartialFromString(data);
+ sink(msg); // $ ir
+}
+
+void test_MergeFromString_string_view() {
+ Person msg;
+ absl::string_view data = source();
+ msg.MergeFromString(data);
+ sink(msg); // $ ir
+}
+
+void test_MergeFromString_Cord() {
+ Person msg;
+ absl::Cord data = source();
+ msg.MergeFromString(data);
+ sink(msg); // $ ir
+}
+
+void test_MergePartialFromString_string_view() {
+ Person msg;
+ absl::string_view data = source();
+ msg.MergePartialFromString(data);
+ sink(msg); // $ ir
+}
+
+void test_MergePartialFromString_Cord() {
+ Person msg;
+ absl::Cord data = source();
+ msg.MergePartialFromString(data);
+ sink(msg); // $ ir
+}
+
+void test_ParseFromArray() {
+ Person msg;
+ std::string data(source());
+ msg.ParseFromArray(data.data(), data.size());
+ sink(msg); // $ ir
+}
+
+void test_ParsePartialFromArray() {
+ Person msg;
+ std::string data(source());
+ msg.ParsePartialFromArray(data.data(), data.size());
+ sink(msg); // $ ir
+}
+
+void test_ParseFromCord() {
+ Person msg;
+ absl::Cord data = source();
+ msg.ParseFromCord(data);
+ sink(msg); // $ ir
+}
+
+void test_ParsePartialFromCord() {
+ Person msg;
+ absl::Cord data = source();
+ msg.ParsePartialFromCord(data);
+ sink(msg); // $ ir
+}
+
+void test_MergeFromCord() {
+ Person msg;
+ absl::Cord data = source();
+ msg.MergeFromCord(data);
+ sink(msg); // $ ir
+}
+
+void test_MergePartialFromCord() {
+ Person msg;
+ absl::Cord data = source();
+ msg.MergePartialFromCord(data);
+ sink(msg); // $ ir
+}
+
+void test_ParseFromIstream() {
+ Person msg;
+ std::istream in = source();
+ msg.ParseFromIstream(&in);
+ sink(msg); // $ ir
+}
+
+void test_ParsePartialFromIstream() {
+ Person msg;
+ std::istream in = source