From f6b7aeaaca57ea933b34be1735d259c1e6dc7d94 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 11 Nov 2025 16:01:10 +0000
Subject: [PATCH 01/70] Rust: Add prototype query.
---
.../CWE-295/DisabledCertificateCheck.ql | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
new file mode 100644
index 00000000000..65b1d85f216
--- /dev/null
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -0,0 +1,22 @@
+/**
+ * @name Disabled TLS certificate check
+ * @description If an application disables TLS certificate checking, it may be vulnerable to
+ * man-in-the-middle attacks.
+ * @kind problem
+ * @problem.severity warning
+ * @security-severity 7.5
+ * @precision high
+ * @id rust/disabled-certificate-check
+ * @tags security
+ * external/cwe/cwe-295
+ */
+
+import rust
+
+from CallExprBase fc
+where
+ fc.getStaticTarget().(Function).getName().getText() = ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
+ fc.getArg(0).(BooleanLiteralExpr).getTextValue() = "true"
+select
+ fc,
+ "Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks." // TODO: proper message.
From f8ef48b9244b0e2ac06111d7e122a1692d85313a Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 11 Nov 2025 16:22:40 +0000
Subject: [PATCH 02/70] Rust: Add query test.
---
.../query-tests/security/CWE-295/Cargo.lock | 1596 +++++++++++++++++
.../CWE-295/DisabledCertificateCheck.expected | 10 +
.../CWE-295/DisabledCertificateCheck.qlref | 4 +
.../test/query-tests/security/CWE-295/main.rs | 108 ++
.../query-tests/security/CWE-295/options.yml | 5 +
5 files changed, 1723 insertions(+)
create mode 100644 rust/ql/test/query-tests/security/CWE-295/Cargo.lock
create mode 100644 rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
create mode 100644 rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.qlref
create mode 100644 rust/ql/test/query-tests/security/CWE-295/main.rs
create mode 100644 rust/ql/test/query-tests/security/CWE-295/options.yml
diff --git a/rust/ql/test/query-tests/security/CWE-295/Cargo.lock b/rust/ql/test/query-tests/security/CWE-295/Cargo.lock
new file mode 100644
index 00000000000..43943439edd
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/Cargo.lock
@@ -0,0 +1,1596 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
+name = "bitflags"
+version = "2.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
+
+[[package]]
+name = "bumpalo"
+version = "3.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
+
+[[package]]
+name = "bytes"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+
+[[package]]
+name = "cc"
+version = "1.2.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe"
+dependencies = [
+ "find-msvc-tools",
+ "shlex",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "core-foundation"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
+name = "find-msvc-tools"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-io"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+dependencies = [
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasip2",
+]
+
+[[package]]
+name = "h2"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
+
+[[package]]
+name = "http"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+dependencies = [
+ "bytes",
+ "http",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
+
+[[package]]
+name = "hyper"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1744436df46f0bde35af3eda22aeaba453aada65d8f1c171cd8a5f59030bd69f"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "itoa",
+ "pin-project-lite",
+ "pin-utils",
+ "smallvec",
+ "tokio",
+ "want",
+]
+
+[[package]]
+name = "hyper-rustls"
+version = "0.27.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
+dependencies = [
+ "http",
+ "hyper",
+ "hyper-util",
+ "rustls",
+ "rustls-pki-types",
+ "tokio",
+ "tokio-rustls",
+ "tower-service",
+]
+
+[[package]]
+name = "hyper-tls"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
+dependencies = [
+ "bytes",
+ "http-body-util",
+ "hyper",
+ "hyper-util",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+ "tower-service",
+]
+
+[[package]]
+name = "hyper-util"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
+dependencies = [
+ "base64",
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "ipnet",
+ "libc",
+ "percent-encoding",
+ "pin-project-lite",
+ "socket2",
+ "system-configuration",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "windows-registry",
+]
+
+[[package]]
+name = "icu_collections"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
+dependencies = [
+ "displaydoc",
+ "potential_utf",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locale_core"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
+dependencies = [
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
+
+[[package]]
+name = "icu_properties"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99"
+dependencies = [
+ "icu_collections",
+ "icu_locale_core",
+ "icu_properties_data",
+ "icu_provider",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899"
+
+[[package]]
+name = "icu_provider"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
+dependencies = [
+ "displaydoc",
+ "icu_locale_core",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "idna"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
+dependencies = [
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
+
+[[package]]
+name = "iri-string"
+version = "0.7.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+
+[[package]]
+name = "js-sys"
+version = "0.3.82"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.177"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
+
+[[package]]
+name = "litemap"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
+
+[[package]]
+name = "log"
+version = "0.4.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
+
+[[package]]
+name = "memchr"
+version = "2.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
+
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
+[[package]]
+name = "mio"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "native-tls"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
+dependencies = [
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "openssl"
+version = "0.10.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.111"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
+
+[[package]]
+name = "potential_utf"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
+dependencies = [
+ "zerovec",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
+dependencies = [
+ "zerocopy",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "r-efi"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
+[[package]]
+name = "rand"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
+dependencies = [
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
+dependencies = [
+ "getrandom 0.3.4",
+]
+
+[[package]]
+name = "reqwest"
+version = "0.12.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f"
+dependencies = [
+ "base64",
+ "bytes",
+ "encoding_rs",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "http-body-util",
+ "hyper",
+ "hyper-rustls",
+ "hyper-tls",
+ "hyper-util",
+ "js-sys",
+ "log",
+ "mime",
+ "native-tls",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls-pki-types",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "tokio",
+ "tokio-native-tls",
+ "tower",
+ "tower-http",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "ring"
+version = "0.17.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "getrandom 0.2.16",
+ "libc",
+ "untrusted",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustix"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "rustls"
+version = "0.23.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
+dependencies = [
+ "once_cell",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a"
+dependencies = [
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.103.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52"
+dependencies = [
+ "ring",
+ "rustls-pki-types",
+ "untrusted",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+
+[[package]]
+name = "ryu"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
+
+[[package]]
+name = "schannel"
+version = "0.1.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "security-framework"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.145"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
+dependencies = [
+ "itoa",
+ "memchr",
+ "ryu",
+ "serde",
+ "serde_core",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "slab"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
+
+[[package]]
+name = "smallvec"
+version = "1.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+
+[[package]]
+name = "socket2"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
+dependencies = [
+ "libc",
+ "windows-sys 0.60.2",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
+
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
+name = "syn"
+version = "2.0.110"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "sync_wrapper"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "system-configuration"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "system-configuration-sys",
+]
+
+[[package]]
+name = "system-configuration-sys"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
+dependencies = [
+ "fastrand",
+ "getrandom 0.3.4",
+ "once_cell",
+ "rustix",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "test"
+version = "0.0.1"
+dependencies = [
+ "native-tls",
+ "rand",
+ "reqwest",
+]
+
+[[package]]
+name = "tinystr"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
+[[package]]
+name = "tokio"
+version = "1.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
+dependencies = [
+ "bytes",
+ "libc",
+ "mio",
+ "pin-project-lite",
+ "socket2",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "tokio-native-tls"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
+dependencies = [
+ "native-tls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
+dependencies = [
+ "rustls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tower"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project-lite",
+ "sync_wrapper",
+ "tokio",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
+dependencies = [
+ "bitflags",
+ "bytes",
+ "futures-util",
+ "http",
+ "http-body",
+ "iri-string",
+ "pin-project-lite",
+ "tower",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
+
+[[package]]
+name = "tower-service"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
+
+[[package]]
+name = "tracing"
+version = "0.1.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+dependencies = [
+ "pin-project-lite",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
+
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "url"
+version = "2.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "wasip2"
+version = "1.0.1+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "once_cell",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc"
+dependencies = [
+ "bumpalo",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "web-sys"
+version = "0.3.82"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-registry"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
+dependencies = [
+ "windows-link 0.1.3",
+ "windows-result",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
+dependencies = [
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
+dependencies = [
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+dependencies = [
+ "windows-targets 0.53.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link 0.2.1",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
+dependencies = [
+ "windows-link 0.2.1",
+ "windows_aarch64_gnullvm 0.53.1",
+ "windows_aarch64_msvc 0.53.1",
+ "windows_i686_gnu 0.53.1",
+ "windows_i686_gnullvm 0.53.1",
+ "windows_i686_msvc 0.53.1",
+ "windows_x86_64_gnu 0.53.1",
+ "windows_x86_64_gnullvm 0.53.1",
+ "windows_x86_64_msvc 0.53.1",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
+
+[[package]]
+name = "wit-bindgen"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
+
+[[package]]
+name = "writeable"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
+
+[[package]]
+name = "yoke"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
+dependencies = [
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+
+[[package]]
+name = "zerotrie"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.11.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
new file mode 100644
index 00000000000..5c10ff87316
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -0,0 +1,10 @@
+| main.rs:3:16:4:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:8:16:9:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:13:16:16:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:13:16:17:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:36:16:37:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:41:16:42:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:46:16:47:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:46:16:48:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:52:16:55:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:52:16:56:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.qlref b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.qlref
new file mode 100644
index 00000000000..cc99c2b151c
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.qlref
@@ -0,0 +1,4 @@
+query: queries/security/CWE-295/DisabledCertificateCheck.ql
+postprocess:
+ - utils/test/PrettyPrintModels.ql
+ - utils/test/InlineExpectationsTestQuery.ql
diff --git a/rust/ql/test/query-tests/security/CWE-295/main.rs b/rust/ql/test/query-tests/security/CWE-295/main.rs
new file mode 100644
index 00000000000..9c603c45c43
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/main.rs
@@ -0,0 +1,108 @@
+fn test_native_tls() {
+ // unsafe
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .min_protocol_version(Some(native_tls::Protocol::Tlsv12))
+ .use_sni(true)
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ // safe
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(false) // good
+ .danger_accept_invalid_hostnames(false) // good
+ .build()
+ .unwrap();
+
+ // default (safe)
+ let _client = native_tls::TlsConnector::builder()
+ .build()
+ .unwrap();
+}
+
+fn test_reqwest() {
+ // unsafe
+ let _client = reqwest::Client::builder()
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = reqwest::blocking::ClientBuilder::new()
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = reqwest::ClientBuilder::new()
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = reqwest::blocking::Client::builder()
+ .tcp_keepalive(std::time::Duration::from_secs(30))
+ .https_only(true)
+ .danger_accept_invalid_certs(true) // $ Alert[rust/disabled-certificate-check]
+ .danger_accept_invalid_hostnames(true) // $ Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ // safe
+ let _client = reqwest::blocking::Client::builder()
+ .danger_accept_invalid_certs(false) // good
+ .danger_accept_invalid_hostnames(false) // good
+ .build()
+ .unwrap();
+
+ // default (safe)
+ let _client = reqwest::blocking::Client::builder()
+ .build()
+ .unwrap();
+}
+
+fn test_data_flow(sometimes_global: bool) {
+ let always = true;
+ let mut sometimes = true;
+ let never = false;
+
+ if rand::random_range(0 .. 2) == 0 {
+ sometimes = false;
+ }
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(always) // $ MISSING: Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(sometimes) // $ MISSING: Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(sometimes_global) // $ MISSING: Alert[rust/disabled-certificate-check]
+ .build()
+ .unwrap();
+
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_certs(never) // good
+ .build()
+ .unwrap();
+}
+
+fn main() {
+ test_native_tls();
+ test_reqwest();
+ test_data_flow(true);
+ test_data_flow(false);
+}
diff --git a/rust/ql/test/query-tests/security/CWE-295/options.yml b/rust/ql/test/query-tests/security/CWE-295/options.yml
new file mode 100644
index 00000000000..711dfe71f8b
--- /dev/null
+++ b/rust/ql/test/query-tests/security/CWE-295/options.yml
@@ -0,0 +1,5 @@
+qltest_cargo_check: true
+qltest_dependencies:
+ - reqwest = { version = "0.12.9", features = ["blocking"] }
+ - native-tls = { version = "0.2.14" }
+ - rand = { version = "0.9.2" }
From 209f394b5effa32d9c740f64ed58a25cbf6a2ad7 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 11 Nov 2025 18:10:32 +0000
Subject: [PATCH 03/70] Rust: Fix the alert message.
---
.../CWE-295/DisabledCertificateCheck.ql | 10 +++++-----
.../CWE-295/DisabledCertificateCheck.expected | 20 +++++++++----------
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 65b1d85f216..9a8ee245e2c 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -15,8 +15,8 @@ import rust
from CallExprBase fc
where
- fc.getStaticTarget().(Function).getName().getText() = ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
- fc.getArg(0).(BooleanLiteralExpr).getTextValue() = "true"
-select
- fc,
- "Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks." // TODO: proper message.
+ fc.getStaticTarget().(Function).getName().getText() =
+ ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
+ fc.getArg(0).(BooleanLiteralExpr).getTextValue() = "true"
+select fc,
+ "Disabling TLS certificate validation can expose the application to man-in-the-middle attacks."
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index 5c10ff87316..113f41731c4 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -1,10 +1,10 @@
-| main.rs:3:16:4:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:8:16:9:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:13:16:16:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:13:16:17:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:36:16:37:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:41:16:42:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:46:16:47:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:46:16:48:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:52:16:55:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
-| main.rs:52:16:56:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation with 'danger_accept_invalid_certs(true)' can expose the application to man-in-the-middle attacks. |
+| main.rs:3:16:4:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:8:16:9:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:13:16:16:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:13:16:17:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:36:16:37:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:41:16:42:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:46:16:47:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:46:16:48:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:52:16:55:36 | ... .danger_accept_invalid_certs(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:52:16:56:40 | ... .danger_accept_invalid_hostnames(...) | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
From c77eef39e2806273ea6a3b66eaad36e085caf847 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 11 Nov 2025 17:55:29 +0000
Subject: [PATCH 04/70] Rust: Convert the query to a path-problem with global
data flow.
---
.../DisabledCertificateCheckExtensions.qll | 42 +++++++++++++++
.../CWE-295/DisabledCertificateCheck.ql | 34 +++++++++---
rust/ql/src/queries/summary/Stats.qll | 1 +
.../CWE-295/DisabledCertificateCheck.expected | 52 +++++++++++++++----
.../test/query-tests/security/CWE-295/main.rs | 12 ++---
5 files changed, 118 insertions(+), 23 deletions(-)
create mode 100644 rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
new file mode 100644
index 00000000000..984dc0f1de1
--- /dev/null
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -0,0 +1,42 @@
+/**
+ * Provides classes and predicates for reasoning about disabled certificate
+ * check vulnerabilities.
+ */
+
+import rust
+private import codeql.rust.dataflow.DataFlow
+private import codeql.rust.dataflow.FlowSink
+private import codeql.rust.Concepts
+
+/**
+ * Provides default sinks for detecting disabled certificate check
+ * vulnerabilities, as well as extension points for adding your own.
+ */
+module DisabledCertificateCheckExtensions {
+ /**
+ * A data flow sink for disabled certificate check vulnerabilities.
+ */
+ abstract class Sink extends QuerySink::Range {
+ override string getSinkType() { result = "DisabledCertificateCheck" }
+ }
+
+ /**
+ * A default sink for disabled certificate check based on function names.
+ */
+ private class DefaultSink extends Sink {
+ DefaultSink() {
+ exists(CallExprBase fc |
+ fc.getStaticTarget().(Function).getName().getText() =
+ ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
+ fc.getArg(0) = this.asExpr().getExpr()
+ )
+ }
+ }
+
+ /**
+ * A sink for disabled certificate check from model data.
+ */
+ private class ModelsAsDataSink extends Sink {
+ ModelsAsDataSink() { sinkNode(this, "disable-certificate") }
+ }
+}
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 9a8ee245e2c..0e5f8daea61 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -2,7 +2,7 @@
* @name Disabled TLS certificate check
* @description If an application disables TLS certificate checking, it may be vulnerable to
* man-in-the-middle attacks.
- * @kind problem
+ * @kind path-problem
* @problem.severity warning
* @security-severity 7.5
* @precision high
@@ -12,11 +12,31 @@
*/
import rust
+import codeql.rust.dataflow.DataFlow
+import codeql.rust.security.DisabledCertificateCheckExtensions
-from CallExprBase fc
-where
- fc.getStaticTarget().(Function).getName().getText() =
- ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
- fc.getArg(0).(BooleanLiteralExpr).getTextValue() = "true"
-select fc,
+/**
+ * A taint configuration for disabling TLS certificate checks.
+ */
+module LogInjectionConfig implements DataFlow::ConfigSig {
+ import DisabledCertificateCheckExtensions
+
+ predicate isSource(DataFlow::Node node) {
+ node.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true"
+ }
+
+ predicate isSink(DataFlow::Node node) { node instanceof Sink }
+
+ predicate observeDiffInformedIncrementalMode() { any() }
+}
+
+module DisabledCertificateCheckExtensionFlow = DataFlow::Global
+In Rust, the
+Do not set
+The following code snippet shows a function that creates a TLS or HTTP client with certificate verification disabled:
+
+While this may be acceptable in a test, it should not be used in production code. Instead, always configure clients to verify certificates and hostnames:
+
-In Rust, the
-Do not set danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification are performed. If set to true, the client will accept any certificate and any host name, making it susceptible to man-in-the-middle attacks.
+danger_accept_invalid_certs or danger_accept_invalid_hostnames to true except in tests or controlled environments. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
+danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification are performed. If set to true, the client will accept any certificate and any host name, making it susceptible to man-in-the-middle attacks.
+The danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification are performed. If set to true, the client will accept any certificate or any host name, making it susceptible to man-in-the-middle attacks.
danger_accept_invalid_certs or danger_accept_invalid_hostnames to true except in tests or controlled environments. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
+Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true except in controlled environments such as tests. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
-While this may be acceptable in a test, it should not be used in production code. Instead, always configure clients to verify certificates and hostnames: +In production code, always configure clients to verify certificates and hostnames:
danger_accept_invalid_certs or danger_accept_inval
-The following code snippet shows a function that creates a TLS or HTTP client with certificate verification disabled:
+The following code snippet shows a function that creates an HTTP client with certificate verification disabled:
-In production code, always configure clients to verify certificates and hostnames:
+In production code, always configure clients to verify certificates:
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs
index 67546a8a2ab..9e4102c64cc 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckBad.rs
@@ -1,12 +1,5 @@
// BAD: Disabling certificate validation in Rust
-// Using native_tls
-let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_certs(true) // disables certificate validation
- .build()
- .unwrap();
-
-// Using reqwest
let _client = reqwest::Client::builder()
.danger_accept_invalid_certs(true) // disables certificate validation
.build()
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs
index 525d7e98549..c726a756c38 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheckGood.rs
@@ -1,18 +1,10 @@
// GOOD: Certificate validation is enabled (default)
-// Using native_tls
-let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_certs(false) // certificate validation enabled
- .build()
- .unwrap();
-
-// Using reqwest
let _client = reqwest::Client::builder()
- .danger_accept_invalid_certs(false) // certificate validation enabled
+ .danger_accept_invalid_certs(false) // certificate validation enabled explicitly
.build()
.unwrap();
-// Or simply use the default builder (safe)
-let _client = native_tls::TlsConnector::builder()
+let _client = native_tls::TlsConnector::builder() // certificate validation enabled by default
.build()
.unwrap();
From 7a62642ed7a4561ffe3182a1c65aeb132536ab3f Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Wed, 12 Nov 2025 18:17:12 +0000
Subject: [PATCH 09/70] Rust: Change note.
---
.../src/change-notes/2025-11-12-disabled-certificate-check.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
diff --git a/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md b/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
new file mode 100644
index 00000000000..43211d9c5e0
--- /dev/null
+++ b/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
@@ -0,0 +1,4 @@
+---
+category: newQuery
+---
+* Added a new query `rust/disabled-certificate-check, to detect disabled TLS certificate checks.
From 0675a29ae690f88b7be87b3203c94e05a3c64ddf Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Wed, 12 Nov 2025 19:26:45 +0000
Subject: [PATCH 10/70] Rust: Minor corrections.
---
.../security/DisabledCertificateCheckExtensions.qll | 4 ++--
.../2025-11-12-disabled-certificate-check.md | 2 +-
.../security/CWE-295/DisabledCertificateCheck.qhelp | 2 +-
.../security/CWE-295/DisabledCertificateCheck.ql | 13 ++++++-------
4 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index 984dc0f1de1..cfc988ae37f 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -21,7 +21,7 @@ module DisabledCertificateCheckExtensions {
}
/**
- * A default sink for disabled certificate check based on function names.
+ * A default sink for disabled certificate check vulnerabilities based on function names.
*/
private class DefaultSink extends Sink {
DefaultSink() {
@@ -34,7 +34,7 @@ module DisabledCertificateCheckExtensions {
}
/**
- * A sink for disabled certificate check from model data.
+ * A sink for disabled certificate check vulnerabilities from model data.
*/
private class ModelsAsDataSink extends Sink {
ModelsAsDataSink() { sinkNode(this, "disable-certificate") }
diff --git a/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md b/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
index 43211d9c5e0..001102eb9d6 100644
--- a/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
+++ b/rust/ql/src/change-notes/2025-11-12-disabled-certificate-check.md
@@ -1,4 +1,4 @@
---
category: newQuery
---
-* Added a new query `rust/disabled-certificate-check, to detect disabled TLS certificate checks.
+* Added a new query `rust/disabled-certificate-check`, to detect disabled TLS certificate checks.
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
index dfb0c1f4db1..4e9ce164f26 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
@@ -11,7 +11,7 @@ The danger_accept_invalid_certs and danger_accept_invalid_hos
-Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true except in controlled environments such as tests. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
+Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true, except in controlled environments such as tests. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 0e5f8daea61..b054ec306f7 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -16,9 +16,9 @@ import codeql.rust.dataflow.DataFlow
import codeql.rust.security.DisabledCertificateCheckExtensions
/**
- * A taint configuration for disabling TLS certificate checks.
+ * A taint configuration for disabled TLS certificate checks.
*/
-module LogInjectionConfig implements DataFlow::ConfigSig {
+module DisabledCertificateCheckConfig implements DataFlow::ConfigSig {
import DisabledCertificateCheckExtensions
predicate isSource(DataFlow::Node node) {
@@ -30,13 +30,12 @@ module LogInjectionConfig implements DataFlow::ConfigSig {
predicate observeDiffInformedIncrementalMode() { any() }
}
-module DisabledCertificateCheckExtensionFlow = DataFlow::Global;
+module DisabledCertificateCheckFlow = DataFlow::Global;
-import DisabledCertificateCheckExtensionFlow::PathGraph
+import DisabledCertificateCheckFlow::PathGraph
from
- DisabledCertificateCheckExtensionFlow::PathNode sourceNode,
- DisabledCertificateCheckExtensionFlow::PathNode sinkNode
-where DisabledCertificateCheckExtensionFlow::flowPath(sourceNode, sinkNode)
+ DisabledCertificateCheckFlow::PathNode sourceNode, DisabledCertificateCheckFlow::PathNode sinkNode
+where DisabledCertificateCheckFlow::flowPath(sourceNode, sinkNode)
select sinkNode.getNode(), sourceNode, sinkNode,
"Disabling TLS certificate validation can expose the application to man-in-the-middle attacks."
From 42aca4a171c844c6e6c08c3c26c2a411e28e3dad Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 08:51:41 +0000
Subject: [PATCH 11/70] Apply suggestions from code review
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
---
.../queries/security/CWE-295/DisabledCertificateCheck.qhelp | 4 ++--
.../src/queries/security/CWE-295/DisabledCertificateCheck.ql | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
index 4e9ce164f26..7284a7da407 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
@@ -5,13 +5,13 @@
-The danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification are performed. If set to true, the client will accept any certificate or any host name, making it susceptible to man-in-the-middle attacks.
+The danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification is performed. If set to true, the client will accept any certificate or any host name, making it susceptible to man-in-the-middle attacks.
-Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true, except in controlled environments such as tests. In production, always ensure certificate and hostname verification are enabled to prevent security risks.
+Do not set danger_accept_invalid_certs or danger_accept_invalid_hostnames to true, except in controlled environments such as tests. In production, always ensure certificate and hostname verification is enabled to prevent security risks.
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index b054ec306f7..d08ca32bb25 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -1,6 +1,6 @@
/**
* @name Disabled TLS certificate check
- * @description If an application disables TLS certificate checking, it may be vulnerable to
+ * @description An application that disables TLS certificate checking is more vulnerable to
* man-in-the-middle attacks.
* @kind path-problem
* @problem.severity warning
From 15fa99a288dba86b8bca7919963505d66fbd4587 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 09:00:46 +0000
Subject: [PATCH 12/70] Rust: Clarify some confusing text in the .qhelp.
---
.../queries/security/CWE-295/DisabledCertificateCheck.qhelp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
index 7284a7da407..1824f6e78df 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.qhelp
@@ -5,7 +5,10 @@
-The danger_accept_invalid_certs and danger_accept_invalid_hostnames options on TLS connectors and HTTP clients control whether certificate and hostname verification is performed. If set to true, the client will accept any certificate or any host name, making it susceptible to man-in-the-middle attacks.
+The danger_accept_invalid_certs option on TLS connectors and HTTP clients controls whether certificate verification is performed. If this option is set to true, the client will accept any certificate, making it susceptible to man-in-the-middle attacks.
+
+
+Similarly, the danger_accept_invalid_hostnames option controls whether hostname verification is performed. If this option is set to true, the client will accept any valid certificate regardless of the site that certificate is for, again making it susceptible to man-in-the-middle attacks.
From 12cbb64ef849da634bc13cc076d40bb82f3416ba Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 08:38:07 +0000
Subject: [PATCH 13/70] Rust: Add query to suite .expected lists.
---
.../query-suite/rust-code-scanning.qls.expected | 1 +
.../query-suite/rust-security-and-quality.qls.expected | 1 +
.../query-suite/rust-security-extended.qls.expected | 1 +
3 files changed, 3 insertions(+)
diff --git a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
index 70e1bcb1064..ea26dc63664 100644
--- a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
@@ -19,6 +19,7 @@ ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
ql/rust/ql/src/queries/security/CWE-918/RequestForgery.ql
diff --git a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
index 596fdef3b20..81594574519 100644
--- a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
@@ -21,6 +21,7 @@ ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
diff --git a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
index 102c63e7942..3809a9fe01b 100644
--- a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
@@ -20,6 +20,7 @@ ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
From e43000f7cf1c19c7b76307f97583d78855b5ac50 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 09:21:04 +0000
Subject: [PATCH 14/70] Rust: Correct ordering in query suite .expected lists.
---
.../query-suite/rust-code-scanning.qls.expected | 2 +-
.../query-suite/rust-security-and-quality.qls.expected | 2 +-
.../query-suite/rust-security-extended.qls.expected | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
index ea26dc63664..aa197cebd2e 100644
--- a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected
@@ -11,6 +11,7 @@ ql/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql
ql/rust/ql/src/queries/security/CWE-020/RegexInjection.ql
ql/rust/ql/src/queries/security/CWE-022/TaintedPath.ql
ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql
@@ -19,7 +20,6 @@ ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
-ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
ql/rust/ql/src/queries/security/CWE-918/RequestForgery.ql
diff --git a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
index 81594574519..30167696554 100644
--- a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected
@@ -12,6 +12,7 @@ ql/rust/ql/src/queries/security/CWE-020/RegexInjection.ql
ql/rust/ql/src/queries/security/CWE-022/TaintedPath.ql
ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql
ql/rust/ql/src/queries/security/CWE-117/LogInjection.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql
@@ -21,7 +22,6 @@ ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
-ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
diff --git a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
index 3809a9fe01b..ebbf9511387 100644
--- a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
+++ b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected
@@ -12,6 +12,7 @@ ql/rust/ql/src/queries/security/CWE-020/RegexInjection.ql
ql/rust/ql/src/queries/security/CWE-022/TaintedPath.ql
ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql
ql/rust/ql/src/queries/security/CWE-117/LogInjection.ql
+ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql
@@ -20,7 +21,6 @@ ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql
ql/rust/ql/src/queries/security/CWE-327/WeakSensitiveDataHashing.ql
ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql
ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql
-ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql
ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql
ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
From e0f0305ace1a07a38802607bd43e6bdf356cb689 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 11:55:34 +0000
Subject: [PATCH 15/70] Rust: Add test cases for rust/access-invalid-pointer
based on real world FPs.
---
.../CWE-825/AccessAfterLifetime.expected | 94 +++++++++----------
.../CWE-825/AccessInvalidPointer.expected | 36 +++----
.../security/CWE-825/deallocation.rs | 72 ++++++++++++++
.../test/query-tests/security/CWE-825/main.rs | 5 +
4 files changed, 142 insertions(+), 65 deletions(-)
diff --git a/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected b/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected
index f58c58bc896..8b521239978 100644
--- a/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected
+++ b/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected
@@ -24,27 +24,27 @@
| lifetime.rs:808:23:808:25 | ptr | lifetime.rs:798:9:798:12 | &val | lifetime.rs:808:23:808:25 | ptr | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:796:6:796:8 | val | val |
| main.rs:64:23:64:24 | p2 | main.rs:44:26:44:28 | &b2 | main.rs:64:23:64:24 | p2 | Access of a pointer to $@ after its lifetime has ended. | main.rs:43:13:43:14 | b2 | b2 |
edges
-| deallocation.rs:148:6:148:7 | p1 | deallocation.rs:151:14:151:15 | p1 | provenance | |
-| deallocation.rs:148:6:148:7 | p1 | deallocation.rs:158:14:158:15 | p1 | provenance | |
-| deallocation.rs:148:30:148:38 | &raw const my_buffer | deallocation.rs:148:6:148:7 | p1 | provenance | |
-| deallocation.rs:228:28:228:43 | ...: ... | deallocation.rs:230:18:230:20 | ptr | provenance | |
-| deallocation.rs:240:27:240:42 | ...: ... | deallocation.rs:248:18:248:20 | ptr | provenance | |
-| deallocation.rs:257:7:257:10 | ptr1 | deallocation.rs:260:4:260:7 | ptr1 | provenance | |
-| deallocation.rs:257:7:257:10 | ptr1 | deallocation.rs:260:4:260:7 | ptr1 | provenance | |
-| deallocation.rs:257:14:257:33 | &raw mut ... | deallocation.rs:257:7:257:10 | ptr1 | provenance | |
-| deallocation.rs:258:7:258:10 | ptr2 | deallocation.rs:261:4:261:7 | ptr2 | provenance | |
-| deallocation.rs:258:7:258:10 | ptr2 | deallocation.rs:261:4:261:7 | ptr2 | provenance | |
-| deallocation.rs:258:14:258:33 | &raw mut ... | deallocation.rs:258:7:258:10 | ptr2 | provenance | |
-| deallocation.rs:260:4:260:7 | ptr1 | deallocation.rs:263:27:263:30 | ptr1 | provenance | |
-| deallocation.rs:261:4:261:7 | ptr2 | deallocation.rs:265:26:265:29 | ptr2 | provenance | |
-| deallocation.rs:263:27:263:30 | ptr1 | deallocation.rs:228:28:228:43 | ...: ... | provenance | |
-| deallocation.rs:265:26:265:29 | ptr2 | deallocation.rs:240:27:240:42 | ...: ... | provenance | |
-| deallocation.rs:276:6:276:9 | ptr1 | deallocation.rs:279:13:279:16 | ptr1 | provenance | |
-| deallocation.rs:276:6:276:9 | ptr1 | deallocation.rs:287:13:287:16 | ptr1 | provenance | |
-| deallocation.rs:276:13:276:28 | &raw mut ... | deallocation.rs:276:6:276:9 | ptr1 | provenance | |
-| deallocation.rs:295:6:295:9 | ptr2 | deallocation.rs:298:13:298:16 | ptr2 | provenance | |
-| deallocation.rs:295:6:295:9 | ptr2 | deallocation.rs:308:13:308:16 | ptr2 | provenance | |
-| deallocation.rs:295:13:295:28 | &raw mut ... | deallocation.rs:295:6:295:9 | ptr2 | provenance | |
+| deallocation.rs:220:6:220:7 | p1 | deallocation.rs:223:14:223:15 | p1 | provenance | |
+| deallocation.rs:220:6:220:7 | p1 | deallocation.rs:230:14:230:15 | p1 | provenance | |
+| deallocation.rs:220:30:220:38 | &raw const my_buffer | deallocation.rs:220:6:220:7 | p1 | provenance | |
+| deallocation.rs:300:28:300:43 | ...: ... | deallocation.rs:302:18:302:20 | ptr | provenance | |
+| deallocation.rs:312:27:312:42 | ...: ... | deallocation.rs:320:18:320:20 | ptr | provenance | |
+| deallocation.rs:329:7:329:10 | ptr1 | deallocation.rs:332:4:332:7 | ptr1 | provenance | |
+| deallocation.rs:329:7:329:10 | ptr1 | deallocation.rs:332:4:332:7 | ptr1 | provenance | |
+| deallocation.rs:329:14:329:33 | &raw mut ... | deallocation.rs:329:7:329:10 | ptr1 | provenance | |
+| deallocation.rs:330:7:330:10 | ptr2 | deallocation.rs:333:4:333:7 | ptr2 | provenance | |
+| deallocation.rs:330:7:330:10 | ptr2 | deallocation.rs:333:4:333:7 | ptr2 | provenance | |
+| deallocation.rs:330:14:330:33 | &raw mut ... | deallocation.rs:330:7:330:10 | ptr2 | provenance | |
+| deallocation.rs:332:4:332:7 | ptr1 | deallocation.rs:335:27:335:30 | ptr1 | provenance | |
+| deallocation.rs:333:4:333:7 | ptr2 | deallocation.rs:337:26:337:29 | ptr2 | provenance | |
+| deallocation.rs:335:27:335:30 | ptr1 | deallocation.rs:300:28:300:43 | ...: ... | provenance | |
+| deallocation.rs:337:26:337:29 | ptr2 | deallocation.rs:312:27:312:42 | ...: ... | provenance | |
+| deallocation.rs:348:6:348:9 | ptr1 | deallocation.rs:351:13:351:16 | ptr1 | provenance | |
+| deallocation.rs:348:6:348:9 | ptr1 | deallocation.rs:359:13:359:16 | ptr1 | provenance | |
+| deallocation.rs:348:13:348:28 | &raw mut ... | deallocation.rs:348:6:348:9 | ptr1 | provenance | |
+| deallocation.rs:367:6:367:9 | ptr2 | deallocation.rs:370:13:370:16 | ptr2 | provenance | |
+| deallocation.rs:367:6:367:9 | ptr2 | deallocation.rs:380:13:380:16 | ptr2 | provenance | |
+| deallocation.rs:367:13:367:28 | &raw mut ... | deallocation.rs:367:6:367:9 | ptr2 | provenance | |
| lifetime.rs:21:2:21:18 | return ... | lifetime.rs:54:11:54:30 | get_local_dangling(...) | provenance | |
| lifetime.rs:21:9:21:18 | &my_local1 | lifetime.rs:21:2:21:18 | return ... | provenance | |
| lifetime.rs:27:2:27:22 | return ... | lifetime.rs:55:11:55:34 | get_local_dangling_mut(...) | provenance | |
@@ -234,32 +234,32 @@ models
| 4 | Summary: ::as_ptr; Argument[0].Reference.Reference; ReturnValue.Reference; value |
| 5 | Summary: core::ptr::from_ref; Argument[0]; ReturnValue; value |
nodes
-| deallocation.rs:148:6:148:7 | p1 | semmle.label | p1 |
-| deallocation.rs:148:30:148:38 | &raw const my_buffer | semmle.label | &raw const my_buffer |
-| deallocation.rs:151:14:151:15 | p1 | semmle.label | p1 |
-| deallocation.rs:158:14:158:15 | p1 | semmle.label | p1 |
-| deallocation.rs:228:28:228:43 | ...: ... | semmle.label | ...: ... |
-| deallocation.rs:230:18:230:20 | ptr | semmle.label | ptr |
-| deallocation.rs:240:27:240:42 | ...: ... | semmle.label | ...: ... |
-| deallocation.rs:248:18:248:20 | ptr | semmle.label | ptr |
-| deallocation.rs:257:7:257:10 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:257:14:257:33 | &raw mut ... | semmle.label | &raw mut ... |
-| deallocation.rs:258:7:258:10 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:258:14:258:33 | &raw mut ... | semmle.label | &raw mut ... |
-| deallocation.rs:260:4:260:7 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:260:4:260:7 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:261:4:261:7 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:261:4:261:7 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:263:27:263:30 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:265:26:265:29 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:276:6:276:9 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:276:13:276:28 | &raw mut ... | semmle.label | &raw mut ... |
-| deallocation.rs:279:13:279:16 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:287:13:287:16 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:295:6:295:9 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:295:13:295:28 | &raw mut ... | semmle.label | &raw mut ... |
-| deallocation.rs:298:13:298:16 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:308:13:308:16 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:220:6:220:7 | p1 | semmle.label | p1 |
+| deallocation.rs:220:30:220:38 | &raw const my_buffer | semmle.label | &raw const my_buffer |
+| deallocation.rs:223:14:223:15 | p1 | semmle.label | p1 |
+| deallocation.rs:230:14:230:15 | p1 | semmle.label | p1 |
+| deallocation.rs:300:28:300:43 | ...: ... | semmle.label | ...: ... |
+| deallocation.rs:302:18:302:20 | ptr | semmle.label | ptr |
+| deallocation.rs:312:27:312:42 | ...: ... | semmle.label | ...: ... |
+| deallocation.rs:320:18:320:20 | ptr | semmle.label | ptr |
+| deallocation.rs:329:7:329:10 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:329:14:329:33 | &raw mut ... | semmle.label | &raw mut ... |
+| deallocation.rs:330:7:330:10 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:330:14:330:33 | &raw mut ... | semmle.label | &raw mut ... |
+| deallocation.rs:332:4:332:7 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:332:4:332:7 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:333:4:333:7 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:333:4:333:7 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:335:27:335:30 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:337:26:337:29 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:348:6:348:9 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:348:13:348:28 | &raw mut ... | semmle.label | &raw mut ... |
+| deallocation.rs:351:13:351:16 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:359:13:359:16 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:367:6:367:9 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:367:13:367:28 | &raw mut ... | semmle.label | &raw mut ... |
+| deallocation.rs:370:13:370:16 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:380:13:380:16 | ptr2 | semmle.label | ptr2 |
| lifetime.rs:21:2:21:18 | return ... | semmle.label | return ... |
| lifetime.rs:21:9:21:18 | &my_local1 | semmle.label | &my_local1 |
| lifetime.rs:27:2:27:22 | return ... | semmle.label | return ... |
diff --git a/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected b/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
index 1e9bdb3c8bb..2ee4afddf2e 100644
--- a/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
+++ b/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
@@ -13,10 +13,10 @@
| deallocation.rs:130:14:130:15 | p1 | deallocation.rs:123:23:123:40 | ...::dangling | deallocation.rs:130:14:130:15 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:123:23:123:40 | ...::dangling | invalid |
| deallocation.rs:131:14:131:15 | p2 | deallocation.rs:124:21:124:42 | ...::dangling_mut | deallocation.rs:131:14:131:15 | p2 | This operation dereferences a pointer that may be $@. | deallocation.rs:124:21:124:42 | ...::dangling_mut | invalid |
| deallocation.rs:132:14:132:15 | p3 | deallocation.rs:125:23:125:36 | ...::null | deallocation.rs:132:14:132:15 | p3 | This operation dereferences a pointer that may be $@. | deallocation.rs:125:23:125:36 | ...::null | invalid |
-| deallocation.rs:180:15:180:16 | p1 | deallocation.rs:176:3:176:25 | ...::drop_in_place | deallocation.rs:180:15:180:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:176:3:176:25 | ...::drop_in_place | invalid |
-| deallocation.rs:180:15:180:16 | p1 | deallocation.rs:176:3:176:25 | ...::drop_in_place | deallocation.rs:180:15:180:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:176:3:176:25 | ...::drop_in_place | invalid |
-| deallocation.rs:248:18:248:20 | ptr | deallocation.rs:242:3:242:25 | ...::drop_in_place | deallocation.rs:248:18:248:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:242:3:242:25 | ...::drop_in_place | invalid |
-| deallocation.rs:248:18:248:20 | ptr | deallocation.rs:242:3:242:25 | ...::drop_in_place | deallocation.rs:248:18:248:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:242:3:242:25 | ...::drop_in_place | invalid |
+| deallocation.rs:252:15:252:16 | p1 | deallocation.rs:248:3:248:25 | ...::drop_in_place | deallocation.rs:252:15:252:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:248:3:248:25 | ...::drop_in_place | invalid |
+| deallocation.rs:252:15:252:16 | p1 | deallocation.rs:248:3:248:25 | ...::drop_in_place | deallocation.rs:252:15:252:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:248:3:248:25 | ...::drop_in_place | invalid |
+| deallocation.rs:320:18:320:20 | ptr | deallocation.rs:314:3:314:25 | ...::drop_in_place | deallocation.rs:320:18:320:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:314:3:314:25 | ...::drop_in_place | invalid |
+| deallocation.rs:320:18:320:20 | ptr | deallocation.rs:314:3:314:25 | ...::drop_in_place | deallocation.rs:320:18:320:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:314:3:314:25 | ...::drop_in_place | invalid |
edges
| deallocation.rs:20:3:20:21 | ...::dealloc | deallocation.rs:20:23:20:24 | [post] m1 | provenance | Src:MaD:3 MaD:3 |
| deallocation.rs:20:23:20:24 | [post] m1 | deallocation.rs:26:15:26:16 | m1 | provenance | |
@@ -44,12 +44,12 @@ edges
| deallocation.rs:125:6:125:7 | p3 | deallocation.rs:132:14:132:15 | p3 | provenance | |
| deallocation.rs:125:23:125:36 | ...::null | deallocation.rs:125:23:125:38 | ...::null(...) | provenance | Src:MaD:7 MaD:7 |
| deallocation.rs:125:23:125:38 | ...::null(...) | deallocation.rs:125:6:125:7 | p3 | provenance | |
-| deallocation.rs:176:3:176:25 | ...::drop_in_place | deallocation.rs:176:27:176:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
-| deallocation.rs:176:3:176:25 | ...::drop_in_place | deallocation.rs:176:27:176:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
-| deallocation.rs:176:27:176:28 | [post] p1 | deallocation.rs:180:15:180:16 | p1 | provenance | |
-| deallocation.rs:242:3:242:25 | ...::drop_in_place | deallocation.rs:242:27:242:29 | [post] ptr | provenance | Src:MaD:6 MaD:6 |
-| deallocation.rs:242:3:242:25 | ...::drop_in_place | deallocation.rs:242:27:242:29 | [post] ptr | provenance | Src:MaD:6 MaD:6 |
-| deallocation.rs:242:27:242:29 | [post] ptr | deallocation.rs:248:18:248:20 | ptr | provenance | |
+| deallocation.rs:248:3:248:25 | ...::drop_in_place | deallocation.rs:248:27:248:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
+| deallocation.rs:248:3:248:25 | ...::drop_in_place | deallocation.rs:248:27:248:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
+| deallocation.rs:248:27:248:28 | [post] p1 | deallocation.rs:252:15:252:16 | p1 | provenance | |
+| deallocation.rs:314:3:314:25 | ...::drop_in_place | deallocation.rs:314:27:314:29 | [post] ptr | provenance | Src:MaD:6 MaD:6 |
+| deallocation.rs:314:3:314:25 | ...::drop_in_place | deallocation.rs:314:27:314:29 | [post] ptr | provenance | Src:MaD:6 MaD:6 |
+| deallocation.rs:314:27:314:29 | [post] ptr | deallocation.rs:320:18:320:20 | ptr | provenance | |
models
| 1 | Sink: core::ptr::read; Argument[0]; pointer-access |
| 2 | Sink: core::ptr::write; Argument[0]; pointer-access |
@@ -92,12 +92,12 @@ nodes
| deallocation.rs:130:14:130:15 | p1 | semmle.label | p1 |
| deallocation.rs:131:14:131:15 | p2 | semmle.label | p2 |
| deallocation.rs:132:14:132:15 | p3 | semmle.label | p3 |
-| deallocation.rs:176:3:176:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
-| deallocation.rs:176:3:176:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
-| deallocation.rs:176:27:176:28 | [post] p1 | semmle.label | [post] p1 |
-| deallocation.rs:180:15:180:16 | p1 | semmle.label | p1 |
-| deallocation.rs:242:3:242:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
-| deallocation.rs:242:3:242:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
-| deallocation.rs:242:27:242:29 | [post] ptr | semmle.label | [post] ptr |
-| deallocation.rs:248:18:248:20 | ptr | semmle.label | ptr |
+| deallocation.rs:248:3:248:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
+| deallocation.rs:248:3:248:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
+| deallocation.rs:248:27:248:28 | [post] p1 | semmle.label | [post] p1 |
+| deallocation.rs:252:15:252:16 | p1 | semmle.label | p1 |
+| deallocation.rs:314:3:314:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
+| deallocation.rs:314:3:314:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
+| deallocation.rs:314:27:314:29 | [post] ptr | semmle.label | [post] ptr |
+| deallocation.rs:320:18:320:20 | ptr | semmle.label | ptr |
subpaths
diff --git a/rust/ql/test/query-tests/security/CWE-825/deallocation.rs b/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
index 89ef0470e99..ab4b1e73a2b 100644
--- a/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
+++ b/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
@@ -137,6 +137,78 @@ pub fn test_ptr_invalid(mode: i32) {
}
}
+struct MyObject {
+ value: i64
+}
+
+impl MyObject {
+ fn is_zero(&self) -> bool {
+ self.value == 0
+ }
+}
+
+pub unsafe fn test_ptr_invalid_conditions(mode: i32) {
+ let layout = std::alloc::Layout::new::();
+ let mut ptr = std::alloc::alloc(layout) as *mut MyObject;
+ (*ptr).value = 0; // good
+
+ if mode == 121 {
+ ptr = std::ptr::null_mut(); // (causes a panic below)
+ }
+
+ if ptr.is_null() {
+ let v = (*ptr).value; // $ MISSING: Alert[rust/access-invalid-pointer]
+ println!(" cond1 v = {v}");
+ } else {
+ let v = (*ptr).value; // good - unreachable with null pointer
+ println!(" cond2 v = {v}");
+ }
+
+ if mode == 122 {
+ ptr = std::ptr::null_mut(); // (causes a panic below)
+ }
+
+ if !(ptr.is_null()) {
+ let v = (*ptr).value; // good - unreachable with null pointer
+ println!(" cond3 v = {v}");
+ } else {
+ let v = (*ptr).value; // $ MISSING: Alert[rust/access-invalid-pointer]
+ println!(" cond4 v = {v}");
+ }
+
+ if mode == 123 {
+ ptr = std::ptr::null_mut(); // (causes a panic below)
+ }
+
+ if ptr.is_null() || (*ptr).value == 0 { // good - deref is protected by short-circuiting
+ println!(" cond5");
+ }
+
+ if ptr.is_null() || (*ptr).is_zero() { // good - deref is protected by short-circuiting
+ println!(" cond6");
+ }
+
+ if !ptr.is_null() || (*ptr).value == 0 { // $ MISSING: Alert[rust/access-invalid-pointer]
+ println!(" cond7");
+ }
+
+ if mode == 124 {
+ ptr = std::ptr::null_mut(); // (causes a panic below)
+ }
+
+ if ptr.is_null() && (*ptr).is_zero() { // $ MISSING: Alert[rust/access-invalid-pointer]
+ println!(" cond8");
+ }
+
+ if mode == 125 {
+ ptr = std::ptr::null_mut(); // (causes a panic below)
+ }
+
+ if (*ptr).is_zero() || ptr.is_null() { // $ MISSING: Alert[rust/access-invalid-pointer]
+ println!(" cond9");
+ }
+}
+
// --- drop ---
struct MyBuffer {
diff --git a/rust/ql/test/query-tests/security/CWE-825/main.rs b/rust/ql/test/query-tests/security/CWE-825/main.rs
index 8d1f2a42146..d15f595e13c 100644
--- a/rust/ql/test/query-tests/security/CWE-825/main.rs
+++ b/rust/ql/test/query-tests/security/CWE-825/main.rs
@@ -126,6 +126,11 @@ fn main() {
println!("test_ptr_invalid:");
test_ptr_invalid(mode);
+ println!("test_ptr_invalid_conditions:");
+ unsafe {
+ test_ptr_invalid_conditions(mode);
+ }
+
println!("test_drop:");
test_drop();
From 3419c00bc0f398e439665c9a384483ee2b226254 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Mon, 17 Nov 2025 12:27:53 +0100
Subject: [PATCH 16/70] Rust: Use `ToIndex` instead of `FromIndex` in ranked
`forex` predicates
`ToIndex` makes more sense, since we start the recursion from `0`.
---
.../internal/typeinference/FunctionType.qll | 10 ++++-----
.../typeinference/internal/TypeInference.qll | 22 +++++++++----------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll
index 727c99fa810..e8b44336e76 100644
--- a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll
+++ b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll
@@ -351,7 +351,7 @@ module ArgsAreInstantiationsOf {
|
rnk = 0
or
- argsAreInstantiationsOfFromIndex(call, abs, f, rnk - 1)
+ argsAreInstantiationsOfToIndex(call, abs, f, rnk - 1)
)
}
@@ -360,15 +360,15 @@ module ArgsAreInstantiationsOf {
}
}
- private module ArgIsInstantiationOfFromIndex =
+ private module ArgIsInstantiationOfToIndex =
ArgIsInstantiationOf;
pragma[nomagic]
- private predicate argsAreInstantiationsOfFromIndex(
+ private predicate argsAreInstantiationsOfToIndex(
Input::Call call, ImplOrTraitItemNode i, Function f, int rnk
) {
exists(FunctionPosition pos |
- ArgIsInstantiationOfFromIndex::argIsInstantiationOf(MkCallAndPos(call, pos), i, _) and
+ ArgIsInstantiationOfToIndex::argIsInstantiationOf(MkCallAndPos(call, pos), i, _) and
call.hasTargetCand(i, f) and
toCheckRanked(i, f, pos, rnk)
)
@@ -381,7 +381,7 @@ module ArgsAreInstantiationsOf {
pragma[nomagic]
predicate argsAreInstantiationsOf(Input::Call call, ImplOrTraitItemNode i, Function f) {
exists(int rnk |
- argsAreInstantiationsOfFromIndex(call, i, f, rnk) and
+ argsAreInstantiationsOfToIndex(call, i, f, rnk) and
rnk = max(int r | toCheckRanked(i, f, _, r))
)
}
diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll
index a827ef3cd79..47b80b9dc18 100644
--- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll
+++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll
@@ -578,7 +578,7 @@ module Make1 Input1> {
}
pragma[nomagic]
- private predicate satisfiesConcreteTypesFromIndex(
+ private predicate satisfiesConcreteTypesToIndex(
App app, TypeAbstraction abs, Constraint constraint, int i
) {
exists(Type t, TypePath path |
@@ -586,13 +586,13 @@ module Make1 Input1> {
if t = abs.getATypeParameter() then any() else app.getTypeAt(path) = t
) and
// Recurse unless we are at the first path
- if i = 0 then any() else satisfiesConcreteTypesFromIndex(app, abs, constraint, i - 1)
+ if i = 0 then any() else satisfiesConcreteTypesToIndex(app, abs, constraint, i - 1)
}
/** Holds if all the concrete types in `constraint` also occur in `app`. */
pragma[nomagic]
private predicate satisfiesConcreteTypes(App app, TypeAbstraction abs, Constraint constraint) {
- satisfiesConcreteTypesFromIndex(app, abs, constraint,
+ satisfiesConcreteTypesToIndex(app, abs, constraint,
max(int i | exists(getNthPath(constraint, i))))
}
@@ -620,7 +620,7 @@ module Make1 Input1> {
}
pragma[nomagic]
- private predicate typeParametersEqualFromIndexBase(
+ private predicate typeParametersEqualToIndexBase(
App app, TypeAbstraction abs, Constraint constraint, TypeParameter tp, TypePath path
) {
path = getNthTypeParameterPath(constraint, tp, 0) and
@@ -630,15 +630,15 @@ module Make1 Input1> {
}
pragma[nomagic]
- private predicate typeParametersEqualFromIndex(
+ private predicate typeParametersEqualToIndex(
App app, TypeAbstraction abs, Constraint constraint, TypeParameter tp, Type t, int i
) {
exists(TypePath path |
t = app.getTypeAt(path) and
if i = 0
- then typeParametersEqualFromIndexBase(app, abs, constraint, tp, path)
+ then typeParametersEqualToIndexBase(app, abs, constraint, tp, path)
else (
- typeParametersEqualFromIndex(app, abs, constraint, tp, t, i - 1) and
+ typeParametersEqualToIndex(app, abs, constraint, tp, t, i - 1) and
path = getNthTypeParameterPath(constraint, tp, i)
)
)
@@ -655,19 +655,19 @@ module Make1 Input1> {
exists(int n | n = max(int i | exists(getNthTypeParameterPath(constraint, tp, i))) |
// If the largest index is 0, then there are no equalities to check as
// the type parameter only occurs once.
- if n = 0 then any() else typeParametersEqualFromIndex(app, abs, constraint, tp, _, n)
+ if n = 0 then any() else typeParametersEqualToIndex(app, abs, constraint, tp, _, n)
)
)
}
- private predicate typeParametersHaveEqualInstantiationFromIndex(
+ private predicate typeParametersHaveEqualInstantiationToIndex(
App app, TypeAbstraction abs, Constraint constraint, int i
) {
exists(TypeParameter tp | tp = getNthTypeParameter(abs, i) |
typeParametersEqual(app, abs, constraint, tp) and
if i = 0
then any()
- else typeParametersHaveEqualInstantiationFromIndex(app, abs, constraint, i - 1)
+ else typeParametersHaveEqualInstantiationToIndex(app, abs, constraint, i - 1)
)
}
@@ -697,7 +697,7 @@ module Make1 Input1> {
not exists(getNthTypeParameter(abs, _))
or
exists(int n | n = max(int i | exists(getNthTypeParameter(abs, i))) |
- typeParametersHaveEqualInstantiationFromIndex(app, abs, constraint, n)
+ typeParametersHaveEqualInstantiationToIndex(app, abs, constraint, n)
)
)
}
From 6c3566ab524ea06f91e85479bfbd13fe74fa1cc8 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Mon, 17 Nov 2025 13:45:36 +0000
Subject: [PATCH 17/70] Rust: It turns out we need test cases for immutable
pointers as well.
---
.../CWE-825/AccessAfterLifetime.expected | 94 +++++++++----------
.../CWE-825/AccessInvalidPointer.expected | 36 +++----
.../security/CWE-825/deallocation.rs | 22 +++++
3 files changed, 87 insertions(+), 65 deletions(-)
diff --git a/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected b/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected
index 8b521239978..3d6c4d190af 100644
--- a/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected
+++ b/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected
@@ -24,27 +24,27 @@
| lifetime.rs:808:23:808:25 | ptr | lifetime.rs:798:9:798:12 | &val | lifetime.rs:808:23:808:25 | ptr | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:796:6:796:8 | val | val |
| main.rs:64:23:64:24 | p2 | main.rs:44:26:44:28 | &b2 | main.rs:64:23:64:24 | p2 | Access of a pointer to $@ after its lifetime has ended. | main.rs:43:13:43:14 | b2 | b2 |
edges
-| deallocation.rs:220:6:220:7 | p1 | deallocation.rs:223:14:223:15 | p1 | provenance | |
-| deallocation.rs:220:6:220:7 | p1 | deallocation.rs:230:14:230:15 | p1 | provenance | |
-| deallocation.rs:220:30:220:38 | &raw const my_buffer | deallocation.rs:220:6:220:7 | p1 | provenance | |
-| deallocation.rs:300:28:300:43 | ...: ... | deallocation.rs:302:18:302:20 | ptr | provenance | |
-| deallocation.rs:312:27:312:42 | ...: ... | deallocation.rs:320:18:320:20 | ptr | provenance | |
-| deallocation.rs:329:7:329:10 | ptr1 | deallocation.rs:332:4:332:7 | ptr1 | provenance | |
-| deallocation.rs:329:7:329:10 | ptr1 | deallocation.rs:332:4:332:7 | ptr1 | provenance | |
-| deallocation.rs:329:14:329:33 | &raw mut ... | deallocation.rs:329:7:329:10 | ptr1 | provenance | |
-| deallocation.rs:330:7:330:10 | ptr2 | deallocation.rs:333:4:333:7 | ptr2 | provenance | |
-| deallocation.rs:330:7:330:10 | ptr2 | deallocation.rs:333:4:333:7 | ptr2 | provenance | |
-| deallocation.rs:330:14:330:33 | &raw mut ... | deallocation.rs:330:7:330:10 | ptr2 | provenance | |
-| deallocation.rs:332:4:332:7 | ptr1 | deallocation.rs:335:27:335:30 | ptr1 | provenance | |
-| deallocation.rs:333:4:333:7 | ptr2 | deallocation.rs:337:26:337:29 | ptr2 | provenance | |
-| deallocation.rs:335:27:335:30 | ptr1 | deallocation.rs:300:28:300:43 | ...: ... | provenance | |
-| deallocation.rs:337:26:337:29 | ptr2 | deallocation.rs:312:27:312:42 | ...: ... | provenance | |
-| deallocation.rs:348:6:348:9 | ptr1 | deallocation.rs:351:13:351:16 | ptr1 | provenance | |
-| deallocation.rs:348:6:348:9 | ptr1 | deallocation.rs:359:13:359:16 | ptr1 | provenance | |
-| deallocation.rs:348:13:348:28 | &raw mut ... | deallocation.rs:348:6:348:9 | ptr1 | provenance | |
-| deallocation.rs:367:6:367:9 | ptr2 | deallocation.rs:370:13:370:16 | ptr2 | provenance | |
-| deallocation.rs:367:6:367:9 | ptr2 | deallocation.rs:380:13:380:16 | ptr2 | provenance | |
-| deallocation.rs:367:13:367:28 | &raw mut ... | deallocation.rs:367:6:367:9 | ptr2 | provenance | |
+| deallocation.rs:242:6:242:7 | p1 | deallocation.rs:245:14:245:15 | p1 | provenance | |
+| deallocation.rs:242:6:242:7 | p1 | deallocation.rs:252:14:252:15 | p1 | provenance | |
+| deallocation.rs:242:30:242:38 | &raw const my_buffer | deallocation.rs:242:6:242:7 | p1 | provenance | |
+| deallocation.rs:322:28:322:43 | ...: ... | deallocation.rs:324:18:324:20 | ptr | provenance | |
+| deallocation.rs:334:27:334:42 | ...: ... | deallocation.rs:342:18:342:20 | ptr | provenance | |
+| deallocation.rs:351:7:351:10 | ptr1 | deallocation.rs:354:4:354:7 | ptr1 | provenance | |
+| deallocation.rs:351:7:351:10 | ptr1 | deallocation.rs:354:4:354:7 | ptr1 | provenance | |
+| deallocation.rs:351:14:351:33 | &raw mut ... | deallocation.rs:351:7:351:10 | ptr1 | provenance | |
+| deallocation.rs:352:7:352:10 | ptr2 | deallocation.rs:355:4:355:7 | ptr2 | provenance | |
+| deallocation.rs:352:7:352:10 | ptr2 | deallocation.rs:355:4:355:7 | ptr2 | provenance | |
+| deallocation.rs:352:14:352:33 | &raw mut ... | deallocation.rs:352:7:352:10 | ptr2 | provenance | |
+| deallocation.rs:354:4:354:7 | ptr1 | deallocation.rs:357:27:357:30 | ptr1 | provenance | |
+| deallocation.rs:355:4:355:7 | ptr2 | deallocation.rs:359:26:359:29 | ptr2 | provenance | |
+| deallocation.rs:357:27:357:30 | ptr1 | deallocation.rs:322:28:322:43 | ...: ... | provenance | |
+| deallocation.rs:359:26:359:29 | ptr2 | deallocation.rs:334:27:334:42 | ...: ... | provenance | |
+| deallocation.rs:370:6:370:9 | ptr1 | deallocation.rs:373:13:373:16 | ptr1 | provenance | |
+| deallocation.rs:370:6:370:9 | ptr1 | deallocation.rs:381:13:381:16 | ptr1 | provenance | |
+| deallocation.rs:370:13:370:28 | &raw mut ... | deallocation.rs:370:6:370:9 | ptr1 | provenance | |
+| deallocation.rs:389:6:389:9 | ptr2 | deallocation.rs:392:13:392:16 | ptr2 | provenance | |
+| deallocation.rs:389:6:389:9 | ptr2 | deallocation.rs:402:13:402:16 | ptr2 | provenance | |
+| deallocation.rs:389:13:389:28 | &raw mut ... | deallocation.rs:389:6:389:9 | ptr2 | provenance | |
| lifetime.rs:21:2:21:18 | return ... | lifetime.rs:54:11:54:30 | get_local_dangling(...) | provenance | |
| lifetime.rs:21:9:21:18 | &my_local1 | lifetime.rs:21:2:21:18 | return ... | provenance | |
| lifetime.rs:27:2:27:22 | return ... | lifetime.rs:55:11:55:34 | get_local_dangling_mut(...) | provenance | |
@@ -234,32 +234,32 @@ models
| 4 | Summary: ::as_ptr; Argument[0].Reference.Reference; ReturnValue.Reference; value |
| 5 | Summary: core::ptr::from_ref; Argument[0]; ReturnValue; value |
nodes
-| deallocation.rs:220:6:220:7 | p1 | semmle.label | p1 |
-| deallocation.rs:220:30:220:38 | &raw const my_buffer | semmle.label | &raw const my_buffer |
-| deallocation.rs:223:14:223:15 | p1 | semmle.label | p1 |
-| deallocation.rs:230:14:230:15 | p1 | semmle.label | p1 |
-| deallocation.rs:300:28:300:43 | ...: ... | semmle.label | ...: ... |
-| deallocation.rs:302:18:302:20 | ptr | semmle.label | ptr |
-| deallocation.rs:312:27:312:42 | ...: ... | semmle.label | ...: ... |
-| deallocation.rs:320:18:320:20 | ptr | semmle.label | ptr |
-| deallocation.rs:329:7:329:10 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:329:14:329:33 | &raw mut ... | semmle.label | &raw mut ... |
-| deallocation.rs:330:7:330:10 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:330:14:330:33 | &raw mut ... | semmle.label | &raw mut ... |
-| deallocation.rs:332:4:332:7 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:332:4:332:7 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:333:4:333:7 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:333:4:333:7 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:335:27:335:30 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:337:26:337:29 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:348:6:348:9 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:348:13:348:28 | &raw mut ... | semmle.label | &raw mut ... |
-| deallocation.rs:351:13:351:16 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:359:13:359:16 | ptr1 | semmle.label | ptr1 |
-| deallocation.rs:367:6:367:9 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:367:13:367:28 | &raw mut ... | semmle.label | &raw mut ... |
-| deallocation.rs:370:13:370:16 | ptr2 | semmle.label | ptr2 |
-| deallocation.rs:380:13:380:16 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:242:6:242:7 | p1 | semmle.label | p1 |
+| deallocation.rs:242:30:242:38 | &raw const my_buffer | semmle.label | &raw const my_buffer |
+| deallocation.rs:245:14:245:15 | p1 | semmle.label | p1 |
+| deallocation.rs:252:14:252:15 | p1 | semmle.label | p1 |
+| deallocation.rs:322:28:322:43 | ...: ... | semmle.label | ...: ... |
+| deallocation.rs:324:18:324:20 | ptr | semmle.label | ptr |
+| deallocation.rs:334:27:334:42 | ...: ... | semmle.label | ...: ... |
+| deallocation.rs:342:18:342:20 | ptr | semmle.label | ptr |
+| deallocation.rs:351:7:351:10 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:351:14:351:33 | &raw mut ... | semmle.label | &raw mut ... |
+| deallocation.rs:352:7:352:10 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:352:14:352:33 | &raw mut ... | semmle.label | &raw mut ... |
+| deallocation.rs:354:4:354:7 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:354:4:354:7 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:355:4:355:7 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:355:4:355:7 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:357:27:357:30 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:359:26:359:29 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:370:6:370:9 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:370:13:370:28 | &raw mut ... | semmle.label | &raw mut ... |
+| deallocation.rs:373:13:373:16 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:381:13:381:16 | ptr1 | semmle.label | ptr1 |
+| deallocation.rs:389:6:389:9 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:389:13:389:28 | &raw mut ... | semmle.label | &raw mut ... |
+| deallocation.rs:392:13:392:16 | ptr2 | semmle.label | ptr2 |
+| deallocation.rs:402:13:402:16 | ptr2 | semmle.label | ptr2 |
| lifetime.rs:21:2:21:18 | return ... | semmle.label | return ... |
| lifetime.rs:21:9:21:18 | &my_local1 | semmle.label | &my_local1 |
| lifetime.rs:27:2:27:22 | return ... | semmle.label | return ... |
diff --git a/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected b/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
index 2ee4afddf2e..b9d308b0572 100644
--- a/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
+++ b/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
@@ -13,10 +13,10 @@
| deallocation.rs:130:14:130:15 | p1 | deallocation.rs:123:23:123:40 | ...::dangling | deallocation.rs:130:14:130:15 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:123:23:123:40 | ...::dangling | invalid |
| deallocation.rs:131:14:131:15 | p2 | deallocation.rs:124:21:124:42 | ...::dangling_mut | deallocation.rs:131:14:131:15 | p2 | This operation dereferences a pointer that may be $@. | deallocation.rs:124:21:124:42 | ...::dangling_mut | invalid |
| deallocation.rs:132:14:132:15 | p3 | deallocation.rs:125:23:125:36 | ...::null | deallocation.rs:132:14:132:15 | p3 | This operation dereferences a pointer that may be $@. | deallocation.rs:125:23:125:36 | ...::null | invalid |
-| deallocation.rs:252:15:252:16 | p1 | deallocation.rs:248:3:248:25 | ...::drop_in_place | deallocation.rs:252:15:252:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:248:3:248:25 | ...::drop_in_place | invalid |
-| deallocation.rs:252:15:252:16 | p1 | deallocation.rs:248:3:248:25 | ...::drop_in_place | deallocation.rs:252:15:252:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:248:3:248:25 | ...::drop_in_place | invalid |
-| deallocation.rs:320:18:320:20 | ptr | deallocation.rs:314:3:314:25 | ...::drop_in_place | deallocation.rs:320:18:320:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:314:3:314:25 | ...::drop_in_place | invalid |
-| deallocation.rs:320:18:320:20 | ptr | deallocation.rs:314:3:314:25 | ...::drop_in_place | deallocation.rs:320:18:320:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:314:3:314:25 | ...::drop_in_place | invalid |
+| deallocation.rs:274:15:274:16 | p1 | deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:274:15:274:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:270:3:270:25 | ...::drop_in_place | invalid |
+| deallocation.rs:274:15:274:16 | p1 | deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:274:15:274:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:270:3:270:25 | ...::drop_in_place | invalid |
+| deallocation.rs:342:18:342:20 | ptr | deallocation.rs:336:3:336:25 | ...::drop_in_place | deallocation.rs:342:18:342:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:336:3:336:25 | ...::drop_in_place | invalid |
+| deallocation.rs:342:18:342:20 | ptr | deallocation.rs:336:3:336:25 | ...::drop_in_place | deallocation.rs:342:18:342:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:336:3:336:25 | ...::drop_in_place | invalid |
edges
| deallocation.rs:20:3:20:21 | ...::dealloc | deallocation.rs:20:23:20:24 | [post] m1 | provenance | Src:MaD:3 MaD:3 |
| deallocation.rs:20:23:20:24 | [post] m1 | deallocation.rs:26:15:26:16 | m1 | provenance | |
@@ -44,12 +44,12 @@ edges
| deallocation.rs:125:6:125:7 | p3 | deallocation.rs:132:14:132:15 | p3 | provenance | |
| deallocation.rs:125:23:125:36 | ...::null | deallocation.rs:125:23:125:38 | ...::null(...) | provenance | Src:MaD:7 MaD:7 |
| deallocation.rs:125:23:125:38 | ...::null(...) | deallocation.rs:125:6:125:7 | p3 | provenance | |
-| deallocation.rs:248:3:248:25 | ...::drop_in_place | deallocation.rs:248:27:248:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
-| deallocation.rs:248:3:248:25 | ...::drop_in_place | deallocation.rs:248:27:248:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
-| deallocation.rs:248:27:248:28 | [post] p1 | deallocation.rs:252:15:252:16 | p1 | provenance | |
-| deallocation.rs:314:3:314:25 | ...::drop_in_place | deallocation.rs:314:27:314:29 | [post] ptr | provenance | Src:MaD:6 MaD:6 |
-| deallocation.rs:314:3:314:25 | ...::drop_in_place | deallocation.rs:314:27:314:29 | [post] ptr | provenance | Src:MaD:6 MaD:6 |
-| deallocation.rs:314:27:314:29 | [post] ptr | deallocation.rs:320:18:320:20 | ptr | provenance | |
+| deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:270:27:270:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
+| deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:270:27:270:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
+| deallocation.rs:270:27:270:28 | [post] p1 | deallocation.rs:274:15:274:16 | p1 | provenance | |
+| deallocation.rs:336:3:336:25 | ...::drop_in_place | deallocation.rs:336:27:336:29 | [post] ptr | provenance | Src:MaD:6 MaD:6 |
+| deallocation.rs:336:3:336:25 | ...::drop_in_place | deallocation.rs:336:27:336:29 | [post] ptr | provenance | Src:MaD:6 MaD:6 |
+| deallocation.rs:336:27:336:29 | [post] ptr | deallocation.rs:342:18:342:20 | ptr | provenance | |
models
| 1 | Sink: core::ptr::read; Argument[0]; pointer-access |
| 2 | Sink: core::ptr::write; Argument[0]; pointer-access |
@@ -92,12 +92,12 @@ nodes
| deallocation.rs:130:14:130:15 | p1 | semmle.label | p1 |
| deallocation.rs:131:14:131:15 | p2 | semmle.label | p2 |
| deallocation.rs:132:14:132:15 | p3 | semmle.label | p3 |
-| deallocation.rs:248:3:248:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
-| deallocation.rs:248:3:248:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
-| deallocation.rs:248:27:248:28 | [post] p1 | semmle.label | [post] p1 |
-| deallocation.rs:252:15:252:16 | p1 | semmle.label | p1 |
-| deallocation.rs:314:3:314:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
-| deallocation.rs:314:3:314:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
-| deallocation.rs:314:27:314:29 | [post] ptr | semmle.label | [post] ptr |
-| deallocation.rs:320:18:320:20 | ptr | semmle.label | ptr |
+| deallocation.rs:270:3:270:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
+| deallocation.rs:270:3:270:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
+| deallocation.rs:270:27:270:28 | [post] p1 | semmle.label | [post] p1 |
+| deallocation.rs:274:15:274:16 | p1 | semmle.label | p1 |
+| deallocation.rs:336:3:336:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
+| deallocation.rs:336:3:336:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
+| deallocation.rs:336:27:336:29 | [post] ptr | semmle.label | [post] ptr |
+| deallocation.rs:342:18:342:20 | ptr | semmle.label | ptr |
subpaths
diff --git a/rust/ql/test/query-tests/security/CWE-825/deallocation.rs b/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
index ab4b1e73a2b..bca375f2429 100644
--- a/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
+++ b/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
@@ -149,6 +149,9 @@ impl MyObject {
pub unsafe fn test_ptr_invalid_conditions(mode: i32) {
let layout = std::alloc::Layout::new::();
+
+ // --- mutable pointer ---
+
let mut ptr = std::alloc::alloc(layout) as *mut MyObject;
(*ptr).value = 0; // good
@@ -207,6 +210,25 @@ pub unsafe fn test_ptr_invalid_conditions(mode: i32) {
if (*ptr).is_zero() || ptr.is_null() { // $ MISSING: Alert[rust/access-invalid-pointer]
println!(" cond9");
}
+
+ // --- immutable pointer ---
+
+ let const_ptr;
+
+ if mode == 126 { // (causes a panic below)
+ const_ptr = std::ptr::null_mut();
+ } else {
+ const_ptr = std::alloc::alloc(layout) as *mut MyObject;
+ (*const_ptr).value = 0; // good
+ }
+
+ if const_ptr.is_null() {
+ let v = (*const_ptr).value; // $ MISSING: Alert[rust/access-invalid-pointer]
+ println!(" cond10 v = {v}");
+ } else {
+ let v = (*const_ptr).value; // good - unreachable with null pointer
+ println!(" cond11 v = {v}");
+ }
}
// --- drop ---
From d80422915842d7b79fd8ba595e3151b6737c1217 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 16:15:25 +0000
Subject: [PATCH 18/70] Rust: Add missing model.
---
.../rust/frameworks/stdlib/core.model.yml | 1 +
.../CWE-825/AccessInvalidPointer.expected | 74 ++++++++++++++++++-
.../security/CWE-825/deallocation.rs | 44 +++++------
3 files changed, 95 insertions(+), 24 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/core.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/core.model.yml
index 46eea8f9c4e..7d1761dd888 100644
--- a/rust/ql/lib/codeql/rust/frameworks/stdlib/core.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/core.model.yml
@@ -60,6 +60,7 @@ extensions:
- ["core::ptr::dangling", "ReturnValue", "pointer-invalidate", "manual"]
- ["core::ptr::dangling_mut", "ReturnValue", "pointer-invalidate", "manual"]
- ["core::ptr::null", "ReturnValue", "pointer-invalidate", "manual"]
+ - ["core::ptr::null_mut", "ReturnValue", "pointer-invalidate", "manual"]
- ["v8::primitives::null", "ReturnValue", "pointer-invalidate", "manual"]
- addsTo:
pack: codeql/rust-all
diff --git a/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected b/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
index b9d308b0572..7abb53a2dfb 100644
--- a/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
+++ b/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
@@ -13,6 +13,20 @@
| deallocation.rs:130:14:130:15 | p1 | deallocation.rs:123:23:123:40 | ...::dangling | deallocation.rs:130:14:130:15 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:123:23:123:40 | ...::dangling | invalid |
| deallocation.rs:131:14:131:15 | p2 | deallocation.rs:124:21:124:42 | ...::dangling_mut | deallocation.rs:131:14:131:15 | p2 | This operation dereferences a pointer that may be $@. | deallocation.rs:124:21:124:42 | ...::dangling_mut | invalid |
| deallocation.rs:132:14:132:15 | p3 | deallocation.rs:125:23:125:36 | ...::null | deallocation.rs:132:14:132:15 | p3 | This operation dereferences a pointer that may be $@. | deallocation.rs:125:23:125:36 | ...::null | invalid |
+| deallocation.rs:163:13:163:15 | ptr | deallocation.rs:159:9:159:26 | ...::null_mut | deallocation.rs:163:13:163:15 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:159:9:159:26 | ...::null_mut | invalid |
+| deallocation.rs:166:13:166:15 | ptr | deallocation.rs:159:9:159:26 | ...::null_mut | deallocation.rs:166:13:166:15 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:159:9:159:26 | ...::null_mut | invalid |
+| deallocation.rs:175:13:175:15 | ptr | deallocation.rs:171:9:171:26 | ...::null_mut | deallocation.rs:175:13:175:15 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:171:9:171:26 | ...::null_mut | invalid |
+| deallocation.rs:178:13:178:15 | ptr | deallocation.rs:171:9:171:26 | ...::null_mut | deallocation.rs:178:13:178:15 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:171:9:171:26 | ...::null_mut | invalid |
+| deallocation.rs:186:24:186:26 | ptr | deallocation.rs:183:9:183:26 | ...::null_mut | deallocation.rs:186:24:186:26 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:183:9:183:26 | ...::null_mut | invalid |
+| deallocation.rs:190:24:190:26 | ptr | deallocation.rs:183:9:183:26 | ...::null_mut | deallocation.rs:190:24:190:26 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:183:9:183:26 | ...::null_mut | invalid |
+| deallocation.rs:194:25:194:27 | ptr | deallocation.rs:183:9:183:26 | ...::null_mut | deallocation.rs:194:25:194:27 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:183:9:183:26 | ...::null_mut | invalid |
+| deallocation.rs:202:24:202:26 | ptr | deallocation.rs:183:9:183:26 | ...::null_mut | deallocation.rs:202:24:202:26 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:183:9:183:26 | ...::null_mut | invalid |
+| deallocation.rs:202:24:202:26 | ptr | deallocation.rs:199:9:199:26 | ...::null_mut | deallocation.rs:202:24:202:26 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:199:9:199:26 | ...::null_mut | invalid |
+| deallocation.rs:210:7:210:9 | ptr | deallocation.rs:183:9:183:26 | ...::null_mut | deallocation.rs:210:7:210:9 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:183:9:183:26 | ...::null_mut | invalid |
+| deallocation.rs:210:7:210:9 | ptr | deallocation.rs:199:9:199:26 | ...::null_mut | deallocation.rs:210:7:210:9 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:199:9:199:26 | ...::null_mut | invalid |
+| deallocation.rs:210:7:210:9 | ptr | deallocation.rs:207:9:207:26 | ...::null_mut | deallocation.rs:210:7:210:9 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:207:9:207:26 | ...::null_mut | invalid |
+| deallocation.rs:226:13:226:21 | const_ptr | deallocation.rs:219:15:219:32 | ...::null_mut | deallocation.rs:226:13:226:21 | const_ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:219:15:219:32 | ...::null_mut | invalid |
+| deallocation.rs:229:13:229:21 | const_ptr | deallocation.rs:219:15:219:32 | ...::null_mut | deallocation.rs:229:13:229:21 | const_ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:219:15:219:32 | ...::null_mut | invalid |
| deallocation.rs:274:15:274:16 | p1 | deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:274:15:274:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:270:3:270:25 | ...::drop_in_place | invalid |
| deallocation.rs:274:15:274:16 | p1 | deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:274:15:274:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:270:3:270:25 | ...::drop_in_place | invalid |
| deallocation.rs:342:18:342:20 | ptr | deallocation.rs:336:3:336:25 | ...::drop_in_place | deallocation.rs:342:18:342:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:336:3:336:25 | ...::drop_in_place | invalid |
@@ -32,7 +46,7 @@ edges
| deallocation.rs:70:23:70:35 | [post] m2 as ... | deallocation.rs:90:7:90:8 | m2 | provenance | |
| deallocation.rs:70:23:70:35 | [post] m2 as ... | deallocation.rs:95:33:95:34 | m2 | provenance | |
| deallocation.rs:95:33:95:34 | m2 | deallocation.rs:95:5:95:31 | ...::write::<...> | provenance | MaD:2 Sink:MaD:2 |
-| deallocation.rs:112:3:112:12 | ...::free | deallocation.rs:112:14:112:40 | [post] my_ptr as ... | provenance | Src:MaD:8 MaD:8 |
+| deallocation.rs:112:3:112:12 | ...::free | deallocation.rs:112:14:112:40 | [post] my_ptr as ... | provenance | Src:MaD:9 MaD:9 |
| deallocation.rs:112:14:112:40 | [post] my_ptr as ... | deallocation.rs:115:13:115:18 | my_ptr | provenance | |
| deallocation.rs:123:6:123:7 | p1 | deallocation.rs:130:14:130:15 | p1 | provenance | |
| deallocation.rs:123:23:123:40 | ...::dangling | deallocation.rs:123:23:123:42 | ...::dangling(...) | provenance | Src:MaD:4 MaD:4 |
@@ -44,6 +58,32 @@ edges
| deallocation.rs:125:6:125:7 | p3 | deallocation.rs:132:14:132:15 | p3 | provenance | |
| deallocation.rs:125:23:125:36 | ...::null | deallocation.rs:125:23:125:38 | ...::null(...) | provenance | Src:MaD:7 MaD:7 |
| deallocation.rs:125:23:125:38 | ...::null(...) | deallocation.rs:125:6:125:7 | p3 | provenance | |
+| deallocation.rs:159:3:159:5 | ptr | deallocation.rs:163:13:163:15 | ptr | provenance | |
+| deallocation.rs:159:3:159:5 | ptr | deallocation.rs:166:13:166:15 | ptr | provenance | |
+| deallocation.rs:159:9:159:26 | ...::null_mut | deallocation.rs:159:9:159:28 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
+| deallocation.rs:159:9:159:28 | ...::null_mut(...) | deallocation.rs:159:3:159:5 | ptr | provenance | |
+| deallocation.rs:171:3:171:5 | ptr | deallocation.rs:175:13:175:15 | ptr | provenance | |
+| deallocation.rs:171:3:171:5 | ptr | deallocation.rs:178:13:178:15 | ptr | provenance | |
+| deallocation.rs:171:9:171:26 | ...::null_mut | deallocation.rs:171:9:171:28 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
+| deallocation.rs:171:9:171:28 | ...::null_mut(...) | deallocation.rs:171:3:171:5 | ptr | provenance | |
+| deallocation.rs:183:3:183:5 | ptr | deallocation.rs:186:24:186:26 | ptr | provenance | |
+| deallocation.rs:183:3:183:5 | ptr | deallocation.rs:190:24:190:26 | ptr | provenance | |
+| deallocation.rs:183:3:183:5 | ptr | deallocation.rs:194:25:194:27 | ptr | provenance | |
+| deallocation.rs:183:3:183:5 | ptr | deallocation.rs:202:24:202:26 | ptr | provenance | |
+| deallocation.rs:183:3:183:5 | ptr | deallocation.rs:210:7:210:9 | ptr | provenance | |
+| deallocation.rs:183:9:183:26 | ...::null_mut | deallocation.rs:183:9:183:28 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
+| deallocation.rs:183:9:183:28 | ...::null_mut(...) | deallocation.rs:183:3:183:5 | ptr | provenance | |
+| deallocation.rs:199:3:199:5 | ptr | deallocation.rs:202:24:202:26 | ptr | provenance | |
+| deallocation.rs:199:3:199:5 | ptr | deallocation.rs:210:7:210:9 | ptr | provenance | |
+| deallocation.rs:199:9:199:26 | ...::null_mut | deallocation.rs:199:9:199:28 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
+| deallocation.rs:199:9:199:28 | ...::null_mut(...) | deallocation.rs:199:3:199:5 | ptr | provenance | |
+| deallocation.rs:207:3:207:5 | ptr | deallocation.rs:210:7:210:9 | ptr | provenance | |
+| deallocation.rs:207:9:207:26 | ...::null_mut | deallocation.rs:207:9:207:28 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
+| deallocation.rs:207:9:207:28 | ...::null_mut(...) | deallocation.rs:207:3:207:5 | ptr | provenance | |
+| deallocation.rs:219:3:219:11 | const_ptr | deallocation.rs:226:13:226:21 | const_ptr | provenance | |
+| deallocation.rs:219:3:219:11 | const_ptr | deallocation.rs:229:13:229:21 | const_ptr | provenance | |
+| deallocation.rs:219:15:219:32 | ...::null_mut | deallocation.rs:219:15:219:34 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
+| deallocation.rs:219:15:219:34 | ...::null_mut(...) | deallocation.rs:219:3:219:11 | const_ptr | provenance | |
| deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:270:27:270:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
| deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:270:27:270:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
| deallocation.rs:270:27:270:28 | [post] p1 | deallocation.rs:274:15:274:16 | p1 | provenance | |
@@ -58,7 +98,8 @@ models
| 5 | Source: core::ptr::dangling_mut; ReturnValue; pointer-invalidate |
| 6 | Source: core::ptr::drop_in_place; Argument[0]; pointer-invalidate |
| 7 | Source: core::ptr::null; ReturnValue; pointer-invalidate |
-| 8 | Source: libc::unix::free; Argument[0]; pointer-invalidate |
+| 8 | Source: core::ptr::null_mut; ReturnValue; pointer-invalidate |
+| 9 | Source: libc::unix::free; Argument[0]; pointer-invalidate |
nodes
| deallocation.rs:20:3:20:21 | ...::dealloc | semmle.label | ...::dealloc |
| deallocation.rs:20:23:20:24 | [post] m1 | semmle.label | [post] m1 |
@@ -92,6 +133,35 @@ nodes
| deallocation.rs:130:14:130:15 | p1 | semmle.label | p1 |
| deallocation.rs:131:14:131:15 | p2 | semmle.label | p2 |
| deallocation.rs:132:14:132:15 | p3 | semmle.label | p3 |
+| deallocation.rs:159:3:159:5 | ptr | semmle.label | ptr |
+| deallocation.rs:159:9:159:26 | ...::null_mut | semmle.label | ...::null_mut |
+| deallocation.rs:159:9:159:28 | ...::null_mut(...) | semmle.label | ...::null_mut(...) |
+| deallocation.rs:163:13:163:15 | ptr | semmle.label | ptr |
+| deallocation.rs:166:13:166:15 | ptr | semmle.label | ptr |
+| deallocation.rs:171:3:171:5 | ptr | semmle.label | ptr |
+| deallocation.rs:171:9:171:26 | ...::null_mut | semmle.label | ...::null_mut |
+| deallocation.rs:171:9:171:28 | ...::null_mut(...) | semmle.label | ...::null_mut(...) |
+| deallocation.rs:175:13:175:15 | ptr | semmle.label | ptr |
+| deallocation.rs:178:13:178:15 | ptr | semmle.label | ptr |
+| deallocation.rs:183:3:183:5 | ptr | semmle.label | ptr |
+| deallocation.rs:183:9:183:26 | ...::null_mut | semmle.label | ...::null_mut |
+| deallocation.rs:183:9:183:28 | ...::null_mut(...) | semmle.label | ...::null_mut(...) |
+| deallocation.rs:186:24:186:26 | ptr | semmle.label | ptr |
+| deallocation.rs:190:24:190:26 | ptr | semmle.label | ptr |
+| deallocation.rs:194:25:194:27 | ptr | semmle.label | ptr |
+| deallocation.rs:199:3:199:5 | ptr | semmle.label | ptr |
+| deallocation.rs:199:9:199:26 | ...::null_mut | semmle.label | ...::null_mut |
+| deallocation.rs:199:9:199:28 | ...::null_mut(...) | semmle.label | ...::null_mut(...) |
+| deallocation.rs:202:24:202:26 | ptr | semmle.label | ptr |
+| deallocation.rs:207:3:207:5 | ptr | semmle.label | ptr |
+| deallocation.rs:207:9:207:26 | ...::null_mut | semmle.label | ...::null_mut |
+| deallocation.rs:207:9:207:28 | ...::null_mut(...) | semmle.label | ...::null_mut(...) |
+| deallocation.rs:210:7:210:9 | ptr | semmle.label | ptr |
+| deallocation.rs:219:3:219:11 | const_ptr | semmle.label | const_ptr |
+| deallocation.rs:219:15:219:32 | ...::null_mut | semmle.label | ...::null_mut |
+| deallocation.rs:219:15:219:34 | ...::null_mut(...) | semmle.label | ...::null_mut(...) |
+| deallocation.rs:226:13:226:21 | const_ptr | semmle.label | const_ptr |
+| deallocation.rs:229:13:229:21 | const_ptr | semmle.label | const_ptr |
| deallocation.rs:270:3:270:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
| deallocation.rs:270:3:270:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
| deallocation.rs:270:27:270:28 | [post] p1 | semmle.label | [post] p1 |
diff --git a/rust/ql/test/query-tests/security/CWE-825/deallocation.rs b/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
index bca375f2429..a9199478a93 100644
--- a/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
+++ b/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
@@ -155,59 +155,59 @@ pub unsafe fn test_ptr_invalid_conditions(mode: i32) {
let mut ptr = std::alloc::alloc(layout) as *mut MyObject;
(*ptr).value = 0; // good
- if mode == 121 {
- ptr = std::ptr::null_mut(); // (causes a panic below)
+ if mode == 121 { // (causes a panic below)
+ ptr = std::ptr::null_mut(); // $ Source[rust/access-invalid-pointer]
}
if ptr.is_null() {
- let v = (*ptr).value; // $ MISSING: Alert[rust/access-invalid-pointer]
+ let v = (*ptr).value; // $ Alert[rust/access-invalid-pointer]
println!(" cond1 v = {v}");
} else {
- let v = (*ptr).value; // good - unreachable with null pointer
+ let v = (*ptr).value; // $ SPURIOUS: Alert[rust/access-invalid-pointer] good - unreachable with null pointer
println!(" cond2 v = {v}");
}
- if mode == 122 {
- ptr = std::ptr::null_mut(); // (causes a panic below)
+ if mode == 122 { // (causes a panic below)
+ ptr = std::ptr::null_mut(); // $ Source[rust/access-invalid-pointer]
}
if !(ptr.is_null()) {
- let v = (*ptr).value; // good - unreachable with null pointer
+ let v = (*ptr).value; // $ SPURIOUS: Alert[rust/access-invalid-pointer] good - unreachable with null pointer
println!(" cond3 v = {v}");
} else {
- let v = (*ptr).value; // $ MISSING: Alert[rust/access-invalid-pointer]
+ let v = (*ptr).value; // $ Alert[rust/access-invalid-pointer]
println!(" cond4 v = {v}");
}
- if mode == 123 {
- ptr = std::ptr::null_mut(); // (causes a panic below)
+ if mode == 123 { // (causes a panic below)
+ ptr = std::ptr::null_mut(); // $ Source[rust/access-invalid-pointer]
}
- if ptr.is_null() || (*ptr).value == 0 { // good - deref is protected by short-circuiting
+ if ptr.is_null() || (*ptr).value == 0 { // $ SPURIOUS: Alert[rust/access-invalid-pointer] good - deref is protected by short-circuiting
println!(" cond5");
}
- if ptr.is_null() || (*ptr).is_zero() { // good - deref is protected by short-circuiting
+ if ptr.is_null() || (*ptr).is_zero() { // $ SPURIOUS: Alert[rust/access-invalid-pointer] good - deref is protected by short-circuiting
println!(" cond6");
}
- if !ptr.is_null() || (*ptr).value == 0 { // $ MISSING: Alert[rust/access-invalid-pointer]
+ if !ptr.is_null() || (*ptr).value == 0 { // $ Alert[rust/access-invalid-pointer]
println!(" cond7");
}
- if mode == 124 {
- ptr = std::ptr::null_mut(); // (causes a panic below)
+ if mode == 124 { // (causes a panic below)
+ ptr = std::ptr::null_mut(); // $ Source[rust/access-invalid-pointer]
}
- if ptr.is_null() && (*ptr).is_zero() { // $ MISSING: Alert[rust/access-invalid-pointer]
+ if ptr.is_null() && (*ptr).is_zero() { // $ Alert[rust/access-invalid-pointer]
println!(" cond8");
}
- if mode == 125 {
- ptr = std::ptr::null_mut(); // (causes a panic below)
+ if mode == 125 { // (causes a panic below)
+ ptr = std::ptr::null_mut(); // $ Source[rust/access-invalid-pointer]
}
- if (*ptr).is_zero() || ptr.is_null() { // $ MISSING: Alert[rust/access-invalid-pointer]
+ if (*ptr).is_zero() || ptr.is_null() { // $ Alert[rust/access-invalid-pointer]
println!(" cond9");
}
@@ -216,17 +216,17 @@ pub unsafe fn test_ptr_invalid_conditions(mode: i32) {
let const_ptr;
if mode == 126 { // (causes a panic below)
- const_ptr = std::ptr::null_mut();
+ const_ptr = std::ptr::null_mut(); // $ Source[rust/access-invalid-pointer]
} else {
const_ptr = std::alloc::alloc(layout) as *mut MyObject;
(*const_ptr).value = 0; // good
}
if const_ptr.is_null() {
- let v = (*const_ptr).value; // $ MISSING: Alert[rust/access-invalid-pointer]
+ let v = (*const_ptr).value; // $ Alert[rust/access-invalid-pointer]
println!(" cond10 v = {v}");
} else {
- let v = (*const_ptr).value; // good - unreachable with null pointer
+ let v = (*const_ptr).value; // $ SPURIOUS: Alert[rust/access-invalid-pointer] good - unreachable with null pointer
println!(" cond11 v = {v}");
}
}
From 41a6bf079d0db669a3753a16c37cb372a0a0b7bd Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 13 Nov 2025 15:09:14 +0000
Subject: [PATCH 19/70] Rust: Add barrier for null pointer checks to the query.
---
.../AccessInvalidPointerExtensions.qll | 7 ++++++
rust/ql/lib/codeql/rust/security/Barriers.qll | 24 +++++++++++++++++++
.../CWE-825/AccessInvalidPointer.expected | 3 ---
.../security/CWE-825/deallocation.rs | 2 +-
4 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll b/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll
index 444db014209..034efd60b91 100644
--- a/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll
@@ -9,6 +9,7 @@ private import codeql.rust.dataflow.FlowSource
private import codeql.rust.dataflow.FlowSink
private import codeql.rust.Concepts
private import codeql.rust.dataflow.internal.Node
+private import codeql.rust.security.Barriers as Barriers
/**
* Provides default sources, sinks and barriers for detecting accesses to
@@ -59,4 +60,10 @@ module AccessInvalidPointer {
private class ModelsAsDataSink extends Sink {
ModelsAsDataSink() { sinkNode(this, "pointer-access") }
}
+
+ /**
+ * A barrier for invalid pointer access vulnerabilities for values found to be `null` in
+ * a comparison.
+ */
+ private class NullCheckBarrier extends Barrier instanceof Barriers::NotNullCheckBarrier { }
}
diff --git a/rust/ql/lib/codeql/rust/security/Barriers.qll b/rust/ql/lib/codeql/rust/security/Barriers.qll
index 398e4f56712..edd97ec8519 100644
--- a/rust/ql/lib/codeql/rust/security/Barriers.qll
+++ b/rust/ql/lib/codeql/rust/security/Barriers.qll
@@ -8,6 +8,8 @@ private import codeql.rust.dataflow.DataFlow
private import codeql.rust.internal.TypeInference as TypeInference
private import codeql.rust.internal.Type
private import codeql.rust.frameworks.stdlib.Builtins
+private import codeql.rust.controlflow.ControlFlowGraph as Cfg
+private import codeql.rust.controlflow.CfgNodes as CfgNodes
/**
* A node whose type is a numeric or boolean type, which may be an appropriate
@@ -40,3 +42,25 @@ class IntegralOrBooleanTypeBarrier extends DataFlow::Node {
)
}
}
+
+/**
+ * Holds if guard expression `g` having result `branch` indicates that the
+ * sub-expression `node` is not null. For example when `ptr.is_null()` is
+ * `false`, we have that `ptr` is not null.
+ */
+private predicate notNullCheck(CfgNodes::AstCfgNode g, Cfg::CfgNode node, boolean branch) {
+ exists(MethodCallExpr call |
+ call.getStaticTarget().getName().getText() = "is_null" and
+ g = call.getACfgNode() and
+ node = call.getReceiver().getACfgNode() and
+ branch = false
+ )
+}
+
+/**
+ * A node representing a check that the value is not null, which may be an
+ * appropriate taint flow barrier for some queries.
+ */
+class NotNullCheckBarrier extends DataFlow::Node {
+ NotNullCheckBarrier() { this = DataFlow::BarrierGuard::getABarrierNode() }
+}
diff --git a/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected b/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
index 7abb53a2dfb..6afe11ad012 100644
--- a/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
+++ b/rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected
@@ -26,7 +26,6 @@
| deallocation.rs:210:7:210:9 | ptr | deallocation.rs:199:9:199:26 | ...::null_mut | deallocation.rs:210:7:210:9 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:199:9:199:26 | ...::null_mut | invalid |
| deallocation.rs:210:7:210:9 | ptr | deallocation.rs:207:9:207:26 | ...::null_mut | deallocation.rs:210:7:210:9 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:207:9:207:26 | ...::null_mut | invalid |
| deallocation.rs:226:13:226:21 | const_ptr | deallocation.rs:219:15:219:32 | ...::null_mut | deallocation.rs:226:13:226:21 | const_ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:219:15:219:32 | ...::null_mut | invalid |
-| deallocation.rs:229:13:229:21 | const_ptr | deallocation.rs:219:15:219:32 | ...::null_mut | deallocation.rs:229:13:229:21 | const_ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:219:15:219:32 | ...::null_mut | invalid |
| deallocation.rs:274:15:274:16 | p1 | deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:274:15:274:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:270:3:270:25 | ...::drop_in_place | invalid |
| deallocation.rs:274:15:274:16 | p1 | deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:274:15:274:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:270:3:270:25 | ...::drop_in_place | invalid |
| deallocation.rs:342:18:342:20 | ptr | deallocation.rs:336:3:336:25 | ...::drop_in_place | deallocation.rs:342:18:342:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:336:3:336:25 | ...::drop_in_place | invalid |
@@ -81,7 +80,6 @@ edges
| deallocation.rs:207:9:207:26 | ...::null_mut | deallocation.rs:207:9:207:28 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
| deallocation.rs:207:9:207:28 | ...::null_mut(...) | deallocation.rs:207:3:207:5 | ptr | provenance | |
| deallocation.rs:219:3:219:11 | const_ptr | deallocation.rs:226:13:226:21 | const_ptr | provenance | |
-| deallocation.rs:219:3:219:11 | const_ptr | deallocation.rs:229:13:229:21 | const_ptr | provenance | |
| deallocation.rs:219:15:219:32 | ...::null_mut | deallocation.rs:219:15:219:34 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
| deallocation.rs:219:15:219:34 | ...::null_mut(...) | deallocation.rs:219:3:219:11 | const_ptr | provenance | |
| deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:270:27:270:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
@@ -161,7 +159,6 @@ nodes
| deallocation.rs:219:15:219:32 | ...::null_mut | semmle.label | ...::null_mut |
| deallocation.rs:219:15:219:34 | ...::null_mut(...) | semmle.label | ...::null_mut(...) |
| deallocation.rs:226:13:226:21 | const_ptr | semmle.label | const_ptr |
-| deallocation.rs:229:13:229:21 | const_ptr | semmle.label | const_ptr |
| deallocation.rs:270:3:270:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
| deallocation.rs:270:3:270:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
| deallocation.rs:270:27:270:28 | [post] p1 | semmle.label | [post] p1 |
diff --git a/rust/ql/test/query-tests/security/CWE-825/deallocation.rs b/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
index a9199478a93..073d03260b3 100644
--- a/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
+++ b/rust/ql/test/query-tests/security/CWE-825/deallocation.rs
@@ -226,7 +226,7 @@ pub unsafe fn test_ptr_invalid_conditions(mode: i32) {
let v = (*const_ptr).value; // $ Alert[rust/access-invalid-pointer]
println!(" cond10 v = {v}");
} else {
- let v = (*const_ptr).value; // $ SPURIOUS: Alert[rust/access-invalid-pointer] good - unreachable with null pointer
+ let v = (*const_ptr).value; // $ good - unreachable with null pointer
println!(" cond11 v = {v}");
}
}
From 725899389bf2dfb8e7ccf92f2123d48731c2fc91 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Mon, 17 Nov 2025 15:08:23 +0000
Subject: [PATCH 20/70] Rust: Clean up the query slightly.
---
.../src/queries/security/CWE-825/AccessInvalidPointer.ql | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql b/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
index 5177e1fb0e0..3c10e2b197a 100644
--- a/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
+++ b/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql
@@ -22,11 +22,13 @@ import AccessInvalidPointerFlow::PathGraph
* A data flow configuration for accesses to invalid pointers.
*/
module AccessInvalidPointerConfig implements DataFlow::ConfigSig {
- predicate isSource(DataFlow::Node node) { node instanceof AccessInvalidPointer::Source }
+ import AccessInvalidPointer
- predicate isSink(DataFlow::Node node) { node instanceof AccessInvalidPointer::Sink }
+ predicate isSource(DataFlow::Node node) { node instanceof Source }
- predicate isBarrier(DataFlow::Node barrier) { barrier instanceof AccessInvalidPointer::Barrier }
+ predicate isSink(DataFlow::Node node) { node instanceof Sink }
+
+ predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier }
predicate isBarrierOut(DataFlow::Node node) {
// make sinks barriers so that we only report the closest instance
From 7c8e44db8e2eae2820928b4ead6e9685be6f0572 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Mon, 17 Nov 2025 15:09:57 +0000
Subject: [PATCH 21/70] Rust: Change note.
---
rust/ql/src/change-notes/2025-17-11-access-invalid-pointer.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 rust/ql/src/change-notes/2025-17-11-access-invalid-pointer.md
diff --git a/rust/ql/src/change-notes/2025-17-11-access-invalid-pointer.md b/rust/ql/src/change-notes/2025-17-11-access-invalid-pointer.md
new file mode 100644
index 00000000000..bc7011dc98a
--- /dev/null
+++ b/rust/ql/src/change-notes/2025-17-11-access-invalid-pointer.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The `rust/access-invalid-pointer` query has been improved with new flow sources and barriers.
From 81096131b6143a7580d42454125ef9c82ffd7ad8 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Mon, 17 Nov 2025 15:25:03 +0000
Subject: [PATCH 22/70] Rust: Correct + clarify qldoc.
---
.../codeql/rust/security/AccessInvalidPointerExtensions.qll | 6 +++---
rust/ql/lib/codeql/rust/security/Barriers.qll | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll b/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll
index 034efd60b91..7fb4e5d3615 100644
--- a/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll
@@ -62,8 +62,8 @@ module AccessInvalidPointer {
}
/**
- * A barrier for invalid pointer access vulnerabilities for values found to be `null` in
- * a comparison.
+ * A barrier for invalid pointer access vulnerabilities for values checked to
+ * be non-`null`.
*/
- private class NullCheckBarrier extends Barrier instanceof Barriers::NotNullCheckBarrier { }
+ private class NotNullCheckBarrier extends Barrier instanceof Barriers::NotNullCheckBarrier { }
}
diff --git a/rust/ql/lib/codeql/rust/security/Barriers.qll b/rust/ql/lib/codeql/rust/security/Barriers.qll
index edd97ec8519..3323f729bb6 100644
--- a/rust/ql/lib/codeql/rust/security/Barriers.qll
+++ b/rust/ql/lib/codeql/rust/security/Barriers.qll
@@ -58,7 +58,7 @@ private predicate notNullCheck(CfgNodes::AstCfgNode g, Cfg::CfgNode node, boolea
}
/**
- * A node representing a check that the value is not null, which may be an
+ * A node representing a value checked to be non-null. This may be an
* appropriate taint flow barrier for some queries.
*/
class NotNullCheckBarrier extends DataFlow::Node {
From 880f7b0f18d2128b2c69b15ae9e6398a6a912b20 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Wed, 29 Oct 2025 15:51:40 +0100
Subject: [PATCH 23/70] Rust: More path resolution and variable tests
---
.../library-tests/path-resolution/main.rs | 44 +++
.../path-resolution/path-resolution.expected | 168 +++++----
.../test/library-tests/variables/Cfg.expected | 348 +++++++++++-------
.../test/library-tests/variables/Ssa.expected | 28 ++
rust/ql/test/library-tests/variables/main.rs | 45 +++
.../variables/variables.expected | 29 ++
6 files changed, 448 insertions(+), 214 deletions(-)
diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs
index 9e7ebf5fb17..d60f12b43d7 100644
--- a/rust/ql/test/library-tests/path-resolution/main.rs
+++ b/rust/ql/test/library-tests/path-resolution/main.rs
@@ -790,6 +790,49 @@ mod impl_with_attribute_macro {
} // impl_with_attribute_macro::test
}
+mod patterns {
+ #[rustfmt::skip]
+ pub fn test() -> Option { // $ item=Option $ item=i32
+ let x = Some(42); // $ item=Some
+ let y : Option = match x { // $ item=Option $ item=i32
+ Some(y) => { // $ item=Some
+ None // $ item=None
+ }
+ None => // $ MISSING: item=None
+ None // $ item=None
+ };
+ match y {
+ N0ne => // local variable
+ N0ne
+ }
+ } // patterns::test
+
+ #[rustfmt::skip]
+ fn test2() -> Option { // $ item=Option $ item=i32
+ let test_alias = test; // $ item=patterns::test
+ let test = test_alias();
+ test
+ }
+
+ #[rustfmt::skip]
+ const z: i32 // $ item=i32
+ = 0; // constz
+
+ #[rustfmt::skip]
+ fn test3() {
+ let x = Some(0); // $ item=Some
+ match x {
+ Some(x) // $ item=Some
+ => x,
+ _ => 0
+ };
+ match x {
+ Some(z) => z, // $ item=Some $ MISSING: item=constz
+ _ => 0
+ };
+ }
+}
+
fn main() {
my::nested::nested1::nested2::f(); // $ item=I4
my::f(); // $ item=I38
@@ -826,4 +869,5 @@ fn main() {
AStruct::z_on_type(); // $ item=I124
AStruct {}.z_on_instance(); // $ item=I123 item=I125
impl_with_attribute_macro::test(); // $ item=impl_with_attribute_macro::test
+ patterns::test(); // $ item=patterns::test
}
diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected
index 0ff48d11e8d..c460fea7f5b 100644
--- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected
+++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected
@@ -32,6 +32,7 @@ mod
| main.rs:629:1:697:1 | mod m24 |
| main.rs:714:1:766:1 | mod associated_types |
| main.rs:772:1:791:1 | mod impl_with_attribute_macro |
+| main.rs:793:1:834:1 | mod patterns |
| my2/mod.rs:1:1:1:16 | mod nested2 |
| my2/mod.rs:20:1:20:12 | mod my3 |
| my2/mod.rs:22:1:23:10 | mod mymod |
@@ -72,7 +73,7 @@ resolvePath
| main.rs:37:17:37:24 | ...::f | main.rs:26:9:28:9 | fn f |
| main.rs:39:17:39:23 | println | {EXTERNAL LOCATION} | MacroRules |
| main.rs:40:17:40:17 | f | main.rs:26:9:28:9 | fn f |
-| main.rs:47:9:47:13 | super | main.rs:1:1:829:2 | SourceFile |
+| main.rs:47:9:47:13 | super | main.rs:1:1:873:2 | SourceFile |
| main.rs:47:9:47:17 | ...::m1 | main.rs:20:1:44:1 | mod m1 |
| main.rs:47:9:47:21 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
| main.rs:47:9:47:24 | ...::g | main.rs:30:9:34:9 | fn g |
@@ -87,7 +88,7 @@ resolvePath
| main.rs:68:17:68:19 | Foo | main.rs:66:9:66:21 | struct Foo |
| main.rs:71:13:71:15 | Foo | main.rs:60:5:60:17 | struct Foo |
| main.rs:73:5:73:5 | f | main.rs:62:5:69:5 | fn f |
-| main.rs:75:5:75:8 | self | main.rs:1:1:829:2 | SourceFile |
+| main.rs:75:5:75:8 | self | main.rs:1:1:873:2 | SourceFile |
| main.rs:75:5:75:11 | ...::i | main.rs:78:1:90:1 | fn i |
| main.rs:79:5:79:11 | println | {EXTERNAL LOCATION} | MacroRules |
| main.rs:81:13:81:15 | Foo | main.rs:55:1:55:13 | struct Foo |
@@ -109,7 +110,7 @@ resolvePath
| main.rs:112:9:112:15 | println | {EXTERNAL LOCATION} | MacroRules |
| main.rs:118:9:118:15 | println | {EXTERNAL LOCATION} | MacroRules |
| main.rs:122:9:122:15 | println | {EXTERNAL LOCATION} | MacroRules |
-| main.rs:125:13:125:17 | super | main.rs:1:1:829:2 | SourceFile |
+| main.rs:125:13:125:17 | super | main.rs:1:1:873:2 | SourceFile |
| main.rs:125:13:125:21 | ...::m5 | main.rs:110:1:114:1 | mod m5 |
| main.rs:126:9:126:9 | f | main.rs:111:5:113:5 | fn f |
| main.rs:126:9:126:9 | f | main.rs:117:5:119:5 | fn f |
@@ -397,77 +398,94 @@ resolvePath
| main.rs:781:21:781:23 | i64 | {EXTERNAL LOCATION} | struct i64 |
| main.rs:783:11:783:13 | i64 | {EXTERNAL LOCATION} | struct i64 |
| main.rs:789:17:789:19 | Foo | main.rs:774:5:774:15 | struct Foo |
-| main.rs:794:5:794:6 | my | main.rs:1:1:1:7 | mod my |
-| main.rs:794:5:794:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
-| main.rs:794:5:794:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
-| main.rs:794:5:794:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
-| main.rs:794:5:794:35 | ...::f | my/nested.rs:3:9:5:9 | fn f |
-| main.rs:795:5:795:6 | my | main.rs:1:1:1:7 | mod my |
-| main.rs:795:5:795:9 | ...::f | my.rs:5:1:7:1 | fn f |
-| main.rs:796:5:796:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
-| main.rs:796:5:796:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
-| main.rs:796:5:796:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
-| main.rs:796:5:796:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f |
-| main.rs:797:5:797:5 | f | my2/nested2.rs:3:9:5:9 | fn f |
-| main.rs:798:5:798:5 | g | my2/nested2.rs:7:9:9:9 | fn g |
-| main.rs:799:5:799:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) |
-| main.rs:799:5:799:12 | ...::h | main.rs:57:1:76:1 | fn h |
-| main.rs:800:5:800:6 | m1 | main.rs:20:1:44:1 | mod m1 |
-| main.rs:800:5:800:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
-| main.rs:800:5:800:13 | ...::g | main.rs:30:9:34:9 | fn g |
-| main.rs:801:5:801:6 | m1 | main.rs:20:1:44:1 | mod m1 |
-| main.rs:801:5:801:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
-| main.rs:801:5:801:14 | ...::m3 | main.rs:36:9:42:9 | mod m3 |
-| main.rs:801:5:801:17 | ...::h | main.rs:37:27:41:13 | fn h |
-| main.rs:802:5:802:6 | m4 | main.rs:46:1:53:1 | mod m4 |
-| main.rs:802:5:802:9 | ...::i | main.rs:49:5:52:5 | fn i |
-| main.rs:803:5:803:5 | h | main.rs:57:1:76:1 | fn h |
-| main.rs:804:5:804:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f |
-| main.rs:805:5:805:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g |
-| main.rs:806:5:806:5 | j | main.rs:104:1:108:1 | fn j |
-| main.rs:807:5:807:6 | m6 | main.rs:116:1:128:1 | mod m6 |
-| main.rs:807:5:807:9 | ...::g | main.rs:121:5:127:5 | fn g |
-| main.rs:808:5:808:6 | m7 | main.rs:130:1:149:1 | mod m7 |
-| main.rs:808:5:808:9 | ...::f | main.rs:141:5:148:5 | fn f |
-| main.rs:809:5:809:6 | m8 | main.rs:151:1:205:1 | mod m8 |
-| main.rs:809:5:809:9 | ...::g | main.rs:189:5:204:5 | fn g |
-| main.rs:810:5:810:6 | m9 | main.rs:207:1:215:1 | mod m9 |
-| main.rs:810:5:810:9 | ...::f | main.rs:210:5:214:5 | fn f |
-| main.rs:811:5:811:7 | m11 | main.rs:238:1:275:1 | mod m11 |
-| main.rs:811:5:811:10 | ...::f | main.rs:243:5:246:5 | fn f |
-| main.rs:812:5:812:7 | m15 | main.rs:306:1:375:1 | mod m15 |
-| main.rs:812:5:812:10 | ...::f | main.rs:362:5:374:5 | fn f |
-| main.rs:813:5:813:7 | m16 | main.rs:377:1:469:1 | mod m16 |
-| main.rs:813:5:813:10 | ...::f | main.rs:444:5:468:5 | fn f |
-| main.rs:814:5:814:20 | trait_visibility | main.rs:471:1:521:1 | mod trait_visibility |
-| main.rs:814:5:814:23 | ...::f | main.rs:498:5:520:5 | fn f |
-| main.rs:815:5:815:7 | m17 | main.rs:523:1:553:1 | mod m17 |
-| main.rs:815:5:815:10 | ...::f | main.rs:547:5:552:5 | fn f |
-| main.rs:816:5:816:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 |
-| main.rs:816:5:816:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f |
-| main.rs:817:5:817:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
-| main.rs:817:5:817:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
-| main.rs:818:5:818:7 | my3 | my2/mod.rs:20:1:20:12 | mod my3 |
-| main.rs:818:5:818:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
-| main.rs:819:5:819:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
-| main.rs:820:5:820:12 | my_alias | main.rs:1:1:1:7 | mod my |
-| main.rs:820:5:820:22 | ...::nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
-| main.rs:821:5:821:7 | m18 | main.rs:555:1:573:1 | mod m18 |
-| main.rs:821:5:821:12 | ...::m19 | main.rs:560:5:572:5 | mod m19 |
-| main.rs:821:5:821:17 | ...::m20 | main.rs:565:9:571:9 | mod m20 |
-| main.rs:821:5:821:20 | ...::g | main.rs:566:13:570:13 | fn g |
-| main.rs:822:5:822:7 | m23 | main.rs:602:1:627:1 | mod m23 |
-| main.rs:822:5:822:10 | ...::f | main.rs:622:5:626:5 | fn f |
-| main.rs:823:5:823:7 | m24 | main.rs:629:1:697:1 | mod m24 |
-| main.rs:823:5:823:10 | ...::f | main.rs:683:5:696:5 | fn f |
-| main.rs:824:5:824:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) |
-| main.rs:824:5:824:11 | ...::h | main.rs:57:1:76:1 | fn h |
-| main.rs:825:5:825:13 | z_changed | main.rs:702:1:702:9 | fn z_changed |
-| main.rs:826:5:826:11 | AStruct | main.rs:704:1:704:17 | struct AStruct |
-| main.rs:826:5:826:22 | ...::z_on_type | main.rs:708:5:708:17 | fn z_on_type |
-| main.rs:827:5:827:11 | AStruct | main.rs:704:1:704:17 | struct AStruct |
-| main.rs:828:5:828:29 | impl_with_attribute_macro | main.rs:772:1:791:1 | mod impl_with_attribute_macro |
-| main.rs:828:5:828:35 | ...::test | main.rs:787:5:790:5 | fn test |
+| main.rs:795:22:795:32 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
+| main.rs:795:29:795:31 | i32 | {EXTERNAL LOCATION} | struct i32 |
+| main.rs:796:17:796:20 | Some | {EXTERNAL LOCATION} | Some |
+| main.rs:797:17:797:27 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
+| main.rs:797:24:797:26 | i32 | {EXTERNAL LOCATION} | struct i32 |
+| main.rs:798:13:798:16 | Some | {EXTERNAL LOCATION} | Some |
+| main.rs:799:17:799:20 | None | {EXTERNAL LOCATION} | None |
+| main.rs:802:17:802:20 | None | {EXTERNAL LOCATION} | None |
+| main.rs:811:19:811:29 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
+| main.rs:811:26:811:28 | i32 | {EXTERNAL LOCATION} | struct i32 |
+| main.rs:812:26:812:29 | test | main.rs:794:5:808:5 | fn test |
+| main.rs:818:14:818:16 | i32 | {EXTERNAL LOCATION} | struct i32 |
+| main.rs:823:17:823:20 | Some | {EXTERNAL LOCATION} | Some |
+| main.rs:825:13:825:16 | Some | {EXTERNAL LOCATION} | Some |
+| main.rs:830:13:830:16 | Some | {EXTERNAL LOCATION} | Some |
+| main.rs:837:5:837:6 | my | main.rs:1:1:1:7 | mod my |
+| main.rs:837:5:837:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
+| main.rs:837:5:837:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
+| main.rs:837:5:837:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
+| main.rs:837:5:837:35 | ...::f | my/nested.rs:3:9:5:9 | fn f |
+| main.rs:838:5:838:6 | my | main.rs:1:1:1:7 | mod my |
+| main.rs:838:5:838:9 | ...::f | my.rs:5:1:7:1 | fn f |
+| main.rs:839:5:839:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
+| main.rs:839:5:839:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
+| main.rs:839:5:839:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
+| main.rs:839:5:839:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f |
+| main.rs:840:5:840:5 | f | my2/nested2.rs:3:9:5:9 | fn f |
+| main.rs:841:5:841:5 | g | my2/nested2.rs:7:9:9:9 | fn g |
+| main.rs:842:5:842:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) |
+| main.rs:842:5:842:12 | ...::h | main.rs:57:1:76:1 | fn h |
+| main.rs:843:5:843:6 | m1 | main.rs:20:1:44:1 | mod m1 |
+| main.rs:843:5:843:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
+| main.rs:843:5:843:13 | ...::g | main.rs:30:9:34:9 | fn g |
+| main.rs:844:5:844:6 | m1 | main.rs:20:1:44:1 | mod m1 |
+| main.rs:844:5:844:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
+| main.rs:844:5:844:14 | ...::m3 | main.rs:36:9:42:9 | mod m3 |
+| main.rs:844:5:844:17 | ...::h | main.rs:37:27:41:13 | fn h |
+| main.rs:845:5:845:6 | m4 | main.rs:46:1:53:1 | mod m4 |
+| main.rs:845:5:845:9 | ...::i | main.rs:49:5:52:5 | fn i |
+| main.rs:846:5:846:5 | h | main.rs:57:1:76:1 | fn h |
+| main.rs:847:5:847:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f |
+| main.rs:848:5:848:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g |
+| main.rs:849:5:849:5 | j | main.rs:104:1:108:1 | fn j |
+| main.rs:850:5:850:6 | m6 | main.rs:116:1:128:1 | mod m6 |
+| main.rs:850:5:850:9 | ...::g | main.rs:121:5:127:5 | fn g |
+| main.rs:851:5:851:6 | m7 | main.rs:130:1:149:1 | mod m7 |
+| main.rs:851:5:851:9 | ...::f | main.rs:141:5:148:5 | fn f |
+| main.rs:852:5:852:6 | m8 | main.rs:151:1:205:1 | mod m8 |
+| main.rs:852:5:852:9 | ...::g | main.rs:189:5:204:5 | fn g |
+| main.rs:853:5:853:6 | m9 | main.rs:207:1:215:1 | mod m9 |
+| main.rs:853:5:853:9 | ...::f | main.rs:210:5:214:5 | fn f |
+| main.rs:854:5:854:7 | m11 | main.rs:238:1:275:1 | mod m11 |
+| main.rs:854:5:854:10 | ...::f | main.rs:243:5:246:5 | fn f |
+| main.rs:855:5:855:7 | m15 | main.rs:306:1:375:1 | mod m15 |
+| main.rs:855:5:855:10 | ...::f | main.rs:362:5:374:5 | fn f |
+| main.rs:856:5:856:7 | m16 | main.rs:377:1:469:1 | mod m16 |
+| main.rs:856:5:856:10 | ...::f | main.rs:444:5:468:5 | fn f |
+| main.rs:857:5:857:20 | trait_visibility | main.rs:471:1:521:1 | mod trait_visibility |
+| main.rs:857:5:857:23 | ...::f | main.rs:498:5:520:5 | fn f |
+| main.rs:858:5:858:7 | m17 | main.rs:523:1:553:1 | mod m17 |
+| main.rs:858:5:858:10 | ...::f | main.rs:547:5:552:5 | fn f |
+| main.rs:859:5:859:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 |
+| main.rs:859:5:859:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f |
+| main.rs:860:5:860:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
+| main.rs:860:5:860:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
+| main.rs:861:5:861:7 | my3 | my2/mod.rs:20:1:20:12 | mod my3 |
+| main.rs:861:5:861:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
+| main.rs:862:5:862:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
+| main.rs:863:5:863:12 | my_alias | main.rs:1:1:1:7 | mod my |
+| main.rs:863:5:863:22 | ...::nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
+| main.rs:864:5:864:7 | m18 | main.rs:555:1:573:1 | mod m18 |
+| main.rs:864:5:864:12 | ...::m19 | main.rs:560:5:572:5 | mod m19 |
+| main.rs:864:5:864:17 | ...::m20 | main.rs:565:9:571:9 | mod m20 |
+| main.rs:864:5:864:20 | ...::g | main.rs:566:13:570:13 | fn g |
+| main.rs:865:5:865:7 | m23 | main.rs:602:1:627:1 | mod m23 |
+| main.rs:865:5:865:10 | ...::f | main.rs:622:5:626:5 | fn f |
+| main.rs:866:5:866:7 | m24 | main.rs:629:1:697:1 | mod m24 |
+| main.rs:866:5:866:10 | ...::f | main.rs:683:5:696:5 | fn f |
+| main.rs:867:5:867:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) |
+| main.rs:867:5:867:11 | ...::h | main.rs:57:1:76:1 | fn h |
+| main.rs:868:5:868:13 | z_changed | main.rs:702:1:702:9 | fn z_changed |
+| main.rs:869:5:869:11 | AStruct | main.rs:704:1:704:17 | struct AStruct |
+| main.rs:869:5:869:22 | ...::z_on_type | main.rs:708:5:708:17 | fn z_on_type |
+| main.rs:870:5:870:11 | AStruct | main.rs:704:1:704:17 | struct AStruct |
+| main.rs:871:5:871:29 | impl_with_attribute_macro | main.rs:772:1:791:1 | mod impl_with_attribute_macro |
+| main.rs:871:5:871:35 | ...::test | main.rs:787:5:790:5 | fn test |
+| main.rs:872:5:872:12 | patterns | main.rs:793:1:834:1 | mod patterns |
+| main.rs:872:5:872:18 | ...::test | main.rs:794:5:808:5 | fn test |
| my2/mod.rs:4:5:4:11 | println | {EXTERNAL LOCATION} | MacroRules |
| my2/mod.rs:5:5:5:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
| my2/mod.rs:5:5:5:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
@@ -493,7 +511,7 @@ resolvePath
| my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g |
| my2/my3/mod.rs:4:5:4:5 | h | main.rs:57:1:76:1 | fn h |
| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:25:34 | SourceFile |
-| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:829:2 | SourceFile |
+| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:873:2 | SourceFile |
| my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:57:1:76:1 | fn h |
| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:25:34 | SourceFile |
| my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g |
diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected
index 7d8da915bfb..3efada83369 100644
--- a/rust/ql/test/library-tests/variables/Cfg.expected
+++ b/rust/ql/test/library-tests/variables/Cfg.expected
@@ -1798,145 +1798,215 @@ edges
| main.rs:753:5:753:16 | print_i64(...) | main.rs:744:18:754:1 | { ... } | |
| main.rs:753:5:753:17 | ExprStmt | main.rs:753:5:753:13 | print_i64 | |
| main.rs:753:15:753:15 | x | main.rs:753:5:753:16 | print_i64(...) | |
-| main.rs:756:1:800:1 | enter fn main | main.rs:757:5:757:25 | ExprStmt | |
-| main.rs:756:1:800:1 | exit fn main (normal) | main.rs:756:1:800:1 | exit fn main | |
-| main.rs:756:11:800:1 | { ... } | main.rs:756:1:800:1 | exit fn main (normal) | |
-| main.rs:757:5:757:22 | immutable_variable | main.rs:757:5:757:24 | immutable_variable(...) | |
-| main.rs:757:5:757:24 | immutable_variable(...) | main.rs:758:5:758:23 | ExprStmt | |
-| main.rs:757:5:757:25 | ExprStmt | main.rs:757:5:757:22 | immutable_variable | |
-| main.rs:758:5:758:20 | mutable_variable | main.rs:758:5:758:22 | mutable_variable(...) | |
-| main.rs:758:5:758:22 | mutable_variable(...) | main.rs:759:5:759:40 | ExprStmt | |
-| main.rs:758:5:758:23 | ExprStmt | main.rs:758:5:758:20 | mutable_variable | |
-| main.rs:759:5:759:37 | mutable_variable_immutable_borrow | main.rs:759:5:759:39 | mutable_variable_immutable_borrow(...) | |
-| main.rs:759:5:759:39 | mutable_variable_immutable_borrow(...) | main.rs:760:5:760:23 | ExprStmt | |
-| main.rs:759:5:759:40 | ExprStmt | main.rs:759:5:759:37 | mutable_variable_immutable_borrow | |
-| main.rs:760:5:760:20 | variable_shadow1 | main.rs:760:5:760:22 | variable_shadow1(...) | |
-| main.rs:760:5:760:22 | variable_shadow1(...) | main.rs:761:5:761:23 | ExprStmt | |
-| main.rs:760:5:760:23 | ExprStmt | main.rs:760:5:760:20 | variable_shadow1 | |
-| main.rs:761:5:761:20 | variable_shadow2 | main.rs:761:5:761:22 | variable_shadow2(...) | |
-| main.rs:761:5:761:22 | variable_shadow2(...) | main.rs:762:5:762:19 | ExprStmt | |
-| main.rs:761:5:761:23 | ExprStmt | main.rs:761:5:761:20 | variable_shadow2 | |
-| main.rs:762:5:762:16 | let_pattern1 | main.rs:762:5:762:18 | let_pattern1(...) | |
-| main.rs:762:5:762:18 | let_pattern1(...) | main.rs:763:5:763:19 | ExprStmt | |
-| main.rs:762:5:762:19 | ExprStmt | main.rs:762:5:762:16 | let_pattern1 | |
-| main.rs:763:5:763:16 | let_pattern2 | main.rs:763:5:763:18 | let_pattern2(...) | |
-| main.rs:763:5:763:18 | let_pattern2(...) | main.rs:764:5:764:19 | ExprStmt | |
-| main.rs:763:5:763:19 | ExprStmt | main.rs:763:5:763:16 | let_pattern2 | |
-| main.rs:764:5:764:16 | let_pattern3 | main.rs:764:5:764:18 | let_pattern3(...) | |
-| main.rs:764:5:764:18 | let_pattern3(...) | main.rs:765:5:765:19 | ExprStmt | |
-| main.rs:764:5:764:19 | ExprStmt | main.rs:764:5:764:16 | let_pattern3 | |
-| main.rs:765:5:765:16 | let_pattern4 | main.rs:765:5:765:18 | let_pattern4(...) | |
-| main.rs:765:5:765:18 | let_pattern4(...) | main.rs:766:5:766:21 | ExprStmt | |
-| main.rs:765:5:765:19 | ExprStmt | main.rs:765:5:765:16 | let_pattern4 | |
-| main.rs:766:5:766:18 | match_pattern1 | main.rs:766:5:766:20 | match_pattern1(...) | |
-| main.rs:766:5:766:20 | match_pattern1(...) | main.rs:767:5:767:21 | ExprStmt | |
-| main.rs:766:5:766:21 | ExprStmt | main.rs:766:5:766:18 | match_pattern1 | |
-| main.rs:767:5:767:18 | match_pattern2 | main.rs:767:5:767:20 | match_pattern2(...) | |
-| main.rs:767:5:767:20 | match_pattern2(...) | main.rs:768:5:768:21 | ExprStmt | |
-| main.rs:767:5:767:21 | ExprStmt | main.rs:767:5:767:18 | match_pattern2 | |
-| main.rs:768:5:768:18 | match_pattern3 | main.rs:768:5:768:20 | match_pattern3(...) | |
-| main.rs:768:5:768:20 | match_pattern3(...) | main.rs:769:5:769:21 | ExprStmt | |
-| main.rs:768:5:768:21 | ExprStmt | main.rs:768:5:768:18 | match_pattern3 | |
-| main.rs:769:5:769:18 | match_pattern4 | main.rs:769:5:769:20 | match_pattern4(...) | |
-| main.rs:769:5:769:20 | match_pattern4(...) | main.rs:770:5:770:21 | ExprStmt | |
-| main.rs:769:5:769:21 | ExprStmt | main.rs:769:5:769:18 | match_pattern4 | |
-| main.rs:770:5:770:18 | match_pattern5 | main.rs:770:5:770:20 | match_pattern5(...) | |
-| main.rs:770:5:770:20 | match_pattern5(...) | main.rs:771:5:771:21 | ExprStmt | |
-| main.rs:770:5:770:21 | ExprStmt | main.rs:770:5:770:18 | match_pattern5 | |
-| main.rs:771:5:771:18 | match_pattern6 | main.rs:771:5:771:20 | match_pattern6(...) | |
-| main.rs:771:5:771:20 | match_pattern6(...) | main.rs:772:5:772:21 | ExprStmt | |
-| main.rs:771:5:771:21 | ExprStmt | main.rs:771:5:771:18 | match_pattern6 | |
-| main.rs:772:5:772:18 | match_pattern7 | main.rs:772:5:772:20 | match_pattern7(...) | |
-| main.rs:772:5:772:20 | match_pattern7(...) | main.rs:773:5:773:21 | ExprStmt | |
-| main.rs:772:5:772:21 | ExprStmt | main.rs:772:5:772:18 | match_pattern7 | |
-| main.rs:773:5:773:18 | match_pattern8 | main.rs:773:5:773:20 | match_pattern8(...) | |
-| main.rs:773:5:773:20 | match_pattern8(...) | main.rs:774:5:774:21 | ExprStmt | |
-| main.rs:773:5:773:21 | ExprStmt | main.rs:773:5:773:18 | match_pattern8 | |
-| main.rs:774:5:774:18 | match_pattern9 | main.rs:774:5:774:20 | match_pattern9(...) | |
-| main.rs:774:5:774:20 | match_pattern9(...) | main.rs:775:5:775:22 | ExprStmt | |
-| main.rs:774:5:774:21 | ExprStmt | main.rs:774:5:774:18 | match_pattern9 | |
-| main.rs:775:5:775:19 | match_pattern10 | main.rs:775:5:775:21 | match_pattern10(...) | |
-| main.rs:775:5:775:21 | match_pattern10(...) | main.rs:776:5:776:22 | ExprStmt | |
-| main.rs:775:5:775:22 | ExprStmt | main.rs:775:5:775:19 | match_pattern10 | |
-| main.rs:776:5:776:19 | match_pattern11 | main.rs:776:5:776:21 | match_pattern11(...) | |
-| main.rs:776:5:776:21 | match_pattern11(...) | main.rs:777:5:777:22 | ExprStmt | |
-| main.rs:776:5:776:22 | ExprStmt | main.rs:776:5:776:19 | match_pattern11 | |
-| main.rs:777:5:777:19 | match_pattern12 | main.rs:777:5:777:21 | match_pattern12(...) | |
-| main.rs:777:5:777:21 | match_pattern12(...) | main.rs:778:5:778:22 | ExprStmt | |
-| main.rs:777:5:777:22 | ExprStmt | main.rs:777:5:777:19 | match_pattern12 | |
-| main.rs:778:5:778:19 | match_pattern13 | main.rs:778:5:778:21 | match_pattern13(...) | |
-| main.rs:778:5:778:21 | match_pattern13(...) | main.rs:779:5:779:22 | ExprStmt | |
-| main.rs:778:5:778:22 | ExprStmt | main.rs:778:5:778:19 | match_pattern13 | |
-| main.rs:779:5:779:19 | match_pattern14 | main.rs:779:5:779:21 | match_pattern14(...) | |
-| main.rs:779:5:779:21 | match_pattern14(...) | main.rs:780:5:780:22 | ExprStmt | |
-| main.rs:779:5:779:22 | ExprStmt | main.rs:779:5:779:19 | match_pattern14 | |
-| main.rs:780:5:780:19 | match_pattern15 | main.rs:780:5:780:21 | match_pattern15(...) | |
-| main.rs:780:5:780:21 | match_pattern15(...) | main.rs:781:5:781:22 | ExprStmt | |
-| main.rs:780:5:780:22 | ExprStmt | main.rs:780:5:780:19 | match_pattern15 | |
-| main.rs:781:5:781:19 | match_pattern16 | main.rs:781:5:781:21 | match_pattern16(...) | |
-| main.rs:781:5:781:21 | match_pattern16(...) | main.rs:782:5:782:36 | ExprStmt | |
-| main.rs:781:5:781:22 | ExprStmt | main.rs:781:5:781:19 | match_pattern16 | |
-| main.rs:782:5:782:18 | param_pattern1 | main.rs:782:20:782:22 | "a" | |
-| main.rs:782:5:782:35 | param_pattern1(...) | main.rs:783:5:783:37 | ExprStmt | |
-| main.rs:782:5:782:36 | ExprStmt | main.rs:782:5:782:18 | param_pattern1 | |
-| main.rs:782:20:782:22 | "a" | main.rs:782:26:782:28 | "b" | |
-| main.rs:782:25:782:34 | TupleExpr | main.rs:782:5:782:35 | param_pattern1(...) | |
-| main.rs:782:26:782:28 | "b" | main.rs:782:31:782:33 | "c" | |
-| main.rs:782:31:782:33 | "c" | main.rs:782:25:782:34 | TupleExpr | |
-| main.rs:783:5:783:18 | param_pattern2 | main.rs:783:20:783:31 | ...::Left | |
-| main.rs:783:5:783:36 | param_pattern2(...) | main.rs:784:5:784:26 | ExprStmt | |
-| main.rs:783:5:783:37 | ExprStmt | main.rs:783:5:783:18 | param_pattern2 | |
-| main.rs:783:20:783:31 | ...::Left | main.rs:783:33:783:34 | 45 | |
-| main.rs:783:20:783:35 | ...::Left(...) | main.rs:783:5:783:36 | param_pattern2(...) | |
-| main.rs:783:33:783:34 | 45 | main.rs:783:20:783:35 | ...::Left(...) | |
-| main.rs:784:5:784:23 | destruct_assignment | main.rs:784:5:784:25 | destruct_assignment(...) | |
-| main.rs:784:5:784:25 | destruct_assignment(...) | main.rs:785:5:785:23 | ExprStmt | |
-| main.rs:784:5:784:26 | ExprStmt | main.rs:784:5:784:23 | destruct_assignment | |
-| main.rs:785:5:785:20 | closure_variable | main.rs:785:5:785:22 | closure_variable(...) | |
-| main.rs:785:5:785:22 | closure_variable(...) | main.rs:786:5:786:22 | ExprStmt | |
-| main.rs:785:5:785:23 | ExprStmt | main.rs:785:5:785:20 | closure_variable | |
-| main.rs:786:5:786:19 | nested_function | main.rs:786:5:786:21 | nested_function(...) | |
-| main.rs:786:5:786:21 | nested_function(...) | main.rs:787:5:787:19 | ExprStmt | |
-| main.rs:786:5:786:22 | ExprStmt | main.rs:786:5:786:19 | nested_function | |
-| main.rs:787:5:787:16 | for_variable | main.rs:787:5:787:18 | for_variable(...) | |
-| main.rs:787:5:787:18 | for_variable(...) | main.rs:788:5:788:17 | ExprStmt | |
-| main.rs:787:5:787:19 | ExprStmt | main.rs:787:5:787:16 | for_variable | |
-| main.rs:788:5:788:14 | add_assign | main.rs:788:5:788:16 | add_assign(...) | |
-| main.rs:788:5:788:16 | add_assign(...) | main.rs:789:5:789:13 | ExprStmt | |
-| main.rs:788:5:788:17 | ExprStmt | main.rs:788:5:788:14 | add_assign | |
-| main.rs:789:5:789:10 | mutate | main.rs:789:5:789:12 | mutate(...) | |
-| main.rs:789:5:789:12 | mutate(...) | main.rs:790:5:790:17 | ExprStmt | |
-| main.rs:789:5:789:13 | ExprStmt | main.rs:789:5:789:10 | mutate | |
-| main.rs:790:5:790:14 | mutate_arg | main.rs:790:5:790:16 | mutate_arg(...) | |
-| main.rs:790:5:790:16 | mutate_arg(...) | main.rs:791:5:791:12 | ExprStmt | |
-| main.rs:790:5:790:17 | ExprStmt | main.rs:790:5:790:14 | mutate_arg | |
-| main.rs:791:5:791:9 | alias | main.rs:791:5:791:11 | alias(...) | |
-| main.rs:791:5:791:11 | alias(...) | main.rs:792:5:792:18 | ExprStmt | |
-| main.rs:791:5:791:12 | ExprStmt | main.rs:791:5:791:9 | alias | |
-| main.rs:792:5:792:15 | capture_mut | main.rs:792:5:792:17 | capture_mut(...) | |
-| main.rs:792:5:792:17 | capture_mut(...) | main.rs:793:5:793:20 | ExprStmt | |
-| main.rs:792:5:792:18 | ExprStmt | main.rs:792:5:792:15 | capture_mut | |
-| main.rs:793:5:793:17 | capture_immut | main.rs:793:5:793:19 | capture_immut(...) | |
-| main.rs:793:5:793:19 | capture_immut(...) | main.rs:794:5:794:26 | ExprStmt | |
-| main.rs:793:5:793:20 | ExprStmt | main.rs:793:5:793:17 | capture_immut | |
-| main.rs:794:5:794:23 | async_block_capture | main.rs:794:5:794:25 | async_block_capture(...) | |
-| main.rs:794:5:794:25 | async_block_capture(...) | main.rs:795:5:795:14 | ExprStmt | |
-| main.rs:794:5:794:26 | ExprStmt | main.rs:794:5:794:23 | async_block_capture | |
-| main.rs:795:5:795:11 | structs | main.rs:795:5:795:13 | structs(...) | |
-| main.rs:795:5:795:13 | structs(...) | main.rs:796:5:796:14 | ExprStmt | |
-| main.rs:795:5:795:14 | ExprStmt | main.rs:795:5:795:11 | structs | |
-| main.rs:796:5:796:11 | ref_arg | main.rs:796:5:796:13 | ref_arg(...) | |
-| main.rs:796:5:796:13 | ref_arg(...) | main.rs:797:5:797:30 | ExprStmt | |
-| main.rs:796:5:796:14 | ExprStmt | main.rs:796:5:796:11 | ref_arg | |
-| main.rs:797:5:797:27 | ref_methodcall_receiver | main.rs:797:5:797:29 | ref_methodcall_receiver(...) | |
-| main.rs:797:5:797:29 | ref_methodcall_receiver(...) | main.rs:798:5:798:23 | ExprStmt | |
-| main.rs:797:5:797:30 | ExprStmt | main.rs:797:5:797:27 | ref_methodcall_receiver | |
-| main.rs:798:5:798:20 | macro_invocation | main.rs:798:5:798:22 | macro_invocation(...) | |
-| main.rs:798:5:798:22 | macro_invocation(...) | main.rs:799:5:799:18 | ExprStmt | |
-| main.rs:798:5:798:23 | ExprStmt | main.rs:798:5:798:20 | macro_invocation | |
-| main.rs:799:5:799:15 | capture_phi | main.rs:799:5:799:17 | capture_phi(...) | |
-| main.rs:799:5:799:17 | capture_phi(...) | main.rs:756:11:800:1 | { ... } | |
-| main.rs:799:5:799:18 | ExprStmt | main.rs:799:5:799:15 | capture_phi | |
+| main.rs:757:5:772:5 | enter fn test | main.rs:759:9:759:25 | let ... = ... | |
+| main.rs:757:5:772:5 | exit fn test (normal) | main.rs:757:5:772:5 | exit fn test | |
+| main.rs:758:34:772:5 | { ... } | main.rs:757:5:772:5 | exit fn test (normal) | |
+| main.rs:759:9:759:25 | let ... = ... | main.rs:759:17:759:20 | Some | |
+| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | |
+| main.rs:759:13:759:13 | x | main.rs:760:9:767:10 | let ... = ... | match |
+| main.rs:759:17:759:20 | Some | main.rs:759:22:759:23 | 42 | |
+| main.rs:759:17:759:24 | Some(...) | main.rs:759:13:759:13 | x | |
+| main.rs:759:22:759:23 | 42 | main.rs:759:17:759:24 | Some(...) | |
+| main.rs:760:9:767:10 | let ... = ... | main.rs:761:19:761:19 | x | |
+| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | |
+| main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y | match |
+| main.rs:761:13:767:9 | match x { ... } | main.rs:760:13:760:13 | y | |
+| main.rs:761:19:761:19 | x | main.rs:762:13:762:19 | Some(...) | |
+| main.rs:762:13:762:19 | Some(...) | main.rs:762:18:762:18 | y | match |
+| main.rs:762:13:762:19 | Some(...) | main.rs:765:13:765:16 | None | no-match |
+| main.rs:762:18:762:18 | y | main.rs:762:18:762:18 | y | |
+| main.rs:762:18:762:18 | y | main.rs:763:17:763:20 | None | match |
+| main.rs:762:24:764:13 | { ... } | main.rs:761:13:767:9 | match x { ... } | |
+| main.rs:763:17:763:20 | None | main.rs:762:24:764:13 | { ... } | |
+| main.rs:765:13:765:16 | None | main.rs:765:13:765:16 | None | |
+| main.rs:765:13:765:16 | None | main.rs:766:17:766:20 | None | match |
+| main.rs:766:17:766:20 | None | main.rs:761:13:767:9 | match x { ... } | |
+| main.rs:768:9:771:9 | match y { ... } | main.rs:758:34:772:5 | { ... } | |
+| main.rs:768:15:768:15 | y | main.rs:769:13:769:16 | N0ne | |
+| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | |
+| main.rs:769:13:769:16 | N0ne | main.rs:770:17:770:20 | N0ne | match |
+| main.rs:770:17:770:20 | N0ne | main.rs:768:9:771:9 | match y { ... } | |
+| main.rs:774:5:781:5 | enter fn test2 | main.rs:776:9:777:17 | let ... = test | |
+| main.rs:774:5:781:5 | exit fn test2 (normal) | main.rs:774:5:781:5 | exit fn test2 | |
+| main.rs:775:31:781:5 | { ... } | main.rs:774:5:781:5 | exit fn test2 (normal) | |
+| main.rs:776:9:777:17 | let ... = test | main.rs:777:13:777:16 | test | |
+| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | |
+| main.rs:776:13:776:22 | test_alias | main.rs:778:9:779:25 | let ... = ... | match |
+| main.rs:777:13:777:16 | test | main.rs:776:13:776:22 | test_alias | |
+| main.rs:778:9:779:25 | let ... = ... | main.rs:779:13:779:22 | test_alias | |
+| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | |
+| main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test | match |
+| main.rs:779:13:779:22 | test_alias | main.rs:779:13:779:24 | test_alias(...) | |
+| main.rs:779:13:779:24 | test_alias(...) | main.rs:778:13:778:16 | test | |
+| main.rs:780:9:780:12 | test | main.rs:775:31:781:5 | { ... } | |
+| main.rs:785:5:798:5 | enter fn test3 | main.rs:787:9:787:24 | let ... = ... | |
+| main.rs:785:5:798:5 | exit fn test3 (normal) | main.rs:785:5:798:5 | exit fn test3 | |
+| main.rs:786:16:798:5 | { ... } | main.rs:785:5:798:5 | exit fn test3 (normal) | |
+| main.rs:787:9:787:24 | let ... = ... | main.rs:787:17:787:20 | Some | |
+| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | |
+| main.rs:787:13:787:13 | x | main.rs:788:9:792:10 | ExprStmt | match |
+| main.rs:787:17:787:20 | Some | main.rs:787:22:787:22 | 0 | |
+| main.rs:787:17:787:23 | Some(...) | main.rs:787:13:787:13 | x | |
+| main.rs:787:22:787:22 | 0 | main.rs:787:17:787:23 | Some(...) | |
+| main.rs:788:9:792:9 | match x { ... } | main.rs:793:9:797:10 | ExprStmt | |
+| main.rs:788:9:792:10 | ExprStmt | main.rs:788:15:788:15 | x | |
+| main.rs:788:15:788:15 | x | main.rs:789:13:789:19 | Some(...) | |
+| main.rs:789:13:789:19 | Some(...) | main.rs:789:18:789:18 | x | match |
+| main.rs:789:13:789:19 | Some(...) | main.rs:791:13:791:13 | _ | no-match |
+| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | |
+| main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x | match |
+| main.rs:790:20:790:20 | x | main.rs:788:9:792:9 | match x { ... } | |
+| main.rs:791:13:791:13 | _ | main.rs:791:18:791:18 | 0 | match |
+| main.rs:791:18:791:18 | 0 | main.rs:788:9:792:9 | match x { ... } | |
+| main.rs:793:9:797:9 | match x { ... } | main.rs:786:16:798:5 | { ... } | |
+| main.rs:793:9:797:10 | ExprStmt | main.rs:793:15:793:15 | x | |
+| main.rs:793:15:793:15 | x | main.rs:794:13:794:19 | Some(...) | |
+| main.rs:794:13:794:19 | Some(...) | main.rs:794:18:794:18 | z | match |
+| main.rs:794:13:794:19 | Some(...) | main.rs:796:13:796:13 | _ | no-match |
+| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z | |
+| main.rs:794:18:794:18 | z | main.rs:795:17:795:17 | z | match |
+| main.rs:795:17:795:17 | z | main.rs:793:9:797:9 | match x { ... } | |
+| main.rs:796:13:796:13 | _ | main.rs:796:18:796:18 | 0 | match |
+| main.rs:796:18:796:18 | 0 | main.rs:793:9:797:9 | match x { ... } | |
+| main.rs:801:1:845:1 | enter fn main | main.rs:802:5:802:25 | ExprStmt | |
+| main.rs:801:1:845:1 | exit fn main (normal) | main.rs:801:1:845:1 | exit fn main | |
+| main.rs:801:11:845:1 | { ... } | main.rs:801:1:845:1 | exit fn main (normal) | |
+| main.rs:802:5:802:22 | immutable_variable | main.rs:802:5:802:24 | immutable_variable(...) | |
+| main.rs:802:5:802:24 | immutable_variable(...) | main.rs:803:5:803:23 | ExprStmt | |
+| main.rs:802:5:802:25 | ExprStmt | main.rs:802:5:802:22 | immutable_variable | |
+| main.rs:803:5:803:20 | mutable_variable | main.rs:803:5:803:22 | mutable_variable(...) | |
+| main.rs:803:5:803:22 | mutable_variable(...) | main.rs:804:5:804:40 | ExprStmt | |
+| main.rs:803:5:803:23 | ExprStmt | main.rs:803:5:803:20 | mutable_variable | |
+| main.rs:804:5:804:37 | mutable_variable_immutable_borrow | main.rs:804:5:804:39 | mutable_variable_immutable_borrow(...) | |
+| main.rs:804:5:804:39 | mutable_variable_immutable_borrow(...) | main.rs:805:5:805:23 | ExprStmt | |
+| main.rs:804:5:804:40 | ExprStmt | main.rs:804:5:804:37 | mutable_variable_immutable_borrow | |
+| main.rs:805:5:805:20 | variable_shadow1 | main.rs:805:5:805:22 | variable_shadow1(...) | |
+| main.rs:805:5:805:22 | variable_shadow1(...) | main.rs:806:5:806:23 | ExprStmt | |
+| main.rs:805:5:805:23 | ExprStmt | main.rs:805:5:805:20 | variable_shadow1 | |
+| main.rs:806:5:806:20 | variable_shadow2 | main.rs:806:5:806:22 | variable_shadow2(...) | |
+| main.rs:806:5:806:22 | variable_shadow2(...) | main.rs:807:5:807:19 | ExprStmt | |
+| main.rs:806:5:806:23 | ExprStmt | main.rs:806:5:806:20 | variable_shadow2 | |
+| main.rs:807:5:807:16 | let_pattern1 | main.rs:807:5:807:18 | let_pattern1(...) | |
+| main.rs:807:5:807:18 | let_pattern1(...) | main.rs:808:5:808:19 | ExprStmt | |
+| main.rs:807:5:807:19 | ExprStmt | main.rs:807:5:807:16 | let_pattern1 | |
+| main.rs:808:5:808:16 | let_pattern2 | main.rs:808:5:808:18 | let_pattern2(...) | |
+| main.rs:808:5:808:18 | let_pattern2(...) | main.rs:809:5:809:19 | ExprStmt | |
+| main.rs:808:5:808:19 | ExprStmt | main.rs:808:5:808:16 | let_pattern2 | |
+| main.rs:809:5:809:16 | let_pattern3 | main.rs:809:5:809:18 | let_pattern3(...) | |
+| main.rs:809:5:809:18 | let_pattern3(...) | main.rs:810:5:810:19 | ExprStmt | |
+| main.rs:809:5:809:19 | ExprStmt | main.rs:809:5:809:16 | let_pattern3 | |
+| main.rs:810:5:810:16 | let_pattern4 | main.rs:810:5:810:18 | let_pattern4(...) | |
+| main.rs:810:5:810:18 | let_pattern4(...) | main.rs:811:5:811:21 | ExprStmt | |
+| main.rs:810:5:810:19 | ExprStmt | main.rs:810:5:810:16 | let_pattern4 | |
+| main.rs:811:5:811:18 | match_pattern1 | main.rs:811:5:811:20 | match_pattern1(...) | |
+| main.rs:811:5:811:20 | match_pattern1(...) | main.rs:812:5:812:21 | ExprStmt | |
+| main.rs:811:5:811:21 | ExprStmt | main.rs:811:5:811:18 | match_pattern1 | |
+| main.rs:812:5:812:18 | match_pattern2 | main.rs:812:5:812:20 | match_pattern2(...) | |
+| main.rs:812:5:812:20 | match_pattern2(...) | main.rs:813:5:813:21 | ExprStmt | |
+| main.rs:812:5:812:21 | ExprStmt | main.rs:812:5:812:18 | match_pattern2 | |
+| main.rs:813:5:813:18 | match_pattern3 | main.rs:813:5:813:20 | match_pattern3(...) | |
+| main.rs:813:5:813:20 | match_pattern3(...) | main.rs:814:5:814:21 | ExprStmt | |
+| main.rs:813:5:813:21 | ExprStmt | main.rs:813:5:813:18 | match_pattern3 | |
+| main.rs:814:5:814:18 | match_pattern4 | main.rs:814:5:814:20 | match_pattern4(...) | |
+| main.rs:814:5:814:20 | match_pattern4(...) | main.rs:815:5:815:21 | ExprStmt | |
+| main.rs:814:5:814:21 | ExprStmt | main.rs:814:5:814:18 | match_pattern4 | |
+| main.rs:815:5:815:18 | match_pattern5 | main.rs:815:5:815:20 | match_pattern5(...) | |
+| main.rs:815:5:815:20 | match_pattern5(...) | main.rs:816:5:816:21 | ExprStmt | |
+| main.rs:815:5:815:21 | ExprStmt | main.rs:815:5:815:18 | match_pattern5 | |
+| main.rs:816:5:816:18 | match_pattern6 | main.rs:816:5:816:20 | match_pattern6(...) | |
+| main.rs:816:5:816:20 | match_pattern6(...) | main.rs:817:5:817:21 | ExprStmt | |
+| main.rs:816:5:816:21 | ExprStmt | main.rs:816:5:816:18 | match_pattern6 | |
+| main.rs:817:5:817:18 | match_pattern7 | main.rs:817:5:817:20 | match_pattern7(...) | |
+| main.rs:817:5:817:20 | match_pattern7(...) | main.rs:818:5:818:21 | ExprStmt | |
+| main.rs:817:5:817:21 | ExprStmt | main.rs:817:5:817:18 | match_pattern7 | |
+| main.rs:818:5:818:18 | match_pattern8 | main.rs:818:5:818:20 | match_pattern8(...) | |
+| main.rs:818:5:818:20 | match_pattern8(...) | main.rs:819:5:819:21 | ExprStmt | |
+| main.rs:818:5:818:21 | ExprStmt | main.rs:818:5:818:18 | match_pattern8 | |
+| main.rs:819:5:819:18 | match_pattern9 | main.rs:819:5:819:20 | match_pattern9(...) | |
+| main.rs:819:5:819:20 | match_pattern9(...) | main.rs:820:5:820:22 | ExprStmt | |
+| main.rs:819:5:819:21 | ExprStmt | main.rs:819:5:819:18 | match_pattern9 | |
+| main.rs:820:5:820:19 | match_pattern10 | main.rs:820:5:820:21 | match_pattern10(...) | |
+| main.rs:820:5:820:21 | match_pattern10(...) | main.rs:821:5:821:22 | ExprStmt | |
+| main.rs:820:5:820:22 | ExprStmt | main.rs:820:5:820:19 | match_pattern10 | |
+| main.rs:821:5:821:19 | match_pattern11 | main.rs:821:5:821:21 | match_pattern11(...) | |
+| main.rs:821:5:821:21 | match_pattern11(...) | main.rs:822:5:822:22 | ExprStmt | |
+| main.rs:821:5:821:22 | ExprStmt | main.rs:821:5:821:19 | match_pattern11 | |
+| main.rs:822:5:822:19 | match_pattern12 | main.rs:822:5:822:21 | match_pattern12(...) | |
+| main.rs:822:5:822:21 | match_pattern12(...) | main.rs:823:5:823:22 | ExprStmt | |
+| main.rs:822:5:822:22 | ExprStmt | main.rs:822:5:822:19 | match_pattern12 | |
+| main.rs:823:5:823:19 | match_pattern13 | main.rs:823:5:823:21 | match_pattern13(...) | |
+| main.rs:823:5:823:21 | match_pattern13(...) | main.rs:824:5:824:22 | ExprStmt | |
+| main.rs:823:5:823:22 | ExprStmt | main.rs:823:5:823:19 | match_pattern13 | |
+| main.rs:824:5:824:19 | match_pattern14 | main.rs:824:5:824:21 | match_pattern14(...) | |
+| main.rs:824:5:824:21 | match_pattern14(...) | main.rs:825:5:825:22 | ExprStmt | |
+| main.rs:824:5:824:22 | ExprStmt | main.rs:824:5:824:19 | match_pattern14 | |
+| main.rs:825:5:825:19 | match_pattern15 | main.rs:825:5:825:21 | match_pattern15(...) | |
+| main.rs:825:5:825:21 | match_pattern15(...) | main.rs:826:5:826:22 | ExprStmt | |
+| main.rs:825:5:825:22 | ExprStmt | main.rs:825:5:825:19 | match_pattern15 | |
+| main.rs:826:5:826:19 | match_pattern16 | main.rs:826:5:826:21 | match_pattern16(...) | |
+| main.rs:826:5:826:21 | match_pattern16(...) | main.rs:827:5:827:36 | ExprStmt | |
+| main.rs:826:5:826:22 | ExprStmt | main.rs:826:5:826:19 | match_pattern16 | |
+| main.rs:827:5:827:18 | param_pattern1 | main.rs:827:20:827:22 | "a" | |
+| main.rs:827:5:827:35 | param_pattern1(...) | main.rs:828:5:828:37 | ExprStmt | |
+| main.rs:827:5:827:36 | ExprStmt | main.rs:827:5:827:18 | param_pattern1 | |
+| main.rs:827:20:827:22 | "a" | main.rs:827:26:827:28 | "b" | |
+| main.rs:827:25:827:34 | TupleExpr | main.rs:827:5:827:35 | param_pattern1(...) | |
+| main.rs:827:26:827:28 | "b" | main.rs:827:31:827:33 | "c" | |
+| main.rs:827:31:827:33 | "c" | main.rs:827:25:827:34 | TupleExpr | |
+| main.rs:828:5:828:18 | param_pattern2 | main.rs:828:20:828:31 | ...::Left | |
+| main.rs:828:5:828:36 | param_pattern2(...) | main.rs:829:5:829:26 | ExprStmt | |
+| main.rs:828:5:828:37 | ExprStmt | main.rs:828:5:828:18 | param_pattern2 | |
+| main.rs:828:20:828:31 | ...::Left | main.rs:828:33:828:34 | 45 | |
+| main.rs:828:20:828:35 | ...::Left(...) | main.rs:828:5:828:36 | param_pattern2(...) | |
+| main.rs:828:33:828:34 | 45 | main.rs:828:20:828:35 | ...::Left(...) | |
+| main.rs:829:5:829:23 | destruct_assignment | main.rs:829:5:829:25 | destruct_assignment(...) | |
+| main.rs:829:5:829:25 | destruct_assignment(...) | main.rs:830:5:830:23 | ExprStmt | |
+| main.rs:829:5:829:26 | ExprStmt | main.rs:829:5:829:23 | destruct_assignment | |
+| main.rs:830:5:830:20 | closure_variable | main.rs:830:5:830:22 | closure_variable(...) | |
+| main.rs:830:5:830:22 | closure_variable(...) | main.rs:831:5:831:22 | ExprStmt | |
+| main.rs:830:5:830:23 | ExprStmt | main.rs:830:5:830:20 | closure_variable | |
+| main.rs:831:5:831:19 | nested_function | main.rs:831:5:831:21 | nested_function(...) | |
+| main.rs:831:5:831:21 | nested_function(...) | main.rs:832:5:832:19 | ExprStmt | |
+| main.rs:831:5:831:22 | ExprStmt | main.rs:831:5:831:19 | nested_function | |
+| main.rs:832:5:832:16 | for_variable | main.rs:832:5:832:18 | for_variable(...) | |
+| main.rs:832:5:832:18 | for_variable(...) | main.rs:833:5:833:17 | ExprStmt | |
+| main.rs:832:5:832:19 | ExprStmt | main.rs:832:5:832:16 | for_variable | |
+| main.rs:833:5:833:14 | add_assign | main.rs:833:5:833:16 | add_assign(...) | |
+| main.rs:833:5:833:16 | add_assign(...) | main.rs:834:5:834:13 | ExprStmt | |
+| main.rs:833:5:833:17 | ExprStmt | main.rs:833:5:833:14 | add_assign | |
+| main.rs:834:5:834:10 | mutate | main.rs:834:5:834:12 | mutate(...) | |
+| main.rs:834:5:834:12 | mutate(...) | main.rs:835:5:835:17 | ExprStmt | |
+| main.rs:834:5:834:13 | ExprStmt | main.rs:834:5:834:10 | mutate | |
+| main.rs:835:5:835:14 | mutate_arg | main.rs:835:5:835:16 | mutate_arg(...) | |
+| main.rs:835:5:835:16 | mutate_arg(...) | main.rs:836:5:836:12 | ExprStmt | |
+| main.rs:835:5:835:17 | ExprStmt | main.rs:835:5:835:14 | mutate_arg | |
+| main.rs:836:5:836:9 | alias | main.rs:836:5:836:11 | alias(...) | |
+| main.rs:836:5:836:11 | alias(...) | main.rs:837:5:837:18 | ExprStmt | |
+| main.rs:836:5:836:12 | ExprStmt | main.rs:836:5:836:9 | alias | |
+| main.rs:837:5:837:15 | capture_mut | main.rs:837:5:837:17 | capture_mut(...) | |
+| main.rs:837:5:837:17 | capture_mut(...) | main.rs:838:5:838:20 | ExprStmt | |
+| main.rs:837:5:837:18 | ExprStmt | main.rs:837:5:837:15 | capture_mut | |
+| main.rs:838:5:838:17 | capture_immut | main.rs:838:5:838:19 | capture_immut(...) | |
+| main.rs:838:5:838:19 | capture_immut(...) | main.rs:839:5:839:26 | ExprStmt | |
+| main.rs:838:5:838:20 | ExprStmt | main.rs:838:5:838:17 | capture_immut | |
+| main.rs:839:5:839:23 | async_block_capture | main.rs:839:5:839:25 | async_block_capture(...) | |
+| main.rs:839:5:839:25 | async_block_capture(...) | main.rs:840:5:840:14 | ExprStmt | |
+| main.rs:839:5:839:26 | ExprStmt | main.rs:839:5:839:23 | async_block_capture | |
+| main.rs:840:5:840:11 | structs | main.rs:840:5:840:13 | structs(...) | |
+| main.rs:840:5:840:13 | structs(...) | main.rs:841:5:841:14 | ExprStmt | |
+| main.rs:840:5:840:14 | ExprStmt | main.rs:840:5:840:11 | structs | |
+| main.rs:841:5:841:11 | ref_arg | main.rs:841:5:841:13 | ref_arg(...) | |
+| main.rs:841:5:841:13 | ref_arg(...) | main.rs:842:5:842:30 | ExprStmt | |
+| main.rs:841:5:841:14 | ExprStmt | main.rs:841:5:841:11 | ref_arg | |
+| main.rs:842:5:842:27 | ref_methodcall_receiver | main.rs:842:5:842:29 | ref_methodcall_receiver(...) | |
+| main.rs:842:5:842:29 | ref_methodcall_receiver(...) | main.rs:843:5:843:23 | ExprStmt | |
+| main.rs:842:5:842:30 | ExprStmt | main.rs:842:5:842:27 | ref_methodcall_receiver | |
+| main.rs:843:5:843:20 | macro_invocation | main.rs:843:5:843:22 | macro_invocation(...) | |
+| main.rs:843:5:843:22 | macro_invocation(...) | main.rs:844:5:844:18 | ExprStmt | |
+| main.rs:843:5:843:23 | ExprStmt | main.rs:843:5:843:20 | macro_invocation | |
+| main.rs:844:5:844:15 | capture_phi | main.rs:844:5:844:17 | capture_phi(...) | |
+| main.rs:844:5:844:17 | capture_phi(...) | main.rs:801:11:845:1 | { ... } | |
+| main.rs:844:5:844:18 | ExprStmt | main.rs:844:5:844:15 | capture_phi | |
breakTarget
| main.rs:326:9:326:13 | break | main.rs:317:5:327:5 | while ... { ... } |
continueTarget
diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected
index 35adac47802..e6075a0cb3f 100644
--- a/rust/ql/test/library-tests/variables/Ssa.expected
+++ b/rust/ql/test/library-tests/variables/Ssa.expected
@@ -196,6 +196,13 @@ definition
| main.rs:748:17:750:9 | SSA phi(x) | main.rs:745:13:745:13 | x |
| main.rs:749:13:749:13 | x | main.rs:745:13:745:13 | x |
| main.rs:752:5:752:13 | x | main.rs:745:13:745:13 | x |
+| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x |
+| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y |
+| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias |
+| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test |
+| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x |
+| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x |
+| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z |
read
| main.rs:5:14:5:14 | s | main.rs:5:14:5:14 | s | main.rs:7:20:7:20 | s |
| main.rs:10:14:10:14 | i | main.rs:10:14:10:14 | i | main.rs:12:20:12:20 | i |
@@ -404,6 +411,14 @@ read
| main.rs:746:13:746:15 | cap | main.rs:746:13:746:15 | cap | main.rs:752:5:752:7 | cap |
| main.rs:746:20:746:20 | b | main.rs:746:20:746:20 | b | main.rs:748:20:748:20 | b |
| main.rs:752:5:752:13 | x | main.rs:745:13:745:13 | x | main.rs:753:15:753:15 | x |
+| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | main.rs:761:19:761:19 | x |
+| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y |
+| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | main.rs:779:13:779:22 | test_alias |
+| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test |
+| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x |
+| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:793:15:793:15 | x |
+| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x |
+| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z | main.rs:795:17:795:17 | z |
firstRead
| main.rs:5:14:5:14 | s | main.rs:5:14:5:14 | s | main.rs:7:20:7:20 | s |
| main.rs:10:14:10:14 | i | main.rs:10:14:10:14 | i | main.rs:12:20:12:20 | i |
@@ -570,6 +585,13 @@ firstRead
| main.rs:746:13:746:15 | cap | main.rs:746:13:746:15 | cap | main.rs:752:5:752:7 | cap |
| main.rs:746:20:746:20 | b | main.rs:746:20:746:20 | b | main.rs:748:20:748:20 | b |
| main.rs:752:5:752:13 | x | main.rs:745:13:745:13 | x | main.rs:753:15:753:15 | x |
+| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | main.rs:761:19:761:19 | x |
+| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y |
+| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | main.rs:779:13:779:22 | test_alias |
+| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test |
+| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x |
+| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x |
+| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z | main.rs:795:17:795:17 | z |
adjacentReads
| main.rs:27:5:27:6 | x2 | main.rs:25:13:25:14 | x2 | main.rs:28:15:28:16 | x2 | main.rs:29:10:29:11 | x2 |
| main.rs:41:9:41:10 | x3 | main.rs:41:9:41:10 | x3 | main.rs:42:15:42:16 | x3 | main.rs:44:9:44:10 | x3 |
@@ -616,6 +638,7 @@ adjacentReads
| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:677:15:677:15 | a | main.rs:678:5:678:5 | a |
| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:678:5:678:5 | a | main.rs:679:15:679:15 | a |
| main.rs:685:9:685:9 | x | main.rs:685:9:685:9 | x | main.rs:686:20:686:20 | x | main.rs:687:15:687:15 | x |
+| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x | main.rs:793:15:793:15 | x |
phi
| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:9:210:44 | a3 | main.rs:210:22:210:23 | a3 |
| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:9:210:44 | a3 | main.rs:210:42:210:43 | a3 |
@@ -773,3 +796,8 @@ assigns
| main.rs:745:13:745:13 | x | main.rs:745:17:745:19 | 100 |
| main.rs:746:13:746:15 | cap | main.rs:746:19:751:5 | \|...\| ... |
| main.rs:749:13:749:13 | x | main.rs:749:17:749:19 | 200 |
+| main.rs:759:13:759:13 | x | main.rs:759:17:759:24 | Some(...) |
+| main.rs:760:13:760:13 | y | main.rs:761:13:767:9 | match x { ... } |
+| main.rs:776:13:776:22 | test_alias | main.rs:777:13:777:16 | test |
+| main.rs:778:13:778:16 | test | main.rs:779:13:779:24 | test_alias(...) |
+| main.rs:787:13:787:13 | x | main.rs:787:17:787:23 | Some(...) |
diff --git a/rust/ql/test/library-tests/variables/main.rs b/rust/ql/test/library-tests/variables/main.rs
index cdfe1091ee3..b8a3187421f 100644
--- a/rust/ql/test/library-tests/variables/main.rs
+++ b/rust/ql/test/library-tests/variables/main.rs
@@ -753,6 +753,51 @@ fn capture_phi() {
print_i64(x); // $ read_access=x
}
+mod patterns {
+ #[rustfmt::skip]
+ pub fn test() -> Option {
+ let x = Some(42); // x
+ let y : Option = // y1
+ match x { // $ read_access=x
+ Some(y) => { // y2
+ None
+ }
+ None =>
+ None
+ };
+ match y { // $ read_access=y1
+ N0ne => // n0ne
+ N0ne // $ MISSING: read_access=n0ne
+ }
+ }
+
+ #[rustfmt::skip]
+ fn test2() -> Option {
+ let test_alias = // test_alias
+ test;
+ let test = // test
+ test_alias(); // $ read_access=test_alias
+ test // $ read_access=test
+ }
+
+ const z: i32 = 0;
+
+ #[rustfmt::skip]
+ fn test3() {
+ let x = Some(0); // x1
+ match x { // $ read_access=x1
+ Some(x) // x2
+ => x, // $ read_access=x2
+ _ => 0
+ };
+ match x { // $ read_access=x1
+ Some(z) =>
+ z, // $ SPURIOUS: read_access=z
+ _ => 0
+ };
+ }
+}
+
fn main() {
immutable_variable();
mutable_variable();
diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected
index 64431803e6d..42d02b51419 100644
--- a/rust/ql/test/library-tests/variables/variables.expected
+++ b/rust/ql/test/library-tests/variables/variables.expected
@@ -142,6 +142,14 @@ variable
| main.rs:745:13:745:13 | x |
| main.rs:746:13:746:15 | cap |
| main.rs:746:20:746:20 | b |
+| main.rs:759:13:759:13 | x |
+| main.rs:760:13:760:13 | y |
+| main.rs:762:18:762:18 | y |
+| main.rs:776:13:776:22 | test_alias |
+| main.rs:778:13:778:16 | test |
+| main.rs:787:13:787:13 | x |
+| main.rs:789:18:789:18 | x |
+| main.rs:794:18:794:18 | z |
variableAccess
| main.rs:7:20:7:20 | s | main.rs:5:14:5:14 | s |
| main.rs:12:20:12:20 | i | main.rs:10:14:10:14 | i |
@@ -364,6 +372,14 @@ variableAccess
| main.rs:749:13:749:13 | x | main.rs:745:13:745:13 | x |
| main.rs:752:5:752:7 | cap | main.rs:746:13:746:15 | cap |
| main.rs:753:15:753:15 | x | main.rs:745:13:745:13 | x |
+| main.rs:761:19:761:19 | x | main.rs:759:13:759:13 | x |
+| main.rs:768:15:768:15 | y | main.rs:760:13:760:13 | y |
+| main.rs:779:13:779:22 | test_alias | main.rs:776:13:776:22 | test_alias |
+| main.rs:780:9:780:12 | test | main.rs:778:13:778:16 | test |
+| main.rs:788:15:788:15 | x | main.rs:787:13:787:13 | x |
+| main.rs:790:20:790:20 | x | main.rs:789:18:789:18 | x |
+| main.rs:793:15:793:15 | x | main.rs:787:13:787:13 | x |
+| main.rs:795:17:795:17 | z | main.rs:794:18:794:18 | z |
variableWriteAccess
| main.rs:27:5:27:6 | x2 | main.rs:25:13:25:14 | x2 |
| main.rs:29:5:29:6 | x2 | main.rs:25:13:25:14 | x2 |
@@ -576,6 +592,14 @@ variableReadAccess
| main.rs:748:20:748:20 | b | main.rs:746:20:746:20 | b |
| main.rs:752:5:752:7 | cap | main.rs:746:13:746:15 | cap |
| main.rs:753:15:753:15 | x | main.rs:745:13:745:13 | x |
+| main.rs:761:19:761:19 | x | main.rs:759:13:759:13 | x |
+| main.rs:768:15:768:15 | y | main.rs:760:13:760:13 | y |
+| main.rs:779:13:779:22 | test_alias | main.rs:776:13:776:22 | test_alias |
+| main.rs:780:9:780:12 | test | main.rs:778:13:778:16 | test |
+| main.rs:788:15:788:15 | x | main.rs:787:13:787:13 | x |
+| main.rs:790:20:790:20 | x | main.rs:789:18:789:18 | x |
+| main.rs:793:15:793:15 | x | main.rs:787:13:787:13 | x |
+| main.rs:795:17:795:17 | z | main.rs:794:18:794:18 | z |
variableInitializer
| main.rs:20:9:20:10 | x1 | main.rs:20:14:20:16 | "a" |
| main.rs:25:13:25:14 | x2 | main.rs:25:18:25:18 | 4 |
@@ -649,6 +673,11 @@ variableInitializer
| main.rs:734:15:734:28 | var_in_macro | main.rs:734:15:734:28 | 0 |
| main.rs:745:13:745:13 | x | main.rs:745:17:745:19 | 100 |
| main.rs:746:13:746:15 | cap | main.rs:746:19:751:5 | \|...\| ... |
+| main.rs:759:13:759:13 | x | main.rs:759:17:759:24 | Some(...) |
+| main.rs:760:13:760:13 | y | main.rs:761:13:767:9 | match x { ... } |
+| main.rs:776:13:776:22 | test_alias | main.rs:777:13:777:16 | test |
+| main.rs:778:13:778:16 | test | main.rs:779:13:779:24 | test_alias(...) |
+| main.rs:787:13:787:13 | x | main.rs:787:17:787:23 | Some(...) |
capturedVariable
| main.rs:557:9:557:9 | x |
| main.rs:568:13:568:13 | x |
From ec3b2c6a8d1d0c2711e40ef458e846ac01b9225c Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Wed, 29 Oct 2025 15:52:00 +0100
Subject: [PATCH 24/70] Rust: Path resolution before variable resolution
---
.../hello-workspace/path-resolution.ql | 2 +-
.../rust/controlflow/internal/Completion.qll | 9 +-
.../rust/elements/internal/CallImpl.qll | 2 +-
.../rust/elements/internal/ConstImpl.qll | 30 ++-
.../FormatTemplateVariableAccessImpl.qll | 2 +
.../rust/elements/internal/PathExprImpl.qll | 7 +
.../rust/elements/internal/VariableImpl.qll | 19 +-
.../lib/codeql/rust/internal/CachedStages.qll | 4 +-
.../lib/codeql/rust/internal/Definitions.qll | 5 +-
.../codeql/rust/internal/PathResolution.qll | 219 ++++++++++++------
.../macro-expansion/PrintAst.expected | 142 ++++++------
.../library-tests/path-resolution/main.rs | 4 +-
.../path-resolution/path-resolution.expected | 3 +
.../path-resolution/path-resolution.ql | 2 +-
.../test/library-tests/variables/Cfg.expected | 1 +
.../test/library-tests/variables/Ssa.expected | 6 +-
rust/ql/test/library-tests/variables/main.rs | 4 +-
.../variables/variables.expected | 6 +-
18 files changed, 277 insertions(+), 190 deletions(-)
diff --git a/rust/ql/integration-tests/hello-workspace/path-resolution.ql b/rust/ql/integration-tests/hello-workspace/path-resolution.ql
index 9ec97b61eeb..574a9553155 100644
--- a/rust/ql/integration-tests/hello-workspace/path-resolution.ql
+++ b/rust/ql/integration-tests/hello-workspace/path-resolution.ql
@@ -2,7 +2,7 @@ import rust
import codeql.rust.internal.PathResolution
import utils.test.PathResolutionInlineExpectationsTest
-query predicate resolveDollarCrate(RelevantPath p, Crate c) {
+query predicate resolveDollarCrate(PathExt p, Crate c) {
c = resolvePath(p) and
p.isDollarCrate() and
p.fromSource() and
diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll
index 0250f1cbc43..33da4db473e 100644
--- a/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll
+++ b/rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll
@@ -1,5 +1,6 @@
private import codeql.util.Boolean
private import codeql.rust.controlflow.ControlFlowGraph
+private import codeql.rust.elements.internal.VariableImpl::Impl as VariableImpl
private import rust
newtype TCompletion =
@@ -123,13 +124,7 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
*/
private predicate cannotCauseMatchFailure(Pat pat) {
pat instanceof RangePat or
- // Identifier patterns that are in fact path patterns can cause failures. For
- // instance `None`. Only if an `@ ...` part is present can we be sure that
- // it's an actual identifier pattern. As a heuristic, if the identifier starts
- // with a lower case letter, then we assume that it's an identifier. This
- // works for code that follows the Rust naming convention for enums and
- // constants.
- pat = any(IdentPat p | p.hasPat() or p.getName().getText().charAt(0).isLowercase()) or
+ pat = any(IdentPat p | p.hasPat() or VariableImpl::variableDecl(_, p.getName(), _)) or
pat instanceof WildcardPat or
pat instanceof RestPat or
pat instanceof RefPat or
diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll
index 210820fd105..71c6cfbffc0 100644
--- a/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll
+++ b/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll
@@ -82,7 +82,7 @@ module Impl {
}
private predicate callHasTraitQualifier(CallExpr call, Trait qualifier) {
- exists(RelevantPath qualifierPath |
+ exists(PathExt qualifierPath |
callHasQualifier(call, _, qualifierPath) and
qualifier = resolvePath(qualifierPath) and
// When the qualifier is `Self` and resolves to a trait, it's inside a
diff --git a/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll
index 0234f7cf730..44114674a56 100644
--- a/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll
+++ b/rust/ql/lib/codeql/rust/elements/internal/ConstImpl.qll
@@ -5,6 +5,8 @@
*/
private import codeql.rust.elements.internal.generated.Const
+private import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl
+private import codeql.rust.elements.internal.IdentPatImpl::Impl as IdentPatImpl
private import codeql.rust.elements.internal.PathExprImpl::Impl as PathExprImpl
private import codeql.rust.internal.PathResolution
@@ -36,14 +38,30 @@ module Impl {
* }
* ```
*/
- class ConstAccess extends PathExprImpl::PathExpr {
- private Const c;
-
- ConstAccess() { c = resolvePath(this.getPath()) }
-
+ abstract class ConstAccess extends AstNodeImpl::AstNode {
/** Gets the constant being accessed. */
- Const getConst() { result = c }
+ abstract Const getConst();
override string getAPrimaryQlClass() { result = "ConstAccess" }
}
+
+ private class PathExprConstAccess extends ConstAccess, PathExprImpl::PathExpr {
+ private Const c;
+
+ PathExprConstAccess() { c = resolvePath(this.getPath()) }
+
+ override Const getConst() { result = c }
+
+ override string getAPrimaryQlClass() { result = ConstAccess.super.getAPrimaryQlClass() }
+ }
+
+ private class IdentPatConstAccess extends ConstAccess, IdentPatImpl::IdentPat {
+ private Const c;
+
+ IdentPatConstAccess() { c = resolvePath(this) }
+
+ override Const getConst() { result = c }
+
+ override string getAPrimaryQlClass() { result = ConstAccess.super.getAPrimaryQlClass() }
+ }
}
diff --git a/rust/ql/lib/codeql/rust/elements/internal/FormatTemplateVariableAccessImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/FormatTemplateVariableAccessImpl.qll
index adb12a35931..35154ae0acb 100644
--- a/rust/ql/lib/codeql/rust/elements/internal/FormatTemplateVariableAccessImpl.qll
+++ b/rust/ql/lib/codeql/rust/elements/internal/FormatTemplateVariableAccessImpl.qll
@@ -31,6 +31,8 @@ module Impl {
override string toStringImpl() { result = this.getName() }
+ override string getAPrimaryQlClass() { result = "FormatTemplateVariableAccess" }
+
/** Gets the name of the variable */
string getName() { result = argument.getName() }
diff --git a/rust/ql/lib/codeql/rust/elements/internal/PathExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/PathExprImpl.qll
index 652dc68b3c9..cb2abc45e10 100644
--- a/rust/ql/lib/codeql/rust/elements/internal/PathExprImpl.qll
+++ b/rust/ql/lib/codeql/rust/elements/internal/PathExprImpl.qll
@@ -4,6 +4,7 @@
* INTERNAL: Do not use.
*/
+private import rust
private import codeql.rust.elements.internal.generated.PathExpr
/**
@@ -25,5 +26,11 @@ module Impl {
override string toStringImpl() { result = this.toAbbreviatedString() }
override string toAbbreviatedString() { result = this.getPath().toStringImpl() }
+
+ override string getAPrimaryQlClass() {
+ if this instanceof VariableAccess
+ then result = "VariableAccess"
+ else result = super.getAPrimaryQlClass()
+ }
}
}
diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll
index 61f022c8bfd..4569a108cd8 100644
--- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll
+++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll
@@ -1,8 +1,9 @@
private import rust
private import codeql.rust.controlflow.ControlFlowGraph
+private import codeql.rust.internal.PathResolution as PathResolution
private import codeql.rust.elements.internal.generated.ParentChild as ParentChild
+private import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl
private import codeql.rust.elements.internal.PathImpl::Impl as PathImpl
-private import codeql.rust.elements.internal.PathExprBaseImpl::Impl as PathExprBaseImpl
private import codeql.rust.elements.internal.FormatTemplateVariableAccessImpl::Impl as FormatTemplateVariableAccessImpl
private import codeql.util.DenseRank
@@ -98,7 +99,7 @@ module Impl {
* pattern.
*/
cached
- private predicate variableDecl(AstNode definingNode, Name name, string text) {
+ predicate variableDecl(AstNode definingNode, Name name, string text) {
Cached::ref() and
exists(SelfParam sp |
name = sp.getName() and
@@ -117,11 +118,7 @@ module Impl {
not exists(getOutermostEnclosingOrPat(pat)) and definingNode = name
) and
text = name.getText() and
- // exclude for now anything starting with an uppercase character, which may be a reference to
- // an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE),
- // which we don't appear to recognize yet anyway. This also assumes programmers follow the
- // naming guidelines, which they generally do, but they're not enforced.
- not text.charAt(0).isUppercase() and
+ not PathResolution::identPatIsResolvable(pat) and
// exclude parameters from functions without a body as these are trait method declarations
// without implementations
not exists(Function f | not f.hasBody() and f.getAParam().getPat() = pat) and
@@ -666,7 +663,7 @@ module Impl {
}
/** A variable access. */
- class VariableAccess extends PathExprBaseImpl::PathExprBase {
+ class VariableAccess extends PathExprBase {
private string name;
private Variable v;
@@ -677,10 +674,6 @@ module Impl {
/** Holds if this access is a capture. */
predicate isCapture() { this.getEnclosingCfgScope() != v.getEnclosingCfgScope() }
-
- override string toStringImpl() { result = name }
-
- override string getAPrimaryQlClass() { result = "VariableAccess" }
}
/** Holds if `e` occurs in the LHS of an assignment or compound assignment. */
@@ -722,7 +715,7 @@ module Impl {
}
/** A nested function access. */
- class NestedFunctionAccess extends PathExprBaseImpl::PathExprBase {
+ class NestedFunctionAccess extends PathExprBase {
private Function f;
NestedFunctionAccess() { nestedFunctionAccess(_, f, this) }
diff --git a/rust/ql/lib/codeql/rust/internal/CachedStages.qll b/rust/ql/lib/codeql/rust/internal/CachedStages.qll
index 132b9ec8f7e..dc80fc09dad 100644
--- a/rust/ql/lib/codeql/rust/internal/CachedStages.qll
+++ b/rust/ql/lib/codeql/rust/internal/CachedStages.qll
@@ -115,13 +115,11 @@ module Stages {
predicate backref() {
1 = 1
or
- exists(resolvePath(_))
+ exists(resolvePathIgnoreVariableShadowing(_))
or
exists(any(ItemNode i).getASuccessor(_, _, _))
or
exists(any(ImplOrTraitItemNode i).getASelfPath())
- or
- any(TypeParamItemNode i).hasTraitBound()
}
}
diff --git a/rust/ql/lib/codeql/rust/internal/Definitions.qll b/rust/ql/lib/codeql/rust/internal/Definitions.qll
index b1b3e475c46..60520a77cbf 100644
--- a/rust/ql/lib/codeql/rust/internal/Definitions.qll
+++ b/rust/ql/lib/codeql/rust/internal/Definitions.qll
@@ -37,6 +37,9 @@ private module Cached {
TFormatArgsArgIndex(Expr e) { e = any(FormatArgsArg a).getExpr() } or
TItemNode(ItemNode i)
+ pragma[nomagic]
+ private predicate isMacroCallLocation(Location loc) { loc = any(MacroCall m).getLocation() }
+
/**
* Gets an element, of kind `kind`, that element `use` uses, if any.
*/
@@ -44,7 +47,7 @@ private module Cached {
Definition definitionOf(Use use, string kind) {
result = use.getDefinition() and
kind = use.getUseType() and
- not result.getLocation() = any(MacroCall m).getLocation()
+ not isMacroCallLocation(result.getLocation())
}
}
diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll
index 54df4a3ca0c..f4349f79327 100644
--- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll
+++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll
@@ -1,9 +1,49 @@
/**
* Provides functionality for resolving paths, using the predicate `resolvePath`.
+ *
+ * Path resolution needs to happen before variable resolution, because otherwise
+ * we cannot know whether an identifier pattern binds a new variable or whether it
+ * refers to a constructor or constant:
+ *
+ * ```rust
+ * let x = ...; // `x` is only a variable if it does not resolve to a constructor/constant
+ * ```
+ *
+ * Even though variable names typically start with a lowercase letter and constructors
+ * with an uppercase letter, this is not enforced by the Rust language.
+ *
+ * Variables may shadow declarations, so variable resolution also needs to affect
+ * path resolution:
+ *
+ * ```rust
+ * fn foo() {} // (1)
+ *
+ * fn bar() {
+ * let f = foo; // `foo` here refers to (1) via path resolution
+ * let foo = f(); // (2)
+ * foo // `foo` here refers to (2) via variable resolution
+ * }
+ * ```
+ *
+ * So it may seem that path resolution and variable resolution must happen in mutual
+ * recursion, but we would like to keep the inherently global path resolution logic
+ * separate from the inherently local variable resolution logic. We acheive this by
+ *
+ * - First computing global path resolution, where variable shadowing is ignored,
+ * exposed as the internal predicate `resolvePathIgnoreVariableShadowing`.
+ * - `resolvePathIgnoreVariableShadowing` is sufficient to determine whether an
+ * identifier pattern resolves to a constructor/constant, since if it does, it cannot
+ * be shadowed by a variable. We expose this as the predicate `identPatIsResolvable`.
+ * - Variable resolution can then be computed as a local property, using only the
+ * global information from `identPatIsResolvable`.
+ * - Finally, path resolution can be computed by restricting
+ * `resolvePathIgnoreVariableShadowing` to paths that are not resolvable via
+ * variable resolution.
*/
private import rust
private import codeql.rust.elements.internal.generated.ParentChild
+private import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl
private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl
private import codeql.rust.internal.CachedStages
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
@@ -184,7 +224,7 @@ abstract class ItemNode extends Locatable {
pragma[nomagic]
final Attr getAttr(string name) {
result = this.getAnAttr() and
- result.getMeta().getPath().(RelevantPath).isUnqualified(name)
+ result.getMeta().getPath().(PathExt).isUnqualified(name)
}
final predicate hasAttr(string name) { exists(this.getAttr(name)) }
@@ -1160,34 +1200,6 @@ final class TypeParamItemNode extends TypeItemNode instanceof TypeParam {
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
- /**
- * Holds if this type parameter has a trait bound. Examples:
- *
- * ```rust
- * impl Foo { ... } // has no trait bound
- *
- * impl Foo { ... } // has trait bound
- *
- * impl Foo where T: Trait { ... } // has trait bound
- * ```
- */
- cached
- predicate hasTraitBound() { Stages::PathResolutionStage::ref() and exists(this.getABoundPath()) }
-
- /**
- * Holds if this type parameter has no trait bound. Examples:
- *
- * ```rust
- * impl Foo { ... } // has no trait bound
- *
- * impl Foo { ... } // has trait bound
- *
- * impl Foo where T: Trait { ... } // has trait bound
- * ```
- */
- pragma[nomagic]
- predicate hasNoTraitBound() { not this.hasTraitBound() }
-
override string getName() { result = TypeParam.super.getName().getText() }
override Namespace getNamespace() { result.isType() }
@@ -1526,20 +1538,22 @@ private predicate declares(ItemNode item, Namespace ns, string name) {
)
}
-/** A path that does not access a local variable. */
-class RelevantPath extends Path {
- RelevantPath() { not this = any(VariableAccess va).(PathExpr).getPath() }
+/**
+ * A `Path` or an `IdentPat`.
+ *
+ * `IdentPat`s are included in order to resolve unqualified references to
+ * constructors in patterns.
+ */
+abstract class PathExt extends AstNode {
+ abstract string getText();
/** Holds if this is an unqualified path with the textual value `name`. */
pragma[nomagic]
- predicate isUnqualified(string name) {
- not exists(this.getQualifier()) and
- not exists(UseTree tree |
- tree.hasPath() and
- this = getAUseTreeUseTree(tree).getPath().getQualifier*()
- ) and
- name = this.getText()
- }
+ abstract predicate isUnqualified(string name);
+
+ abstract Path getQualifier();
+
+ abstract string toStringDebug();
/**
* Holds if this is an unqualified path with the textual value `name` and
@@ -1561,6 +1575,33 @@ class RelevantPath extends Path {
predicate isDollarCrate() { this.isUnqualified("$crate", _) }
}
+private class PathExtPath extends PathExt instanceof Path {
+ override string getText() { result = Path.super.getText() }
+
+ override predicate isUnqualified(string name) {
+ not exists(Path.super.getQualifier()) and
+ not exists(UseTree tree |
+ tree.hasPath() and
+ this = getAUseTreeUseTree(tree).getPath().getQualifier*()
+ ) and
+ name = Path.super.getText()
+ }
+
+ override Path getQualifier() { result = Path.super.getQualifier() }
+
+ override string toStringDebug() { result = Path.super.toStringDebug() }
+}
+
+private class PathExtIdentPat extends PathExt, IdentPat {
+ override string getText() { result = this.getName().getText() }
+
+ override predicate isUnqualified(string name) { name = this.getText() }
+
+ override Path getQualifier() { none() }
+
+ override string toStringDebug() { result = this.getText() }
+}
+
private predicate isModule(ItemNode m) { m instanceof Module }
/** Holds if source file `source` contains the module `m`. */
@@ -1584,7 +1625,7 @@ private ItemNode getOuterScope(ItemNode i) {
pragma[nomagic]
private predicate unqualifiedPathLookup(ItemNode ancestor, string name, Namespace ns, ItemNode encl) {
// lookup in the immediately enclosing item
- exists(RelevantPath path |
+ exists(PathExt path |
path.isUnqualified(name, encl) and
ancestor = encl and
not name = ["crate", "$crate", "super", "self"]
@@ -1620,7 +1661,7 @@ private ItemNode getASuccessor(
private predicate isSourceFile(ItemNode source) { source instanceof SourceFileItemNode }
-private predicate hasCratePath(ItemNode i) { any(RelevantPath path).isCratePath(_, i) }
+private predicate hasCratePath(ItemNode i) { any(PathExt path).isCratePath(_, i) }
private predicate hasChild(ItemNode parent, ItemNode child) { child.getImmediateParent() = parent }
@@ -1632,7 +1673,7 @@ private predicate sourceFileHasCratePathTc(ItemNode i1, ItemNode i2) =
* `name` may be looked up inside `ancestor`.
*/
pragma[nomagic]
-private predicate keywordLookup(ItemNode ancestor, string name, RelevantPath p) {
+private predicate keywordLookup(ItemNode ancestor, string name, PathExt p) {
// For `crate`, jump directly to the root module
exists(ItemNode i | p.isCratePath(name, i) |
ancestor instanceof SourceFile and
@@ -1646,7 +1687,7 @@ private predicate keywordLookup(ItemNode ancestor, string name, RelevantPath p)
}
pragma[nomagic]
-private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKind kind) {
+private ItemNode unqualifiedPathLookup(PathExt p, Namespace ns, SuccessorKind kind) {
exists(ItemNode ancestor, string name |
result = getASuccessor(ancestor, pragma[only_bind_into](name), ns, kind, _) and
kind.isInternalOrBoth()
@@ -1661,7 +1702,7 @@ private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKi
}
pragma[nomagic]
-private predicate isUnqualifiedSelfPath(RelevantPath path) { path.isUnqualified("Self") }
+private predicate isUnqualifiedSelfPath(PathExt path) { path.isUnqualified("Self") }
/** Provides the input to `TraitIsVisible`. */
signature predicate relevantTraitVisibleSig(Element element, Trait trait);
@@ -1744,14 +1785,14 @@ private module DollarCrateResolution {
isDollarCrateSupportedMacroExpansion(_, expansion)
}
- private predicate isDollarCratePath(RelevantPath p) { p.isDollarCrate() }
+ private predicate isDollarCratePath(PathExt p) { p.isDollarCrate() }
- private predicate isInDollarCrateMacroExpansion(RelevantPath p, AstNode expansion) =
+ private predicate isInDollarCrateMacroExpansion(PathExt p, AstNode expansion) =
doublyBoundedFastTC(hasParent/2, isDollarCratePath/1, isDollarCrateSupportedMacroExpansion/1)(p,
expansion)
pragma[nomagic]
- private predicate isInDollarCrateMacroExpansionFromFile(File macroDefFile, RelevantPath p) {
+ private predicate isInDollarCrateMacroExpansionFromFile(File macroDefFile, PathExt p) {
exists(Path macroDefPath, AstNode expansion |
isDollarCrateSupportedMacroExpansion(macroDefPath, expansion) and
isInDollarCrateMacroExpansion(p, expansion) and
@@ -1766,17 +1807,17 @@ private module DollarCrateResolution {
* calls.
*/
pragma[nomagic]
- predicate resolveDollarCrate(RelevantPath p, CrateItemNode crate) {
+ predicate resolveDollarCrate(PathExt p, CrateItemNode crate) {
isInDollarCrateMacroExpansionFromFile(crate.getASourceFile().getFile(), p)
}
}
pragma[nomagic]
-private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
+private ItemNode resolvePathCand0(PathExt path, Namespace ns) {
exists(ItemNode res |
res = unqualifiedPathLookup(path, ns, _) and
if
- not any(RelevantPath parent).getQualifier() = path and
+ not any(PathExt parent).getQualifier() = path and
isUnqualifiedSelfPath(path) and
res instanceof ImplItemNode
then result = res.(ImplItemNodeImpl).resolveSelfTyCand()
@@ -1791,13 +1832,16 @@ private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
result = resolveUseTreeListItem(_, _, path, _) and
ns = result.getNamespace()
or
- result = resolveBuiltin(path.getSegment().getTypeRepr()) and
- not path.getSegment().hasTraitTypeRepr() and
- ns.isType()
+ exists(PathSegment seg |
+ seg = path.(Path).getSegment() and
+ result = resolveBuiltin(seg.getTypeRepr()) and
+ not seg.hasTraitTypeRepr() and
+ ns.isType()
+ )
}
pragma[nomagic]
-private ItemNode resolvePathCandQualifier(RelevantPath qualifier, RelevantPath path, string name) {
+private ItemNode resolvePathCandQualifier(PathExt qualifier, PathExt path, string name) {
qualifier = path.getQualifier() and
result = resolvePathCand(qualifier) and
name = path.getText()
@@ -1845,9 +1889,7 @@ private predicate checkQualifiedVisibility(
* qualifier of `path` and `qualifier` resolves to `q`, if any.
*/
pragma[nomagic]
-private ItemNode resolvePathCandQualified(
- RelevantPath qualifier, ItemNode q, RelevantPath path, Namespace ns
-) {
+private ItemNode resolvePathCandQualified(PathExt qualifier, ItemNode q, PathExt path, Namespace ns) {
exists(string name, SuccessorKind kind, UseOption useOpt |
q = resolvePathCandQualifier(qualifier, path, name) and
result = getASuccessor(q, name, ns, kind, useOpt) and
@@ -1856,12 +1898,14 @@ private ItemNode resolvePathCandQualified(
}
/** Holds if path `p` must be looked up in namespace `n`. */
-private predicate pathUsesNamespace(Path p, Namespace n) {
+private predicate pathUsesNamespace(PathExt p, Namespace n) {
n.isValue() and
(
p = any(PathExpr pe).getPath()
or
p = any(TupleStructPat tsp).getPath()
+ or
+ p instanceof PathExtIdentPat
)
or
n.isType() and
@@ -1937,7 +1981,7 @@ private predicate macroUseEdge(
* result in non-monotonic recursion.
*/
pragma[nomagic]
-private ItemNode resolvePathCand(RelevantPath path) {
+private ItemNode resolvePathCand(PathExt path) {
exists(Namespace ns |
result = resolvePathCand0(path, ns) and
if path = any(ImplItemNode i).getSelfPath()
@@ -1950,7 +1994,13 @@ private ItemNode resolvePathCand(RelevantPath path) {
else
if path = any(PathTypeRepr p).getPath()
then result instanceof TypeItemNode
- else any()
+ else
+ if path instanceof IdentPat
+ then
+ result instanceof VariantItemNode or
+ result instanceof StructItemNode or
+ result instanceof ConstItemNode
+ else any()
|
pathUsesNamespace(path, ns)
or
@@ -1967,7 +2017,7 @@ private ItemNode resolvePathCand(RelevantPath path) {
}
/** Get a trait that should be visible when `path` resolves to `node`, if any. */
-private Trait getResolvePathTraitUsed(RelevantPath path, AssocItemNode node) {
+private Trait getResolvePathTraitUsed(PathExt path, AssocItemNode node) {
exists(TypeItemNode type, ImplItemNodeImpl impl |
node = resolvePathCandQualified(_, type, path, _) and
typeImplEdge(type, impl, _, _, node, _) and
@@ -1979,9 +2029,9 @@ private predicate pathTraitUsed(Element path, Trait trait) {
trait = getResolvePathTraitUsed(path, _)
}
-/** Gets the item that `path` resolves to, if any. */
+/** INTERNAL: Do not use; use `resolvePath` instead. */
cached
-ItemNode resolvePath(RelevantPath path) {
+ItemNode resolvePathIgnoreVariableShadowing(PathExt path) {
result = resolvePathCand(path) and
not path = any(Path parent | exists(resolvePathCand(parent))).getQualifier() and
(
@@ -1994,29 +2044,43 @@ ItemNode resolvePath(RelevantPath path) {
or
// if `path` is the qualifier of a resolvable `parent`, then we should
// resolve `path` to something consistent with what `parent` resolves to
- exists(RelevantPath parent |
- resolvePathCandQualified(path, result, parent, _) = resolvePath(parent)
+ exists(PathExt parent |
+ resolvePathCandQualified(path, result, parent, _) = resolvePathIgnoreVariableShadowing(parent)
)
}
-private predicate isUseTreeSubPath(UseTree tree, RelevantPath path) {
+/**
+ * Holds if `ip` resolves to some constructor.
+ */
+// use `forceLocal` once we implement overlay support
+pragma[nomagic]
+predicate identPatIsResolvable(IdentPat ip) { exists(resolvePathIgnoreVariableShadowing(ip)) }
+
+/** Gets the item that `path` resolves to, if any. */
+pragma[nomagic]
+ItemNode resolvePath(PathExt path) {
+ result = resolvePathIgnoreVariableShadowing(path) and
+ not path = any(VariableAccess va).(PathExpr).getPath()
+}
+
+private predicate isUseTreeSubPath(UseTree tree, PathExt path) {
path = tree.getPath()
or
- exists(RelevantPath mid |
+ exists(PathExt mid |
isUseTreeSubPath(tree, mid) and
path = mid.getQualifier()
)
}
pragma[nomagic]
-private predicate isUseTreeSubPathUnqualified(UseTree tree, RelevantPath path, string name) {
+private predicate isUseTreeSubPathUnqualified(UseTree tree, PathExt path, string name) {
isUseTreeSubPath(tree, path) and
not exists(path.getQualifier()) and
name = path.getText()
}
pragma[nomagic]
-private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path, SuccessorKind kind) {
+private ItemNode resolveUseTreeListItem(Use use, UseTree tree, PathExt path, SuccessorKind kind) {
exists(UseOption useOpt | checkQualifiedVisibility(use, result, kind, useOpt) |
exists(UseTree midTree, ItemNode mid, string name |
mid = resolveUseTreeListItem(use, midTree) and
@@ -2033,9 +2097,7 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
}
pragma[nomagic]
-private ItemNode resolveUseTreeListItemQualifier(
- Use use, UseTree tree, RelevantPath path, string name
-) {
+private ItemNode resolveUseTreeListItemQualifier(Use use, UseTree tree, PathExt path, string name) {
result = resolveUseTreeListItem(use, tree, path.getQualifier(), _) and
name = path.getText()
}
@@ -2187,7 +2249,7 @@ private module Debug {
}
predicate debugUnqualifiedPathLookup(
- RelevantPath p, string name, Namespace ns, ItemNode ancestor, string path
+ PathExt p, string name, Namespace ns, ItemNode ancestor, string path
) {
p = getRelevantLocatable() and
exists(ItemNode encl |
@@ -2197,14 +2259,19 @@ private module Debug {
path = p.toStringDebug()
}
+ ItemNode debugUnqualifiedPathLookup(PathExt p, Namespace ns, SuccessorKind kind) {
+ p = getRelevantLocatable() and
+ result = unqualifiedPathLookup(p, ns, kind)
+ }
+
predicate debugItemNode(ItemNode item) { item = getRelevantLocatable() }
- ItemNode debugResolvePath(RelevantPath path) {
+ ItemNode debugResolvePath(PathExt path) {
path = getRelevantLocatable() and
result = resolvePath(path)
}
- ItemNode debugResolveUseTreeListItem(Use use, UseTree tree, RelevantPath path, SuccessorKind kind) {
+ ItemNode debugResolveUseTreeListItem(Use use, UseTree tree, PathExt path, SuccessorKind kind) {
use = getRelevantLocatable() and
result = resolveUseTreeListItem(use, tree, path, kind)
}
diff --git a/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected b/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected
index 1a0ded6950d..5174e0bd618 100644
--- a/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected
+++ b/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected
@@ -660,7 +660,7 @@ macro_expansion.rs:
# 71| getSegment(): [PathSegment] i32
# 71| getIdentifier(): [NameRef] i32
# 72| getTailExpr(): [CastExpr] a as ...
-# 72| getExpr(): [PathExpr,VariableAccess] a
+# 72| getExpr(): [VariableAccess] a
# 72| getPath(): [Path] a
# 72| getSegment(): [PathSegment] a
# 72| getIdentifier(): [NameRef] a
@@ -738,7 +738,7 @@ macro_expansion.rs:
# 84| getFunctionBody(): [BlockExpr] { ... }
# 84| getStmtList(): [StmtList] StmtList
# 84| getTailExpr(): [MatchExpr] match self { ... }
-# 83| getScrutinee(): [PathExpr,VariableAccess] self
+# 83| getScrutinee(): [VariableAccess] self
# 83| getPath(): [Path] self
# 83| getSegment(): [PathSegment] self
# 83| getIdentifier(): [NameRef] self
@@ -751,7 +751,7 @@ macro_expansion.rs:
# 85| getArgList(): [ArgList] ArgList
# 83| getArg(0): [StringLiteralExpr] "field"
# 85| getArg(1): [RefExpr] &field
-# 85| getExpr(): [PathExpr,VariableAccess] field
+# 85| getExpr(): [VariableAccess] field
# 85| getPath(): [Path] field
# 85| getSegment(): [PathSegment] field
# 85| getIdentifier(): [NameRef] field
@@ -760,7 +760,7 @@ macro_expansion.rs:
# 83| getArgList(): [ArgList] ArgList
# 83| getArg(0): [StringLiteralExpr] "MyDerive"
# 83| getIdentifier(): [NameRef] debug_struct
-# 83| getReceiver(): [PathExpr,VariableAccess] f
+# 83| getReceiver(): [VariableAccess] f
# 83| getPath(): [Path] f
# 83| getSegment(): [PathSegment] f
# 83| getIdentifier(): [NameRef] f
@@ -836,11 +836,11 @@ macro_expansion.rs:
# 89| getStmtList(): [StmtList] StmtList
# 89| getTailExpr(): [MatchExpr] match ... { ... }
# 88| getScrutinee(): [TupleExpr] TupleExpr
-# 88| getField(0): [PathExpr,VariableAccess] self
+# 88| getField(0): [VariableAccess] self
# 88| getPath(): [Path] self
# 88| getSegment(): [PathSegment] self
# 88| getIdentifier(): [NameRef] self
-# 88| getField(1): [PathExpr,VariableAccess] other
+# 88| getField(1): [VariableAccess] other
# 88| getPath(): [Path] other
# 88| getSegment(): [PathSegment] other
# 88| getIdentifier(): [NameRef] other
@@ -1076,7 +1076,7 @@ proc_macro.rs:
# 6| getMacroCallExpansion(): [MatchExpr] match ... { ... }
# 6| getScrutinee(): [CallExpr] ...::parse::<...>(...)
# 6| getArgList(): [ArgList] ArgList
-# 6| getArg(0): [PathExpr,VariableAccess] attr
+# 6| getArg(0): [VariableAccess] attr
# 6| getPath(): [Path] attr
# 6| getSegment(): [PathSegment] attr
# 6| getIdentifier(): [NameRef] attr
@@ -1098,7 +1098,7 @@ proc_macro.rs:
# 6| getIdentifier(): [NameRef] parse
# 6| getMatchArmList(): [MatchArmList] MatchArmList
# 6| getArm(0): [MatchArm] ... => data
-# 6| getExpr(): [PathExpr,VariableAccess] data
+# 6| getExpr(): [VariableAccess] data
# 6| getPath(): [Path] data
# 6| getSegment(): [PathSegment] data
# 6| getIdentifier(): [NameRef] data
@@ -1124,7 +1124,7 @@ proc_macro.rs:
# 6| getArg(0): [MethodCallExpr] err.to_compile_error()
# 6| getArgList(): [ArgList] ArgList
# 6| getIdentifier(): [NameRef] to_compile_error
-# 6| getReceiver(): [PathExpr,VariableAccess] err
+# 6| getReceiver(): [VariableAccess] err
# 6| getPath(): [Path] err
# 6| getSegment(): [PathSegment] err
# 6| getIdentifier(): [NameRef] err
@@ -1168,7 +1168,7 @@ proc_macro.rs:
# 7| getMacroCallExpansion(): [MatchExpr] match ... { ... }
# 7| getScrutinee(): [CallExpr] ...::parse::<...>(...)
# 7| getArgList(): [ArgList] ArgList
-# 7| getArg(0): [PathExpr,VariableAccess] item
+# 7| getArg(0): [VariableAccess] item
# 7| getPath(): [Path] item
# 7| getSegment(): [PathSegment] item
# 7| getIdentifier(): [NameRef] item
@@ -1190,7 +1190,7 @@ proc_macro.rs:
# 7| getIdentifier(): [NameRef] parse
# 7| getMatchArmList(): [MatchArmList] MatchArmList
# 7| getArm(0): [MatchArm] ... => data
-# 7| getExpr(): [PathExpr,VariableAccess] data
+# 7| getExpr(): [VariableAccess] data
# 7| getPath(): [Path] data
# 7| getSegment(): [PathSegment] data
# 7| getIdentifier(): [NameRef] data
@@ -1216,7 +1216,7 @@ proc_macro.rs:
# 7| getArg(0): [MethodCallExpr] err.to_compile_error()
# 7| getArgList(): [ArgList] ArgList
# 7| getIdentifier(): [NameRef] to_compile_error
-# 7| getReceiver(): [PathExpr,VariableAccess] err
+# 7| getReceiver(): [VariableAccess] err
# 7| getPath(): [Path] err
# 7| getSegment(): [PathSegment] err
# 7| getIdentifier(): [NameRef] err
@@ -1273,7 +1273,7 @@ proc_macro.rs:
# 10| getInitializer(): [MethodCallExpr] ast.clone()
# 10| getArgList(): [ArgList] ArgList
# 10| getIdentifier(): [NameRef] clone
-# 10| getReceiver(): [PathExpr,VariableAccess] ast
+# 10| getReceiver(): [VariableAccess] ast
# 10| getPath(): [Path] ast
# 10| getSegment(): [PathSegment] ast
# 10| getIdentifier(): [NameRef] ast
@@ -1283,7 +1283,7 @@ proc_macro.rs:
# 11| getExpr(): [AssignmentExpr] ... = ...
# 11| getLhs(): [FieldExpr] ... .ident
# 11| getContainer(): [FieldExpr] new_ast.sig
-# 11| getContainer(): [PathExpr,VariableAccess] new_ast
+# 11| getContainer(): [VariableAccess] new_ast
# 11| getPath(): [Path] new_ast
# 11| getSegment(): [PathSegment] new_ast
# 11| getIdentifier(): [NameRef] new_ast
@@ -1320,14 +1320,14 @@ proc_macro.rs:
# 11| getArg(0): [FormatArgsArg] FormatArgsArg
# 11| getExpr(): [FieldExpr] ... .ident
# 11| getContainer(): [FieldExpr] ast.sig
-# 11| getContainer(): [PathExpr,VariableAccess] ast
+# 11| getContainer(): [VariableAccess] ast
# 11| getPath(): [Path] ast
# 11| getSegment(): [PathSegment] ast
# 11| getIdentifier(): [NameRef] ast
# 11| getIdentifier(): [NameRef] sig
# 11| getIdentifier(): [NameRef] ident
# 11| getArg(1): [FormatArgsArg] FormatArgsArg
-# 11| getExpr(): [PathExpr,VariableAccess] i
+# 11| getExpr(): [VariableAccess] i
# 11| getPath(): [Path] i
# 11| getSegment(): [PathSegment] i
# 11| getIdentifier(): [NameRef] i
@@ -1359,7 +1359,7 @@ proc_macro.rs:
# 11| getIdentifier(): [NameRef] span
# 11| getReceiver(): [FieldExpr] ... .ident
# 11| getContainer(): [FieldExpr] ast.sig
-# 11| getContainer(): [PathExpr,VariableAccess] ast
+# 11| getContainer(): [VariableAccess] ast
# 11| getPath(): [Path] ast
# 11| getSegment(): [PathSegment] ast
# 11| getIdentifier(): [NameRef] ast
@@ -1375,14 +1375,14 @@ proc_macro.rs:
# 11| getIdentifier(): [NameRef] Ident
# 11| getSegment(): [PathSegment] new
# 11| getIdentifier(): [NameRef] new
-# 12| getTailExpr(): [PathExpr,VariableAccess] new_ast
+# 12| getTailExpr(): [VariableAccess] new_ast
# 12| getPath(): [Path] new_ast
# 12| getSegment(): [PathSegment] new_ast
# 12| getIdentifier(): [NameRef] new_ast
# 9| getIdentifier(): [NameRef] map
# 8| getReceiver(): [ParenExpr] (...)
# 8| getExpr(): [RangeExpr] 0..number
-# 8| getEnd(): [PathExpr,VariableAccess] number
+# 8| getEnd(): [VariableAccess] number
# 8| getPath(): [Path] number
# 8| getSegment(): [PathSegment] number
# 8| getIdentifier(): [NameRef] number
@@ -1614,7 +1614,7 @@ proc_macro.rs:
# 16| getInitializer(): [MethodCallExpr] items.quote_into_iter()
# 15| getArgList(): [ArgList] ArgList
# 15| getIdentifier(): [NameRef] quote_into_iter
-# 16| getReceiver(): [PathExpr,VariableAccess] items
+# 16| getReceiver(): [VariableAccess] items
# 16| getPath(): [Path] items
# 16| getSegment(): [PathSegment] items
# 16| getIdentifier(): [NameRef] items
@@ -1625,11 +1625,11 @@ proc_macro.rs:
# 15| getName(): [Name] i
# 15| getStatement(1): [LetStmt] let ... = ...
# 15| getInitializer(): [BinaryExpr] ... | ...
-# 15| getLhs(): [PathExpr,VariableAccess] has_iter
+# 15| getLhs(): [VariableAccess] has_iter
# 15| getPath(): [Path] has_iter
# 15| getSegment(): [PathSegment] has_iter
# 15| getIdentifier(): [NameRef] has_iter
-# 15| getRhs(): [PathExpr,VariableAccess] i
+# 15| getRhs(): [VariableAccess] i
# 15| getPath(): [Path] i
# 15| getSegment(): [PathSegment] i
# 15| getIdentifier(): [NameRef] i
@@ -1646,7 +1646,7 @@ proc_macro.rs:
# 16| getTokenTree(): [TokenTree] TokenTree
# 15| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
# 15| getStatement(3): [LetStmt] let _ = has_iter
-# 15| getInitializer(): [PathExpr,VariableAccess] has_iter
+# 15| getInitializer(): [VariableAccess] has_iter
# 15| getPath(): [Path] has_iter
# 15| getSegment(): [PathSegment] has_iter
# 15| getIdentifier(): [NameRef] has_iter
@@ -1764,7 +1764,7 @@ proc_macro.rs:
# 16| getScrutinee(): [MethodCallExpr] items.next()
# 15| getArgList(): [ArgList] ArgList
# 15| getIdentifier(): [NameRef] next
-# 16| getReceiver(): [PathExpr,VariableAccess] items
+# 16| getReceiver(): [VariableAccess] items
# 16| getPath(): [Path] items
# 16| getSegment(): [PathSegment] items
# 16| getIdentifier(): [NameRef] items
@@ -1772,7 +1772,7 @@ proc_macro.rs:
# 15| getArm(0): [MatchArm] ... => ...
# 15| getExpr(): [CallExpr] ...::RepInterp(...)
# 15| getArgList(): [ArgList] ArgList
-# 15| getArg(0): [PathExpr] _x
+# 15| getArg(0): [VariableAccess] _x
# 15| getPath(): [Path] _x
# 15| getSegment(): [PathSegment] _x
# 15| getIdentifier(): [NameRef] _x
@@ -1876,12 +1876,12 @@ proc_macro.rs:
# 16| getExpr(): [CallExpr] ...::to_tokens(...)
# 16| getArgList(): [ArgList] ArgList
# 16| getArg(0): [RefExpr] &items
-# 16| getExpr(): [PathExpr,VariableAccess] items
+# 16| getExpr(): [VariableAccess] items
# 16| getPath(): [Path] items
# 16| getSegment(): [PathSegment] items
# 16| getIdentifier(): [NameRef] items
# 15| getArg(1): [RefExpr] &mut _s
-# 15| getExpr(): [PathExpr] _s
+# 15| getExpr(): [VariableAccess] _s
# 15| getPath(): [Path] _s
# 15| getSegment(): [PathSegment] _s
# 15| getIdentifier(): [NameRef] _s
@@ -1993,7 +1993,7 @@ proc_macro.rs:
# 15| getIdentifier(): [NameRef] quote_token_with_context
# 16| getTokenTree(): [TokenTree] TokenTree
# 15| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
-# 15| getTailExpr(): [PathExpr] _s
+# 15| getTailExpr(): [VariableAccess] _s
# 15| getPath(): [Path] _s
# 15| getSegment(): [PathSegment] _s
# 15| getIdentifier(): [NameRef] _s
@@ -2040,7 +2040,7 @@ proc_macro.rs:
# 22| getMacroCallExpansion(): [MatchExpr] match ... { ... }
# 22| getScrutinee(): [CallExpr] ...::parse::<...>(...)
# 22| getArgList(): [ArgList] ArgList
-# 22| getArg(0): [PathExpr,VariableAccess] item
+# 22| getArg(0): [VariableAccess] item
# 22| getPath(): [Path] item
# 22| getSegment(): [PathSegment] item
# 22| getIdentifier(): [NameRef] item
@@ -2062,7 +2062,7 @@ proc_macro.rs:
# 22| getIdentifier(): [NameRef] parse
# 22| getMatchArmList(): [MatchArmList] MatchArmList
# 22| getArm(0): [MatchArm] ... => data
-# 22| getExpr(): [PathExpr,VariableAccess] data
+# 22| getExpr(): [VariableAccess] data
# 22| getPath(): [Path] data
# 22| getSegment(): [PathSegment] data
# 22| getIdentifier(): [NameRef] data
@@ -2088,7 +2088,7 @@ proc_macro.rs:
# 22| getArg(0): [MethodCallExpr] err.to_compile_error()
# 22| getArgList(): [ArgList] ArgList
# 22| getIdentifier(): [NameRef] to_compile_error
-# 22| getReceiver(): [PathExpr,VariableAccess] err
+# 22| getReceiver(): [VariableAccess] err
# 22| getPath(): [Path] err
# 22| getSegment(): [PathSegment] err
# 22| getIdentifier(): [NameRef] err
@@ -2123,7 +2123,7 @@ proc_macro.rs:
# 23| getInitializer(): [MethodCallExpr] ast.clone()
# 23| getArgList(): [ArgList] ArgList
# 23| getIdentifier(): [NameRef] clone
-# 23| getReceiver(): [PathExpr,VariableAccess] ast
+# 23| getReceiver(): [VariableAccess] ast
# 23| getPath(): [Path] ast
# 23| getSegment(): [PathSegment] ast
# 23| getIdentifier(): [NameRef] ast
@@ -2133,7 +2133,7 @@ proc_macro.rs:
# 24| getExpr(): [AssignmentExpr] ... = ...
# 24| getLhs(): [FieldExpr] ... .ident
# 24| getContainer(): [FieldExpr] new_ast.sig
-# 24| getContainer(): [PathExpr,VariableAccess] new_ast
+# 24| getContainer(): [VariableAccess] new_ast
# 24| getPath(): [Path] new_ast
# 24| getSegment(): [PathSegment] new_ast
# 24| getIdentifier(): [NameRef] new_ast
@@ -2170,7 +2170,7 @@ proc_macro.rs:
# 24| getArg(0): [FormatArgsArg] FormatArgsArg
# 24| getExpr(): [FieldExpr] ... .ident
# 24| getContainer(): [FieldExpr] ast.sig
-# 24| getContainer(): [PathExpr,VariableAccess] ast
+# 24| getContainer(): [VariableAccess] ast
# 24| getPath(): [Path] ast
# 24| getSegment(): [PathSegment] ast
# 24| getIdentifier(): [NameRef] ast
@@ -2203,7 +2203,7 @@ proc_macro.rs:
# 24| getIdentifier(): [NameRef] span
# 24| getReceiver(): [FieldExpr] ... .ident
# 24| getContainer(): [FieldExpr] ast.sig
-# 24| getContainer(): [PathExpr,VariableAccess] ast
+# 24| getContainer(): [VariableAccess] ast
# 24| getPath(): [Path] ast
# 24| getSegment(): [PathSegment] ast
# 24| getIdentifier(): [NameRef] ast
@@ -2317,12 +2317,12 @@ proc_macro.rs:
# 26| getExpr(): [CallExpr] ...::to_tokens(...)
# 26| getArgList(): [ArgList] ArgList
# 26| getArg(0): [RefExpr] &ast
-# 26| getExpr(): [PathExpr,VariableAccess] ast
+# 26| getExpr(): [VariableAccess] ast
# 26| getPath(): [Path] ast
# 26| getSegment(): [PathSegment] ast
# 26| getIdentifier(): [NameRef] ast
# 25| getArg(1): [RefExpr] &mut _s
-# 25| getExpr(): [PathExpr] _s
+# 25| getExpr(): [VariableAccess] _s
# 25| getPath(): [Path] _s
# 25| getSegment(): [PathSegment] _s
# 25| getIdentifier(): [NameRef] _s
@@ -2362,12 +2362,12 @@ proc_macro.rs:
# 27| getExpr(): [CallExpr] ...::to_tokens(...)
# 27| getArgList(): [ArgList] ArgList
# 27| getArg(0): [RefExpr] &new_ast
-# 27| getExpr(): [PathExpr,VariableAccess] new_ast
+# 27| getExpr(): [VariableAccess] new_ast
# 27| getPath(): [Path] new_ast
# 27| getSegment(): [PathSegment] new_ast
# 27| getIdentifier(): [NameRef] new_ast
# 25| getArg(1): [RefExpr] &mut _s
-# 25| getExpr(): [PathExpr] _s
+# 25| getExpr(): [VariableAccess] _s
# 25| getPath(): [Path] _s
# 25| getSegment(): [PathSegment] _s
# 25| getIdentifier(): [NameRef] _s
@@ -2424,7 +2424,7 @@ proc_macro.rs:
# 25| getIdentifier(): [NameRef] quote_token_with_context
# 27| getTokenTree(): [TokenTree] TokenTree
# 25| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
-# 25| getTailExpr(): [PathExpr] _s
+# 25| getTailExpr(): [VariableAccess] _s
# 25| getPath(): [Path] _s
# 25| getSegment(): [PathSegment] _s
# 25| getIdentifier(): [NameRef] _s
@@ -2504,7 +2504,7 @@ proc_macro.rs:
# 38| getMacroCallExpansion(): [MatchExpr] match ... { ... }
# 38| getScrutinee(): [CallExpr] ...::parse::<...>(...)
# 38| getArgList(): [ArgList] ArgList
-# 38| getArg(0): [PathExpr,VariableAccess] input
+# 38| getArg(0): [VariableAccess] input
# 38| getPath(): [Path] input
# 38| getSegment(): [PathSegment] input
# 38| getIdentifier(): [NameRef] input
@@ -2526,7 +2526,7 @@ proc_macro.rs:
# 38| getIdentifier(): [NameRef] parse
# 38| getMatchArmList(): [MatchArmList] MatchArmList
# 38| getArm(0): [MatchArm] ... => data
-# 38| getExpr(): [PathExpr,VariableAccess] data
+# 38| getExpr(): [VariableAccess] data
# 38| getPath(): [Path] data
# 38| getSegment(): [PathSegment] data
# 38| getIdentifier(): [NameRef] data
@@ -2552,7 +2552,7 @@ proc_macro.rs:
# 38| getArg(0): [MethodCallExpr] err.to_compile_error()
# 38| getArgList(): [ArgList] ArgList
# 38| getIdentifier(): [NameRef] to_compile_error
-# 38| getReceiver(): [PathExpr,VariableAccess] err
+# 38| getReceiver(): [VariableAccess] err
# 38| getPath(): [Path] err
# 38| getSegment(): [PathSegment] err
# 38| getIdentifier(): [NameRef] err
@@ -2586,7 +2586,7 @@ proc_macro.rs:
# 39| getStatement(1): [LetStmt] let ... = ...
# 39| getInitializer(): [RefExpr] &...
# 39| getExpr(): [FieldExpr] ast.ident
-# 39| getContainer(): [PathExpr,VariableAccess] ast
+# 39| getContainer(): [VariableAccess] ast
# 39| getPath(): [Path] ast
# 39| getSegment(): [PathSegment] ast
# 39| getIdentifier(): [NameRef] ast
@@ -2623,7 +2623,7 @@ proc_macro.rs:
# 40| getTokenTree(): [TokenTree] TokenTree
# 40| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
# 40| getArg(0): [FormatArgsArg] FormatArgsArg
-# 40| getExpr(): [PathExpr,VariableAccess] name
+# 40| getExpr(): [VariableAccess] name
# 40| getPath(): [Path] name
# 40| getSegment(): [PathSegment] name
# 40| getIdentifier(): [NameRef] name
@@ -2652,7 +2652,7 @@ proc_macro.rs:
# 40| getArg(1): [MethodCallExpr] name.span()
# 40| getArgList(): [ArgList] ArgList
# 40| getIdentifier(): [NameRef] span
-# 40| getReceiver(): [PathExpr,VariableAccess] name
+# 40| getReceiver(): [VariableAccess] name
# 40| getPath(): [Path] name
# 40| getSegment(): [PathSegment] name
# 40| getIdentifier(): [NameRef] name
@@ -2776,7 +2776,7 @@ proc_macro.rs:
# 42| getExpr(): [CallExpr] ...::push_ident(...)
# 42| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -2812,12 +2812,12 @@ proc_macro.rs:
# 42| getExpr(): [CallExpr] ...::to_tokens(...)
# 42| getArgList(): [ArgList] ArgList
# 42| getArg(0): [RefExpr] &const_ident
-# 42| getExpr(): [PathExpr,VariableAccess] const_ident
+# 42| getExpr(): [VariableAccess] const_ident
# 42| getPath(): [Path] const_ident
# 42| getSegment(): [PathSegment] const_ident
# 42| getIdentifier(): [NameRef] const_ident
# 41| getArg(1): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -2867,7 +2867,7 @@ proc_macro.rs:
# 41| getExpr(): [CallExpr] ...::push_colon(...)
# 41| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -2906,7 +2906,7 @@ proc_macro.rs:
# 42| getExpr(): [CallExpr] ...::push_ident(...)
# 42| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -2952,7 +2952,7 @@ proc_macro.rs:
# 41| getExpr(): [CallExpr] ...::push_eq(...)
# 41| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -2991,7 +2991,7 @@ proc_macro.rs:
# 42| getExpr(): [CallExpr] ...::parse(...)
# 42| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3037,7 +3037,7 @@ proc_macro.rs:
# 41| getExpr(): [CallExpr] ...::push_semi(...)
# 41| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3076,7 +3076,7 @@ proc_macro.rs:
# 44| getExpr(): [CallExpr] ...::push_ident(...)
# 44| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3122,7 +3122,7 @@ proc_macro.rs:
# 44| getExpr(): [CallExpr] ...::push_ident(...)
# 44| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3168,7 +3168,7 @@ proc_macro.rs:
# 44| getExpr(): [CallExpr] ...::push_ident(...)
# 44| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3204,12 +3204,12 @@ proc_macro.rs:
# 44| getExpr(): [CallExpr] ...::to_tokens(...)
# 44| getArgList(): [ArgList] ArgList
# 44| getArg(0): [RefExpr] &name
-# 44| getExpr(): [PathExpr,VariableAccess] name
+# 44| getExpr(): [VariableAccess] name
# 44| getPath(): [Path] name
# 44| getSegment(): [PathSegment] name
# 44| getIdentifier(): [NameRef] name
# 41| getArg(1): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3259,7 +3259,7 @@ proc_macro.rs:
# 45| getExpr(): [CallExpr] ...::push_group(...)
# 45| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3384,7 +3384,7 @@ proc_macro.rs:
# 45| getExpr(): [CallExpr] ...::push_ident(...)
# 45| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3430,7 +3430,7 @@ proc_macro.rs:
# 45| getExpr(): [CallExpr] ...::push_ident(...)
# 45| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3476,7 +3476,7 @@ proc_macro.rs:
# 41| getExpr(): [CallExpr] ...::push_group(...)
# 41| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3552,7 +3552,7 @@ proc_macro.rs:
# 41| getExpr(): [CallExpr] ...::push_rarrow(...)
# 41| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3591,7 +3591,7 @@ proc_macro.rs:
# 45| getExpr(): [CallExpr] ...::push_ident(...)
# 45| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3637,7 +3637,7 @@ proc_macro.rs:
# 46| getExpr(): [CallExpr] ...::push_group(...)
# 46| getArgList(): [ArgList] ArgList
# 41| getArg(0): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3687,12 +3687,12 @@ proc_macro.rs:
# 46| getExpr(): [CallExpr] ...::to_tokens(...)
# 46| getArgList(): [ArgList] ArgList
# 46| getArg(0): [RefExpr] &const_ident
-# 46| getExpr(): [PathExpr,VariableAccess] const_ident
+# 46| getExpr(): [VariableAccess] const_ident
# 46| getPath(): [Path] const_ident
# 46| getSegment(): [PathSegment] const_ident
# 46| getIdentifier(): [NameRef] const_ident
# 41| getArg(1): [RefExpr] &mut _s
-# 41| getExpr(): [PathExpr] _s
+# 41| getExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3706,7 +3706,7 @@ proc_macro.rs:
# 41| getIdentifier(): [NameRef] ToTokens
# 41| getSegment(): [PathSegment] to_tokens
# 41| getIdentifier(): [NameRef] to_tokens
-# 41| getTailExpr(): [PathExpr] _s
+# 41| getTailExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3752,7 +3752,7 @@ proc_macro.rs:
# 41| getIdentifier(): [NameRef] quote_token_with_context
# 45| getTokenTree(): [TokenTree] TokenTree
# 41| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
-# 41| getTailExpr(): [PathExpr] _s
+# 41| getTailExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
@@ -3798,7 +3798,7 @@ proc_macro.rs:
# 41| getIdentifier(): [NameRef] quote_token_with_context
# 44| getTokenTree(): [TokenTree] TokenTree
# 41| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
-# 41| getTailExpr(): [PathExpr] _s
+# 41| getTailExpr(): [VariableAccess] _s
# 41| getPath(): [Path] _s
# 41| getSegment(): [PathSegment] _s
# 41| getIdentifier(): [NameRef] _s
diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs
index d60f12b43d7..c0f37bcd18e 100644
--- a/rust/ql/test/library-tests/path-resolution/main.rs
+++ b/rust/ql/test/library-tests/path-resolution/main.rs
@@ -798,7 +798,7 @@ mod patterns {
Some(y) => { // $ item=Some
None // $ item=None
}
- None => // $ MISSING: item=None
+ None => // $ item=None
None // $ item=None
};
match y {
@@ -827,7 +827,7 @@ mod patterns {
_ => 0
};
match x {
- Some(z) => z, // $ item=Some $ MISSING: item=constz
+ Some(z) => z, // $ item=Some item=constz
_ => 0
};
}
diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected
index c460fea7f5b..20c7e7799be 100644
--- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected
+++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected
@@ -405,6 +405,7 @@ resolvePath
| main.rs:797:24:797:26 | i32 | {EXTERNAL LOCATION} | struct i32 |
| main.rs:798:13:798:16 | Some | {EXTERNAL LOCATION} | Some |
| main.rs:799:17:799:20 | None | {EXTERNAL LOCATION} | None |
+| main.rs:801:13:801:16 | None | {EXTERNAL LOCATION} | None |
| main.rs:802:17:802:20 | None | {EXTERNAL LOCATION} | None |
| main.rs:811:19:811:29 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
| main.rs:811:26:811:28 | i32 | {EXTERNAL LOCATION} | struct i32 |
@@ -413,6 +414,8 @@ resolvePath
| main.rs:823:17:823:20 | Some | {EXTERNAL LOCATION} | Some |
| main.rs:825:13:825:16 | Some | {EXTERNAL LOCATION} | Some |
| main.rs:830:13:830:16 | Some | {EXTERNAL LOCATION} | Some |
+| main.rs:830:18:830:18 | z | main.rs:817:5:819:12 | Const |
+| main.rs:830:24:830:24 | z | main.rs:817:5:819:12 | Const |
| main.rs:837:5:837:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:837:5:837:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
| main.rs:837:5:837:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.ql b/rust/ql/test/library-tests/path-resolution/path-resolution.ql
index 0fe49a8e386..f7955929b83 100644
--- a/rust/ql/test/library-tests/path-resolution/path-resolution.ql
+++ b/rust/ql/test/library-tests/path-resolution/path-resolution.ql
@@ -5,7 +5,7 @@ import TestUtils
query predicate mod(Module m) { toBeTested(m) }
-query predicate resolvePath(Path p, ItemNode i) {
+query predicate resolvePath(PathExt p, ItemNode i) {
toBeTested(p) and
not p.isFromMacroExpansion() and
i = resolvePath(p)
diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected
index 3efada83369..f93586d373b 100644
--- a/rust/ql/test/library-tests/variables/Cfg.expected
+++ b/rust/ql/test/library-tests/variables/Cfg.expected
@@ -1865,6 +1865,7 @@ edges
| main.rs:794:13:794:19 | Some(...) | main.rs:796:13:796:13 | _ | no-match |
| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z | |
| main.rs:794:18:794:18 | z | main.rs:795:17:795:17 | z | match |
+| main.rs:794:18:794:18 | z | main.rs:796:13:796:13 | _ | no-match |
| main.rs:795:17:795:17 | z | main.rs:793:9:797:9 | match x { ... } | |
| main.rs:796:13:796:13 | _ | main.rs:796:18:796:18 | 0 | match |
| main.rs:796:18:796:18 | 0 | main.rs:793:9:797:9 | match x { ... } | |
diff --git a/rust/ql/test/library-tests/variables/Ssa.expected b/rust/ql/test/library-tests/variables/Ssa.expected
index e6075a0cb3f..0acf3e94c5b 100644
--- a/rust/ql/test/library-tests/variables/Ssa.expected
+++ b/rust/ql/test/library-tests/variables/Ssa.expected
@@ -198,11 +198,11 @@ definition
| main.rs:752:5:752:13 | x | main.rs:745:13:745:13 | x |
| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x |
| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y |
+| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne |
| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias |
| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test |
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x |
| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x |
-| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z |
read
| main.rs:5:14:5:14 | s | main.rs:5:14:5:14 | s | main.rs:7:20:7:20 | s |
| main.rs:10:14:10:14 | i | main.rs:10:14:10:14 | i | main.rs:12:20:12:20 | i |
@@ -413,12 +413,12 @@ read
| main.rs:752:5:752:13 | x | main.rs:745:13:745:13 | x | main.rs:753:15:753:15 | x |
| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | main.rs:761:19:761:19 | x |
| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y |
+| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | main.rs:770:17:770:20 | N0ne |
| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | main.rs:779:13:779:22 | test_alias |
| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test |
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x |
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:793:15:793:15 | x |
| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x |
-| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z | main.rs:795:17:795:17 | z |
firstRead
| main.rs:5:14:5:14 | s | main.rs:5:14:5:14 | s | main.rs:7:20:7:20 | s |
| main.rs:10:14:10:14 | i | main.rs:10:14:10:14 | i | main.rs:12:20:12:20 | i |
@@ -587,11 +587,11 @@ firstRead
| main.rs:752:5:752:13 | x | main.rs:745:13:745:13 | x | main.rs:753:15:753:15 | x |
| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | main.rs:761:19:761:19 | x |
| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y |
+| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | main.rs:770:17:770:20 | N0ne |
| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | main.rs:779:13:779:22 | test_alias |
| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test |
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x |
| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x |
-| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z | main.rs:795:17:795:17 | z |
adjacentReads
| main.rs:27:5:27:6 | x2 | main.rs:25:13:25:14 | x2 | main.rs:28:15:28:16 | x2 | main.rs:29:10:29:11 | x2 |
| main.rs:41:9:41:10 | x3 | main.rs:41:9:41:10 | x3 | main.rs:42:15:42:16 | x3 | main.rs:44:9:44:10 | x3 |
diff --git a/rust/ql/test/library-tests/variables/main.rs b/rust/ql/test/library-tests/variables/main.rs
index b8a3187421f..fe13f89b177 100644
--- a/rust/ql/test/library-tests/variables/main.rs
+++ b/rust/ql/test/library-tests/variables/main.rs
@@ -767,7 +767,7 @@ mod patterns {
};
match y { // $ read_access=y1
N0ne => // n0ne
- N0ne // $ MISSING: read_access=n0ne
+ N0ne // $ read_access=n0ne
}
}
@@ -792,7 +792,7 @@ mod patterns {
};
match x { // $ read_access=x1
Some(z) =>
- z, // $ SPURIOUS: read_access=z
+ z,
_ => 0
};
}
diff --git a/rust/ql/test/library-tests/variables/variables.expected b/rust/ql/test/library-tests/variables/variables.expected
index 42d02b51419..ea360357d97 100644
--- a/rust/ql/test/library-tests/variables/variables.expected
+++ b/rust/ql/test/library-tests/variables/variables.expected
@@ -145,11 +145,11 @@ variable
| main.rs:759:13:759:13 | x |
| main.rs:760:13:760:13 | y |
| main.rs:762:18:762:18 | y |
+| main.rs:769:13:769:16 | N0ne |
| main.rs:776:13:776:22 | test_alias |
| main.rs:778:13:778:16 | test |
| main.rs:787:13:787:13 | x |
| main.rs:789:18:789:18 | x |
-| main.rs:794:18:794:18 | z |
variableAccess
| main.rs:7:20:7:20 | s | main.rs:5:14:5:14 | s |
| main.rs:12:20:12:20 | i | main.rs:10:14:10:14 | i |
@@ -374,12 +374,12 @@ variableAccess
| main.rs:753:15:753:15 | x | main.rs:745:13:745:13 | x |
| main.rs:761:19:761:19 | x | main.rs:759:13:759:13 | x |
| main.rs:768:15:768:15 | y | main.rs:760:13:760:13 | y |
+| main.rs:770:17:770:20 | N0ne | main.rs:769:13:769:16 | N0ne |
| main.rs:779:13:779:22 | test_alias | main.rs:776:13:776:22 | test_alias |
| main.rs:780:9:780:12 | test | main.rs:778:13:778:16 | test |
| main.rs:788:15:788:15 | x | main.rs:787:13:787:13 | x |
| main.rs:790:20:790:20 | x | main.rs:789:18:789:18 | x |
| main.rs:793:15:793:15 | x | main.rs:787:13:787:13 | x |
-| main.rs:795:17:795:17 | z | main.rs:794:18:794:18 | z |
variableWriteAccess
| main.rs:27:5:27:6 | x2 | main.rs:25:13:25:14 | x2 |
| main.rs:29:5:29:6 | x2 | main.rs:25:13:25:14 | x2 |
@@ -594,12 +594,12 @@ variableReadAccess
| main.rs:753:15:753:15 | x | main.rs:745:13:745:13 | x |
| main.rs:761:19:761:19 | x | main.rs:759:13:759:13 | x |
| main.rs:768:15:768:15 | y | main.rs:760:13:760:13 | y |
+| main.rs:770:17:770:20 | N0ne | main.rs:769:13:769:16 | N0ne |
| main.rs:779:13:779:22 | test_alias | main.rs:776:13:776:22 | test_alias |
| main.rs:780:9:780:12 | test | main.rs:778:13:778:16 | test |
| main.rs:788:15:788:15 | x | main.rs:787:13:787:13 | x |
| main.rs:790:20:790:20 | x | main.rs:789:18:789:18 | x |
| main.rs:793:15:793:15 | x | main.rs:787:13:787:13 | x |
-| main.rs:795:17:795:17 | z | main.rs:794:18:794:18 | z |
variableInitializer
| main.rs:20:9:20:10 | x1 | main.rs:20:14:20:16 | "a" |
| main.rs:25:13:25:14 | x2 | main.rs:25:18:25:18 | 4 |
From 7d746d4e3f383f5e3a1d22d682b547d65dfa8b4a Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Fri, 14 Nov 2025 08:22:15 +0100
Subject: [PATCH 25/70] C#: Move .NET 10 RC2 basic integration test all
platforms folder.
---
.../{windows/dotnet_10_rc2 => all-platforms/dotnet_10}/Program.cs | 0
.../dotnet_10_rc2 => all-platforms/dotnet_10}/dotnet_build.csproj | 0
.../dotnet_10_rc2 => all-platforms/dotnet_10}/global.json | 0
.../{windows/dotnet_10_rc2 => all-platforms/dotnet_10}/test.py | 0
4 files changed, 0 insertions(+), 0 deletions(-)
rename csharp/ql/integration-tests/{windows/dotnet_10_rc2 => all-platforms/dotnet_10}/Program.cs (100%)
rename csharp/ql/integration-tests/{windows/dotnet_10_rc2 => all-platforms/dotnet_10}/dotnet_build.csproj (100%)
rename csharp/ql/integration-tests/{windows/dotnet_10_rc2 => all-platforms/dotnet_10}/global.json (100%)
rename csharp/ql/integration-tests/{windows/dotnet_10_rc2 => all-platforms/dotnet_10}/test.py (100%)
diff --git a/csharp/ql/integration-tests/windows/dotnet_10_rc2/Program.cs b/csharp/ql/integration-tests/all-platforms/dotnet_10/Program.cs
similarity index 100%
rename from csharp/ql/integration-tests/windows/dotnet_10_rc2/Program.cs
rename to csharp/ql/integration-tests/all-platforms/dotnet_10/Program.cs
diff --git a/csharp/ql/integration-tests/windows/dotnet_10_rc2/dotnet_build.csproj b/csharp/ql/integration-tests/all-platforms/dotnet_10/dotnet_build.csproj
similarity index 100%
rename from csharp/ql/integration-tests/windows/dotnet_10_rc2/dotnet_build.csproj
rename to csharp/ql/integration-tests/all-platforms/dotnet_10/dotnet_build.csproj
diff --git a/csharp/ql/integration-tests/windows/dotnet_10_rc2/global.json b/csharp/ql/integration-tests/all-platforms/dotnet_10/global.json
similarity index 100%
rename from csharp/ql/integration-tests/windows/dotnet_10_rc2/global.json
rename to csharp/ql/integration-tests/all-platforms/dotnet_10/global.json
diff --git a/csharp/ql/integration-tests/windows/dotnet_10_rc2/test.py b/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py
similarity index 100%
rename from csharp/ql/integration-tests/windows/dotnet_10_rc2/test.py
rename to csharp/ql/integration-tests/all-platforms/dotnet_10/test.py
From d7545f21cb07c8b9e8bf4b3ccaa976e5e9a22275 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Fri, 14 Nov 2025 08:23:14 +0100
Subject: [PATCH 26/70] C#: Enable tests for all platforms and use .NET 10
instead of .NET 10 RC 2.
---
csharp/ql/integration-tests/all-platforms/dotnet_10/global.json | 2 +-
csharp/ql/integration-tests/all-platforms/dotnet_10/test.py | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/csharp/ql/integration-tests/all-platforms/dotnet_10/global.json b/csharp/ql/integration-tests/all-platforms/dotnet_10/global.json
index e870e2cf7bd..481e95ec7be 100644
--- a/csharp/ql/integration-tests/all-platforms/dotnet_10/global.json
+++ b/csharp/ql/integration-tests/all-platforms/dotnet_10/global.json
@@ -1,5 +1,5 @@
{
"sdk": {
- "version": "10.0.100-rc.2.25502.107"
+ "version": "10.0.100"
}
}
diff --git a/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py b/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py
index 00905b67cd4..35612501c3c 100644
--- a/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py
+++ b/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py
@@ -1,6 +1,5 @@
import os
import runs_on
-@runs_on.windows
def test(codeql, csharp):
codeql.database.create()
From ed92352faf889fc5ed9c8fb8efa53f52655c87d5 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Fri, 14 Nov 2025 08:23:47 +0100
Subject: [PATCH 27/70] C#: Remove the linux specific .NET 10 RC 2 test.
---
.../integration-tests/linux/dotnet_10_rc2/Program.cs | 1 -
.../linux/dotnet_10_rc2/dotnet_build.csproj | 10 ----------
.../integration-tests/linux/dotnet_10_rc2/global.json | 5 -----
.../ql/integration-tests/linux/dotnet_10_rc2/test.py | 6 ------
4 files changed, 22 deletions(-)
delete mode 100644 csharp/ql/integration-tests/linux/dotnet_10_rc2/Program.cs
delete mode 100644 csharp/ql/integration-tests/linux/dotnet_10_rc2/dotnet_build.csproj
delete mode 100644 csharp/ql/integration-tests/linux/dotnet_10_rc2/global.json
delete mode 100644 csharp/ql/integration-tests/linux/dotnet_10_rc2/test.py
diff --git a/csharp/ql/integration-tests/linux/dotnet_10_rc2/Program.cs b/csharp/ql/integration-tests/linux/dotnet_10_rc2/Program.cs
deleted file mode 100644
index bd44629f7e2..00000000000
--- a/csharp/ql/integration-tests/linux/dotnet_10_rc2/Program.cs
+++ /dev/null
@@ -1 +0,0 @@
-Console.WriteLine($"{string.Join(",", args)} ");
diff --git a/csharp/ql/integration-tests/linux/dotnet_10_rc2/dotnet_build.csproj b/csharp/ql/integration-tests/linux/dotnet_10_rc2/dotnet_build.csproj
deleted file mode 100644
index dfb40caafcf..00000000000
--- a/csharp/ql/integration-tests/linux/dotnet_10_rc2/dotnet_build.csproj
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
- Exe
- net10.0
- enable
- enable
-
-
-
diff --git a/csharp/ql/integration-tests/linux/dotnet_10_rc2/global.json b/csharp/ql/integration-tests/linux/dotnet_10_rc2/global.json
deleted file mode 100644
index e870e2cf7bd..00000000000
--- a/csharp/ql/integration-tests/linux/dotnet_10_rc2/global.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "sdk": {
- "version": "10.0.100-rc.2.25502.107"
- }
-}
diff --git a/csharp/ql/integration-tests/linux/dotnet_10_rc2/test.py b/csharp/ql/integration-tests/linux/dotnet_10_rc2/test.py
deleted file mode 100644
index 148626b1cb8..00000000000
--- a/csharp/ql/integration-tests/linux/dotnet_10_rc2/test.py
+++ /dev/null
@@ -1,6 +0,0 @@
-import os
-import runs_on
-
-@runs_on.linux
-def test(codeql, csharp):
- codeql.database.create()
From 8df57d81a0c6ce66f616723218f0e552fe9c1792 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Fri, 14 Nov 2025 11:13:26 +0100
Subject: [PATCH 28/70] C#: Add basic buildless test for .NET 10.
---
.../ql/integration-tests/all-platforms/dotnet_10/test.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py b/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py
index 35612501c3c..903d3430061 100644
--- a/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py
+++ b/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py
@@ -1,5 +1,5 @@
-import os
-import runs_on
-
-def test(codeql, csharp):
+def test1(codeql, csharp):
codeql.database.create()
+
+def test2(codeql, csharp):
+ codeql.database.create(build_mode="none")
From 0daee6fbf2d9fa1d60afbcdc3123b4a3d6caac8a Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Tue, 18 Nov 2025 14:54:40 +0100
Subject: [PATCH 29/70] C#: Specifically download .NET for Arm architecture.
---
.../DotNet.cs | 28 +++++++++++++------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs
index 4a4fd651a5b..761062bd6af 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs
@@ -254,7 +254,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
else
{
var dotnetInstallPath = actions.PathCombine(tempWorkingDirectory, ".dotnet", "dotnet-install.sh");
-
var downloadDotNetInstallSh = BuildScript.DownloadFile(
"https://dot.net/v1/dotnet-install.sh",
dotnetInstallPath,
@@ -269,14 +268,25 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
prelude = downloadDotNetInstallSh & chmod.Script;
postlude = shouldCleanUp ? BuildScript.DeleteFile(dotnetInstallPath) : BuildScript.Success;
- getInstall = version => new CommandBuilder(actions).
- RunCommand(dotnetInstallPath).
- Argument("--channel").
- Argument("release").
- Argument("--version").
- Argument(version).
- Argument("--install-dir").
- Argument(path).Script;
+ getInstall = version =>
+ {
+ var cb = new CommandBuilder(actions).
+ RunCommand(dotnetInstallPath).
+ Argument("--channel").
+ Argument("release").
+ Argument("--version").
+ Argument(version);
+
+ // Request ARM64 architecture on Apple Silicon machines
+ if (actions.IsRunningOnAppleSilicon())
+ {
+ cb.Argument("--architecture").
+ Argument("arm64");
+ }
+
+ return cb.Argument("--install-dir").
+ Argument(path).Script;
+ };
}
var dotnetInfo = new CommandBuilder(actions).
From fba496f911ff146822f85fa6c55cfcc66430dac1 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Tue, 18 Nov 2025 16:31:09 +0100
Subject: [PATCH 30/70] C#: Add proper .NET environment for dotnet info and
list-sdks and streamline the minimal dotnet environment.
---
.../Semmle.Autobuild.CSharp/DotNetRule.cs | 6 +-----
.../DotNet.cs | 7 +++++--
.../DotNetCliInvoker.cs | 11 +++++++----
.../IDotNetCliInvoker.cs | 13 +++++++++++++
4 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs
index a29079d205b..a396ab751ea 100644
--- a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs
+++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs
@@ -84,11 +84,7 @@ namespace Semmle.Autobuild.CSharp
var temp = FileUtils.GetTemporaryWorkingDirectory(builder.Actions.GetEnvironmentVariable, builder.Options.Language.UpperCaseName, out var shouldCleanUp);
return DotNet.WithDotNet(builder.Actions, builder.Logger, builder.Paths.Select(x => x.Item1), temp, shouldCleanUp, ensureDotNetAvailable, builder.Options.DotNetVersion, installDir =>
{
- var env = new Dictionary
- {
- { "DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "true" },
- { "MSBUILDDISABLENODEREUSE", "1" }
- };
+ var env = DotNet.MinimalEnvironment.ToDictionary();
if (installDir is not null)
{
// The installation succeeded, so use the newly installed .NET
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs
index 761062bd6af..7bc79238415 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;
@@ -140,6 +141,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
// The version number should be kept in sync with the version .NET version used for building the application.
public const string LatestDotNetSdkVersion = "9.0.300";
+ public static ReadOnlyDictionary MinimalEnvironment => IDotNetCliInvoker.MinimalEnvironment;
+
///
/// Returns a script for downloading relevant versions of the
/// .NET SDK. The SDK(s) will be installed at installDir
@@ -289,7 +292,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
};
}
- var dotnetInfo = new CommandBuilder(actions).
+ var dotnetInfo = new CommandBuilder(actions, environment: MinimalEnvironment).
RunCommand(actions.PathCombine(path, "dotnet")).
Argument("--info").Script;
@@ -321,7 +324,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private static BuildScript GetInstalledSdksScript(IBuildActions actions)
{
- var listSdks = new CommandBuilder(actions, silent: true).
+ var listSdks = new CommandBuilder(actions, silent: true, environment: MinimalEnvironment).
RunCommand("dotnet").
Argument("--list-sdks");
return listSdks.Script;
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs
index e3efce09481..45f69a1fdfc 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Diagnostics;
using Semmle.Util;
using Semmle.Util.Logging;
@@ -36,10 +37,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
startInfo.WorkingDirectory = workingDirectory;
}
- // Set the .NET CLI language to English to avoid localized output.
- startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] = "en";
- startInfo.EnvironmentVariables["MSBUILDDISABLENODEREUSE"] = "1";
- startInfo.EnvironmentVariables["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "true";
+
+ // Set minimal environment variables.
+ foreach (var kvp in IDotNetCliInvoker.MinimalEnvironment)
+ {
+ startInfo.EnvironmentVariables[kvp.Key] = kvp.Value;
+ }
// Configure the proxy settings, if applicable.
if (this.proxy != null)
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs
index 89631ffa861..6e80e1cb2bf 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Collections.ObjectModel;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
@@ -9,6 +10,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
///
string Exec { get; }
+ ///
+ /// A minimal environment for running the .NET CLI.
+ ///
+ /// The .NET CLI language is set to English to avoid localized output.
+ ///
+ static ReadOnlyDictionary MinimalEnvironment { get; } = new(new Dictionary
+ {
+ {"DOTNET_CLI_UI_LANGUAGE", "en"},
+ {"MSBUILDDISABLENODEREUSE", "1"},
+ {"DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "true"}
+ });
+
///
/// Execute `dotnet ` and return true if the command succeeded, otherwise false.
/// If `silent` is true the output of the command is logged as `debug` otherwise as `info`.
From 34de2f53180455cc4f2cfbdb6fbfba709e50c5ba Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Wed, 19 Nov 2025 10:48:25 +0100
Subject: [PATCH 31/70] C#: Update linux integration tests (as we have added
CLI preferred language as english).
---
.../linux/compiler_args/CompilerArgs.expected | 387 +++++++++---------
1 file changed, 194 insertions(+), 193 deletions(-)
diff --git a/csharp/ql/integration-tests/linux/compiler_args/CompilerArgs.expected b/csharp/ql/integration-tests/linux/compiler_args/CompilerArgs.expected
index cb1f6163d71..ee3063b3c2b 100644
--- a/csharp/ql/integration-tests/linux/compiler_args/CompilerArgs.expected
+++ b/csharp/ql/integration-tests/linux/compiler_args/CompilerArgs.expected
@@ -7,196 +7,197 @@
| 6 | /errorreport:prompt |
| 7 | /warn:9 |
| 8 | /define:TRACE;DEBUG;NET;NET9_0;NETCOREAPP;NET5_0_OR_GREATER;NET6_0_OR_GREATER;NET7_0_OR_GREATER;NET8_0_OR_GREATER;NET9_0_OR_GREATER;NETCOREAPP1_0_OR_GREATER;NETCOREAPP1_1_OR_GREATER;NETCOREAPP2_0_OR_GREATER;NETCOREAPP2_1_OR_GREATER;NETCOREAPP2_2_OR_GREATER;NETCOREAPP3_0_OR_GREATER;NETCOREAPP3_1_OR_GREATER |
-| 9 | /highentropyva+ |
-| 10 | /nullable:enable |
-| 11 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.CSharp.dll |
-| 12 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.VisualBasic.Core.dll |
-| 13 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.VisualBasic.dll |
-| 14 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.Win32.Primitives.dll |
-| 15 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.Win32.Registry.dll |
-| 16 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/mscorlib.dll |
-| 17 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/netstandard.dll |
-| 18 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.AppContext.dll |
-| 19 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Buffers.dll |
-| 20 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.Concurrent.dll |
-| 21 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.dll |
-| 22 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.Immutable.dll |
-| 23 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.NonGeneric.dll |
-| 24 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.Specialized.dll |
-| 25 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.Annotations.dll |
-| 26 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.DataAnnotations.dll |
-| 27 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.dll |
-| 28 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.EventBasedAsync.dll |
-| 29 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.Primitives.dll |
-| 30 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.TypeConverter.dll |
-| 31 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Configuration.dll |
-| 32 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Console.dll |
-| 33 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Core.dll |
-| 34 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Data.Common.dll |
-| 35 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Data.DataSetExtensions.dll |
-| 36 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Data.dll |
-| 37 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Contracts.dll |
-| 38 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Debug.dll |
-| 39 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.DiagnosticSource.dll |
-| 40 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.FileVersionInfo.dll |
-| 41 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Process.dll |
-| 42 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.StackTrace.dll |
-| 43 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.TextWriterTraceListener.dll |
-| 44 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Tools.dll |
-| 45 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.TraceSource.dll |
-| 46 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Tracing.dll |
-| 47 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.dll |
-| 48 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Drawing.dll |
-| 49 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Drawing.Primitives.dll |
-| 50 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Dynamic.Runtime.dll |
-| 51 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Formats.Asn1.dll |
-| 52 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Formats.Tar.dll |
-| 53 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Globalization.Calendars.dll |
-| 54 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Globalization.dll |
-| 55 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Globalization.Extensions.dll |
-| 56 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Compression.Brotli.dll |
-| 57 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Compression.dll |
-| 58 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Compression.FileSystem.dll |
-| 59 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Compression.ZipFile.dll |
-| 60 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.dll |
-| 61 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.AccessControl.dll |
-| 62 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.dll |
-| 63 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.DriveInfo.dll |
-| 64 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.Primitives.dll |
-| 65 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.Watcher.dll |
-| 66 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.IsolatedStorage.dll |
-| 67 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.MemoryMappedFiles.dll |
-| 68 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Pipelines.dll |
-| 69 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Pipes.AccessControl.dll |
-| 70 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Pipes.dll |
-| 71 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.UnmanagedMemoryStream.dll |
-| 72 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Linq.dll |
-| 73 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Linq.Expressions.dll |
-| 74 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Linq.Parallel.dll |
-| 75 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Linq.Queryable.dll |
-| 76 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Memory.dll |
-| 77 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.dll |
-| 78 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Http.dll |
-| 79 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Http.Json.dll |
-| 80 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.HttpListener.dll |
-| 81 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Mail.dll |
-| 82 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.NameResolution.dll |
-| 83 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.NetworkInformation.dll |
-| 84 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Ping.dll |
-| 85 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Primitives.dll |
-| 86 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Quic.dll |
-| 87 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Requests.dll |
-| 88 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Security.dll |
-| 89 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.ServicePoint.dll |
-| 90 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Sockets.dll |
-| 91 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebClient.dll |
-| 92 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebHeaderCollection.dll |
-| 93 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebProxy.dll |
-| 94 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebSockets.Client.dll |
-| 95 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebSockets.dll |
-| 96 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Numerics.dll |
-| 97 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Numerics.Vectors.dll |
-| 98 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ObjectModel.dll |
-| 99 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.DispatchProxy.dll |
-| 100 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.dll |
-| 101 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Emit.dll |
-| 102 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Emit.ILGeneration.dll |
-| 103 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Emit.Lightweight.dll |
-| 104 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Extensions.dll |
-| 105 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Metadata.dll |
-| 106 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Primitives.dll |
-| 107 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.TypeExtensions.dll |
-| 108 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Resources.Reader.dll |
-| 109 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Resources.ResourceManager.dll |
-| 110 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Resources.Writer.dll |
-| 111 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.CompilerServices.Unsafe.dll |
-| 112 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.CompilerServices.VisualC.dll |
-| 113 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.dll |
-| 114 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Extensions.dll |
-| 115 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Handles.dll |
-| 116 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.InteropServices.dll |
-| 117 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.InteropServices.JavaScript.dll |
-| 118 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.InteropServices.RuntimeInformation.dll |
-| 119 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Intrinsics.dll |
-| 120 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Loader.dll |
-| 121 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Numerics.dll |
-| 122 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.dll |
-| 123 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.Formatters.dll |
-| 124 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.Json.dll |
-| 125 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.Primitives.dll |
-| 126 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.Xml.dll |
-| 127 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.AccessControl.dll |
-| 128 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Claims.dll |
-| 129 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Algorithms.dll |
-| 130 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Cng.dll |
-| 131 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Csp.dll |
-| 132 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.dll |
-| 133 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Encoding.dll |
-| 134 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.OpenSsl.dll |
-| 135 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Primitives.dll |
-| 136 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.X509Certificates.dll |
-| 137 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.dll |
-| 138 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Principal.dll |
-| 139 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Principal.Windows.dll |
-| 140 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.SecureString.dll |
-| 141 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ServiceModel.Web.dll |
-| 142 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ServiceProcess.dll |
-| 143 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Encoding.CodePages.dll |
-| 144 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Encoding.dll |
-| 145 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Encoding.Extensions.dll |
-| 146 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Encodings.Web.dll |
-| 147 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Json.dll |
-| 148 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.RegularExpressions.dll |
-| 149 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Channels.dll |
-| 150 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.dll |
-| 151 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Overlapped.dll |
-| 152 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Tasks.Dataflow.dll |
-| 153 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Tasks.dll |
-| 154 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Tasks.Extensions.dll |
-| 155 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Tasks.Parallel.dll |
-| 156 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Thread.dll |
-| 157 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.ThreadPool.dll |
-| 158 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Timer.dll |
-| 159 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Transactions.dll |
-| 160 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Transactions.Local.dll |
-| 161 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ValueTuple.dll |
-| 162 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Web.dll |
-| 163 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Web.HttpUtility.dll |
-| 164 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Windows.dll |
-| 165 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.dll |
-| 166 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.Linq.dll |
-| 167 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.ReaderWriter.dll |
-| 168 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.Serialization.dll |
-| 169 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XDocument.dll |
-| 170 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XmlDocument.dll |
-| 171 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XmlSerializer.dll |
-| 172 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XPath.dll |
-| 173 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XPath.XDocument.dll |
-| 174 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/WindowsBase.dll |
-| 175 | /debug+ |
-| 176 | /debug:portable |
-| 177 | /filealign:512 |
-| 178 | /generatedfilesout:obj/Debug/net9.0//generated |
-| 179 | /optimize- |
-| 180 | /out:obj/Debug/net9.0/test.dll |
-| 181 | /refout:obj/Debug/net9.0/refint/test.dll |
-| 182 | /target:exe |
-| 183 | /warnaserror- |
-| 184 | /utf8output |
-| 185 | /deterministic+ |
-| 186 | /langversion:13.0 |
-| 187 | /analyzerconfig:obj/Debug/net9.0/test.GeneratedMSBuildEditorConfig.editorconfig |
-| 188 | /analyzerconfig:/usr/share/dotnet/sdk/9.0.304/Sdks/Microsoft.NET.Sdk/analyzers/build/config/analysislevel_9_default.globalconfig |
-| 189 | /analyzer:/usr/share/dotnet/sdk/9.0.304/Sdks/Microsoft.NET.Sdk/targets/../analyzers/Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll |
-| 190 | /analyzer:/usr/share/dotnet/sdk/9.0.304/Sdks/Microsoft.NET.Sdk/targets/../analyzers/Microsoft.CodeAnalysis.NetAnalyzers.dll |
-| 191 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/Microsoft.Interop.ComInterfaceGenerator.dll |
-| 192 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/Microsoft.Interop.JavaScript.JSImportGenerator.dll |
-| 193 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/Microsoft.Interop.LibraryImportGenerator.dll |
-| 194 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/Microsoft.Interop.SourceGeneration.dll |
-| 195 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/System.Text.Json.SourceGeneration.dll |
-| 196 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/System.Text.RegularExpressions.Generator.dll |
-| 197 | Program.cs |
-| 198 | obj/Debug/net9.0/test.GlobalUsings.g.cs |
-| 199 | obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs |
-| 200 | obj/Debug/net9.0/test.AssemblyInfo.cs |
-| 201 | /warnaserror+:NU1605,SYSLIB0011 |
+| 9 | /preferreduilang:en |
+| 10 | /highentropyva+ |
+| 11 | /nullable:enable |
+| 12 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.CSharp.dll |
+| 13 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.VisualBasic.Core.dll |
+| 14 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.VisualBasic.dll |
+| 15 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.Win32.Primitives.dll |
+| 16 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/Microsoft.Win32.Registry.dll |
+| 17 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/mscorlib.dll |
+| 18 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/netstandard.dll |
+| 19 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.AppContext.dll |
+| 20 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Buffers.dll |
+| 21 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.Concurrent.dll |
+| 22 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.dll |
+| 23 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.Immutable.dll |
+| 24 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.NonGeneric.dll |
+| 25 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Collections.Specialized.dll |
+| 26 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.Annotations.dll |
+| 27 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.DataAnnotations.dll |
+| 28 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.dll |
+| 29 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.EventBasedAsync.dll |
+| 30 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.Primitives.dll |
+| 31 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ComponentModel.TypeConverter.dll |
+| 32 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Configuration.dll |
+| 33 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Console.dll |
+| 34 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Core.dll |
+| 35 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Data.Common.dll |
+| 36 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Data.DataSetExtensions.dll |
+| 37 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Data.dll |
+| 38 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Contracts.dll |
+| 39 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Debug.dll |
+| 40 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.DiagnosticSource.dll |
+| 41 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.FileVersionInfo.dll |
+| 42 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Process.dll |
+| 43 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.StackTrace.dll |
+| 44 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.TextWriterTraceListener.dll |
+| 45 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Tools.dll |
+| 46 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.TraceSource.dll |
+| 47 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Diagnostics.Tracing.dll |
+| 48 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.dll |
+| 49 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Drawing.dll |
+| 50 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Drawing.Primitives.dll |
+| 51 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Dynamic.Runtime.dll |
+| 52 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Formats.Asn1.dll |
+| 53 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Formats.Tar.dll |
+| 54 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Globalization.Calendars.dll |
+| 55 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Globalization.dll |
+| 56 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Globalization.Extensions.dll |
+| 57 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Compression.Brotli.dll |
+| 58 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Compression.dll |
+| 59 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Compression.FileSystem.dll |
+| 60 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Compression.ZipFile.dll |
+| 61 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.dll |
+| 62 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.AccessControl.dll |
+| 63 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.dll |
+| 64 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.DriveInfo.dll |
+| 65 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.Primitives.dll |
+| 66 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.FileSystem.Watcher.dll |
+| 67 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.IsolatedStorage.dll |
+| 68 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.MemoryMappedFiles.dll |
+| 69 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Pipelines.dll |
+| 70 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Pipes.AccessControl.dll |
+| 71 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.Pipes.dll |
+| 72 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.IO.UnmanagedMemoryStream.dll |
+| 73 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Linq.dll |
+| 74 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Linq.Expressions.dll |
+| 75 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Linq.Parallel.dll |
+| 76 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Linq.Queryable.dll |
+| 77 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Memory.dll |
+| 78 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.dll |
+| 79 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Http.dll |
+| 80 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Http.Json.dll |
+| 81 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.HttpListener.dll |
+| 82 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Mail.dll |
+| 83 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.NameResolution.dll |
+| 84 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.NetworkInformation.dll |
+| 85 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Ping.dll |
+| 86 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Primitives.dll |
+| 87 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Quic.dll |
+| 88 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Requests.dll |
+| 89 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Security.dll |
+| 90 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.ServicePoint.dll |
+| 91 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.Sockets.dll |
+| 92 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebClient.dll |
+| 93 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebHeaderCollection.dll |
+| 94 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebProxy.dll |
+| 95 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebSockets.Client.dll |
+| 96 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Net.WebSockets.dll |
+| 97 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Numerics.dll |
+| 98 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Numerics.Vectors.dll |
+| 99 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ObjectModel.dll |
+| 100 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.DispatchProxy.dll |
+| 101 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.dll |
+| 102 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Emit.dll |
+| 103 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Emit.ILGeneration.dll |
+| 104 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Emit.Lightweight.dll |
+| 105 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Extensions.dll |
+| 106 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Metadata.dll |
+| 107 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.Primitives.dll |
+| 108 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Reflection.TypeExtensions.dll |
+| 109 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Resources.Reader.dll |
+| 110 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Resources.ResourceManager.dll |
+| 111 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Resources.Writer.dll |
+| 112 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.CompilerServices.Unsafe.dll |
+| 113 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.CompilerServices.VisualC.dll |
+| 114 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.dll |
+| 115 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Extensions.dll |
+| 116 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Handles.dll |
+| 117 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.InteropServices.dll |
+| 118 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.InteropServices.JavaScript.dll |
+| 119 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.InteropServices.RuntimeInformation.dll |
+| 120 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Intrinsics.dll |
+| 121 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Loader.dll |
+| 122 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Numerics.dll |
+| 123 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.dll |
+| 124 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.Formatters.dll |
+| 125 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.Json.dll |
+| 126 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.Primitives.dll |
+| 127 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Runtime.Serialization.Xml.dll |
+| 128 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.AccessControl.dll |
+| 129 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Claims.dll |
+| 130 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Algorithms.dll |
+| 131 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Cng.dll |
+| 132 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Csp.dll |
+| 133 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.dll |
+| 134 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Encoding.dll |
+| 135 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.OpenSsl.dll |
+| 136 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.Primitives.dll |
+| 137 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Cryptography.X509Certificates.dll |
+| 138 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.dll |
+| 139 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Principal.dll |
+| 140 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.Principal.Windows.dll |
+| 141 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Security.SecureString.dll |
+| 142 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ServiceModel.Web.dll |
+| 143 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ServiceProcess.dll |
+| 144 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Encoding.CodePages.dll |
+| 145 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Encoding.dll |
+| 146 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Encoding.Extensions.dll |
+| 147 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Encodings.Web.dll |
+| 148 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.Json.dll |
+| 149 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Text.RegularExpressions.dll |
+| 150 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Channels.dll |
+| 151 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.dll |
+| 152 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Overlapped.dll |
+| 153 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Tasks.Dataflow.dll |
+| 154 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Tasks.dll |
+| 155 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Tasks.Extensions.dll |
+| 156 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Tasks.Parallel.dll |
+| 157 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Thread.dll |
+| 158 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.ThreadPool.dll |
+| 159 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Threading.Timer.dll |
+| 160 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Transactions.dll |
+| 161 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Transactions.Local.dll |
+| 162 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.ValueTuple.dll |
+| 163 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Web.dll |
+| 164 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Web.HttpUtility.dll |
+| 165 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Windows.dll |
+| 166 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.dll |
+| 167 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.Linq.dll |
+| 168 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.ReaderWriter.dll |
+| 169 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.Serialization.dll |
+| 170 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XDocument.dll |
+| 171 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XmlDocument.dll |
+| 172 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XmlSerializer.dll |
+| 173 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XPath.dll |
+| 174 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/System.Xml.XPath.XDocument.dll |
+| 175 | /reference:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/ref/net9.0/WindowsBase.dll |
+| 176 | /debug+ |
+| 177 | /debug:portable |
+| 178 | /filealign:512 |
+| 179 | /generatedfilesout:obj/Debug/net9.0//generated |
+| 180 | /optimize- |
+| 181 | /out:obj/Debug/net9.0/test.dll |
+| 182 | /refout:obj/Debug/net9.0/refint/test.dll |
+| 183 | /target:exe |
+| 184 | /warnaserror- |
+| 185 | /utf8output |
+| 186 | /deterministic+ |
+| 187 | /langversion:13.0 |
+| 188 | /analyzerconfig:obj/Debug/net9.0/test.GeneratedMSBuildEditorConfig.editorconfig |
+| 189 | /analyzerconfig:/usr/share/dotnet/sdk/9.0.304/Sdks/Microsoft.NET.Sdk/analyzers/build/config/analysislevel_9_default.globalconfig |
+| 190 | /analyzer:/usr/share/dotnet/sdk/9.0.304/Sdks/Microsoft.NET.Sdk/targets/../analyzers/Microsoft.CodeAnalysis.CSharp.NetAnalyzers.dll |
+| 191 | /analyzer:/usr/share/dotnet/sdk/9.0.304/Sdks/Microsoft.NET.Sdk/targets/../analyzers/Microsoft.CodeAnalysis.NetAnalyzers.dll |
+| 192 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/Microsoft.Interop.ComInterfaceGenerator.dll |
+| 193 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/Microsoft.Interop.JavaScript.JSImportGenerator.dll |
+| 194 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/Microsoft.Interop.LibraryImportGenerator.dll |
+| 195 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/Microsoft.Interop.SourceGeneration.dll |
+| 196 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/System.Text.Json.SourceGeneration.dll |
+| 197 | /analyzer:/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/9.0.8/analyzers/dotnet/cs/System.Text.RegularExpressions.Generator.dll |
+| 198 | Program.cs |
+| 199 | obj/Debug/net9.0/test.GlobalUsings.g.cs |
+| 200 | obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs |
+| 201 | obj/Debug/net9.0/test.AssemblyInfo.cs |
+| 202 | /warnaserror+:NU1605,SYSLIB0011 |
From edabbfc12fb0331a2d53b22f6be0578844129dd5 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Wed, 19 Nov 2025 11:29:25 +0100
Subject: [PATCH 32/70] C#: Add change note.
---
.../ql/lib/change-notes/2025-11-19-autobuilder-stability.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 csharp/ql/lib/change-notes/2025-11-19-autobuilder-stability.md
diff --git a/csharp/ql/lib/change-notes/2025-11-19-autobuilder-stability.md b/csharp/ql/lib/change-notes/2025-11-19-autobuilder-stability.md
new file mode 100644
index 00000000000..719c44ac8ad
--- /dev/null
+++ b/csharp/ql/lib/change-notes/2025-11-19-autobuilder-stability.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* Improved stability when downloading .NET versions by setting appropriate environment variables for `dotnet` commands. The correct architecture-specific version of .NET is now downloaded on ARM runners.
From 5cdfb3c0a98417b536f169f00c9038d3eae56410 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Wed, 19 Nov 2025 12:58:59 +0100
Subject: [PATCH 33/70] C#: Address review comments.
---
.../IDotNetCliInvoker.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs
index 6e80e1cb2bf..3a599afe96d 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs
@@ -13,7 +13,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
///
/// A minimal environment for running the .NET CLI.
///
- /// The .NET CLI language is set to English to avoid localized output.
+ /// DOTNET_CLI_UI_LANGUAGE: The .NET CLI language is set to English to avoid localized output.
+ /// MSBUILDDISABLENODEREUSE: To ensure clean environment for each build.
+ /// DOTNET_SKIP_FIRST_TIME_EXPERIENCE: To skip first time experience messages.
///
static ReadOnlyDictionary MinimalEnvironment { get; } = new(new Dictionary
{
From 42f0ce74cabbb34d2f523dd82804753d633c6603 Mon Sep 17 00:00:00 2001
From: Ian Lynagh
Date: Fri, 14 Nov 2025 17:34:12 +0000
Subject: [PATCH 34/70] C++: Enable overlay compilation
---
cpp/ql/lib/qlpack.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml
index febb297cb8d..5c2083a8613 100644
--- a/cpp/ql/lib/qlpack.yml
+++ b/cpp/ql/lib/qlpack.yml
@@ -21,3 +21,4 @@ dataExtensions:
- ext/deallocation/*.model.yml
- ext/allocation/*.model.yml
warnOnImplicitThis: true
+compileForOverlayEval: true
From 132f02c51bb0073479383441d369e2da016d7ebe Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Thu, 20 Nov 2025 14:34:02 +0100
Subject: [PATCH 35/70] Update
rust/ql/lib/codeql/rust/internal/PathResolution.qll
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
rust/ql/lib/codeql/rust/internal/PathResolution.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll
index f4349f79327..491f1572f26 100644
--- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll
+++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll
@@ -27,7 +27,7 @@
*
* So it may seem that path resolution and variable resolution must happen in mutual
* recursion, but we would like to keep the inherently global path resolution logic
- * separate from the inherently local variable resolution logic. We acheive this by
+ * separate from the inherently local variable resolution logic. We achieve this by
*
* - First computing global path resolution, where variable shadowing is ignored,
* exposed as the internal predicate `resolvePathIgnoreVariableShadowing`.
From 30d68d8906af22ba374b566fc8e5d5aabec09f47 Mon Sep 17 00:00:00 2001
From: Anders Schack-Mulligen
Date: Fri, 7 Nov 2025 11:33:52 +0100
Subject: [PATCH 36/70] Java: Add missing deprecated annotations.
---
java/ql/lib/semmle/code/java/dataflow/SSA.qll | 14 +++++++-------
.../semmle/code/java/dataflow/internal/SsaImpl.qll | 8 ++++----
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/java/ql/lib/semmle/code/java/dataflow/SSA.qll b/java/ql/lib/semmle/code/java/dataflow/SSA.qll
index 233b083a4eb..a627904174b 100644
--- a/java/ql/lib/semmle/code/java/dataflow/SSA.qll
+++ b/java/ql/lib/semmle/code/java/dataflow/SSA.qll
@@ -193,7 +193,7 @@ VarRead ssaGetAFirstUse(SsaDefinition def) { firstUse(def, result) }
*
* An SSA variable.
*/
-class SsaVariable extends Definition {
+deprecated class SsaVariable extends Definition {
/** Gets the SSA source variable underlying this SSA variable. */
SsaSourceVariable getSourceVariable() { result = super.getSourceVariable() }
@@ -203,7 +203,7 @@ class SsaVariable extends Definition {
* Gets the `ControlFlowNode` at which this SSA variable is defined.
*/
pragma[nomagic]
- ControlFlowNode getCfgNode() {
+ deprecated ControlFlowNode getCfgNode() {
exists(BasicBlock bb, int i |
this.definesAt(_, bb, i) and
// phi nodes are inserted at position `-1`
@@ -225,7 +225,7 @@ class SsaVariable extends Definition {
*
* Gets an access of this SSA variable.
*/
- VarRead getAUse() { result = getAUse(this) }
+ deprecated VarRead getAUse() { result = getAUse(this) }
/**
* DEPRECATED: Use `ssaGetAFirstUse(SsaDefinition)` instead.
@@ -272,7 +272,7 @@ class SsaVariable extends Definition {
*
* An SSA variable that either explicitly or implicitly updates the variable.
*/
-class SsaUpdate extends SsaVariable instanceof WriteDefinition {
+deprecated class SsaUpdate extends SsaVariable instanceof WriteDefinition {
SsaUpdate() { not this instanceof SsaImplicitInit }
}
@@ -281,7 +281,7 @@ class SsaUpdate extends SsaVariable instanceof WriteDefinition {
*
* An SSA variable that is defined by a `VariableUpdate`.
*/
-class SsaExplicitUpdate extends SsaUpdate {
+deprecated class SsaExplicitUpdate extends SsaUpdate {
private VariableUpdate upd;
SsaExplicitUpdate() { ssaExplicitUpdate(this, upd) }
@@ -409,7 +409,7 @@ deprecated class SsaUncertainImplicitUpdate extends SsaImplicitUpdate {
* An SSA variable that is defined by its initial value in the callable. This
* includes initial values of parameters, fields, and closure variables.
*/
-class SsaImplicitInit extends SsaVariable instanceof WriteDefinition {
+deprecated class SsaImplicitInit extends SsaVariable instanceof WriteDefinition {
SsaImplicitInit() { ssaImplicitInit(this) }
override string toString() { result = "SSA init(" + this.getSourceVariable() + ")" }
@@ -422,7 +422,7 @@ class SsaImplicitInit extends SsaVariable instanceof WriteDefinition {
*
* Holds if the SSA variable is a parameter defined by its initial value in the callable.
*/
- predicate isParameterDefinition(Parameter p) {
+ deprecated predicate isParameterDefinition(Parameter p) {
this.getSourceVariable() = TLocalVar(p.getCallable(), p) and
p.getCallable().getBody().getControlFlowNode() = this.getCfgNode()
}
diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll
index 21843f3e93b..624f82fd341 100644
--- a/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll
+++ b/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll
@@ -244,7 +244,7 @@ final class UncertainWriteDefinition = Impl::UncertainWriteDefinition;
final class PhiNode = Impl::PhiNode;
-predicate ssaExplicitUpdate(SsaUpdate def, VariableUpdate upd) {
+deprecated predicate ssaExplicitUpdate(SsaUpdate def, VariableUpdate upd) {
exists(SsaSourceVariable v, BasicBlock bb, int i |
def.definesAt(v, bb, i) and
certainVariableUpdate(v, upd.getControlFlowNode(), bb, i) and
@@ -259,7 +259,7 @@ deprecated predicate ssaUncertainImplicitUpdate(SsaImplicitUpdate def) {
)
}
-predicate ssaImplicitInit(WriteDefinition def) {
+deprecated predicate ssaImplicitInit(WriteDefinition def) {
exists(SsaSourceVariable v, BasicBlock bb, int i |
def.definesAt(v, bb, i) and
hasEntryDef(v, bb) and
@@ -275,7 +275,7 @@ deprecated predicate ssaDefReachesUncertainDef(TrackedSsaDef def, SsaUncertainIm
Impl::uncertainWriteDefinitionInput(redef, def)
}
-VarRead getAUse(Definition def) {
+deprecated VarRead getAUse(Definition def) {
exists(SsaSourceVariable v, BasicBlock bb, int i |
Impl::ssaDefReachesRead(v, def, bb, i) and
result.getControlFlowNode() = bb.getNode(i) and
@@ -283,7 +283,7 @@ VarRead getAUse(Definition def) {
)
}
-predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def) {
+deprecated predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def) {
Impl::ssaDefReachesEndOfBlock(bb, def, _)
}
From e76e7ab26a16a6eff8e25fd43b4008cf91b4764d Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Thu, 13 Nov 2025 14:31:02 +0100
Subject: [PATCH 37/70] C#: Read from dependency directory from extractor
option.
---
.../DependencyDirectory.cs | 62 +++++++++++++++++++
.../NugetExeWrapper.cs | 6 +-
.../NugetPackageRestorer.cs | 12 ++--
.../Semmle.Util/EnvironmentVariables.cs | 10 +++
4 files changed, 81 insertions(+), 9 deletions(-)
create mode 100644 csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyDirectory.cs
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyDirectory.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyDirectory.cs
new file mode 100644
index 00000000000..8efcb5d7d78
--- /dev/null
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyDirectory.cs
@@ -0,0 +1,62 @@
+using System;
+using System.IO;
+using Semmle.Util;
+using Semmle.Util.Logging;
+
+namespace Semmle.Extraction.CSharp.DependencyFetching
+{
+ ///
+ /// A directory used for storing fetched dependencies.
+ /// When a specific directory is set via the dependency directory extractor option,
+ /// we store dependencies in that directory for caching purposes.
+ /// Otherwise, we create a temporary directory that is deleted upon disposal.
+ ///
+ public sealed class DependencyDirectory : IDisposable
+ {
+ private readonly string userReportedDirectoryPurpose;
+ private readonly ILogger logger;
+ private readonly bool attemptCleanup;
+
+ public DirectoryInfo DirInfo { get; }
+
+ public DependencyDirectory(string subfolderName, string userReportedDirectoryPurpose, ILogger logger)
+ {
+ this.logger = logger;
+ this.userReportedDirectoryPurpose = userReportedDirectoryPurpose;
+
+ string path;
+ if (EnvironmentVariables.GetBuildlessDependencyDir() is string dir)
+ {
+ path = dir;
+ attemptCleanup = false;
+ }
+ else
+ {
+ path = FileUtils.GetTemporaryWorkingDirectory(out _);
+ attemptCleanup = true;
+ }
+ DirInfo = new DirectoryInfo(Path.Join(path, subfolderName));
+ DirInfo.Create();
+ }
+
+ public void Dispose()
+ {
+ if (!attemptCleanup)
+ {
+ logger.LogInfo($"Keeping {userReportedDirectoryPurpose} directory {DirInfo.FullName} for possible caching purposes.");
+ return;
+ }
+
+ try
+ {
+ DirInfo.Delete(true);
+ }
+ catch (Exception exc)
+ {
+ logger.LogInfo($"Couldn't delete {userReportedDirectoryPurpose} directory {exc.Message}");
+ }
+ }
+
+ public override string ToString() => DirInfo.FullName.ToString();
+ }
+}
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs
index c77daa8899c..10d89b1e009 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs
@@ -25,15 +25,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
///
/// The computed packages directory.
- /// This will be in the Temp location
+ /// This will be in the Cached or Temp location
/// so as to not trample the source tree.
///
- private readonly TemporaryDirectory packageDirectory;
+ private readonly DependencyDirectory packageDirectory;
///
/// Create the package manager for a specified source tree.
///
- public NugetExeWrapper(FileProvider fileProvider, TemporaryDirectory packageDirectory, Semmle.Util.Logging.ILogger logger)
+ public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger)
{
this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory;
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs
index e0e1bc649fa..e2e548a46a9 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetPackageRestorer.cs
@@ -24,12 +24,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly IDotNet dotnet;
private readonly DependabotProxy? dependabotProxy;
private readonly IDiagnosticsWriter diagnosticsWriter;
- private readonly TemporaryDirectory legacyPackageDirectory;
- private readonly TemporaryDirectory missingPackageDirectory;
+ private readonly DependencyDirectory legacyPackageDirectory;
+ private readonly DependencyDirectory missingPackageDirectory;
private readonly ILogger logger;
private readonly ICompilationInfoContainer compilationInfoContainer;
- public TemporaryDirectory PackageDirectory { get; }
+ public DependencyDirectory PackageDirectory { get; }
public NugetPackageRestorer(
FileProvider fileProvider,
@@ -48,9 +48,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
this.logger = logger;
this.compilationInfoContainer = compilationInfoContainer;
- PackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("packages"), "package", logger);
- legacyPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("legacypackages"), "legacy package", logger);
- missingPackageDirectory = new TemporaryDirectory(ComputeTempDirectoryPath("missingpackages"), "missing package", logger);
+ PackageDirectory = new DependencyDirectory("packages", "package", logger);
+ legacyPackageDirectory = new DependencyDirectory("legacypackages", "legacy package", logger);
+ missingPackageDirectory = new DependencyDirectory("missingpackages", "missing package", logger);
}
public string? TryRestore(string package)
diff --git a/csharp/extractor/Semmle.Util/EnvironmentVariables.cs b/csharp/extractor/Semmle.Util/EnvironmentVariables.cs
index edce64a53fe..9f1519653de 100644
--- a/csharp/extractor/Semmle.Util/EnvironmentVariables.cs
+++ b/csharp/extractor/Semmle.Util/EnvironmentVariables.cs
@@ -76,5 +76,15 @@ namespace Semmle.Util
{
return Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OVERLAY_BASE_METADATA_OUT");
}
+
+ ///
+ /// If set, returns the directory where buildless dependencies should be stored.
+ /// This is needed for caching dependencies.
+ ///
+ ///
+ public static string? GetBuildlessDependencyDir()
+ {
+ return Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OPTION_BUILDLESS_DEPENDENCY_DIR");
+ }
}
}
From 1256ccf2ebe769bf5b9167a772801590d7249443 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Thu, 13 Nov 2025 14:33:25 +0100
Subject: [PATCH 38/70] C#: Add extractor option for buildless dependency
directory.
---
csharp/codeql-extractor.yml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/csharp/codeql-extractor.yml b/csharp/codeql-extractor.yml
index da7d665f7a7..8cba8f18e47 100644
--- a/csharp/codeql-extractor.yml
+++ b/csharp/codeql-extractor.yml
@@ -74,3 +74,8 @@ options:
[EXPERIMENTAL] The value is a path to the MsBuild binary log file that should be extracted.
This option only works when `--build-mode none` is also specified.
type: array
+ buildless_dependency_dir:
+ title: The path where buildless (standalone) extraction should keep dependencies.
+ description: >
+ If set, the buildless (standalone) extractor will store dependencies in this directory.
+ type: string
From 2700843a9cb97096674b2e93f6372076afb0899c Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Mon, 17 Nov 2025 12:01:59 +0100
Subject: [PATCH 39/70] C#: Add an integration test for setting the dependency
directory in BMN.
---
.../Assemblies.expected | 1 +
.../standalone_dependency_dir/Assemblies.ql | 7 +++++++
.../standalone_dependency_dir/proj/Program.cs | 6 ++++++
.../standalone_dependency_dir/proj/global.json | 5 +++++
.../proj/standalone.csproj | 16 ++++++++++++++++
.../standalone_dependency_dir/test.py | 8 ++++++++
6 files changed, 43 insertions(+)
create mode 100644 csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/Assemblies.expected
create mode 100644 csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/Assemblies.ql
create mode 100644 csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/Program.cs
create mode 100644 csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/global.json
create mode 100644 csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/standalone.csproj
create mode 100644 csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py
diff --git a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/Assemblies.expected b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/Assemblies.expected
new file mode 100644
index 00000000000..b98f10a366c
--- /dev/null
+++ b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/Assemblies.expected
@@ -0,0 +1 @@
+| dependencies/packages/newtonsoft.json/13.0.1/lib/netstandard2.0/Newtonsoft.Json.dll:0:0:0:0 | Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed |
diff --git a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/Assemblies.ql b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/Assemblies.ql
new file mode 100644
index 00000000000..625fc299761
--- /dev/null
+++ b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/Assemblies.ql
@@ -0,0 +1,7 @@
+import csharp
+
+from Assembly a
+where
+ not a.getCompilation().getOutputAssembly() = a and
+ a.getName().matches("%Newtonsoft%")
+select a
diff --git a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/Program.cs b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/Program.cs
new file mode 100644
index 00000000000..39a9e95bb6e
--- /dev/null
+++ b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/Program.cs
@@ -0,0 +1,6 @@
+class Program
+{
+ static void Main(string[] args)
+ {
+ }
+}
\ No newline at end of file
diff --git a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/global.json b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/global.json
new file mode 100644
index 00000000000..4c6e2601f69
--- /dev/null
+++ b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/global.json
@@ -0,0 +1,5 @@
+{
+ "sdk": {
+ "version": "9.0.304"
+ }
+}
diff --git a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/standalone.csproj b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/standalone.csproj
new file mode 100644
index 00000000000..29604e2cbd8
--- /dev/null
+++ b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/proj/standalone.csproj
@@ -0,0 +1,16 @@
+
+
+
+ Exe
+ net9.0
+
+
+
+
+
+
+
+
+
+
+
diff --git a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py
new file mode 100644
index 00000000000..6aeb36182dd
--- /dev/null
+++ b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py
@@ -0,0 +1,8 @@
+import os
+
+def test(codeql, csharp, cwd):
+ path = os.path.join(cwd, "dependencies")
+ os.environ["CODEQL_EXTRACTOR_CSHARP_OPTION_BUILDLESS_DEPENDENCY_DIR"] = path
+ # The Assemblies.ql query shows that the Newtonsoft assembly is found in the
+ # dependency directory set above.
+ codeql.database.create(source_root="proj", build_mode="none")
From 90dbb7a8eb61876e7c0fcf424cd4093f6874ebbd Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Mon, 17 Nov 2025 12:50:18 +0100
Subject: [PATCH 40/70] C#: Add change note.
---
.../ql/lib/change-notes/2025-11-17-dependencies-directory.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 csharp/ql/lib/change-notes/2025-11-17-dependencies-directory.md
diff --git a/csharp/ql/lib/change-notes/2025-11-17-dependencies-directory.md b/csharp/ql/lib/change-notes/2025-11-17-dependencies-directory.md
new file mode 100644
index 00000000000..ec86dca35b9
--- /dev/null
+++ b/csharp/ql/lib/change-notes/2025-11-17-dependencies-directory.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* Added a new extractor option to specify a custom directory for dependency downloads in buildless mode. Use `-O buildless_dependency_dir=` to configure the target directory.
From 138441b662a0b884365f15d9aae63a53750dd082 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Mon, 17 Nov 2025 16:03:53 +0100
Subject: [PATCH 41/70] C#: Address review comments.
---
.../DependencyDirectory.cs | 2 +-
.../NugetExeWrapper.cs | 4 ++--
csharp/extractor/Semmle.Util/EnvironmentVariables.cs | 3 +--
.../all-platforms/standalone_dependency_dir/test.py | 6 ++++++
4 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyDirectory.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyDirectory.cs
index 8efcb5d7d78..7c816ed5837 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyDirectory.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyDirectory.cs
@@ -57,6 +57,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
- public override string ToString() => DirInfo.FullName.ToString();
+ public override string ToString() => DirInfo.FullName;
}
}
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs
index 10d89b1e009..b90b388e865 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/NugetExeWrapper.cs
@@ -24,8 +24,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly FileProvider fileProvider;
///
- /// The computed packages directory.
- /// This will be in the Cached or Temp location
+ /// The packages directory.
+ /// This will be in the user-specified or computed Temp location
/// so as to not trample the source tree.
///
private readonly DependencyDirectory packageDirectory;
diff --git a/csharp/extractor/Semmle.Util/EnvironmentVariables.cs b/csharp/extractor/Semmle.Util/EnvironmentVariables.cs
index 9f1519653de..1af05b9d4ad 100644
--- a/csharp/extractor/Semmle.Util/EnvironmentVariables.cs
+++ b/csharp/extractor/Semmle.Util/EnvironmentVariables.cs
@@ -79,9 +79,8 @@ namespace Semmle.Util
///
/// If set, returns the directory where buildless dependencies should be stored.
- /// This is needed for caching dependencies.
+ /// This can be used for caching dependencies.
///
- ///
public static string? GetBuildlessDependencyDir()
{
return Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OPTION_BUILDLESS_DEPENDENCY_DIR");
diff --git a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py
index 6aeb36182dd..d5574979c63 100644
--- a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py
+++ b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py
@@ -1,4 +1,5 @@
import os
+import shutil
def test(codeql, csharp, cwd):
path = os.path.join(cwd, "dependencies")
@@ -6,3 +7,8 @@ def test(codeql, csharp, cwd):
# The Assemblies.ql query shows that the Newtonsoft assembly is found in the
# dependency directory set above.
codeql.database.create(source_root="proj", build_mode="none")
+
+ # Check that the packages directory has been created in the dependecies folder.
+ packages_dir = os.path.join(path, "packages")
+ assert os.path.isdir(packages_dir), "The packages directory was not created in the specified dependency directory."
+ shutil.rmtree(path)
From 5c454d23e87cf0c5c25b0ece30ec2f5016ab0090 Mon Sep 17 00:00:00 2001
From: Michael Nebel
Date: Fri, 21 Nov 2025 10:18:41 +0100
Subject: [PATCH 42/70] C#: Fix typo.
---
.../all-platforms/standalone_dependency_dir/test.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py
index d5574979c63..3629693ad29 100644
--- a/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py
+++ b/csharp/ql/integration-tests/all-platforms/standalone_dependency_dir/test.py
@@ -8,7 +8,7 @@ def test(codeql, csharp, cwd):
# dependency directory set above.
codeql.database.create(source_root="proj", build_mode="none")
- # Check that the packages directory has been created in the dependecies folder.
+ # Check that the packages directory has been created in the dependencies folder.
packages_dir = os.path.join(path, "packages")
assert os.path.isdir(packages_dir), "The packages directory was not created in the specified dependency directory."
shutil.rmtree(path)
From d5399300e9ece38e440dc4f7b5185abeff7722b9 Mon Sep 17 00:00:00 2001
From: Ian Lynagh
Date: Wed, 19 Nov 2025 15:32:38 +0000
Subject: [PATCH 43/70] C++: Add `databaseMetadata` and `overlayChangedFiles`
tables to dbscheme
---
cpp/ql/lib/semmlecode.cpp.dbscheme | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme
index 1a6854060d5..a42ce5fc943 100644
--- a/cpp/ql/lib/semmlecode.cpp.dbscheme
+++ b/cpp/ql/lib/semmlecode.cpp.dbscheme
@@ -1,3 +1,4 @@
+
/*- Compilations -*/
/**
@@ -2378,6 +2379,24 @@ link_parent(
int link_target : @link_target ref
);
+/**
+ * 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
+);
+
+/**
+ * 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(
From c2f96b94e3e21c4d3341f62939b7ebfe0ce22b0d Mon Sep 17 00:00:00 2001
From: Ian Lynagh
Date: Fri, 21 Nov 2025 11:28:16 +0000
Subject: [PATCH 44/70] C++: Update stats
---
cpp/ql/lib/semmlecode.cpp.dbscheme.stats | 2694 +++++++++++-----------
1 file changed, 1373 insertions(+), 1321 deletions(-)
diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
index 1d796c9aa9a..4ff7d2dd67b 100644
--- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
+++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
@@ -2,7 +2,7 @@
@compilation
- 12640
+ 12641
@externalDataElement
@@ -10,35 +10,35 @@
@file
- 65198
+ 65204
@folder
- 12387
+ 12388
@diagnostic
359
-
- @location_default
- 46943795
-
@pch
249
+
+ @location_default
+ 46943825
+
@macro_expansion
- 40272403
+ 40272429
@other_macro_reference
- 300697
+ 300698
@normal_function
- 2737947
+ 2737949
@unknown_function
@@ -46,7 +46,7 @@
@constructor
- 698677
+ 698692
@destructor
@@ -58,7 +58,7 @@
@operator
- 652426
+ 652427
@user_defined_literal
@@ -70,23 +70,23 @@
@fun_decl
- 4202851
+ 4202854
@var_decl
- 9383095
+ 9383101
@type_decl
- 1633437
+ 1633438
@namespace_decl
- 407917
+ 407918
@using_declaration
- 267880
+ 268041
@using_directive
@@ -102,11 +102,11 @@
@parameter
- 7019638
+ 7019643
@membervariable
- 1499493
+ 1499494
@globalvariable
@@ -114,7 +114,7 @@
@localvariable
- 725806
+ 726016
@enumconstant
@@ -378,7 +378,7 @@
@routineptr
- 684266
+ 684282
@reference
@@ -404,6 +404,10 @@
@scalable_vector
1
+
+ @decltype
+ 102350
+
@typeof
816
@@ -484,13 +488,9 @@
@remove_reference
5715
-
- @decltype
- 102350
-
@struct
- 979711
+ 979799
@union
@@ -502,11 +502,11 @@
@template_parameter
- 866907
+ 866985
@alias
- 1762011
+ 1762169
@unknown_usertype
@@ -514,7 +514,7 @@
@class
- 324965
+ 324966
@template_template_parameter
@@ -522,7 +522,7 @@
@proxy_class
- 48429
+ 48433
@scoped_enum
@@ -530,7 +530,7 @@
@template_struct
- 212038
+ 212057
@template_class
@@ -542,23 +542,23 @@
@mangledname
- 6364342
+ 6364346
@type_mention
- 5907627
+ 5907630
@concept_template
- 3610
+ 3609
@routinetype
- 604482
+ 604495
@ptrtomember
- 9725
+ 9726
@specifier
@@ -582,15 +582,15 @@
@alignas
- 2163
+ 2164
@attribute_arg_token
- 16692
+ 16693
@attribute_arg_constant_expr
- 71883
+ 71889
@attribute_arg_expr
@@ -606,23 +606,23 @@
@attribute_arg_type
- 459
+ 460
@derivation
- 476867
+ 476878
@frienddecl
- 699835
+ 700430
@comment
- 11233093
+ 11233100
@namespace
- 8648
+ 8649
@specialnamequalifyingelement
@@ -630,15 +630,15 @@
@namequalifier
- 3037999
+ 3037638
@value
- 13474763
+ 13474772
@initialiser
- 2247635
+ 2247637
@address_of
@@ -650,19 +650,19 @@
@array_to_pointer
- 1953766
+ 1953767
@parexpr
- 4915246
+ 4915249
@arithnegexpr
- 586538
+ 586539
@unaryplusexpr
- 4067
+ 4068
@complementexpr
@@ -694,11 +694,11 @@
@addexpr
- 571559
+ 571560
@subexpr
- 466802
+ 466803
@mulexpr
@@ -734,11 +734,11 @@
@andexpr
- 481223
+ 481224
@orexpr
- 194057
+ 194058
@xorexpr
@@ -746,11 +746,11 @@
@eqexpr
- 643379
+ 643380
@neexpr
- 411873
+ 411874
@gtexpr
@@ -770,7 +770,7 @@
@assignexpr
- 1281159
+ 1281160
@assignaddexpr
@@ -782,7 +782,7 @@
@assignmulexpr
- 11183
+ 11184
@assigndivexpr
@@ -838,7 +838,7 @@
@callexpr
- 239762
+ 239767
@vastartexpr
@@ -858,7 +858,7 @@
@varaccess
- 8254728
+ 8254733
@runtime_sizeof
@@ -866,7 +866,7 @@
@runtime_alignof
- 49873
+ 49874
@expr_stmt
@@ -874,11 +874,11 @@
@routineexpr
- 5730574
+ 5729912
@type_operand
- 1405379
+ 1405380
@offsetofexpr
@@ -886,11 +886,11 @@
@typescompexpr
- 701942
+ 701943
@literal
- 7966636
+ 7966268
@aggregateliteral
@@ -898,23 +898,23 @@
@c_style_cast
- 6026984
+ 6026987
@temp_init
- 991871
+ 990622
@errorexpr
- 45479
+ 45480
@reference_to
- 1902179
+ 1903214
@ref_indirect
- 2107171
+ 2107218
@vacuous_destructor_call
@@ -974,11 +974,11 @@
@thisaccess
- 1555763
+ 1555764
@new_expr
- 46194
+ 46195
@delete_expr
@@ -986,19 +986,19 @@
@throw_expr
- 24145
+ 24214
@condition_decl
- 408385
+ 408340
@braced_init_list
- 2151
+ 2146
@type_id
- 47898
+ 47899
@sizeof_pack
@@ -1106,7 +1106,7 @@
@ctordirectinit
- 112829
+ 112831
@ctorvirtualinit
@@ -1122,7 +1122,7 @@
@dtordirectdestruct
- 39449
+ 39450
@dtorvirtualdestruct
@@ -1130,7 +1130,7 @@
@dtorfielddestruct
- 39824
+ 39825
@static_cast
@@ -1154,11 +1154,11 @@
@param_ref
- 163939
+ 163867
@noopexpr
- 64
+ 48
@istriviallyconstructibleexpr
@@ -1186,7 +1186,7 @@
@istrivialexpr
- 3367
+ 3375
@isstandardlayoutexpr
@@ -1258,7 +1258,7 @@
@noexceptexpr
- 28343
+ 28463
@builtinshufflevector
@@ -1322,7 +1322,7 @@
@issame
- 4534
+ 4533
@isfunction
@@ -1430,7 +1430,7 @@
@reuseexpr
- 845931
+ 845836
@istriviallycopyassignable
@@ -1530,7 +1530,7 @@
@requires_expr
- 16481
+ 16479
@nested_requirement
@@ -1538,11 +1538,11 @@
@compound_requirement
- 10937
+ 10936
@concept_id
- 90315
+ 90305
@lambdacapture
@@ -1550,11 +1550,11 @@
@stmt_expr
- 2031638
+ 2031639
@stmt_if
- 990226
+ 990227
@stmt_while
@@ -1562,23 +1562,23 @@
@stmt_goto
- 157874
+ 157889
@stmt_label
- 78008
+ 78015
@stmt_return
- 1241721
+ 1241800
@stmt_block
- 1728619
+ 1728620
@stmt_end_test_while
- 233643
+ 233644
@stmt_for
@@ -1586,11 +1586,11 @@
@stmt_switch_case
- 835058
+ 834964
@stmt_switch
- 411329
+ 411283
@stmt_asm
@@ -1598,11 +1598,11 @@
@stmt_decl
- 771065
+ 771066
@stmt_empty
- 428842
+ 428794
@stmt_continue
@@ -1614,7 +1614,7 @@
@stmt_try_block
- 26736
+ 26771
@stmt_microsoft_try
@@ -1634,15 +1634,15 @@
@stmt_range_based_for
- 6384
+ 6372
@stmt_handler
- 43770
+ 43779
@stmt_constexpr_if
- 106034
+ 106035
@stmt_co_return
@@ -1670,11 +1670,11 @@
@ppd_ifndef
- 160377
+ 160378
@ppd_elif
- 21912
+ 21914
@ppd_else
@@ -1686,11 +1686,11 @@
@ppd_plain_include
- 318495
+ 318524
@ppd_define
- 2750047
+ 2750049
@ppd_undef
@@ -1706,7 +1706,7 @@
@ppd_line
- 18799
+ 18805
@ppd_error
@@ -1762,13 +1762,60 @@
+
+ databaseMetadata
+ 1
+
+
+ metadataKey
+ 1
+
+
+ value
+ 1
+
+
+
+
+ metadataKey
+ value
+
+
+ 12
+
+
+
+
+
+ value
+ metadataKey
+
+
+ 12
+
+
+
+
+
+
+
+ overlayChangedFiles
+ 50
+
+
+ path
+ 50
+
+
+
+
compilations
- 12640
+ 12641
id
- 12640
+ 12641
cwd
@@ -1786,7 +1833,7 @@
1
2
- 12640
+ 12641
@@ -1812,11 +1859,11 @@
compilation_args
- 1011994
+ 1012084
id
- 12640
+ 12641
num
@@ -1824,7 +1871,7 @@
arg
- 29262
+ 29264
@@ -1893,7 +1940,7 @@
103
104
- 1995
+ 1996
104
@@ -1984,7 +2031,7 @@
79
89
- 1129
+ 1130
89
@@ -2152,12 +2199,12 @@
1
2
- 13400
+ 13402
2
3
- 12682
+ 12683
3
@@ -2183,12 +2230,12 @@
1
2
- 19377
+ 19379
2
3
- 8722
+ 8723
3
@@ -2203,11 +2250,11 @@
compilation_expanded_args
- 1011994
+ 1012084
id
- 12640
+ 12641
num
@@ -2215,7 +2262,7 @@
arg
- 29262
+ 29264
@@ -2284,7 +2331,7 @@
103
104
- 1995
+ 1996
104
@@ -2375,7 +2422,7 @@
79
89
- 1129
+ 1130
89
@@ -2543,12 +2590,12 @@
1
2
- 13400
+ 13402
2
3
- 12682
+ 12683
3
@@ -2574,12 +2621,12 @@
1
2
- 19377
+ 19379
2
3
- 8722
+ 8723
3
@@ -2904,7 +2951,7 @@
seconds
- 14485
+ 18352
@@ -2985,27 +3032,27 @@
3
4
- 544
+ 653
4
5
- 816
+ 707
6
- 7
- 163
+ 9
+ 217
- 8
+ 9
10
- 217
+ 108
10
11
- 108
+ 163
11
@@ -3013,19 +3060,24 @@
217
- 13
- 18
+ 15
+ 17
+ 163
+
+
+ 17
+ 21
217
- 18
- 22
+ 21
+ 51
217
- 25
- 98
- 217
+ 118
+ 119
+ 54
@@ -3098,12 +3150,12 @@
3
4
- 1089
+ 1252
4
5
- 1306
+ 1089
5
@@ -3113,32 +3165,32 @@
6
7
- 599
+ 544
7
8
- 217
+ 272
8
9
- 217
+ 326
9
- 13
+ 17
381
- 17
- 46
+ 23
+ 53
381
- 50
- 90
- 108
+ 98
+ 99
+ 54
@@ -3186,16 +3238,21 @@
4
5
- 108
-
-
- 154
- 155
54
- 171
- 172
+ 5
+ 6
+ 54
+
+
+ 195
+ 196
+ 54
+
+
+ 197
+ 198
54
@@ -3212,22 +3269,22 @@
1
2
- 7732
+ 12198
2
3
- 3376
+ 4084
3
4
- 2341
+ 1415
4
- 46
- 1034
+ 44
+ 653
@@ -3243,27 +3300,22 @@
1
2
- 7242
+ 10891
2
3
- 3158
+ 4465
3
4
- 1960
+ 1579
4
- 6
- 1306
-
-
- 6
- 77
- 816
+ 71
+ 1415
@@ -3279,12 +3331,12 @@
1
2
- 10837
+ 14866
2
3
- 3648
+ 3485
@@ -3560,19 +3612,19 @@
compilation_finished
- 12640
+ 12641
id
- 12640
+ 12641
cpu_seconds
- 9630
+ 9409
elapsed_seconds
- 221
+ 200
@@ -3586,7 +3638,7 @@
1
2
- 12640
+ 12641
@@ -3602,7 +3654,7 @@
1
2
- 12640
+ 12641
@@ -3618,17 +3670,17 @@
1
2
- 8268
+ 7846
2
3
- 1013
+ 1130
3
- 37
- 348
+ 35
+ 433
@@ -3644,12 +3696,12 @@
1
2
- 8923
+ 8744
2
3
- 707
+ 665
@@ -3665,12 +3717,17 @@
1
2
- 63
+ 42
+
+
+ 2
+ 3
+ 10
3
4
- 21
+ 10
4
@@ -3678,14 +3735,19 @@
10
- 8
- 9
+ 9
+ 10
+ 10
+
+
+ 10
+ 11
10
11
12
- 21
+ 10
12
@@ -3693,43 +3755,43 @@
10
- 13
- 14
+ 14
+ 15
10
- 20
- 21
+ 19
+ 20
10
- 29
- 30
+ 32
+ 33
10
- 59
- 60
+ 57
+ 58
10
- 150
- 151
+ 154
+ 155
10
- 247
- 248
+ 251
+ 252
10
- 302
- 303
+ 306
+ 307
10
- 319
- 320
+ 309
+ 310
10
@@ -3746,12 +3808,17 @@
1
2
- 63
+ 42
+
+
+ 2
+ 3
+ 10
3
4
- 21
+ 10
4
@@ -3759,14 +3826,19 @@
10
- 8
- 9
+ 9
+ 10
+ 10
+
+
+ 10
+ 11
10
11
12
- 21
+ 10
12
@@ -3774,13 +3846,13 @@
10
- 13
- 14
+ 14
+ 15
10
- 20
- 21
+ 18
+ 19
10
@@ -3789,28 +3861,28 @@
10
- 59
- 60
+ 54
+ 55
10
- 148
- 149
+ 149
+ 150
10
- 159
- 160
+ 152
+ 153
10
- 237
- 238
+ 228
+ 229
10
- 256
- 257
+ 255
+ 256
10
@@ -4048,11 +4120,11 @@
locations_default
- 46943795
+ 46943825
id
- 46943795
+ 46943825
file
@@ -4060,7 +4132,7 @@
beginLine
- 7500413
+ 7500418
beginColumn
@@ -4068,7 +4140,7 @@
endLine
- 7501536
+ 7501541
endColumn
@@ -4086,7 +4158,7 @@
1
2
- 46943795
+ 46943825
@@ -4102,7 +4174,7 @@
1
2
- 46943795
+ 46943825
@@ -4118,7 +4190,7 @@
1
2
- 46943795
+ 46943825
@@ -4134,7 +4206,7 @@
1
2
- 46943795
+ 46943825
@@ -4150,7 +4222,7 @@
1
2
- 46943795
+ 46943825
@@ -4551,7 +4623,7 @@
1
2
- 4957321
+ 4957324
2
@@ -4561,7 +4633,7 @@
3
4
- 543896
+ 543897
4
@@ -4592,7 +4664,7 @@
1
2
- 5019320
+ 5019323
2
@@ -4607,7 +4679,7 @@
6
57
- 563232
+ 563233
57
@@ -4628,7 +4700,7 @@
1
2
- 5641184
+ 5641187
2
@@ -4643,7 +4715,7 @@
7
25
- 565228
+ 565229
25
@@ -4664,12 +4736,12 @@
1
2
- 7034358
+ 7034363
2
85
- 466054
+ 466055
@@ -4685,7 +4757,7 @@
1
2
- 5026306
+ 5026309
2
@@ -4700,12 +4772,12 @@
4
12
- 586934
+ 586935
12
72
- 564105
+ 564106
72
@@ -5106,12 +5178,12 @@
1
2
- 4955200
+ 4955203
2
3
- 781539
+ 781540
3
@@ -5147,7 +5219,7 @@
1
2
- 5016451
+ 5016454
2
@@ -5162,7 +5234,7 @@
6
52
- 564105
+ 564106
52
@@ -5183,7 +5255,7 @@
1
2
- 7051449
+ 7051453
2
@@ -5204,7 +5276,7 @@
1
2
- 5640311
+ 5640314
2
@@ -5240,17 +5312,17 @@
1
2
- 5024934
+ 5024937
2
3
- 743741
+ 743742
3
4
- 539530
+ 539531
4
@@ -5260,7 +5332,7 @@
12
72
- 562733
+ 562734
72
@@ -5580,15 +5652,15 @@
files
- 65198
+ 65204
id
- 65198
+ 65204
name
- 65198
+ 65204
@@ -5602,7 +5674,7 @@
1
2
- 65198
+ 65204
@@ -5618,7 +5690,7 @@
1
2
- 65198
+ 65204
@@ -5628,15 +5700,15 @@
folders
- 12387
+ 12388
id
- 12387
+ 12388
name
- 12387
+ 12388
@@ -5650,7 +5722,7 @@
1
2
- 12387
+ 12388
@@ -5666,7 +5738,7 @@
1
2
- 12387
+ 12388
@@ -5676,15 +5748,15 @@
containerparent
- 77564
+ 77571
parent
- 12387
+ 12388
child
- 77564
+ 77571
@@ -5698,7 +5770,7 @@
1
2
- 6029
+ 6030
2
@@ -5749,7 +5821,7 @@
1
2
- 77564
+ 77571
@@ -5759,11 +5831,11 @@
numlines
- 807861
+ 807862
element_id
- 806738
+ 806739
num_lines
@@ -7237,11 +7309,11 @@
fileannotations
- 4199643
+ 4200019
id
- 5765
+ 5766
kind
@@ -7249,11 +7321,11 @@
name
- 58704
+ 58709
value
- 39505
+ 39509
@@ -7288,12 +7360,12 @@
1
86
- 432
+ 433
88
206
- 432
+ 433
212
@@ -7303,17 +7375,17 @@
291
359
- 432
+ 433
362
401
- 432
+ 433
402
479
- 432
+ 433
480
@@ -7328,7 +7400,7 @@
553
628
- 432
+ 433
631
@@ -7359,17 +7431,17 @@
1
98
- 432
+ 433
102
244
- 432
+ 433
244
351
- 432
+ 433
352
@@ -7384,7 +7456,7 @@
490
628
- 432
+ 433
632
@@ -7399,22 +7471,22 @@
710
939
- 432
+ 433
939
1038
- 432
+ 433
1066
1853
- 432
+ 433
1853
3292
- 432
+ 433
3423
@@ -7498,7 +7570,7 @@
1
2
- 11024
+ 11025
2
@@ -7518,12 +7590,12 @@
7
9
- 4593
+ 4594
9
16
- 4329
+ 4330
16
@@ -7533,12 +7605,12 @@
19
27
- 4255
+ 4256
27
47
- 4836
+ 4837
47
@@ -7569,7 +7641,7 @@
1
2
- 58704
+ 58709
@@ -7585,12 +7657,12 @@
1
2
- 11584
+ 11585
2
3
- 7687
+ 7688
3
@@ -7600,7 +7672,7 @@
4
6
- 4065
+ 4066
6
@@ -7630,7 +7702,7 @@
41
95
- 4466
+ 4467
95
@@ -7691,12 +7763,12 @@
51
58
- 3030
+ 3031
58
80
- 2977
+ 2978
81
@@ -7706,7 +7778,7 @@
151
334
- 2977
+ 2978
334
@@ -7732,7 +7804,7 @@
1
2
- 39495
+ 39498
2
@@ -7763,7 +7835,7 @@
4
5
- 3051
+ 3052
5
@@ -7773,7 +7845,7 @@
8
14
- 3484
+ 3485
14
@@ -7783,17 +7855,17 @@
18
28
- 3199
+ 3200
28
34
- 3146
+ 3147
34
41
- 3199
+ 3200
41
@@ -7813,7 +7885,7 @@
113
145
- 3030
+ 3031
145
@@ -7828,15 +7900,15 @@
inmacroexpansion
- 149997201
+ 149997296
id
- 24671160
+ 24671176
inv
- 3705370
+ 3705372
@@ -7850,37 +7922,37 @@
1
3
- 2209511
+ 2209512
3
5
- 1474989
+ 1474990
5
6
- 1620381
+ 1620382
6
7
- 6582595
+ 6582599
7
8
- 8719067
+ 8719073
8
9
- 3557076
+ 3557078
9
22
- 507538
+ 507539
@@ -7901,7 +7973,7 @@
2
3
- 743238
+ 743239
3
@@ -7931,12 +8003,12 @@
10
11
- 444653
+ 444654
11
337
- 307800
+ 307801
339
@@ -7956,15 +8028,15 @@
affectedbymacroexpansion
- 48736214
+ 48736245
id
- 7044796
+ 7044800
inv
- 3803150
+ 3803153
@@ -7978,12 +8050,12 @@
1
2
- 3846740
+ 3846743
2
3
- 766310
+ 766311
3
@@ -7993,7 +8065,7 @@
4
5
- 772742
+ 772743
5
@@ -8003,7 +8075,7 @@
12
50
- 556271
+ 556272
50
@@ -8054,7 +8126,7 @@
14
15
- 408041
+ 408042
15
@@ -8064,7 +8136,7 @@
16
17
- 377680
+ 377681
17
@@ -8094,11 +8166,11 @@
macroinvocations
- 40354035
+ 40354061
id
- 40354035
+ 40354061
macro_id
@@ -8106,7 +8178,7 @@
location
- 5919825
+ 5919829
kind
@@ -8124,7 +8196,7 @@
1
2
- 40354035
+ 40354061
@@ -8140,7 +8212,7 @@
1
2
- 40354035
+ 40354061
@@ -8156,7 +8228,7 @@
1
2
- 40354035
+ 40354061
@@ -8279,7 +8351,7 @@
1
2
- 177858
+ 177859
2
@@ -8300,12 +8372,12 @@
1
2
- 5256857
+ 5256860
2
4
- 428527
+ 428528
4
@@ -8326,7 +8398,7 @@
1
2
- 5897661
+ 5897665
2
@@ -8347,7 +8419,7 @@
1
2
- 5919825
+ 5919829
@@ -8420,15 +8492,15 @@
macroparent
- 33658296
+ 33658318
id
- 33658296
+ 33658318
parent_id
- 15929098
+ 15929108
@@ -8442,7 +8514,7 @@
1
2
- 33658296
+ 33658318
@@ -8458,17 +8530,17 @@
1
2
- 7809235
+ 7809240
2
3
- 1595502
+ 1595503
3
4
- 4703022
+ 4703025
4
@@ -8488,15 +8560,15 @@
macrolocationbind
- 6032778
+ 6033959
id
- 4216419
+ 4217710
location
- 2276207
+ 2276069
@@ -8510,12 +8582,12 @@
1
2
- 3291436
+ 3292783
2
3
- 490596
+ 490566
3
@@ -8525,12 +8597,12 @@
4
5
- 413328
+ 413303
5
17
- 13171
+ 13170
@@ -8546,12 +8618,12 @@
1
2
- 1335195
+ 1335114
2
3
- 481486
+ 481456
3
@@ -8561,12 +8633,12 @@
4
5
- 427639
+ 427613
5
522
- 24087
+ 24085
@@ -8576,19 +8648,19 @@
macro_argument_unexpanded
- 82481176
+ 82486758
invocation
- 26280397
+ 26280952
argument_index
- 696
+ 697
text
- 343195
+ 343226
@@ -8602,22 +8674,22 @@
1
2
- 9681115
+ 9680186
2
3
- 9768522
+ 9769396
3
4
- 5001183
+ 5001631
4
67
- 1829575
+ 1829739
@@ -8633,22 +8705,22 @@
1
2
- 9863712
+ 9862798
2
3
- 9786062
+ 9786938
3
4
- 4844554
+ 4844988
4
67
- 1786067
+ 1786227
@@ -8673,7 +8745,7 @@
646840
- 2488628
+ 2488458
31
@@ -8716,52 +8788,52 @@
1
2
- 39695
+ 39699
2
3
- 62315
+ 62321
3
4
- 21025
+ 21027
4
5
- 34574
+ 34577
5
6
- 39241
+ 39245
6
9
- 30867
+ 30870
9
15
- 28977
+ 28979
15
26
- 25883
+ 25885
26
57
- 27139
+ 27142
57
517
- 25988
+ 25990
518
@@ -8782,17 +8854,17 @@
1
2
- 243127
+ 243149
2
3
- 89856
+ 89864
3
9
- 10211
+ 10212
@@ -8802,19 +8874,19 @@
macro_argument_expanded
- 82481176
+ 82486758
invocation
- 26280397
+ 26280952
argument_index
- 696
+ 697
text
- 207888
+ 207906
@@ -8828,22 +8900,22 @@
1
2
- 9681115
+ 9680186
2
3
- 9768522
+ 9769396
3
4
- 5001183
+ 5001631
4
67
- 1829575
+ 1829739
@@ -8859,22 +8931,22 @@
1
2
- 12639154
+ 12638489
2
3
- 8426648
+ 8427402
3
4
- 4224417
+ 4224795
4
9
- 990177
+ 990265
@@ -8899,7 +8971,7 @@
646840
- 2488628
+ 2488458
31
@@ -8942,22 +9014,22 @@
1
2
- 21827
+ 21829
2
3
- 26854
+ 26856
3
4
- 43486
+ 43490
4
5
- 15903
+ 15905
5
@@ -8967,32 +9039,32 @@
6
7
- 18395
+ 18397
7
10
- 18966
+ 18967
10
19
- 18321
+ 18323
19
51
- 15776
+ 15778
51
252
- 15597
+ 15598
252
- 1169531
- 9493
+ 1169361
+ 9494
@@ -9008,17 +9080,17 @@
1
2
- 105063
+ 105072
2
3
- 88895
+ 88903
3
66
- 13928
+ 13930
@@ -9028,15 +9100,15 @@
functions
- 4049287
+ 4049290
id
- 4049287
+ 4049290
name
- 1693315
+ 1693316
kind
@@ -9054,7 +9126,7 @@
1
2
- 4049287
+ 4049290
@@ -9070,7 +9142,7 @@
1
2
- 4049287
+ 4049290
@@ -9112,7 +9184,7 @@
1
2
- 1690446
+ 1690447
2
@@ -9219,26 +9291,26 @@
builtin_functions
- 30920
+ 30923
id
- 30920
+ 30923
function_entry_point
- 1141750
+ 1141776
id
- 1138003
+ 1138028
entry_point
- 1141750
+ 1141776
@@ -9252,7 +9324,7 @@
1
2
- 1134801
+ 1134826
2
@@ -9273,7 +9345,7 @@
1
2
- 1141750
+ 1141776
@@ -9283,11 +9355,11 @@
function_return_type
- 4066752
+ 4066754
id
- 4049287
+ 4049290
return_type
@@ -9305,7 +9377,7 @@
1
2
- 4031823
+ 4031825
2
@@ -9637,33 +9709,33 @@
function_deleted
- 87973
+ 87963
id
- 87973
+ 87963
function_defaulted
- 51614
+ 51609
id
- 51614
+ 51609
function_prototyped
- 4047790
+ 4047793
id
- 4047790
+ 4047793
@@ -9743,11 +9815,11 @@
member_function_this_type
- 674132
+ 674133
id
- 674132
+ 674133
this_type
@@ -9765,7 +9837,7 @@
1
2
- 674132
+ 674133
@@ -9821,15 +9893,15 @@
fun_decls
- 4208839
+ 4208841
id
- 4202851
+ 4202854
function
- 4024712
+ 4024715
type_id
@@ -9837,11 +9909,11 @@
name
- 1691818
+ 1691819
location
- 2813169
+ 2813171
@@ -9855,7 +9927,7 @@
1
2
- 4202851
+ 4202854
@@ -9871,7 +9943,7 @@
1
2
- 4196863
+ 4196866
2
@@ -9892,7 +9964,7 @@
1
2
- 4202851
+ 4202854
@@ -9908,7 +9980,7 @@
1
2
- 4202851
+ 4202854
@@ -9924,7 +9996,7 @@
1
2
- 3861169
+ 3861171
2
@@ -9945,7 +10017,7 @@
1
2
- 4006250
+ 4006252
2
@@ -9966,7 +10038,7 @@
1
2
- 4024712
+ 4024715
@@ -9982,7 +10054,7 @@
1
2
- 3881627
+ 3881630
2
@@ -10039,7 +10111,7 @@
1
2
- 305255
+ 305256
2
@@ -10194,7 +10266,7 @@
1
2
- 1602001
+ 1602002
2
@@ -10215,7 +10287,7 @@
1
2
- 1367227
+ 1367228
2
@@ -10241,12 +10313,12 @@
1
2
- 2420216
+ 2420218
2
3
- 251489
+ 251490
3
@@ -10267,12 +10339,12 @@
1
2
- 2438928
+ 2438930
2
3
- 233276
+ 233277
3
@@ -10293,7 +10365,7 @@
1
2
- 2698776
+ 2698778
2
@@ -10314,7 +10386,7 @@
1
2
- 2773999
+ 2774000
2
@@ -10329,11 +10401,11 @@
fun_def
- 1422240
+ 1422241
id
- 1422240
+ 1422241
@@ -10362,11 +10434,11 @@
fun_decl_specifiers
- 4279570
+ 4279573
id
- 1748204
+ 1748205
name
@@ -10394,7 +10466,7 @@
3
4
- 1100143
+ 1100144
4
@@ -10607,15 +10679,15 @@
fun_decl_noexcept
- 141820
+ 141823
fun_decl
- 141820
+ 141823
constant
- 141343
+ 141346
@@ -10629,7 +10701,7 @@
1
2
- 141820
+ 141823
@@ -10645,7 +10717,7 @@
1
2
- 140900
+ 140903
2
@@ -10671,15 +10743,15 @@
fun_decl_typedef_type
- 2759
+ 2760
fun_decl
- 2759
+ 2760
typedeftype_id
- 123
+ 124
@@ -10693,7 +10765,7 @@
1
2
- 2759
+ 2760
@@ -10709,57 +10781,57 @@
1
2
- 39
+ 40
2
3
- 11
+ 12
3
4
- 11
+ 12
5
13
- 7
+ 8
16
17
- 11
+ 12
17
18
- 3
+ 4
21
22
- 7
+ 8
25
43
- 7
+ 8
46
55
- 7
+ 8
89
128
- 7
+ 8
158
159
- 3
+ 4
@@ -10769,11 +10841,11 @@
fun_requires
- 29073
+ 29070
id
- 10099
+ 10098
kind
@@ -10781,7 +10853,7 @@
constraint
- 28837
+ 28834
@@ -10795,7 +10867,7 @@
1
2
- 10035
+ 10033
2
@@ -10816,7 +10888,7 @@
1
2
- 7263
+ 7262
2
@@ -10899,7 +10971,7 @@
1
2
- 28600
+ 28597
2
@@ -10920,7 +10992,7 @@
1
2
- 28837
+ 28834
@@ -10930,11 +11002,11 @@
param_decl_bind
- 7310174
+ 7310179
id
- 7310174
+ 7310179
index
@@ -10942,7 +11014,7 @@
fun_decl
- 3531587
+ 3531589
@@ -10956,7 +11028,7 @@
1
2
- 7310174
+ 7310179
@@ -10972,7 +11044,7 @@
1
2
- 7310174
+ 7310179
@@ -11070,7 +11142,7 @@
1
2
- 1508939
+ 1508940
2
@@ -11106,7 +11178,7 @@
1
2
- 1508939
+ 1508940
2
@@ -11136,19 +11208,19 @@
var_decls
- 9389956
+ 9389962
id
- 9383095
+ 9383101
variable
- 9034677
+ 9034682
type_id
- 1456421
+ 1456422
name
@@ -11156,7 +11228,7 @@
location
- 6274400
+ 6274404
@@ -11170,7 +11242,7 @@
1
2
- 9383095
+ 9383101
@@ -11186,7 +11258,7 @@
1
2
- 9376234
+ 9376240
2
@@ -11207,7 +11279,7 @@
1
2
- 9383095
+ 9383101
@@ -11223,7 +11295,7 @@
1
2
- 9383095
+ 9383101
@@ -11239,12 +11311,12 @@
1
2
- 8703723
+ 8703728
2
5
- 330953
+ 330954
@@ -11260,7 +11332,7 @@
1
2
- 8981160
+ 8981166
2
@@ -11281,7 +11353,7 @@
1
2
- 8929265
+ 8929271
2
@@ -11302,7 +11374,7 @@
1
2
- 8783062
+ 8783068
2
@@ -11328,7 +11400,7 @@
2
3
- 284048
+ 284049
3
@@ -11395,7 +11467,7 @@
1
2
- 1119479
+ 1119480
2
@@ -11426,7 +11498,7 @@
1
2
- 985376
+ 985377
2
@@ -11482,7 +11554,7 @@
7
25
- 64119
+ 64120
25
@@ -11503,7 +11575,7 @@
1
2
- 478903
+ 478904
2
@@ -11611,7 +11683,7 @@
1
2
- 5774663
+ 5774667
2
@@ -11637,7 +11709,7 @@
1
2
- 5855499
+ 5855503
2
@@ -11658,7 +11730,7 @@
1
2
- 5975880
+ 5975884
2
@@ -11679,7 +11751,7 @@
1
2
- 6262050
+ 6262054
2
@@ -11694,11 +11766,11 @@
var_def
- 3766860
+ 3766862
id
- 3766860
+ 3766862
@@ -11848,19 +11920,19 @@
type_decls
- 1633437
+ 1633438
id
- 1633437
+ 1633438
type_id
- 1614475
+ 1614476
location
- 1547361
+ 1547362
@@ -11874,7 +11946,7 @@
1
2
- 1633437
+ 1633438
@@ -11890,7 +11962,7 @@
1
2
- 1633437
+ 1633438
@@ -11906,7 +11978,7 @@
1
2
- 1598133
+ 1598134
2
@@ -11927,7 +11999,7 @@
1
2
- 1598258
+ 1598259
2
@@ -11948,7 +12020,7 @@
1
2
- 1525281
+ 1525282
2
@@ -11969,7 +12041,7 @@
1
2
- 1525406
+ 1525407
2
@@ -11995,18 +12067,18 @@
type_decl_top
- 675275
+ 675276
type_decl
- 675275
+ 675276
type_requires
- 7671
+ 7670
id
@@ -12014,7 +12086,7 @@
constraint
- 7649
+ 7648
@@ -12064,7 +12136,7 @@
1
2
- 7628
+ 7627
2
@@ -12079,11 +12151,11 @@
namespace_decls
- 407917
+ 407918
id
- 407917
+ 407918
namespace_id
@@ -12091,11 +12163,11 @@
location
- 407917
+ 407918
bodylocation
- 407917
+ 407918
@@ -12109,7 +12181,7 @@
1
2
- 407917
+ 407918
@@ -12125,7 +12197,7 @@
1
2
- 407917
+ 407918
@@ -12141,7 +12213,7 @@
1
2
- 407917
+ 407918
@@ -12355,7 +12427,7 @@
1
2
- 407917
+ 407918
@@ -12371,7 +12443,7 @@
1
2
- 407917
+ 407918
@@ -12387,7 +12459,7 @@
1
2
- 407917
+ 407918
@@ -12403,7 +12475,7 @@
1
2
- 407917
+ 407918
@@ -12419,7 +12491,7 @@
1
2
- 407917
+ 407918
@@ -12435,7 +12507,7 @@
1
2
- 407917
+ 407918
@@ -12445,19 +12517,19 @@
usings
- 272030
+ 272192
id
- 272030
+ 272192
element_id
- 59042
+ 59184
location
- 26844
+ 26846
kind
@@ -12475,7 +12547,7 @@
1
2
- 272030
+ 272192
@@ -12491,7 +12563,7 @@
1
2
- 272030
+ 272192
@@ -12507,7 +12579,7 @@
1
2
- 272030
+ 272192
@@ -12523,12 +12595,12 @@
1
2
- 51312
+ 51453
2
5
- 5385
+ 5386
5
@@ -12549,12 +12621,12 @@
1
2
- 51312
+ 51453
2
5
- 5385
+ 5386
5
@@ -12575,7 +12647,7 @@
1
2
- 59042
+ 59184
@@ -12591,21 +12663,21 @@
1
2
- 21173
+ 21175
2
4
- 2302
+ 2291
4
132
- 1943
+ 1953
145
- 367
+ 371
1425
@@ -12622,21 +12694,21 @@
1
2
- 21173
+ 21175
2
4
- 2302
+ 2291
4
132
- 1943
+ 1953
145
- 367
+ 371
1425
@@ -12653,7 +12725,7 @@
1
2
- 26844
+ 26846
@@ -12672,8 +12744,8 @@
10
- 25367
- 25368
+ 25380
+ 25381
10
@@ -12693,8 +12765,8 @@
10
- 5377
- 5378
+ 5390
+ 5391
10
@@ -12726,15 +12798,15 @@
using_container
- 580040
+ 580229
parent
- 21891
+ 21914
child
- 272030
+ 272192
@@ -12748,7 +12820,7 @@
1
2
- 10370
+ 10371
2
@@ -12763,7 +12835,7 @@
6
7
- 2291
+ 2312
7
@@ -12778,7 +12850,7 @@
145
146
- 2618
+ 2619
146
@@ -12799,27 +12871,27 @@
1
2
- 96583
+ 96729
2
3
- 120259
+ 120270
3
4
- 20096
+ 20097
4
5
- 26706
+ 26709
5
65
- 8384
+ 8385
@@ -13094,7 +13166,7 @@
1
2
- 30262
+ 30263
2
@@ -13170,7 +13242,7 @@
17
18
- 4386
+ 4387
19
@@ -13231,7 +13303,7 @@
17
18
- 4386
+ 4387
19
@@ -13437,15 +13509,15 @@
params
- 7060555
+ 7060560
id
- 7019638
+ 7019643
function
- 3404844
+ 3404846
index
@@ -13467,7 +13539,7 @@
1
2
- 7019638
+ 7019643
@@ -13483,7 +13555,7 @@
1
2
- 7019638
+ 7019643
@@ -13499,7 +13571,7 @@
1
2
- 6978721
+ 6978726
2
@@ -13520,12 +13592,12 @@
1
2
- 1473137
+ 1473138
2
3
- 926246
+ 926247
3
@@ -13540,7 +13612,7 @@
5
65
- 145953
+ 145954
@@ -13556,12 +13628,12 @@
1
2
- 1473137
+ 1473138
2
3
- 926246
+ 926247
3
@@ -13576,7 +13648,7 @@
5
65
- 145953
+ 145954
@@ -13592,17 +13664,17 @@
1
2
- 1781636
+ 1781637
2
3
- 1030659
+ 1030660
3
4
- 437487
+ 437488
4
@@ -13782,7 +13854,7 @@
1
2
- 819587
+ 819588
2
@@ -13818,7 +13890,7 @@
1
2
- 995106
+ 995107
2
@@ -13916,11 +13988,11 @@
membervariables
- 1501943
+ 1501944
id
- 1499493
+ 1499494
type_id
@@ -13928,7 +14000,7 @@
name
- 642219
+ 642220
@@ -13942,7 +14014,7 @@
1
2
- 1497151
+ 1497152
2
@@ -13963,7 +14035,7 @@
1
2
- 1499493
+ 1499494
@@ -14046,7 +14118,7 @@
2
3
- 122420
+ 122421
3
@@ -14278,19 +14350,19 @@
localvariables
- 725806
+ 726016
id
- 725806
+ 726016
type_id
- 53403
+ 53423
name
- 101564
+ 101594
@@ -14304,7 +14376,7 @@
1
2
- 725806
+ 726016
@@ -14320,7 +14392,7 @@
1
2
- 725806
+ 726016
@@ -14336,37 +14408,37 @@
1
2
- 28845
+ 28857
2
3
- 7838
+ 7840
3
4
- 4027
+ 4028
4
6
- 4063
+ 4064
6
12
- 4131
+ 4132
12
162
- 4007
+ 4008
162
19347
- 491
+ 492
@@ -14382,22 +14454,22 @@
1
2
- 38343
+ 38358
2
3
- 6702
+ 6704
3
5
- 4474
+ 4476
5
3509
- 3883
+ 3884
@@ -14413,32 +14485,32 @@
1
2
- 62497
+ 62515
2
3
- 16028
+ 16032
3
4
- 6526
+ 6528
4
8
- 8142
+ 8144
8
134
- 7618
+ 7620
134
7549
- 751
+ 752
@@ -14454,22 +14526,22 @@
1
2
- 84528
+ 84553
2
3
- 8406
+ 8408
3
15
- 7678
+ 7680
15
1509
- 951
+ 952
@@ -14547,15 +14619,15 @@
orphaned_variables
- 44320
+ 44321
var
- 44320
+ 44321
function
- 41050
+ 41051
@@ -14569,7 +14641,7 @@
1
2
- 44320
+ 44321
@@ -14585,7 +14657,7 @@
1
2
- 40198
+ 40199
2
@@ -15318,7 +15390,7 @@
1
2
- 347167
+ 347168
2
@@ -15339,7 +15411,7 @@
1
2
- 347167
+ 347168
2
@@ -15392,7 +15464,7 @@
1
2
- 347167
+ 347168
2
@@ -16179,15 +16251,15 @@
derivedtypes
- 3030853
+ 3030855
id
- 3030853
+ 3030855
name
- 1460537
+ 1460538
kind
@@ -16195,7 +16267,7 @@
type_id
- 1946677
+ 1946678
@@ -16209,7 +16281,7 @@
1
2
- 3030853
+ 3030855
@@ -16225,7 +16297,7 @@
1
2
- 3030853
+ 3030855
@@ -16241,7 +16313,7 @@
1
2
- 3030853
+ 3030855
@@ -16257,7 +16329,7 @@
1
2
- 1344024
+ 1344025
2
@@ -16283,7 +16355,7 @@
1
2
- 1460537
+ 1460538
@@ -16299,7 +16371,7 @@
1
2
- 1344148
+ 1344149
2
@@ -16510,7 +16582,7 @@
1
2
- 1319324
+ 1319325
2
@@ -16535,11 +16607,11 @@
pointerishsize
- 2247317
+ 2247318
id
- 2247317
+ 2247318
size
@@ -16561,7 +16633,7 @@
1
2
- 2247317
+ 2247318
@@ -16577,7 +16649,7 @@
1
2
- 2247317
+ 2247318
@@ -17100,15 +17172,15 @@
typedefbase
- 1762011
+ 1762169
id
- 1762011
+ 1762169
type_id
- 837877
+ 837952
@@ -17122,7 +17194,7 @@
1
2
- 1762011
+ 1762169
@@ -17138,22 +17210,22 @@
1
2
- 662420
+ 662479
2
3
- 80933
+ 80940
3
6
- 64163
+ 64169
6
4526
- 30360
+ 30363
@@ -17163,7 +17235,7 @@
decltypes
- 814485
+ 814486
id
@@ -17171,7 +17243,7 @@
expr
- 814485
+ 814486
kind
@@ -17301,7 +17373,7 @@
1
2
- 814485
+ 814486
@@ -17317,7 +17389,7 @@
1
2
- 814485
+ 814486
@@ -17333,7 +17405,7 @@
1
2
- 814485
+ 814486
@@ -17349,7 +17421,7 @@
1
2
- 814485
+ 814486
@@ -17611,15 +17683,15 @@
type_operators
- 7950
+ 7949
id
- 7950
+ 7949
arg_type
- 7177
+ 7176
kind
@@ -17627,7 +17699,7 @@
base_type
- 5243
+ 5242
@@ -17641,7 +17713,7 @@
1
2
- 7950
+ 7949
@@ -17657,7 +17729,7 @@
1
2
- 7950
+ 7949
@@ -17673,7 +17745,7 @@
1
2
- 7950
+ 7949
@@ -17689,7 +17761,7 @@
1
2
- 6403
+ 6402
2
@@ -17710,7 +17782,7 @@
1
2
- 6403
+ 6402
2
@@ -17731,7 +17803,7 @@
1
2
- 7155
+ 7154
2
@@ -17927,15 +17999,15 @@
usertypes
- 4150876
+ 4151247
id
- 4150876
+ 4151247
name
- 918367
+ 918449
kind
@@ -17953,7 +18025,7 @@
1
2
- 4150876
+ 4151247
@@ -17969,7 +18041,7 @@
1
2
- 4150876
+ 4151247
@@ -17985,22 +18057,22 @@
1
2
- 654151
+ 654210
2
3
- 158635
+ 158649
3
8
- 70552
+ 70559
8
32672
- 35028
+ 35031
@@ -18016,12 +18088,12 @@
1
2
- 866633
+ 866710
2
10
- 51734
+ 51739
@@ -18173,11 +18245,11 @@
usertypesize
- 1363554
+ 1363676
id
- 1363554
+ 1363676
size
@@ -18199,7 +18271,7 @@
1
2
- 1363554
+ 1363676
@@ -18215,7 +18287,7 @@
1
2
- 1363554
+ 1363676
@@ -18473,11 +18545,11 @@
usertype_alias_kind
- 1762011
+ 1762169
id
- 1762011
+ 1762169
alias_kind
@@ -18495,7 +18567,7 @@
1
2
- 1762011
+ 1762169
@@ -18526,26 +18598,26 @@
nontype_template_parameters
- 766231
+ 766248
id
- 766231
+ 766248
type_template_type_constraint
- 27118
+ 27115
id
- 13365
+ 13364
constraint
- 25979
+ 25976
@@ -18559,7 +18631,7 @@
1
2
- 10206
+ 10205
2
@@ -18595,7 +18667,7 @@
1
2
- 24840
+ 24837
2
@@ -18610,15 +18682,15 @@
mangled_name
- 7853946
+ 7853951
id
- 7853946
+ 7853951
mangled_name
- 6364342
+ 6364346
is_complete
@@ -18636,7 +18708,7 @@
1
2
- 7853946
+ 7853951
@@ -18652,7 +18724,7 @@
1
2
- 7853946
+ 7853951
@@ -18668,7 +18740,7 @@
1
2
- 6036258
+ 6036261
2
@@ -18689,7 +18761,7 @@
1
2
- 6364342
+ 6364346
@@ -18741,59 +18813,59 @@
is_pod_class
- 593785
+ 593798
id
- 593785
+ 593798
is_standard_layout_class
- 1124207
+ 1124307
id
- 1124207
+ 1124307
is_complete
- 1346034
+ 1346155
id
- 1346034
+ 1346155
is_class_template
- 232123
+ 232144
id
- 232123
+ 232144
class_instantiation
- 1125875
+ 1125965
to
- 1122823
+ 1122924
from
- 71788
+ 71794
@@ -18807,12 +18879,12 @@
1
2
- 1120680
+ 1120790
2
8
- 2143
+ 2133
@@ -18828,12 +18900,12 @@
1
2
- 20497
+ 20499
2
3
- 12883
+ 12884
3
@@ -18848,27 +18920,27 @@
5
7
- 6061
+ 6072
7
10
- 5723
+ 5713
10
17
- 5913
+ 5903
17
51
- 5385
+ 5396
51
4223
- 3558
+ 3559
@@ -18878,11 +18950,11 @@
class_template_argument
- 2898088
+ 2898347
type_id
- 1366848
+ 1366971
index
@@ -18890,7 +18962,7 @@
arg_type
- 821942
+ 822016
@@ -18904,27 +18976,27 @@
1
2
- 579258
+ 579310
2
3
- 410210
+ 410247
3
4
- 250994
+ 251017
4
7
- 103078
+ 103087
7
113
- 23306
+ 23308
@@ -18940,22 +19012,22 @@
1
2
- 607792
+ 607846
2
3
- 424213
+ 424251
3
4
- 251829
+ 251851
4
113
- 83013
+ 83021
@@ -19063,22 +19135,22 @@
1
2
- 513626
+ 513672
2
3
- 167611
+ 167626
3
5
- 75072
+ 75079
5
47
- 61724
+ 61729
47
@@ -19099,17 +19171,17 @@
1
2
- 723679
+ 723744
2
3
- 79898
+ 79905
3
22
- 18364
+ 18365
@@ -19119,11 +19191,11 @@
class_template_argument_value
- 510048
+ 510060
type_id
- 205797
+ 205802
index
@@ -19131,7 +19203,7 @@
arg_value
- 509912
+ 509924
@@ -19145,12 +19217,12 @@
1
2
- 155787
+ 155791
2
3
- 43367
+ 43368
3
@@ -19171,12 +19243,12 @@
1
2
- 147918
+ 147921
2
3
- 40471
+ 40472
3
@@ -19314,7 +19386,7 @@
1
2
- 509776
+ 509787
2
@@ -19335,7 +19407,7 @@
1
2
- 509912
+ 509924
@@ -19345,15 +19417,15 @@
is_proxy_class_for
- 48429
+ 48433
id
- 48429
+ 48433
templ_param_id
- 45757
+ 45761
@@ -19367,7 +19439,7 @@
1
2
- 48429
+ 48433
@@ -19383,7 +19455,7 @@
1
2
- 45039
+ 45043
2
@@ -19398,11 +19470,11 @@
type_mentions
- 5907627
+ 5907630
id
- 5907627
+ 5907630
type_id
@@ -19410,7 +19482,7 @@
location
- 5851317
+ 5851321
kind
@@ -19428,7 +19500,7 @@
1
2
- 5907627
+ 5907630
@@ -19444,7 +19516,7 @@
1
2
- 5907627
+ 5907630
@@ -19460,7 +19532,7 @@
1
2
- 5907627
+ 5907630
@@ -19594,7 +19666,7 @@
1
2
- 5805627
+ 5805631
2
@@ -19615,7 +19687,7 @@
1
2
- 5805627
+ 5805631
2
@@ -19636,7 +19708,7 @@
1
2
- 5851317
+ 5851321
@@ -19705,15 +19777,15 @@
function_instantiation
- 973767
+ 973788
to
- 973767
+ 973788
from
- 182700
+ 182704
@@ -19727,7 +19799,7 @@
1
2
- 973767
+ 973788
@@ -19743,12 +19815,12 @@
1
2
- 110581
+ 110583
2
3
- 42787
+ 42788
3
@@ -19758,7 +19830,7 @@
9
104
- 13728
+ 13729
119
@@ -19773,11 +19845,11 @@
function_template_argument
- 2484632
+ 2484687
function_id
- 1453189
+ 1453222
index
@@ -19785,7 +19857,7 @@
arg_type
- 297982
+ 297989
@@ -19799,22 +19871,22 @@
1
2
- 782958
+ 782976
2
3
- 413128
+ 413137
3
4
- 171799
+ 171802
4
15
- 85303
+ 85305
@@ -19830,22 +19902,22 @@
1
2
- 802104
+ 802122
2
3
- 411221
+ 411230
3
4
- 169618
+ 169622
4
9
- 70245
+ 70247
@@ -19983,12 +20055,12 @@
1
2
- 174762
+ 174766
2
3
- 26333
+ 26334
3
@@ -20003,17 +20075,17 @@
6
11
- 23233
+ 23234
11
76
- 23369
+ 23370
79
2452
- 7630
+ 7631
@@ -20029,7 +20101,7 @@
1
2
- 256795
+ 256801
2
@@ -20049,11 +20121,11 @@
function_template_argument_value
- 452748
+ 452758
function_id
- 196770
+ 196774
index
@@ -20061,7 +20133,7 @@
arg_value
- 450057
+ 450067
@@ -20075,12 +20147,12 @@
1
2
- 151393
+ 151396
2
3
- 42890
+ 42891
3
@@ -20101,7 +20173,7 @@
1
2
- 144477
+ 144480
2
@@ -20254,7 +20326,7 @@
1
2
- 447365
+ 447375
2
@@ -20275,7 +20347,7 @@
1
2
- 450057
+ 450067
@@ -20379,7 +20451,7 @@
variable_template_argument
- 768940
+ 768941
variable_id
@@ -20849,7 +20921,7 @@
template_template_argument
- 9673
+ 9674
type_id
@@ -20861,7 +20933,7 @@
arg_type
- 9081
+ 9082
@@ -21080,7 +21152,7 @@
1
2
- 9060
+ 9061
2
@@ -21231,19 +21303,19 @@
concept_templates
- 3610
+ 3609
concept_id
- 3610
+ 3609
name
- 3610
+ 3609
location
- 3610
+ 3609
@@ -21257,7 +21329,7 @@
1
2
- 3610
+ 3609
@@ -21273,7 +21345,7 @@
1
2
- 3610
+ 3609
@@ -21289,7 +21361,7 @@
1
2
- 3610
+ 3609
@@ -21305,7 +21377,7 @@
1
2
- 3610
+ 3609
@@ -21321,7 +21393,7 @@
1
2
- 3610
+ 3609
@@ -21337,7 +21409,7 @@
1
2
- 3610
+ 3609
@@ -21347,15 +21419,15 @@
concept_instantiation
- 90315
+ 90305
to
- 90315
+ 90305
from
- 3438
+ 3437
@@ -21369,7 +21441,7 @@
1
2
- 90315
+ 90305
@@ -21465,22 +21537,22 @@
is_type_constraint
- 36852
+ 36848
concept_id
- 36852
+ 36848
concept_template_argument
- 112899
+ 112887
concept_id
- 76283
+ 76275
index
@@ -21488,7 +21560,7 @@
arg_type
- 21402
+ 21399
@@ -21502,12 +21574,12 @@
1
2
- 46414
+ 46409
2
3
- 24647
+ 24644
3
@@ -21528,12 +21600,12 @@
1
2
- 50024
+ 50019
2
3
- 22347
+ 22345
3
@@ -21636,7 +21708,7 @@
1
2
- 10378
+ 10377
2
@@ -21687,12 +21759,12 @@
1
2
- 18007
+ 18005
2
3
- 3266
+ 3265
3
@@ -21838,15 +21910,15 @@
routinetypes
- 604482
+ 604495
id
- 604482
+ 604495
return_type
- 283845
+ 283851
@@ -21860,7 +21932,7 @@
1
2
- 604482
+ 604495
@@ -21876,7 +21948,7 @@
1
2
- 234073
+ 234078
2
@@ -21896,7 +21968,7 @@
routinetypeargs
- 1178519
+ 1178520
routine
@@ -21908,7 +21980,7 @@
type_id
- 112073
+ 112074
@@ -22262,15 +22334,15 @@
ptrtomembers
- 9725
+ 9726
id
- 9725
+ 9726
type_id
- 7972
+ 7973
class_id
@@ -22288,7 +22360,7 @@
1
2
- 9725
+ 9726
@@ -22304,7 +22376,7 @@
1
2
- 9725
+ 9726
@@ -22362,7 +22434,7 @@
1
2
- 3896
+ 3897
2
@@ -22393,7 +22465,7 @@
1
2
- 3896
+ 3897
2
@@ -22466,15 +22538,15 @@
typespecifiers
- 854142
+ 854164
type_id
- 846657
+ 849020
spec_id
- 1621
+ 95
@@ -22488,12 +22560,12 @@
1
2
- 839173
+ 843877
2
3
- 7484
+ 5143
@@ -22507,69 +22579,49 @@
12
- 1
- 2
- 124
+ 168
+ 169
+ 10
- 2
- 3
- 124
+ 215
+ 216
+ 10
- 16
- 17
- 124
+ 225
+ 226
+ 10
- 17
- 18
- 124
+ 533
+ 534
+ 10
- 24
- 25
- 124
+ 821
+ 822
+ 10
- 44
- 45
- 124
+ 1568
+ 1569
+ 10
- 49
- 50
- 124
+ 4195
+ 4196
+ 10
- 51
- 52
- 124
+ 18295
+ 18296
+ 10
- 112
- 113
- 124
-
-
- 199
- 200
- 124
-
-
- 325
- 326
- 124
-
-
- 545
- 546
- 124
-
-
- 5462
- 5463
- 124
+ 54858
+ 54859
+ 10
@@ -22579,11 +22631,11 @@
funspecifiers
- 9714174
+ 9714180
func_id
- 4008745
+ 4008747
spec_id
@@ -22601,7 +22653,7 @@
1
2
- 1527028
+ 1527029
2
@@ -22616,7 +22668,7 @@
4
5
- 692844
+ 692845
5
@@ -22737,11 +22789,11 @@
varspecifiers
- 3075512
+ 3075514
var_id
- 2315054
+ 2315056
spec_id
@@ -22759,7 +22811,7 @@
1
2
- 1658261
+ 1658263
2
@@ -23405,7 +23457,7 @@
1
2
- 642571
+ 642572
2
@@ -23979,11 +24031,11 @@
attribute_arg_value
- 16692
+ 16693
arg
- 16692
+ 16693
value
@@ -24001,7 +24053,7 @@
1
2
- 16692
+ 16693
@@ -24072,15 +24124,15 @@
attribute_arg_type
- 459
+ 460
arg
- 459
+ 460
type_id
- 83
+ 84
@@ -24094,7 +24146,7 @@
1
2
- 459
+ 460
@@ -24110,22 +24162,22 @@
1
2
- 71
+ 72
2
3
- 3
+ 4
35
36
- 3
+ 4
60
61
- 3
+ 4
@@ -24135,15 +24187,15 @@
attribute_arg_constant
- 71883
+ 71889
arg
- 71883
+ 71889
constant
- 71883
+ 71889
@@ -24157,7 +24209,7 @@
1
2
- 71883
+ 71889
@@ -24173,7 +24225,7 @@
1
2
- 71883
+ 71889
@@ -24351,7 +24403,7 @@
func_id
- 799004
+ 799005
spec_id
@@ -24369,7 +24421,7 @@
1
2
- 758960
+ 758961
2
@@ -24594,15 +24646,15 @@
unspecifiedtype
- 7174200
+ 7174204
type_id
- 7174200
+ 7174204
unspecified_type_id
- 3962838
+ 3962840
@@ -24616,7 +24668,7 @@
1
2
- 7174200
+ 7174204
@@ -24632,12 +24684,12 @@
1
2
- 2481093
+ 2481094
2
3
- 1116610
+ 1116611
3
@@ -24657,7 +24709,7 @@
member
- 4189503
+ 4189506
parent
@@ -24669,7 +24721,7 @@
child
- 4184887
+ 4184890
@@ -24703,7 +24755,7 @@
5
6
- 42413
+ 42414
6
@@ -24947,7 +24999,7 @@
1
2
- 4184887
+ 4184890
@@ -24963,7 +25015,7 @@
1
2
- 4180272
+ 4180274
2
@@ -24978,15 +25030,15 @@
enclosingfunction
- 114805
+ 114807
child
- 114805
+ 114807
parent
- 71335
+ 71337
@@ -25000,7 +25052,7 @@
1
2
- 114805
+ 114807
@@ -25016,7 +25068,7 @@
1
2
- 49328
+ 49329
2
@@ -25041,15 +25093,15 @@
derivations
- 476867
+ 476878
derivation
- 476867
+ 476878
sub
- 455133
+ 455143
index
@@ -25057,11 +25109,11 @@
super
- 235538
+ 235543
location
- 35395
+ 35396
@@ -25075,7 +25127,7 @@
1
2
- 476867
+ 476878
@@ -25091,7 +25143,7 @@
1
2
- 476867
+ 476878
@@ -25107,7 +25159,7 @@
1
2
- 476867
+ 476878
@@ -25123,7 +25175,7 @@
1
2
- 476867
+ 476878
@@ -25139,7 +25191,7 @@
1
2
- 438610
+ 438620
2
@@ -25160,7 +25212,7 @@
1
2
- 438610
+ 438620
2
@@ -25181,7 +25233,7 @@
1
2
- 438610
+ 438620
2
@@ -25202,7 +25254,7 @@
1
2
- 438610
+ 438620
2
@@ -25362,7 +25414,7 @@
1
2
- 225726
+ 225732
2
@@ -25383,7 +25435,7 @@
1
2
- 225726
+ 225732
2
@@ -25404,7 +25456,7 @@
1
2
- 235095
+ 235100
2
@@ -25425,7 +25477,7 @@
1
2
- 230189
+ 230194
2
@@ -25518,7 +25570,7 @@
1
2
- 35395
+ 35396
@@ -25559,11 +25611,11 @@
derspecifiers
- 478639
+ 478649
der_id
- 476424
+ 476435
spec_id
@@ -25581,7 +25633,7 @@
1
2
- 474210
+ 474221
2
@@ -25627,11 +25679,11 @@
direct_base_offsets
- 449955
+ 449965
der_id
- 449955
+ 449965
offset
@@ -25649,7 +25701,7 @@
1
2
- 449955
+ 449965
@@ -25846,23 +25898,23 @@
frienddecls
- 699835
+ 700430
id
- 699835
+ 700430
type_id
- 42413
+ 42414
decl_id
- 77876
+ 77742
location
- 6097
+ 6098
@@ -25876,7 +25928,7 @@
1
2
- 699835
+ 700430
@@ -25892,7 +25944,7 @@
1
2
- 699835
+ 700430
@@ -25908,7 +25960,7 @@
1
2
- 699835
+ 700430
@@ -25924,12 +25976,12 @@
1
2
- 6200
+ 6166
2
3
- 14001
+ 13967
3
@@ -25944,7 +25996,7 @@
12
20
- 3577
+ 3645
20
@@ -25980,12 +26032,12 @@
1
2
- 6200
+ 6166
2
3
- 14001
+ 13967
3
@@ -26000,7 +26052,7 @@
12
20
- 3577
+ 3645
20
@@ -26036,7 +26088,7 @@
1
2
- 41050
+ 41051
2
@@ -26057,12 +26109,12 @@
1
2
- 48170
+ 47864
2
3
- 5893
+ 6064
3
@@ -26072,17 +26124,17 @@
8
15
- 5995
+ 6064
15
40
- 6097
+ 6064
40
164
- 5723
+ 5689
@@ -26098,12 +26150,12 @@
1
2
- 48170
+ 47864
2
3
- 5893
+ 6064
3
@@ -26113,17 +26165,17 @@
8
15
- 5995
+ 6064
15
40
- 6097
+ 6064
40
164
- 5723
+ 5689
@@ -26139,7 +26191,7 @@
1
2
- 77195
+ 77060
2
@@ -26164,7 +26216,7 @@
2
- 20354
+ 20371
374
@@ -26206,7 +26258,7 @@
2
- 2133
+ 2129
340
@@ -26217,19 +26269,19 @@
comments
- 11233093
+ 11233100
id
- 11233093
+ 11233100
contents
- 4303522
+ 4303524
location
- 11233093
+ 11233100
@@ -26243,7 +26295,7 @@
1
2
- 11233093
+ 11233100
@@ -26259,7 +26311,7 @@
1
2
- 11233093
+ 11233100
@@ -26275,12 +26327,12 @@
1
2
- 3928782
+ 3928784
2
6
- 322969
+ 322970
6
@@ -26301,12 +26353,12 @@
1
2
- 3928782
+ 3928784
2
6
- 322969
+ 322970
6
@@ -26327,7 +26379,7 @@
1
2
- 11233093
+ 11233100
@@ -26343,7 +26395,7 @@
1
2
- 11233093
+ 11233100
@@ -26353,15 +26405,15 @@
commentbinding
- 3914685
+ 3914688
id
- 3350704
+ 3350706
element
- 3749146
+ 3749148
@@ -26375,7 +26427,7 @@
1
2
- 3289079
+ 3289081
2
@@ -26396,7 +26448,7 @@
1
2
- 3583607
+ 3583609
2
@@ -26411,15 +26463,15 @@
exprconv
- 9633161
+ 9633168
converted
- 9633056
+ 9633062
conversion
- 9633161
+ 9633168
@@ -26433,7 +26485,7 @@
1
2
- 9632950
+ 9632957
2
@@ -26454,7 +26506,7 @@
1
2
- 9633161
+ 9633168
@@ -26464,22 +26516,22 @@
compgenerated
- 9893081
+ 9895967
id
- 9893081
+ 9895967
synthetic_destructor_call
- 1669514
+ 1669328
element
- 1243336
+ 1243197
i
@@ -26487,7 +26539,7 @@
destructor_call
- 1669514
+ 1669328
@@ -26501,17 +26553,17 @@
1
2
- 827601
+ 827509
2
3
- 408944
+ 408898
3
19
- 6790
+ 6789
@@ -26527,17 +26579,17 @@
1
2
- 827601
+ 827509
2
3
- 408944
+ 408898
3
19
- 6790
+ 6789
@@ -26685,7 +26737,7 @@
1
2
- 1669514
+ 1669328
@@ -26701,7 +26753,7 @@
1
2
- 1669514
+ 1669328
@@ -26711,11 +26763,11 @@
namespaces
- 8648
+ 8649
id
- 8648
+ 8649
name
@@ -26733,7 +26785,7 @@
1
2
- 8648
+ 8649
@@ -26780,7 +26832,7 @@
namespacembrs
- 2038490
+ 2038492
parentid
@@ -26788,7 +26840,7 @@
memberid
- 2038490
+ 2038492
@@ -26878,7 +26930,7 @@
1
2
- 2038490
+ 2038492
@@ -26888,11 +26940,11 @@
exprparents
- 19454445
+ 19454457
expr_id
- 19454445
+ 19454457
child_index
@@ -26900,7 +26952,7 @@
parent_id
- 12940139
+ 12940148
@@ -26914,7 +26966,7 @@
1
2
- 19454445
+ 19454457
@@ -26930,7 +26982,7 @@
1
2
- 19454445
+ 19454457
@@ -27048,17 +27100,17 @@
1
2
- 7394844
+ 7394848
2
3
- 5082739
+ 5082743
3
712
- 462555
+ 462556
@@ -27074,17 +27126,17 @@
1
2
- 7394844
+ 7394848
2
3
- 5082739
+ 5082743
3
712
- 462555
+ 462556
@@ -27094,22 +27146,22 @@
expr_isload
- 6899307
+ 6899311
expr_id
- 6899307
+ 6899311
conversionkinds
- 6050440
+ 6050443
expr_id
- 6050440
+ 6050443
kind
@@ -27127,7 +27179,7 @@
1
2
- 6050440
+ 6050443
@@ -27171,8 +27223,8 @@
1
- 5831532
- 5831533
+ 5831535
+ 5831536
1
@@ -27183,11 +27235,11 @@
iscall
- 5800862
+ 5800192
caller
- 5800862
+ 5800192
kind
@@ -27205,7 +27257,7 @@
1
2
- 5800862
+ 5800192
@@ -27229,8 +27281,8 @@
21
- 268316
- 268317
+ 268315
+ 268316
21
@@ -27241,11 +27293,11 @@
numtemplatearguments
- 627726
+ 627727
expr_id
- 627726
+ 627727
num
@@ -27263,7 +27315,7 @@
1
2
- 627726
+ 627727
@@ -27347,23 +27399,23 @@
namequalifiers
- 3037999
+ 3037638
id
- 3037999
+ 3037638
qualifiableelement
- 3037999
+ 3037638
qualifyingelement
- 47424
+ 47419
location
- 551734
+ 551672
@@ -27377,7 +27429,7 @@
1
2
- 3037999
+ 3037638
@@ -27393,7 +27445,7 @@
1
2
- 3037999
+ 3037638
@@ -27409,7 +27461,7 @@
1
2
- 3037999
+ 3037638
@@ -27425,7 +27477,7 @@
1
2
- 3037999
+ 3037638
@@ -27441,7 +27493,7 @@
1
2
- 3037999
+ 3037638
@@ -27457,7 +27509,7 @@
1
2
- 3037999
+ 3037638
@@ -27473,22 +27525,22 @@
1
2
- 31501
+ 31498
2
3
- 8165
+ 8164
3
5
- 4104
+ 4103
5
- 6811
- 3567
+ 6810
+ 3566
19018
@@ -27509,22 +27561,22 @@
1
2
- 31501
+ 31498
2
3
- 8165
+ 8164
3
5
- 4104
+ 4103
5
- 6811
- 3567
+ 6810
+ 3566
19018
@@ -27545,17 +27597,17 @@
1
2
- 34359
+ 34356
2
3
- 7349
+ 7348
3
6
- 3567
+ 3566
6
@@ -27576,22 +27628,22 @@
1
2
- 79034
+ 79046
2
6
- 38055
+ 38030
6
7
- 398479
+ 398435
7
192
- 36164
+ 36160
@@ -27607,22 +27659,22 @@
1
2
- 79034
+ 79046
2
6
- 38055
+ 38030
6
7
- 398479
+ 398435
7
192
- 36164
+ 36160
@@ -27638,22 +27690,22 @@
1
2
- 111395
+ 111383
2
4
- 13279
+ 13278
4
5
- 414767
+ 414721
5
33
- 12291
+ 12289
@@ -27663,15 +27715,15 @@
varbind
- 8254728
+ 8254733
expr
- 8254728
+ 8254733
var
- 1050388
+ 1050389
@@ -27685,7 +27737,7 @@
1
2
- 8254728
+ 8254733
@@ -27701,12 +27753,12 @@
1
2
- 171537
+ 171538
2
3
- 188702
+ 188703
3
@@ -27756,15 +27808,15 @@
funbind
- 5810554
+ 5809904
expr
- 5808083
+ 5807433
fun
- 275716
+ 275686
@@ -27778,12 +27830,12 @@
1
2
- 5805611
+ 5804962
2
3
- 2471
+ 2470
@@ -27799,27 +27851,27 @@
1
2
- 181318
+ 181298
2
3
- 38786
+ 38782
3
4
- 17169
+ 17167
4
8
- 22713
+ 22710
8
37798
- 15729
+ 15727
@@ -27829,11 +27881,11 @@
expr_allocator
- 45240
+ 45241
expr
- 45240
+ 45241
func
@@ -27855,7 +27907,7 @@
1
2
- 45240
+ 45241
@@ -27871,7 +27923,7 @@
1
2
- 45240
+ 45241
@@ -27955,11 +28007,11 @@
expr_deallocator
- 53825
+ 53826
expr
- 53825
+ 53826
func
@@ -27981,7 +28033,7 @@
1
2
- 53825
+ 53826
@@ -27997,7 +28049,7 @@
1
2
- 53825
+ 53826
@@ -28246,11 +28298,11 @@
values
- 13474763
+ 13474772
id
- 13474763
+ 13474772
str
@@ -28268,7 +28320,7 @@
1
2
- 13474763
+ 13474772
@@ -28314,11 +28366,11 @@
valuetext
- 6647515
+ 6647555
id
- 6647515
+ 6647555
text
@@ -28336,7 +28388,7 @@
1
2
- 6647515
+ 6647555
@@ -28377,15 +28429,15 @@
valuebind
- 13583347
+ 13583356
val
- 13474763
+ 13474772
expr
- 13583347
+ 13583356
@@ -28399,7 +28451,7 @@
1
2
- 13384208
+ 13384216
2
@@ -28420,7 +28472,7 @@
1
2
- 13583347
+ 13583356
@@ -28430,11 +28482,11 @@
fieldoffsets
- 1499493
+ 1499494
id
- 1499493
+ 1499494
byteoffset
@@ -28456,7 +28508,7 @@
1
2
- 1499493
+ 1499494
@@ -28472,7 +28524,7 @@
1
2
- 1499493
+ 1499494
@@ -28817,19 +28869,19 @@
initialisers
- 2247635
+ 2247637
init
- 2247635
+ 2247637
var
- 979695
+ 979696
expr
- 2247635
+ 2247637
location
@@ -28847,7 +28899,7 @@
1
2
- 2247635
+ 2247637
@@ -28863,7 +28915,7 @@
1
2
- 2247635
+ 2247637
@@ -28879,7 +28931,7 @@
1
2
- 2247635
+ 2247637
@@ -28947,7 +28999,7 @@
1
2
- 979687
+ 979688
2
@@ -28968,7 +29020,7 @@
1
2
- 2247635
+ 2247637
@@ -28984,7 +29036,7 @@
1
2
- 2247635
+ 2247637
@@ -29000,7 +29052,7 @@
1
2
- 2247635
+ 2247637
@@ -29016,7 +29068,7 @@
1
2
- 414607
+ 414608
2
@@ -29073,7 +29125,7 @@
1
2
- 414607
+ 414608
2
@@ -29098,26 +29150,26 @@
braced_initialisers
- 68436
+ 68305
init
- 68436
+ 68305
expr_ancestor
- 1675488
+ 1675301
exp
- 1675488
+ 1675301
ancestor
- 838560
+ 838467
@@ -29131,7 +29183,7 @@
1
2
- 1675488
+ 1675301
@@ -29147,17 +29199,17 @@
1
2
- 17061
+ 17059
2
3
- 811442
+ 811351
3
19
- 10056
+ 10055
@@ -29167,11 +29219,11 @@
exprs
- 25210871
+ 25210887
id
- 25210871
+ 25210887
kind
@@ -29179,7 +29231,7 @@
location
- 10585982
+ 10585988
@@ -29193,7 +29245,7 @@
1
2
- 25210871
+ 25210887
@@ -29209,7 +29261,7 @@
1
2
- 25210871
+ 25210887
@@ -29387,7 +29439,7 @@
1
2
- 8903992
+ 8903998
2
@@ -29418,7 +29470,7 @@
1
2
- 9043396
+ 9043402
2
@@ -29438,15 +29490,15 @@
expr_reuse
- 845931
+ 845836
reuse
- 845931
+ 845836
original
- 845931
+ 845836
value_category
@@ -29464,7 +29516,7 @@
1
2
- 845931
+ 845836
@@ -29480,7 +29532,7 @@
1
2
- 845931
+ 845836
@@ -29496,7 +29548,7 @@
1
2
- 845931
+ 845836
@@ -29512,7 +29564,7 @@
1
2
- 845931
+ 845836
@@ -29564,11 +29616,11 @@
expr_types
- 25210871
+ 25210887
id
- 25210871
+ 25210887
typeid
@@ -29590,7 +29642,7 @@
1
2
- 25210871
+ 25210887
@@ -29606,7 +29658,7 @@
1
2
- 25210871
+ 25210887
@@ -29751,15 +29803,15 @@
new_allocated_type
- 46194
+ 46195
expr
- 46194
+ 46195
type_id
- 27389
+ 27390
@@ -29773,7 +29825,7 @@
1
2
- 46194
+ 46195
@@ -31208,15 +31260,15 @@
condition_decl_bind
- 408385
+ 408340
expr
- 408385
+ 408340
decl
- 408385
+ 408340
@@ -31230,7 +31282,7 @@
1
2
- 408385
+ 408340
@@ -31246,7 +31298,7 @@
1
2
- 408385
+ 408340
@@ -31256,11 +31308,11 @@
typeid_bind
- 47898
+ 47899
expr
- 47898
+ 47899
type_id
@@ -31278,7 +31330,7 @@
1
2
- 47898
+ 47899
@@ -31367,11 +31419,11 @@
sizeof_bind
- 242029
+ 242030
expr
- 242029
+ 242030
type_id
@@ -31389,7 +31441,7 @@
1
2
- 242029
+ 242030
@@ -33088,11 +33140,11 @@
stmts
- 6358197
+ 6358201
id
- 6358197
+ 6358201
kind
@@ -33100,7 +33152,7 @@
location
- 2679767
+ 2679769
@@ -33114,7 +33166,7 @@
1
2
- 6358197
+ 6358201
@@ -33130,7 +33182,7 @@
1
2
- 6358197
+ 6358201
@@ -33368,7 +33420,7 @@
1
2
- 2221078
+ 2221080
2
@@ -33399,7 +33451,7 @@
1
2
- 2596949
+ 2596951
2
@@ -33569,15 +33621,15 @@
if_then
- 990226
+ 990227
if_stmt
- 990226
+ 990227
then_id
- 990226
+ 990227
@@ -33591,7 +33643,7 @@
1
2
- 990226
+ 990227
@@ -33607,7 +33659,7 @@
1
2
- 990226
+ 990227
@@ -33617,15 +33669,15 @@
if_else
- 436535
+ 436486
if_stmt
- 436535
+ 436486
else_id
- 436535
+ 436486
@@ -33639,7 +33691,7 @@
1
2
- 436535
+ 436486
@@ -33655,7 +33707,7 @@
1
2
- 436535
+ 436486
@@ -33713,15 +33765,15 @@
constexpr_if_then
- 106034
+ 106035
constexpr_if_stmt
- 106034
+ 106035
then_id
- 106034
+ 106035
@@ -33735,7 +33787,7 @@
1
2
- 106034
+ 106035
@@ -33751,7 +33803,7 @@
1
2
- 106034
+ 106035
@@ -33953,15 +34005,15 @@
do_body
- 233643
+ 233644
do_stmt
- 233643
+ 233644
body_id
- 233643
+ 233644
@@ -33975,7 +34027,7 @@
1
2
- 233643
+ 233644
@@ -33991,7 +34043,7 @@
1
2
- 233643
+ 233644
@@ -34049,11 +34101,11 @@
switch_case
- 835058
+ 834964
switch_stmt
- 411329
+ 411283
index
@@ -34061,7 +34113,7 @@
case_id
- 835058
+ 834964
@@ -34080,7 +34132,7 @@
2
3
- 408450
+ 408404
3
@@ -34106,7 +34158,7 @@
2
3
- 408450
+ 408404
3
@@ -34269,7 +34321,7 @@
1
2
- 835058
+ 834964
@@ -34285,7 +34337,7 @@
1
2
- 835058
+ 834964
@@ -34295,15 +34347,15 @@
switch_body
- 411329
+ 411283
switch_stmt
- 411329
+ 411283
body_id
- 411329
+ 411283
@@ -34317,7 +34369,7 @@
1
2
- 411329
+ 411283
@@ -34333,7 +34385,7 @@
1
2
- 411329
+ 411283
@@ -34535,11 +34587,11 @@
stmtparents
- 5618643
+ 5618647
id
- 5618643
+ 5618647
index
@@ -34547,7 +34599,7 @@
parent
- 2377534
+ 2377536
@@ -34561,7 +34613,7 @@
1
2
- 5618643
+ 5618647
@@ -34577,7 +34629,7 @@
1
2
- 5618643
+ 5618647
@@ -34715,12 +34767,12 @@
1
2
- 1356880
+ 1356881
2
3
- 516457
+ 516458
3
@@ -34756,12 +34808,12 @@
1
2
- 1356880
+ 1356881
2
3
- 516457
+ 516458
3
@@ -34791,22 +34843,22 @@
ishandler
- 43770
+ 43779
block
- 43770
+ 43779
stmt_decl_bind
- 724592
+ 724593
stmt
- 714042
+ 714043
num
@@ -34814,7 +34866,7 @@
decl
- 724592
+ 724593
@@ -34828,7 +34880,7 @@
1
2
- 706590
+ 706591
2
@@ -34849,7 +34901,7 @@
1
2
- 706590
+ 706591
2
@@ -34982,7 +35034,7 @@
1
2
- 724592
+ 724593
@@ -34998,7 +35050,7 @@
1
2
- 724592
+ 724593
@@ -35008,11 +35060,11 @@
stmt_decl_entry_bind
- 724592
+ 724593
stmt
- 714042
+ 714043
num
@@ -35020,7 +35072,7 @@
decl_entry
- 724592
+ 724593
@@ -35034,7 +35086,7 @@
1
2
- 706590
+ 706591
2
@@ -35055,7 +35107,7 @@
1
2
- 706590
+ 706591
2
@@ -35188,7 +35240,7 @@
1
2
- 724592
+ 724593
@@ -35204,7 +35256,7 @@
1
2
- 724592
+ 724593
@@ -35214,15 +35266,15 @@
blockscope
- 1644290
+ 1644291
block
- 1644290
+ 1644291
enclosing
- 1427105
+ 1427106
@@ -35236,7 +35288,7 @@
1
2
- 1644290
+ 1644291
@@ -35252,7 +35304,7 @@
1
2
- 1294499
+ 1294500
2
@@ -35272,11 +35324,11 @@
jumpinfo
- 348324
+ 348325
id
- 348324
+ 348325
str
@@ -35284,7 +35336,7 @@
target
- 72706
+ 72707
@@ -35298,7 +35350,7 @@
1
2
- 348324
+ 348325
@@ -35314,7 +35366,7 @@
1
2
- 348324
+ 348325
@@ -35443,7 +35495,7 @@
1
2
- 72706
+ 72707
@@ -35453,11 +35505,11 @@
preprocdirects
- 5408281
+ 5408285
id
- 5408281
+ 5408285
kind
@@ -35465,7 +35517,7 @@
location
- 5405038
+ 5405041
@@ -35479,7 +35531,7 @@
1
2
- 5408281
+ 5408285
@@ -35495,7 +35547,7 @@
1
2
- 5408281
+ 5408285
@@ -35643,7 +35695,7 @@
1
2
- 5404913
+ 5404916
27
@@ -35664,7 +35716,7 @@
1
2
- 5405038
+ 5405041
@@ -35674,7 +35726,7 @@
preprocpair
- 1141185
+ 1141186
begin
@@ -35682,7 +35734,7 @@
elseelifend
- 1141185
+ 1141186
@@ -35696,7 +35748,7 @@
1
2
- 649557
+ 649558
2
@@ -35722,7 +35774,7 @@
1
2
- 1141185
+ 1141186
@@ -35732,11 +35784,11 @@
preproctrue
- 439358
+ 439359
branch
- 439358
+ 439359
@@ -35754,19 +35806,19 @@
preproctext
- 4352298
+ 4352301
id
- 4352298
+ 4352301
head
- 2955007
+ 2955008
body
- 1683336
+ 1683337
@@ -35780,7 +35832,7 @@
1
2
- 4352298
+ 4352301
@@ -35796,7 +35848,7 @@
1
2
- 4352298
+ 4352301
@@ -35812,7 +35864,7 @@
1
2
- 2756409
+ 2756411
2
@@ -35833,7 +35885,7 @@
1
2
- 2873796
+ 2873798
2
@@ -35854,12 +35906,12 @@
1
2
- 1535136
+ 1535137
2
10
- 127241
+ 127242
10
@@ -35880,7 +35932,7 @@
1
2
- 1539378
+ 1539379
2
@@ -35900,15 +35952,15 @@
includes
- 318569
+ 318598
id
- 318569
+ 318598
included
- 58683
+ 58688
@@ -35922,7 +35974,7 @@
1
2
- 318569
+ 318598
@@ -35938,17 +35990,17 @@
1
2
- 29040
+ 29043
2
3
- 9440
+ 9441
3
4
- 4952
+ 4953
4
@@ -35958,7 +36010,7 @@
6
11
- 4519
+ 4520
11
@@ -36026,11 +36078,11 @@
link_parent
- 30400377
+ 30401054
element
- 3866383
+ 3866469
link_target
@@ -36048,17 +36100,17 @@
1
2
- 530489
+ 530500
2
9
- 26946
+ 26947
9
10
- 3308947
+ 3309021
From 6c7370ea95fb8ac1b92584aaa04cc61d0141198b Mon Sep 17 00:00:00 2001
From: Ian Lynagh
Date: Fri, 21 Nov 2025 11:30:58 +0000
Subject: [PATCH 45/70] C++: Add up/downgrade scripts
---
.../old.dbscheme | 2469 +++++++++++++++++
.../semmlecode.dbscheme | 2450 ++++++++++++++++
.../upgrade.properties | 4 +
.../old.dbscheme | 2450 ++++++++++++++++
.../semmlecode.cpp.dbscheme | 2469 +++++++++++++++++
.../upgrade.properties | 2 +
6 files changed, 9844 insertions(+)
create mode 100644 cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/old.dbscheme
create mode 100644 cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/semmlecode.dbscheme
create mode 100644 cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/upgrade.properties
create mode 100644 cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/old.dbscheme
create mode 100644 cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/semmlecode.cpp.dbscheme
create mode 100644 cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/upgrade.properties
diff --git a/cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/old.dbscheme b/cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/old.dbscheme
new file mode 100644
index 00000000000..a42ce5fc943
--- /dev/null
+++ b/cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/old.dbscheme
@@ -0,0 +1,2469 @@
+
+/*- 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
+)
+
+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 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _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
+);
+
+@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
+);
+
+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
+);
+
+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;
+
+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
+;
+
+@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
+ ;
+
+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
+);
+
+/**
+ * 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
+| 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
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/**
+ * 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
+);
+
+/**
+ * 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/a42ce5fc943254097f85471b94ae2247e819104a/semmlecode.dbscheme b/cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/semmlecode.dbscheme
new file mode 100644
index 00000000000..1a6854060d5
--- /dev/null
+++ b/cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/semmlecode.dbscheme
@@ -0,0 +1,2450 @@
+/*- 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
+)
+
+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 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _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
+);
+
+@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
+);
+
+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
+);
+
+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;
+
+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
+;
+
+@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
+ ;
+
+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
+);
+
+/**
+ * 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
+| 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
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/upgrade.properties b/cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/upgrade.properties
new file mode 100644
index 00000000000..1a7cdb0ad71
--- /dev/null
+++ b/cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/upgrade.properties
@@ -0,0 +1,4 @@
+description: Add databaseMetadata and overlayChangedFiles relations
+compatibility: full
+databaseMetadata.rel: delete
+overlayChangedFiles.rel: delete
diff --git a/cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/old.dbscheme b/cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/old.dbscheme
new file mode 100644
index 00000000000..1a6854060d5
--- /dev/null
+++ b/cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/old.dbscheme
@@ -0,0 +1,2450 @@
+/*- 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
+)
+
+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 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _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
+);
+
+@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
+);
+
+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
+);
+
+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;
+
+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
+;
+
+@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
+ ;
+
+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
+);
+
+/**
+ * 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
+| 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
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/*- XML Files -*/
+
+xmlEncoding(
+ unique int id: @file ref,
+ string encoding: string ref
+);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref
+);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref
+);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref
+);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref
+);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref
+);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref
+);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref
+);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
diff --git a/cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/semmlecode.cpp.dbscheme
new file mode 100644
index 00000000000..a42ce5fc943
--- /dev/null
+++ b/cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/semmlecode.cpp.dbscheme
@@ -0,0 +1,2469 @@
+
+/*- 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
+)
+
+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 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _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
+);
+
+@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
+);
+
+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
+);
+
+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;
+
+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
+;
+
+@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
+ ;
+
+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
+);
+
+/**
+ * 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
+| 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
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/**
+ * 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
+);
+
+/**
+ * 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/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/upgrade.properties b/cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/upgrade.properties
new file mode 100644
index 00000000000..52b67d65af7
--- /dev/null
+++ b/cpp/ql/lib/upgrades/1a6854060d5d3ada16c580a29f8c5ce21f3367f8/upgrade.properties
@@ -0,0 +1,2 @@
+description: Add databaseMetadata and overlayChangedFiles relations
+compatibility: full
From 298e4cfcc5829f662f20e0ede76d35fb1e2b8b69 Mon Sep 17 00:00:00 2001
From: Anders Schack-Mulligen
Date: Fri, 21 Nov 2025 12:53:39 +0100
Subject: [PATCH 46/70] Java: Recognize int-sized long literals.
---
java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll | 2 ++
1 file changed, 2 insertions(+)
diff --git a/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll b/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll
index 269c47dc3b7..6985053735c 100644
--- a/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll
+++ b/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll
@@ -86,6 +86,8 @@ pragma[nomagic]
private predicate constantIntegerExpr(Expr e, int val) {
e.(CompileTimeConstantExpr).getIntValue() = val
or
+ e.(LongLiteral).getValue().toInt() = val
+ or
exists(SsaExplicitWrite v, Expr src |
e = v.getARead() and
src = v.getValue() and
From 2da0814f652698096e9280beb7f1781fc7d623a7 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 20 Nov 2025 19:15:33 +0000
Subject: [PATCH 47/70] Rust: Add test case involving taint.
---
.../CWE-295/DisabledCertificateCheck.expected | 12 +++--
.../test/query-tests/security/CWE-295/main.rs | 49 +++++++++++++++++++
2 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index e060b50494d..87ca24ddd2f 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -11,14 +11,17 @@
| main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:83:32:83:37 | always | main.rs:74:15:74:18 | true | main.rs:83:32:83:37 | always | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:88:32:88:40 | sometimes | main.rs:75:22:75:25 | true | main.rs:88:32:88:40 | sometimes | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:93:32:93:47 | sometimes_global | main.rs:106:17:106:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:93:32:93:47 | sometimes_global | main.rs:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
| main.rs:74:6:74:11 | always | main.rs:83:32:83:37 | always | provenance | |
| main.rs:74:15:74:18 | true | main.rs:74:6:74:11 | always | provenance | |
| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | |
| main.rs:75:22:75:25 | true | main.rs:75:6:75:18 | mut sometimes | provenance | |
-| main.rs:106:17:106:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
+| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
+| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
+| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
nodes
| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:36:9:39 | true | semmle.label | true |
@@ -38,5 +41,8 @@ nodes
| main.rs:83:32:83:37 | always | semmle.label | always |
| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
-| main.rs:106:17:106:20 | true | semmle.label | true |
+| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
+| main.rs:144:39:144:42 | true | semmle.label | true |
+| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
+| main.rs:154:17:154:20 | true | semmle.label | true |
subpaths
diff --git a/rust/ql/test/query-tests/security/CWE-295/main.rs b/rust/ql/test/query-tests/security/CWE-295/main.rs
index 02bd61976e5..f12f0858060 100644
--- a/rust/ql/test/query-tests/security/CWE-295/main.rs
+++ b/rust/ql/test/query-tests/security/CWE-295/main.rs
@@ -100,9 +100,58 @@ fn test_data_flow(sometimes_global: bool) {
.unwrap();
}
+fn test_threat_model_source() {
+ // hostname setting from `fs` functions returning `bool` directly
+ // (these are highly unnatural but serve to create simple tests)
+
+ let b1: bool = std::fs::exists("main.rs").unwrap();
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b1) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .build()
+ .unwrap();
+
+ let b2 = std::path::Path::new("main.rs").metadata().unwrap().is_file();
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b2) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .build()
+ .unwrap();
+
+ let b3 = std::fs::metadata("main.rs").unwrap().is_dir();
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b3) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .build()
+ .unwrap();
+
+ // hostname setting from `stdin`, parsed to `bool`
+ // (these are a little closer to something real)
+
+ let mut input_line = String::new();
+ let input = std::io::stdin();
+ input.read_line(&mut input_line).unwrap();
+
+ let b4: bool = input_line.parse::().unwrap_or(false);
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b4) // $ MISSING: Alert[rust/disabled-certificate-check]=stdin
+ .build()
+ .unwrap();
+
+ let b5 = std::str::FromStr::from_str(&input_line).unwrap_or(false);
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b5) // $ MISSING: Alert[rust/disabled-certificate-check]=stdin
+ .build()
+ .unwrap();
+
+ let b6 = if (input_line == "true") { true } else { false }; // $ Source=true
+ let _client = native_tls::TlsConnector::builder()
+ .danger_accept_invalid_hostnames(b6) // $ Alert[rust/disabled-certificate-check]=true
+ .build()
+ .unwrap();
+}
+
fn main() {
test_native_tls();
test_reqwest();
test_data_flow(true); // $ Source=arg
test_data_flow(false);
+ test_threat_model_source();
}
From 8145264b770b92daa2f55fd06145ecf86e7536ef Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Thu, 20 Nov 2025 19:01:16 +0000
Subject: [PATCH 48/70] Rust: Add threat model sources as additional sources
for the query.
---
.../src/queries/security/CWE-295/DisabledCertificateCheck.ql | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index d08ca32bb25..487a2a00912 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -14,6 +14,7 @@
import rust
import codeql.rust.dataflow.DataFlow
import codeql.rust.security.DisabledCertificateCheckExtensions
+import codeql.rust.Concepts
/**
* A taint configuration for disabled TLS certificate checks.
@@ -22,7 +23,11 @@ module DisabledCertificateCheckConfig implements DataFlow::ConfigSig {
import DisabledCertificateCheckExtensions
predicate isSource(DataFlow::Node node) {
+ // the constant `true`
node.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true"
+ or
+ // a value controlled by a potential attacker
+ node instanceof ActiveThreatModelSource
}
predicate isSink(DataFlow::Node node) { node instanceof Sink }
From aca7877be23afde4c588d134064a162b9840aa95 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 13:42:22 +0000
Subject: [PATCH 49/70] Rust: Add some missing path / file metadata models.
---
.../rust/frameworks/stdlib/fs.model.yml | 22 +++++++++++++++++++
.../CWE-295/DisabledCertificateCheck.expected | 13 +++++++++++
.../test/query-tests/security/CWE-295/main.rs | 4 ++--
3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml
index 79b0b16f41e..076cea745fb 100644
--- a/rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/fs.model.yml
@@ -3,14 +3,27 @@ extensions:
pack: codeql/rust-all
extensible: sourceModel
data:
+ - ["std::fs::exists", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["std::fs::read", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["std::fs::read_dir", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["std::fs::read_to_string", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["std::fs::read_link", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["std::fs::metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["std::fs::symlink_metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["::path", "ReturnValue", "file", "manual"]
- ["::file_name", "ReturnValue", "file", "manual"]
- ["::open", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["::open_buffered", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- ["::open", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::exists", "ReturnValue", "file", "manual"]
+ - ["::try_exists", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::is_file", "ReturnValue", "file", "manual"]
+ - ["::is_dir", "ReturnValue", "file", "manual"]
+ - ["::is_symlink", "ReturnValue", "file", "manual"]
+ - ["::metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::symlink_metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::read_dir", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
+ - ["::read_link", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
- addsTo:
pack: codeql/rust-all
extensible: sinkModel
@@ -68,3 +81,12 @@ extensions:
- ["::with_extension", "Argument[Self].Reference", "ReturnValue", "taint", "manual"]
- ["::with_file_name", "Argument[Self].Reference", "ReturnValue", "taint", "manual"]
- ["::with_file_name", "Argument[0]", "ReturnValue", "taint", "manual"]
+ - ["::accessed", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
+ - ["::created", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
+ - ["::file_type", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::is_file", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::is_dir", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::is_symlink", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::len", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
+ - ["::modified", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
+ - ["::permissions", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index 87ca24ddd2f..06773d55e08 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -12,6 +12,7 @@
| main.rs:83:32:83:37 | always | main.rs:74:15:74:18 | true | main.rs:83:32:83:37 | always | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:88:32:88:40 | sometimes | main.rs:75:22:75:25 | true | main.rs:88:32:88:40 | sometimes | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:93:32:93:47 | sometimes_global | main.rs:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
@@ -19,9 +20,16 @@ edges
| main.rs:74:15:74:18 | true | main.rs:74:6:74:11 | always | provenance | |
| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | |
| main.rs:75:22:75:25 | true | main.rs:75:6:75:18 | mut sometimes | provenance | |
+| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
+| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:1 |
+| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:2 |
+| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
+models
+| 1 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 2 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
nodes
| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:36:9:39 | true | semmle.label | true |
@@ -41,6 +49,11 @@ nodes
| main.rs:83:32:83:37 | always | semmle.label | always |
| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
+| main.rs:107:6:107:7 | b1 | semmle.label | b1 |
+| main.rs:107:17:107:31 | ...::exists | semmle.label | ...::exists |
+| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
+| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
+| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
diff --git a/rust/ql/test/query-tests/security/CWE-295/main.rs b/rust/ql/test/query-tests/security/CWE-295/main.rs
index f12f0858060..e62e0e4f4a2 100644
--- a/rust/ql/test/query-tests/security/CWE-295/main.rs
+++ b/rust/ql/test/query-tests/security/CWE-295/main.rs
@@ -104,9 +104,9 @@ fn test_threat_model_source() {
// hostname setting from `fs` functions returning `bool` directly
// (these are highly unnatural but serve to create simple tests)
- let b1: bool = std::fs::exists("main.rs").unwrap();
+ let b1: bool = std::fs::exists("main.rs").unwrap(); // $ Source=exists
let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_hostnames(b1) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .danger_accept_invalid_hostnames(b1) // $ Alert[rust/disabled-certificate-check]=exists
.build()
.unwrap();
From 89a9c4654764375abc284819818ad3a9ec2c9750 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 14:46:26 +0000
Subject: [PATCH 50/70] Rust: Second change note.
---
rust/ql/lib/change-notes/2025-11-21-fs.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 rust/ql/lib/change-notes/2025-11-21-fs.md
diff --git a/rust/ql/lib/change-notes/2025-11-21-fs.md b/rust/ql/lib/change-notes/2025-11-21-fs.md
new file mode 100644
index 00000000000..438acd94f9f
--- /dev/null
+++ b/rust/ql/lib/change-notes/2025-11-21-fs.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* Added more detailed models for `std::fs` and `std::path`.
From 785754ec651c7e5c6af89e60b1e53e8587c25804 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 14:15:15 +0000
Subject: [PATCH 51/70] Rust: Switch the query to taint flow, since some taint
summaries are relevant now.
---
.../CWE-295/DisabledCertificateCheck.ql | 3 +-
.../CWE-295/DisabledCertificateCheck.expected | 36 ++++++++++++++++---
.../test/query-tests/security/CWE-295/main.rs | 8 ++---
3 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 487a2a00912..35b6d6e7324 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -13,6 +13,7 @@
import rust
import codeql.rust.dataflow.DataFlow
+import codeql.rust.dataflow.TaintTracking
import codeql.rust.security.DisabledCertificateCheckExtensions
import codeql.rust.Concepts
@@ -35,7 +36,7 @@ module DisabledCertificateCheckConfig implements DataFlow::ConfigSig {
predicate observeDiffInformedIncrementalMode() { any() }
}
-module DisabledCertificateCheckFlow = DataFlow::Global;
+module DisabledCertificateCheckFlow = TaintTracking::Global;
import DisabledCertificateCheckFlow::PathGraph
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index 06773d55e08..9d491193efd 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -13,6 +13,8 @@
| main.rs:88:32:88:40 | sometimes | main.rs:75:22:75:25 | true | main.rs:88:32:88:40 | sometimes | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:93:32:93:47 | sometimes_global | main.rs:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:115:36:115:37 | b2 | main.rs:113:43:113:50 | metadata | main.rs:115:36:115:37 | b2 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:121:36:121:37 | b3 | main.rs:119:11:119:27 | ...::metadata | main.rs:121:36:121:37 | b3 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
@@ -21,15 +23,29 @@ edges
| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | |
| main.rs:75:22:75:25 | true | main.rs:75:6:75:18 | mut sometimes | provenance | |
| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
-| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:1 |
-| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:2 |
+| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:2 |
+| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:4 |
| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
+| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
+| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:4 |
+| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:6 |
+| main.rs:113:11:113:71 | ... .is_file() | main.rs:113:6:113:7 | b2 | provenance | |
+| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:1 |
+| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
+| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:3 |
+| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:4 |
+| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:5 |
+| main.rs:119:11:119:56 | ... .is_dir() | main.rs:119:6:119:7 | b3 | provenance | |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
models
-| 1 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
-| 2 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
+| 1 | Source: ::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 2 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 3 | Source: std::fs::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 4 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
+| 5 | Summary: ::is_dir; Argument[self].Reference; ReturnValue; taint |
+| 6 | Summary: ::is_file; Argument[self].Reference; ReturnValue; taint |
nodes
| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:36:9:39 | true | semmle.label | true |
@@ -54,6 +70,18 @@ nodes
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
+| main.rs:113:6:113:7 | b2 | semmle.label | b2 |
+| main.rs:113:11:113:52 | ... .metadata() [Ok] | semmle.label | ... .metadata() [Ok] |
+| main.rs:113:11:113:61 | ... .unwrap() | semmle.label | ... .unwrap() |
+| main.rs:113:11:113:71 | ... .is_file() | semmle.label | ... .is_file() |
+| main.rs:113:43:113:50 | metadata | semmle.label | metadata |
+| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
+| main.rs:119:6:119:7 | b3 | semmle.label | b3 |
+| main.rs:119:11:119:27 | ...::metadata | semmle.label | ...::metadata |
+| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | semmle.label | ...::metadata(...) [Ok] |
+| main.rs:119:11:119:47 | ... .unwrap() | semmle.label | ... .unwrap() |
+| main.rs:119:11:119:56 | ... .is_dir() | semmle.label | ... .is_dir() |
+| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
diff --git a/rust/ql/test/query-tests/security/CWE-295/main.rs b/rust/ql/test/query-tests/security/CWE-295/main.rs
index e62e0e4f4a2..6088e6fc1be 100644
--- a/rust/ql/test/query-tests/security/CWE-295/main.rs
+++ b/rust/ql/test/query-tests/security/CWE-295/main.rs
@@ -110,15 +110,15 @@ fn test_threat_model_source() {
.build()
.unwrap();
- let b2 = std::path::Path::new("main.rs").metadata().unwrap().is_file();
+ let b2 = std::path::Path::new("main.rs").metadata().unwrap().is_file(); // $ Source=is_file
let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_hostnames(b2) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .danger_accept_invalid_hostnames(b2) // $ Alert[rust/disabled-certificate-check]=is_file
.build()
.unwrap();
- let b3 = std::fs::metadata("main.rs").unwrap().is_dir();
+ let b3 = std::fs::metadata("main.rs").unwrap().is_dir(); // $ Source=is_dir
let _client = native_tls::TlsConnector::builder()
- .danger_accept_invalid_hostnames(b3) // $ MISSING: Alert[rust/disabled-certificate-check]=fs
+ .danger_accept_invalid_hostnames(b3) // $ Alert[rust/disabled-certificate-check]=is_dir
.build()
.unwrap();
From ace7a77fd6b0a5d5107e86f6fa023b0a7bdfab67 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 16:01:59 +0000
Subject: [PATCH 52/70] Rust: Switch to MaD models.
---
.../rust/frameworks/native-tls.model.yml | 7 ++
.../codeql/rust/frameworks/reqwest.model.yml | 4 +
.../DisabledCertificateCheckExtensions.qll | 13 ---
.../CWE-295/DisabledCertificateCheck.expected | 102 ++++++++++++------
4 files changed, 82 insertions(+), 44 deletions(-)
create mode 100644 rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
diff --git a/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml b/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
new file mode 100644
index 00000000000..5af3245238a
--- /dev/null
+++ b/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
@@ -0,0 +1,7 @@
+extensions:
+ - addsTo:
+ pack: codeql/rust-all
+ extensible: sinkModel
+ data:
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
diff --git a/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml b/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml
index 5457460919f..e9bc66b4be7 100644
--- a/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/reqwest.model.yml
@@ -11,6 +11,10 @@ extensions:
data:
- ["::request", "Argument[1]", "request-url", "manual"]
- ["::request", "Argument[1]", "request-url", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- addsTo:
pack: codeql/rust-all
extensible: summaryModel
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index cfc988ae37f..08cf20670d6 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -20,19 +20,6 @@ module DisabledCertificateCheckExtensions {
override string getSinkType() { result = "DisabledCertificateCheck" }
}
- /**
- * A default sink for disabled certificate check vulnerabilities based on function names.
- */
- private class DefaultSink extends Sink {
- DefaultSink() {
- exists(CallExprBase fc |
- fc.getStaticTarget().(Function).getName().getText() =
- ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
- fc.getArg(0) = this.asExpr().getExpr()
- )
- }
- }
-
/**
* A sink for disabled certificate check vulnerabilities from model data.
*/
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index 9d491193efd..bbc67f6fd18 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -1,89 +1,129 @@
#select
-| main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:83:32:83:37 | always | main.rs:74:15:74:18 | true | main.rs:83:32:83:37 | always | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:88:32:88:40 | sometimes | main.rs:75:22:75:25 | true | main.rs:88:32:88:40 | sometimes | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:93:32:93:47 | sometimes_global | main.rs:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:115:36:115:37 | b2 | main.rs:113:43:113:50 | metadata | main.rs:115:36:115:37 | b2 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:121:36:121:37 | b3 | main.rs:119:11:119:27 | ...::metadata | main.rs:121:36:121:37 | b3 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:4:4:4:30 | danger_accept_invalid_certs | main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:16:4:16:30 | danger_accept_invalid_certs | main.rs:16:32:16:35 | true | main.rs:16:4:16:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | main.rs:17:36:17:39 | true | main.rs:17:4:17:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:37:4:37:30 | danger_accept_invalid_certs | main.rs:37:32:37:35 | true | main.rs:37:4:37:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | main.rs:42:36:42:39 | true | main.rs:42:4:42:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:47:4:47:30 | danger_accept_invalid_certs | main.rs:47:32:47:35 | true | main.rs:47:4:47:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | main.rs:48:36:48:39 | true | main.rs:48:4:48:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:55:4:55:30 | danger_accept_invalid_certs | main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:83:4:83:30 | danger_accept_invalid_certs | main.rs:74:15:74:18 | true | main.rs:83:4:83:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:88:4:88:30 | danger_accept_invalid_certs | main.rs:75:22:75:25 | true | main.rs:88:4:88:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:93:4:93:30 | danger_accept_invalid_certs | main.rs:154:17:154:20 | true | main.rs:93:4:93:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | main.rs:107:17:107:31 | ...::exists | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | main.rs:113:43:113:50 | metadata | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | main.rs:119:11:119:27 | ...::metadata | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | main.rs:144:39:144:42 | true | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
+| main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
+| main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
+| main.rs:16:32:16:35 | true | main.rs:16:4:16:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
+| main.rs:17:36:17:39 | true | main.rs:17:4:17:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
+| main.rs:37:32:37:35 | true | main.rs:37:4:37:30 | danger_accept_invalid_certs | provenance | MaD:3 Sink:MaD:3 |
+| main.rs:42:36:42:39 | true | main.rs:42:4:42:34 | danger_accept_invalid_hostnames | provenance | MaD:6 Sink:MaD:6 |
+| main.rs:47:32:47:35 | true | main.rs:47:4:47:30 | danger_accept_invalid_certs | provenance | MaD:3 Sink:MaD:3 |
+| main.rs:48:36:48:39 | true | main.rs:48:4:48:34 | danger_accept_invalid_hostnames | provenance | MaD:4 Sink:MaD:4 |
+| main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | provenance | MaD:5 Sink:MaD:5 |
+| main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | provenance | MaD:6 Sink:MaD:6 |
| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
| main.rs:74:6:74:11 | always | main.rs:83:32:83:37 | always | provenance | |
| main.rs:74:15:74:18 | true | main.rs:74:6:74:11 | always | provenance | |
| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | |
| main.rs:75:22:75:25 | true | main.rs:75:6:75:18 | mut sometimes | provenance | |
+| main.rs:83:32:83:37 | always | main.rs:83:4:83:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
+| main.rs:88:32:88:40 | sometimes | main.rs:88:4:88:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
+| main.rs:93:32:93:47 | sometimes_global | main.rs:93:4:93:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
-| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:2 |
-| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:4 |
+| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:8 |
+| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:10 |
| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
+| main.rs:109:36:109:37 | b1 | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
-| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:4 |
-| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:6 |
+| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:10 |
+| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:12 |
| main.rs:113:11:113:71 | ... .is_file() | main.rs:113:6:113:7 | b2 | provenance | |
-| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:1 |
+| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:7 |
+| main.rs:115:36:115:37 | b2 | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
-| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:3 |
-| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:4 |
-| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:5 |
+| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:9 |
+| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:10 |
+| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:11 |
| main.rs:119:11:119:56 | ... .is_dir() | main.rs:119:6:119:7 | b3 | provenance | |
+| main.rs:121:36:121:37 | b3 | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
+| main.rs:146:36:146:37 | b6 | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
models
-| 1 | Source: ::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
-| 2 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
-| 3 | Source: std::fs::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
-| 4 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
-| 5 | Summary: ::is_dir; Argument[self].Reference; ReturnValue; taint |
-| 6 | Summary: ::is_file; Argument[self].Reference; ReturnValue; taint |
+| 1 | Sink: ::danger_accept_invalid_certs; Argument[0]; disable-certificate |
+| 2 | Sink: ::danger_accept_invalid_hostnames; Argument[0]; disable-certificate |
+| 3 | Sink: ::danger_accept_invalid_certs; Argument[0]; disable-certificate |
+| 4 | Sink: ::danger_accept_invalid_hostnames; Argument[0]; disable-certificate |
+| 5 | Sink: ::danger_accept_invalid_certs; Argument[0]; disable-certificate |
+| 6 | Sink: ::danger_accept_invalid_hostnames; Argument[0]; disable-certificate |
+| 7 | Source: ::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 8 | Source: std::fs::exists; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 9 | Source: std::fs::metadata; ReturnValue.Field[core::result::Result::Ok(0)]; file |
+| 10 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value |
+| 11 | Summary: ::is_dir; Argument[self].Reference; ReturnValue; taint |
+| 12 | Summary: ::is_file; Argument[self].Reference; ReturnValue; taint |
nodes
+| main.rs:4:4:4:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:4:32:4:35 | true | semmle.label | true |
+| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:9:36:9:39 | true | semmle.label | true |
+| main.rs:16:4:16:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:16:32:16:35 | true | semmle.label | true |
+| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:17:36:17:39 | true | semmle.label | true |
+| main.rs:37:4:37:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:37:32:37:35 | true | semmle.label | true |
+| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:42:36:42:39 | true | semmle.label | true |
+| main.rs:47:4:47:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:47:32:47:35 | true | semmle.label | true |
+| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:48:36:48:39 | true | semmle.label | true |
+| main.rs:55:4:55:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:55:32:55:35 | true | semmle.label | true |
+| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:56:36:56:39 | true | semmle.label | true |
| main.rs:73:19:73:40 | ...: bool | semmle.label | ...: bool |
| main.rs:74:6:74:11 | always | semmle.label | always |
| main.rs:74:15:74:18 | true | semmle.label | true |
| main.rs:75:6:75:18 | mut sometimes | semmle.label | mut sometimes |
| main.rs:75:22:75:25 | true | semmle.label | true |
+| main.rs:83:4:83:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:83:32:83:37 | always | semmle.label | always |
+| main.rs:88:4:88:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
+| main.rs:93:4:93:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
| main.rs:107:6:107:7 | b1 | semmle.label | b1 |
| main.rs:107:17:107:31 | ...::exists | semmle.label | ...::exists |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
+| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
| main.rs:113:6:113:7 | b2 | semmle.label | b2 |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | semmle.label | ... .metadata() [Ok] |
| main.rs:113:11:113:61 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:113:11:113:71 | ... .is_file() | semmle.label | ... .is_file() |
| main.rs:113:43:113:50 | metadata | semmle.label | metadata |
+| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
| main.rs:119:6:119:7 | b3 | semmle.label | b3 |
| main.rs:119:11:119:27 | ...::metadata | semmle.label | ...::metadata |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | semmle.label | ...::metadata(...) [Ok] |
| main.rs:119:11:119:47 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:119:11:119:56 | ... .is_dir() | semmle.label | ... .is_dir() |
+| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
+| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
| main.rs:154:17:154:20 | true | semmle.label | true |
subpaths
From 3ad014b2f9c426efe062a99bef63bc666fb9d773 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 16:33:59 +0000
Subject: [PATCH 53/70] Rust: Additional sinks found in MRVA-1000.
---
.../ql/lib/codeql/rust/frameworks/attohttpc.model.yml | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
diff --git a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
new file mode 100644
index 00000000000..0015d605f19
--- /dev/null
+++ b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
@@ -0,0 +1,11 @@
+extensions:
+ - addsTo:
+ pack: codeql/rust-all
+ extensible: sinkModel
+ data:
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
From e01c871b70a8d0b58b1dcfcd0b11eed603dc27a4 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 17:12:23 +0000
Subject: [PATCH 54/70] Rust: Accept changes to the dataflow/sources/file test.
---
.../library-tests/dataflow/sources/file/TaintSources.expected | 2 ++
rust/ql/test/library-tests/dataflow/sources/file/test.rs | 4 ++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/rust/ql/test/library-tests/dataflow/sources/file/TaintSources.expected b/rust/ql/test/library-tests/dataflow/sources/file/TaintSources.expected
index d73106fb1cf..f7687e025d7 100644
--- a/rust/ql/test/library-tests/dataflow/sources/file/TaintSources.expected
+++ b/rust/ql/test/library-tests/dataflow/sources/file/TaintSources.expected
@@ -4,8 +4,10 @@
| test.rs:17:31:17:38 | ...::read | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:22:22:22:39 | ...::read_to_string | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:22:22:22:39 | ...::read_to_string | Flow source 'FileSource' of type file (DEFAULT). |
+| test.rs:26:18:26:29 | ...::read_dir | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:29:22:29:25 | path | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:43:27:43:35 | file_name | Flow source 'FileSource' of type file (DEFAULT). |
+| test.rs:51:52:51:59 | read_dir | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:54:22:54:25 | path | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:55:27:55:35 | file_name | Flow source 'FileSource' of type file (DEFAULT). |
| test.rs:65:22:65:34 | ...::read_link | Flow source 'FileSource' of type file (DEFAULT). |
diff --git a/rust/ql/test/library-tests/dataflow/sources/file/test.rs b/rust/ql/test/library-tests/dataflow/sources/file/test.rs
index 35a7d2cc1b8..0124d2a094e 100644
--- a/rust/ql/test/library-tests/dataflow/sources/file/test.rs
+++ b/rust/ql/test/library-tests/dataflow/sources/file/test.rs
@@ -23,7 +23,7 @@ fn test_fs() -> Result<(), Box> {
sink(buffer); // $ hasTaintFlow="file.txt"
}
- for entry in fs::read_dir("directory")? {
+ for entry in fs::read_dir("directory")? { // $ Alert[rust/summary/taint-sources]
let e = entry?;
let path = e.path(); // $ Alert[rust/summary/taint-sources]
@@ -48,7 +48,7 @@ fn test_fs() -> Result<(), Box> {
sink(file_name.clone().as_encoded_bytes()); // $ MISSING: hasTaintFlow
sink(file_name); // $ hasTaintFlow
}
- for entry in std::path::Path::new("directory").read_dir()? {
+ for entry in std::path::Path::new("directory").read_dir()? { // $ Alert[rust/summary/taint-sources]
let e = entry?;
let path = e.path(); // $ Alert[rust/summary/taint-sources]
From 9db1722060a3353bb94e21350b6a6337d7a13013 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 17:35:34 +0000
Subject: [PATCH 55/70] Rust: Accept consistency check changes.
---
.../CONSISTENCY/PathResolutionConsistency.expected | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/rust/ql/test/query-tests/security/CWE-825/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/query-tests/security/CWE-825/CONSISTENCY/PathResolutionConsistency.expected
index 81f06adcde3..40e59cf662a 100644
--- a/rust/ql/test/query-tests/security/CWE-825/CONSISTENCY/PathResolutionConsistency.expected
+++ b/rust/ql/test/query-tests/security/CWE-825/CONSISTENCY/PathResolutionConsistency.expected
@@ -1,6 +1,14 @@
multipleCallTargets
-| deallocation.rs:260:11:260:29 | ...::from(...) |
-| deallocation.rs:261:11:261:29 | ...::from(...) |
+| deallocation.rs:162:5:162:17 | ptr.is_null() |
+| deallocation.rs:174:7:174:19 | ptr.is_null() |
+| deallocation.rs:186:5:186:17 | ptr.is_null() |
+| deallocation.rs:190:5:190:17 | ptr.is_null() |
+| deallocation.rs:194:6:194:18 | ptr.is_null() |
+| deallocation.rs:202:5:202:17 | ptr.is_null() |
+| deallocation.rs:210:25:210:37 | ptr.is_null() |
+| deallocation.rs:225:5:225:23 | const_ptr.is_null() |
+| deallocation.rs:354:11:354:29 | ...::from(...) |
+| deallocation.rs:355:11:355:29 | ...::from(...) |
| lifetime.rs:610:13:610:31 | ...::from(...) |
| lifetime.rs:611:13:611:31 | ...::from(...) |
| lifetime.rs:628:13:628:31 | ...::from(...) |
From 988aca1f851d9a812725c1cc843ad8b42316ca92 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 18:13:08 +0000
Subject: [PATCH 56/70] Rust: Correct QLDoc comment.
---
rust/ql/lib/codeql/rust/security/Barriers.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/ql/lib/codeql/rust/security/Barriers.qll b/rust/ql/lib/codeql/rust/security/Barriers.qll
index 14df5eb5ae5..fbe3691b412 100644
--- a/rust/ql/lib/codeql/rust/security/Barriers.qll
+++ b/rust/ql/lib/codeql/rust/security/Barriers.qll
@@ -45,7 +45,7 @@ class IntegralOrBooleanTypeBarrier extends DataFlow::Node {
/**
* Holds if guard expression `g` having result `branch` indicates that the
- * sub-expression `node` is not null. For example when `ptr.is_null()` is
+ * sub-expression `e` is not null. For example when `ptr.is_null()` is
* `false`, we have that `ptr` is not null.
*/
private predicate notNullCheck(AstNode g, Expr e, boolean branch) {
From 2ce4c47646806910a684f747d3b59617a3b19631 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 18:43:35 +0000
Subject: [PATCH 57/70] Rust: More sinks from the MRVA-1000.
---
rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml | 2 ++
rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml | 2 ++
2 files changed, 4 insertions(+)
diff --git a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
index 0015d605f19..47e1beb3925 100644
--- a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
@@ -9,3 +9,5 @@ extensions:
- ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
diff --git a/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml b/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
index 5af3245238a..1da63eb7961 100644
--- a/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
+++ b/rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
@@ -5,3 +5,5 @@ extensions:
data:
- ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
+ - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
From eb674d08d63c48e9beb4f94e773cb5281b801540 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 18:45:47 +0000
Subject: [PATCH 58/70] Rust: Reinstate the original function names model but
call it a heuristic now.
---
.../lib/codeql/rust/frameworks/attohttpc.model.yml | 13 -------------
.../security/DisabledCertificateCheckExtensions.qll | 13 +++++++++++++
2 files changed, 13 insertions(+), 13 deletions(-)
delete mode 100644 rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
diff --git a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml b/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
deleted file mode 100644
index 47e1beb3925..00000000000
--- a/rust/ql/lib/codeql/rust/frameworks/attohttpc.model.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-extensions:
- - addsTo:
- pack: codeql/rust-all
- extensible: sinkModel
- data:
- - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
- - ["::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index 08cf20670d6..67efbc5b5ad 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -26,4 +26,17 @@ module DisabledCertificateCheckExtensions {
private class ModelsAsDataSink extends Sink {
ModelsAsDataSink() { sinkNode(this, "disable-certificate") }
}
+
+ /**
+ * A heuristic sink for disabled certificate check vulnerabilities based on function names.
+ */
+ private class HeuristicSink extends Sink {
+ HeuristicSink() {
+ exists(CallExprBase fc |
+ fc.getStaticTarget().(Function).getName().getText() =
+ ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
+ fc.getArg(0) = this.asExpr()
+ )
+ }
+ }
}
From ff8032a4ec220ef1ca181cac68966eea6206ae09 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 18:53:57 +0000
Subject: [PATCH 59/70] Rust: Fix after merge.
---
.../ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
index 35b6d6e7324..ae22a3c9d2c 100644
--- a/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
+++ b/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
@@ -25,7 +25,7 @@ module DisabledCertificateCheckConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
// the constant `true`
- node.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true"
+ node.asExpr().(BooleanLiteralExpr).getTextValue() = "true"
or
// a value controlled by a potential attacker
node instanceof ActiveThreatModelSource
From 0ea28b402613611deb1e572b4c5e8526e1ab7e59 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 18:56:53 +0000
Subject: [PATCH 60/70] Rust: Test .expected changes.
---
.../CWE-295/DisabledCertificateCheck.expected | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index bbc67f6fd18..d01cdfda84b 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -1,21 +1,38 @@
#select
| main.rs:4:4:4:30 | danger_accept_invalid_certs | main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:16:4:16:30 | danger_accept_invalid_certs | main.rs:16:32:16:35 | true | main.rs:16:4:16:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | main.rs:17:36:17:39 | true | main.rs:17:4:17:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:37:4:37:30 | danger_accept_invalid_certs | main.rs:37:32:37:35 | true | main.rs:37:4:37:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | main.rs:42:36:42:39 | true | main.rs:42:4:42:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:47:4:47:30 | danger_accept_invalid_certs | main.rs:47:32:47:35 | true | main.rs:47:4:47:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | main.rs:48:36:48:39 | true | main.rs:48:4:48:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:55:4:55:30 | danger_accept_invalid_certs | main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:83:4:83:30 | danger_accept_invalid_certs | main.rs:74:15:74:18 | true | main.rs:83:4:83:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:83:32:83:37 | always | main.rs:74:15:74:18 | true | main.rs:83:32:83:37 | always | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:88:4:88:30 | danger_accept_invalid_certs | main.rs:75:22:75:25 | true | main.rs:88:4:88:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:88:32:88:40 | sometimes | main.rs:75:22:75:25 | true | main.rs:88:32:88:40 | sometimes | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:93:4:93:30 | danger_accept_invalid_certs | main.rs:154:17:154:20 | true | main.rs:93:4:93:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:93:32:93:47 | sometimes_global | main.rs:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | main.rs:107:17:107:31 | ...::exists | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | main.rs:113:43:113:50 | metadata | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:115:36:115:37 | b2 | main.rs:113:43:113:50 | metadata | main.rs:115:36:115:37 | b2 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | main.rs:119:11:119:27 | ...::metadata | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:121:36:121:37 | b3 | main.rs:119:11:119:27 | ...::metadata | main.rs:121:36:121:37 | b3 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | main.rs:144:39:144:42 | true | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
+| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
| main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
@@ -28,31 +45,38 @@ edges
| main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | provenance | MaD:5 Sink:MaD:5 |
| main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | provenance | MaD:6 Sink:MaD:6 |
| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
+| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
+| main.rs:74:6:74:11 | always | main.rs:83:32:83:37 | always | provenance | |
| main.rs:74:6:74:11 | always | main.rs:83:32:83:37 | always | provenance | |
| main.rs:74:15:74:18 | true | main.rs:74:6:74:11 | always | provenance | |
| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | |
+| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | |
| main.rs:75:22:75:25 | true | main.rs:75:6:75:18 | mut sometimes | provenance | |
| main.rs:83:32:83:37 | always | main.rs:83:4:83:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:88:32:88:40 | sometimes | main.rs:88:4:88:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:93:32:93:47 | sometimes_global | main.rs:93:4:93:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
+| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:8 |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:10 |
| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
| main.rs:109:36:109:37 | b1 | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
+| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:10 |
| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:12 |
| main.rs:113:11:113:71 | ... .is_file() | main.rs:113:6:113:7 | b2 | provenance | |
| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:7 |
| main.rs:115:36:115:37 | b2 | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
+| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:9 |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:10 |
| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:11 |
| main.rs:119:11:119:56 | ... .is_dir() | main.rs:119:6:119:7 | b3 | provenance | |
| main.rs:121:36:121:37 | b3 | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
+| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
| main.rs:146:36:146:37 | b6 | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
@@ -72,24 +96,34 @@ models
nodes
| main.rs:4:4:4:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:4:32:4:35 | true | semmle.label | true |
+| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:9:36:9:39 | true | semmle.label | true |
+| main.rs:9:36:9:39 | true | semmle.label | true |
| main.rs:16:4:16:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:16:32:16:35 | true | semmle.label | true |
+| main.rs:16:32:16:35 | true | semmle.label | true |
| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:17:36:17:39 | true | semmle.label | true |
+| main.rs:17:36:17:39 | true | semmle.label | true |
| main.rs:37:4:37:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:37:32:37:35 | true | semmle.label | true |
+| main.rs:37:32:37:35 | true | semmle.label | true |
| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:42:36:42:39 | true | semmle.label | true |
+| main.rs:42:36:42:39 | true | semmle.label | true |
| main.rs:47:4:47:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:47:32:47:35 | true | semmle.label | true |
+| main.rs:47:32:47:35 | true | semmle.label | true |
| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:48:36:48:39 | true | semmle.label | true |
+| main.rs:48:36:48:39 | true | semmle.label | true |
| main.rs:55:4:55:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:55:32:55:35 | true | semmle.label | true |
+| main.rs:55:32:55:35 | true | semmle.label | true |
| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:56:36:56:39 | true | semmle.label | true |
+| main.rs:56:36:56:39 | true | semmle.label | true |
| main.rs:73:19:73:40 | ...: bool | semmle.label | ...: bool |
| main.rs:74:6:74:11 | always | semmle.label | always |
| main.rs:74:15:74:18 | true | semmle.label | true |
@@ -97,16 +131,20 @@ nodes
| main.rs:75:22:75:25 | true | semmle.label | true |
| main.rs:83:4:83:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:83:32:83:37 | always | semmle.label | always |
+| main.rs:83:32:83:37 | always | semmle.label | always |
| main.rs:88:4:88:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
+| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
| main.rs:93:4:93:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
+| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
| main.rs:107:6:107:7 | b1 | semmle.label | b1 |
| main.rs:107:17:107:31 | ...::exists | semmle.label | ...::exists |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
+| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
| main.rs:113:6:113:7 | b2 | semmle.label | b2 |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | semmle.label | ... .metadata() [Ok] |
| main.rs:113:11:113:61 | ... .unwrap() | semmle.label | ... .unwrap() |
@@ -114,6 +152,7 @@ nodes
| main.rs:113:43:113:50 | metadata | semmle.label | metadata |
| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
+| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
| main.rs:119:6:119:7 | b3 | semmle.label | b3 |
| main.rs:119:11:119:27 | ...::metadata | semmle.label | ...::metadata |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | semmle.label | ...::metadata(...) [Ok] |
@@ -121,9 +160,11 @@ nodes
| main.rs:119:11:119:56 | ... .is_dir() | semmle.label | ... .is_dir() |
| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
+| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
+| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
| main.rs:154:17:154:20 | true | semmle.label | true |
subpaths
From 993154ed57b46ff0db88348fe53b2b9baa4ada49 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 21 Nov 2025 19:33:40 +0000
Subject: [PATCH 61/70] Rust: Avoid duplicating sinks.
---
.../DisabledCertificateCheckExtensions.qll | 5 ++-
.../CWE-295/DisabledCertificateCheck.expected | 41 -------------------
2 files changed, 4 insertions(+), 42 deletions(-)
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index 67efbc5b5ad..e2870746547 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -7,6 +7,7 @@ import rust
private import codeql.rust.dataflow.DataFlow
private import codeql.rust.dataflow.FlowSink
private import codeql.rust.Concepts
+private import codeql.rust.dataflow.internal.Node as Node
/**
* Provides default sinks for detecting disabled certificate check
@@ -35,7 +36,9 @@ module DisabledCertificateCheckExtensions {
exists(CallExprBase fc |
fc.getStaticTarget().(Function).getName().getText() =
["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
- fc.getArg(0) = this.asExpr()
+ fc.getArg(0) = this.asExpr() and
+ // don't duplicate modelled sinks
+ not exists(ModelsAsDataSink s | s.(Node::FlowSummaryNode).getSinkElement().getCall() = fc)
)
}
}
diff --git a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
index d01cdfda84b..bbc67f6fd18 100644
--- a/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
+++ b/rust/ql/test/query-tests/security/CWE-295/DisabledCertificateCheck.expected
@@ -1,38 +1,21 @@
#select
| main.rs:4:4:4:30 | danger_accept_invalid_certs | main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | main.rs:4:32:4:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | main.rs:9:36:9:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:16:4:16:30 | danger_accept_invalid_certs | main.rs:16:32:16:35 | true | main.rs:16:4:16:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | main.rs:16:32:16:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | main.rs:17:36:17:39 | true | main.rs:17:4:17:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | main.rs:17:36:17:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:37:4:37:30 | danger_accept_invalid_certs | main.rs:37:32:37:35 | true | main.rs:37:4:37:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | main.rs:37:32:37:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | main.rs:42:36:42:39 | true | main.rs:42:4:42:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | main.rs:42:36:42:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:47:4:47:30 | danger_accept_invalid_certs | main.rs:47:32:47:35 | true | main.rs:47:4:47:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | main.rs:47:32:47:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | main.rs:48:36:48:39 | true | main.rs:48:4:48:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | main.rs:48:36:48:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:55:4:55:30 | danger_accept_invalid_certs | main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | main.rs:55:32:55:35 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | main.rs:56:36:56:39 | true | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:83:4:83:30 | danger_accept_invalid_certs | main.rs:74:15:74:18 | true | main.rs:83:4:83:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:83:32:83:37 | always | main.rs:74:15:74:18 | true | main.rs:83:32:83:37 | always | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:88:4:88:30 | danger_accept_invalid_certs | main.rs:75:22:75:25 | true | main.rs:88:4:88:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:88:32:88:40 | sometimes | main.rs:75:22:75:25 | true | main.rs:88:32:88:40 | sometimes | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:93:4:93:30 | danger_accept_invalid_certs | main.rs:154:17:154:20 | true | main.rs:93:4:93:30 | danger_accept_invalid_certs | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:93:32:93:47 | sometimes_global | main.rs:154:17:154:20 | true | main.rs:93:32:93:47 | sometimes_global | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | main.rs:107:17:107:31 | ...::exists | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:109:36:109:37 | b1 | main.rs:107:17:107:31 | ...::exists | main.rs:109:36:109:37 | b1 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | main.rs:113:43:113:50 | metadata | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:115:36:115:37 | b2 | main.rs:113:43:113:50 | metadata | main.rs:115:36:115:37 | b2 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | main.rs:119:11:119:27 | ...::metadata | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:121:36:121:37 | b3 | main.rs:119:11:119:27 | ...::metadata | main.rs:121:36:121:37 | b3 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | main.rs:144:39:144:42 | true | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
-| main.rs:146:36:146:37 | b6 | main.rs:144:39:144:42 | true | main.rs:146:36:146:37 | b6 | Disabling TLS certificate validation can expose the application to man-in-the-middle attacks. |
edges
| main.rs:4:32:4:35 | true | main.rs:4:4:4:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:9:36:9:39 | true | main.rs:9:4:9:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
@@ -45,38 +28,31 @@ edges
| main.rs:55:32:55:35 | true | main.rs:55:4:55:30 | danger_accept_invalid_certs | provenance | MaD:5 Sink:MaD:5 |
| main.rs:56:36:56:39 | true | main.rs:56:4:56:34 | danger_accept_invalid_hostnames | provenance | MaD:6 Sink:MaD:6 |
| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
-| main.rs:73:19:73:40 | ...: bool | main.rs:93:32:93:47 | sometimes_global | provenance | |
-| main.rs:74:6:74:11 | always | main.rs:83:32:83:37 | always | provenance | |
| main.rs:74:6:74:11 | always | main.rs:83:32:83:37 | always | provenance | |
| main.rs:74:15:74:18 | true | main.rs:74:6:74:11 | always | provenance | |
| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | |
-| main.rs:75:6:75:18 | mut sometimes | main.rs:88:32:88:40 | sometimes | provenance | |
| main.rs:75:22:75:25 | true | main.rs:75:6:75:18 | mut sometimes | provenance | |
| main.rs:83:32:83:37 | always | main.rs:83:4:83:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:88:32:88:40 | sometimes | main.rs:88:4:88:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:93:32:93:47 | sometimes_global | main.rs:93:4:93:30 | danger_accept_invalid_certs | provenance | MaD:1 Sink:MaD:1 |
| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
-| main.rs:107:6:107:7 | b1 | main.rs:109:36:109:37 | b1 | provenance | |
| main.rs:107:17:107:31 | ...::exists | main.rs:107:17:107:42 | ...::exists(...) [Ok] | provenance | Src:MaD:8 |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | main.rs:107:17:107:51 | ... .unwrap() | provenance | MaD:10 |
| main.rs:107:17:107:51 | ... .unwrap() | main.rs:107:6:107:7 | b1 | provenance | |
| main.rs:109:36:109:37 | b1 | main.rs:109:4:109:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
-| main.rs:113:6:113:7 | b2 | main.rs:115:36:115:37 | b2 | provenance | |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | main.rs:113:11:113:61 | ... .unwrap() | provenance | MaD:10 |
| main.rs:113:11:113:61 | ... .unwrap() | main.rs:113:11:113:71 | ... .is_file() | provenance | MaD:12 |
| main.rs:113:11:113:71 | ... .is_file() | main.rs:113:6:113:7 | b2 | provenance | |
| main.rs:113:43:113:50 | metadata | main.rs:113:11:113:52 | ... .metadata() [Ok] | provenance | Src:MaD:7 |
| main.rs:115:36:115:37 | b2 | main.rs:115:4:115:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
-| main.rs:119:6:119:7 | b3 | main.rs:121:36:121:37 | b3 | provenance | |
| main.rs:119:11:119:27 | ...::metadata | main.rs:119:11:119:38 | ...::metadata(...) [Ok] | provenance | Src:MaD:9 |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | main.rs:119:11:119:47 | ... .unwrap() | provenance | MaD:10 |
| main.rs:119:11:119:47 | ... .unwrap() | main.rs:119:11:119:56 | ... .is_dir() | provenance | MaD:11 |
| main.rs:119:11:119:56 | ... .is_dir() | main.rs:119:6:119:7 | b3 | provenance | |
| main.rs:121:36:121:37 | b3 | main.rs:121:4:121:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
-| main.rs:144:6:144:7 | b6 | main.rs:146:36:146:37 | b6 | provenance | |
| main.rs:144:39:144:42 | true | main.rs:144:6:144:7 | b6 | provenance | |
| main.rs:146:36:146:37 | b6 | main.rs:146:4:146:34 | danger_accept_invalid_hostnames | provenance | MaD:2 Sink:MaD:2 |
| main.rs:154:17:154:20 | true | main.rs:73:19:73:40 | ...: bool | provenance | |
@@ -96,34 +72,24 @@ models
nodes
| main.rs:4:4:4:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:4:32:4:35 | true | semmle.label | true |
-| main.rs:4:32:4:35 | true | semmle.label | true |
| main.rs:9:4:9:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:9:36:9:39 | true | semmle.label | true |
-| main.rs:9:36:9:39 | true | semmle.label | true |
| main.rs:16:4:16:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:16:32:16:35 | true | semmle.label | true |
-| main.rs:16:32:16:35 | true | semmle.label | true |
| main.rs:17:4:17:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:17:36:17:39 | true | semmle.label | true |
-| main.rs:17:36:17:39 | true | semmle.label | true |
| main.rs:37:4:37:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:37:32:37:35 | true | semmle.label | true |
-| main.rs:37:32:37:35 | true | semmle.label | true |
| main.rs:42:4:42:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:42:36:42:39 | true | semmle.label | true |
-| main.rs:42:36:42:39 | true | semmle.label | true |
| main.rs:47:4:47:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:47:32:47:35 | true | semmle.label | true |
-| main.rs:47:32:47:35 | true | semmle.label | true |
| main.rs:48:4:48:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:48:36:48:39 | true | semmle.label | true |
-| main.rs:48:36:48:39 | true | semmle.label | true |
| main.rs:55:4:55:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:55:32:55:35 | true | semmle.label | true |
-| main.rs:55:32:55:35 | true | semmle.label | true |
| main.rs:56:4:56:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:56:36:56:39 | true | semmle.label | true |
-| main.rs:56:36:56:39 | true | semmle.label | true |
| main.rs:73:19:73:40 | ...: bool | semmle.label | ...: bool |
| main.rs:74:6:74:11 | always | semmle.label | always |
| main.rs:74:15:74:18 | true | semmle.label | true |
@@ -131,20 +97,16 @@ nodes
| main.rs:75:22:75:25 | true | semmle.label | true |
| main.rs:83:4:83:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:83:32:83:37 | always | semmle.label | always |
-| main.rs:83:32:83:37 | always | semmle.label | always |
| main.rs:88:4:88:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
-| main.rs:88:32:88:40 | sometimes | semmle.label | sometimes |
| main.rs:93:4:93:30 | danger_accept_invalid_certs | semmle.label | danger_accept_invalid_certs |
| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
-| main.rs:93:32:93:47 | sometimes_global | semmle.label | sometimes_global |
| main.rs:107:6:107:7 | b1 | semmle.label | b1 |
| main.rs:107:17:107:31 | ...::exists | semmle.label | ...::exists |
| main.rs:107:17:107:42 | ...::exists(...) [Ok] | semmle.label | ...::exists(...) [Ok] |
| main.rs:107:17:107:51 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:109:4:109:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
-| main.rs:109:36:109:37 | b1 | semmle.label | b1 |
| main.rs:113:6:113:7 | b2 | semmle.label | b2 |
| main.rs:113:11:113:52 | ... .metadata() [Ok] | semmle.label | ... .metadata() [Ok] |
| main.rs:113:11:113:61 | ... .unwrap() | semmle.label | ... .unwrap() |
@@ -152,7 +114,6 @@ nodes
| main.rs:113:43:113:50 | metadata | semmle.label | metadata |
| main.rs:115:4:115:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
-| main.rs:115:36:115:37 | b2 | semmle.label | b2 |
| main.rs:119:6:119:7 | b3 | semmle.label | b3 |
| main.rs:119:11:119:27 | ...::metadata | semmle.label | ...::metadata |
| main.rs:119:11:119:38 | ...::metadata(...) [Ok] | semmle.label | ...::metadata(...) [Ok] |
@@ -160,11 +121,9 @@ nodes
| main.rs:119:11:119:56 | ... .is_dir() | semmle.label | ... .is_dir() |
| main.rs:121:4:121:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
-| main.rs:121:36:121:37 | b3 | semmle.label | b3 |
| main.rs:144:6:144:7 | b6 | semmle.label | b6 |
| main.rs:144:39:144:42 | true | semmle.label | true |
| main.rs:146:4:146:34 | danger_accept_invalid_hostnames | semmle.label | danger_accept_invalid_hostnames |
| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
-| main.rs:146:36:146:37 | b6 | semmle.label | b6 |
| main.rs:154:17:154:20 | true | semmle.label | true |
subpaths
From b62968fa0ff8c4bbc04b0527cd1cc7ed6ba637ef Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Sat, 22 Nov 2025 09:22:33 +0000
Subject: [PATCH 62/70] Rust: Spelling.
---
.../codeql/rust/security/DisabledCertificateCheckExtensions.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
index e2870746547..6a885828ee9 100644
--- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
+++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll
@@ -37,7 +37,7 @@ module DisabledCertificateCheckExtensions {
fc.getStaticTarget().(Function).getName().getText() =
["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
fc.getArg(0) = this.asExpr() and
- // don't duplicate modelled sinks
+ // don't duplicate modeled sinks
not exists(ModelsAsDataSink s | s.(Node::FlowSummaryNode).getSinkElement().getCall() = fc)
)
}
From b16f8c20a98c94a2fdef30f21678cc87d0531eb6 Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Sun, 23 Nov 2025 19:05:24 +0100
Subject: [PATCH 63/70] Update
rust/ql/lib/codeql/rust/internal/PathResolution.qll
Co-authored-by: Simon Friis Vindum
---
rust/ql/lib/codeql/rust/internal/PathResolution.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll
index 491f1572f26..acb1f7a8541 100644
--- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll
+++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll
@@ -2050,7 +2050,7 @@ ItemNode resolvePathIgnoreVariableShadowing(PathExt path) {
}
/**
- * Holds if `ip` resolves to some constructor.
+ * Holds if `ip` resolves to some constructor or constant.
*/
// use `forceLocal` once we implement overlay support
pragma[nomagic]
From 17e1e1713e4d30a3c51ebe1be370427e932d1c9f Mon Sep 17 00:00:00 2001
From: Tom Hvitved
Date: Sun, 23 Nov 2025 20:24:05 +0100
Subject: [PATCH 64/70] Rust: Add placeholder declarations for `&mut` and
`*mut`
---
.../elements/builtintypes/BuiltinTypes.expected | 2 ++
rust/tools/builtins/types.rs | 6 ++++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/rust/ql/test/library-tests/elements/builtintypes/BuiltinTypes.expected b/rust/ql/test/library-tests/elements/builtintypes/BuiltinTypes.expected
index cfab22cd61c..e08eb561b58 100644
--- a/rust/ql/test/library-tests/elements/builtintypes/BuiltinTypes.expected
+++ b/rust/ql/test/library-tests/elements/builtintypes/BuiltinTypes.expected
@@ -1,6 +1,8 @@
| struct Array | |
| struct Ptr | |
+| struct PtrMut | |
| struct Ref | |
+| struct RefMut | |
| struct Slice | |
| struct Tuple0 | |
| struct Tuple1 | |
diff --git a/rust/tools/builtins/types.rs b/rust/tools/builtins/types.rs
index 0c6025b4d37..fc0be525ab4 100644
--- a/rust/tools/builtins/types.rs
+++ b/rust/tools/builtins/types.rs
@@ -26,8 +26,10 @@ pub struct f64;
struct Slice;
struct Array;
-struct Ref; // todo: add mut variant
-struct Ptr; // todo: add mut variant
+struct Ref;
+struct RefMut;
+struct Ptr;
+struct PtrMut;
// tuples
struct Tuple0;
From ecb80cb4fc68d40f756ff0a616cd5c94cd8f0ad1 Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Thu, 20 Nov 2025 19:57:18 +0000
Subject: [PATCH 65/70] C++: Represent field content using a column that is
shared by all template instantiations.
---
.../cpp/ir/dataflow/internal/DataFlowUtil.qll | 170 +++++++++++++++---
1 file changed, 147 insertions(+), 23 deletions(-)
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 7c2b15b1812..872b8c97314 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
@@ -2078,38 +2078,150 @@ predicate localExprFlow(Expr e1, Expr e2) {
localExprFlowPlus(e1, e2)
}
+/**
+ * A canonical representation of a field.
+ *
+ * For performance reasons we we want a unique `Content` that represents
+ * a given field across any template instantiation of a class.
+ *
+ * This is possible in _almost_ all cases, but there are cases where it is
+ * not possible to map between a field in the uninstantiated template to a
+ * field in the instantiated template. This problem appears to be only in the
+ * case of a local class definition. So this abstract class has two
+ * implementations: a non-local case (where we can represent a canonical field
+ * as the field declaration from an uninstantiated class template or a non-
+ * templated class), and a local case (where we simply use the field from the
+ * instantiated class).
+ */
+abstract private class CanonicalField extends Field {
+ /** Gets a field represented by this canonical field. */
+ abstract Field getAField();
+
+ /**
+ * Gets a class that declares a field represented by this canonical field.
+ */
+ abstract Class getADeclaringType();
+
+ /**
+ * Gets a type that this canonical field may have. Note that this may
+ * not be a unique type. For example, consider this case:
+ * ```
+ * template
+ * struct S { T x; };
+ *
+ * S s1;
+ * S s2;
+ * ```
+ * In this case the canonical field corresponding to `S::x` has two types:
+ * `int` and `char`.
+ */
+ Type getAType() { result = this.getAField().getType() }
+
+ Type getAnUnspecifiedType() { result = this.getAType().getUnspecifiedType() }
+}
+
+private class NonLocalCanonicalField extends CanonicalField {
+ Class declaringType;
+
+ NonLocalCanonicalField() {
+ declaringType = this.getDeclaringType() and
+ not declaringType.isFromTemplateInstantiation(_) and
+ not declaringType.isLocal() // handled in LocalCanonicalField
+ }
+
+ override Field getAField() {
+ exists(Class c | result.getDeclaringType() = c |
+ // Either the declaring class of the field is a template instantiation
+ // that has been constructed from this canonical declaration
+ c.isConstructedFrom(declaringType) and
+ pragma[only_bind_out](result.getName()) = pragma[only_bind_out](this.getName())
+ or
+ // or this canonical declaration is not a template.
+ not c.isConstructedFrom(_) and
+ result = this
+ )
+ }
+
+ override Class getADeclaringType() {
+ result = this.getDeclaringType()
+ or
+ result.isConstructedFrom(this.getDeclaringType())
+ }
+}
+
+private class LocalCanonicalField extends CanonicalField {
+ Class declaringType;
+
+ LocalCanonicalField() {
+ declaringType = this.getDeclaringType() and
+ declaringType.isLocal()
+ }
+
+ override Field getAField() { result = this }
+
+ override Class getADeclaringType() { result = declaringType }
+}
+
+/**
+ * A canonical representation of a `Union`. See `CanonicalField` for the explanation for
+ * why we need a canonical representation.
+ */
+abstract private class CanonicalUnion extends Union {
+ /** Gets a union represented by this canonical union. */
+ abstract Union getAUnion();
+
+ /** Gets a canonical field of this canonical union. */
+ CanonicalField getACanonicalField() { result.getDeclaringType() = this }
+}
+
+private class NonLocalCanonicalUnion extends CanonicalUnion {
+ NonLocalCanonicalUnion() { not this.isFromTemplateInstantiation(_) and not this.isLocal() }
+
+ override Union getAUnion() {
+ result = this
+ or
+ result.isConstructedFrom(this)
+ }
+}
+
+private class LocalCanonicalUnion extends CanonicalUnion {
+ LocalCanonicalUnion() { this.isLocal() }
+
+ override Union getAUnion() { result = this }
+}
+
bindingset[f]
pragma[inline_late]
-private int getFieldSize(Field f) { result = f.getType().getSize() }
+private int getFieldSize(CanonicalField f) { result = max(f.getAType().getSize()) }
/**
* Gets a field in the union `u` whose size
* is `bytes` number of bytes.
*/
-private Field getAFieldWithSize(Union u, int bytes) {
- result = u.getAField() and
+private CanonicalField getAFieldWithSize(CanonicalUnion u, int bytes) {
+ result = u.getACanonicalField() and
bytes = getFieldSize(result)
}
cached
private newtype TContent =
- TNonUnionContent(Field f, int indirectionIndex) {
+ 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 .. SsaImpl::getMaxIndirectionsForType(f.getUnspecifiedType())] and
+ indirectionIndex = [1 .. max(SsaImpl::getMaxIndirectionsForType(f.getAnUnspecifiedType()))] and
// Reads and writes of union fields are tracked using `UnionContent`.
not f.getDeclaringType() instanceof Union
} or
- TUnionContent(Union u, int bytes, int indirectionIndex) {
- exists(Field f |
- f = u.getAField() and
+ TUnionContent(CanonicalUnion u, int bytes, int indirectionIndex) {
+ exists(CanonicalField f |
+ f = u.getACanonicalField() and
bytes = getFieldSize(f) and
// We key `UnionContent` by the union instead of its fields since a write to one
// 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)
- .getUnspecifiedType())
+ .getAnUnspecifiedType())
)]
)
} or
@@ -2175,8 +2287,12 @@ class FieldContent extends Content, TFieldContent {
/**
* Gets the field associated with this `Content`, if a unique one exists.
+ *
+ * For fields from template instantiations this predicate may still return
+ * more than field, but all the fields will be constructed from the same
+ * template.
*/
- final Field getField() { result = unique( | | this.getAField()) }
+ Field getField() { none() } // overridden in subclasses
override int getIndirectionIndex() { none() } // overridden in subclasses
@@ -2187,32 +2303,33 @@ class FieldContent extends Content, TFieldContent {
/** A reference through a non-union instance field. */
class NonUnionFieldContent extends FieldContent, TNonUnionContent {
- private Field f;
+ private CanonicalField f;
private int indirectionIndex;
NonUnionFieldContent() { this = TNonUnionContent(f, indirectionIndex) }
override string toString() { result = contentStars(this) + f.toString() }
- override Field getAField() { result = f }
+ final override Field getField() { result = f.getAField() }
+
+ override Field getAField() { result = this.getField() }
/** Gets the indirection index of this `FieldContent`. */
override int getIndirectionIndex() { result = indirectionIndex }
override predicate impliesClearOf(Content c) {
- exists(FieldContent fc |
- fc = c and
- fc.getField() = f and
+ exists(int i |
+ c = TNonUnionContent(f, i) and
// If `this` is `f` then `c` is cleared if it's of the
// form `*f`, `**f`, etc.
- fc.getIndirectionIndex() >= indirectionIndex
+ i >= indirectionIndex
)
}
}
/** A reference through an instance field of a union. */
class UnionContent extends FieldContent, TUnionContent {
- private Union u;
+ private CanonicalUnion u;
private int indirectionIndex;
private int bytes;
@@ -2220,24 +2337,31 @@ class UnionContent extends FieldContent, TUnionContent {
override string toString() { result = contentStars(this) + u.toString() }
+ final override Field getField() { result = unique( | | u.getACanonicalField()).getAField() }
+
/** Gets a field of the underlying union of this `UnionContent`, if any. */
- override Field getAField() { result = u.getAField() and getFieldSize(result) = bytes }
+ override Field getAField() {
+ exists(CanonicalField cf |
+ cf = u.getACanonicalField() and
+ result = cf.getAField() and
+ getFieldSize(cf) = bytes
+ )
+ }
/** Gets the underlying union of this `UnionContent`. */
- Union getUnion() { result = u }
+ Union getUnion() { result = u.getAUnion() }
/** Gets the indirection index of this `UnionContent`. */
override int getIndirectionIndex() { result = indirectionIndex }
override predicate impliesClearOf(Content c) {
- exists(UnionContent uc |
- uc = c and
- uc.getUnion() = u and
+ exists(int i |
+ c = TUnionContent(u, _, i) and
// If `this` is `u` then `c` is cleared if it's of the
// form `*u`, `**u`, etc. (and we ignore `bytes` because
// we know the entire union is overwritten because it's a
// union).
- uc.getIndirectionIndex() >= indirectionIndex
+ i >= indirectionIndex
)
}
}
From 0487e0622aa4488e565b550889a492ba31e6ffdd Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Mon, 24 Nov 2025 14:04:35 +0000
Subject: [PATCH 66/70] C++: Accept test changes from tests that use
getAQlClass.
---
.../variables/variables/variable.expected | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/cpp/ql/test/library-tests/variables/variables/variable.expected b/cpp/ql/test/library-tests/variables/variables/variable.expected
index 1ef5902a9a8..c6ada1f3615 100644
--- a/cpp/ql/test/library-tests/variables/variables/variable.expected
+++ b/cpp/ql/test/library-tests/variables/variables/variable.expected
@@ -2,10 +2,10 @@
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | address && | SemanticStackVariable | | |
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | const __va_list_tag & | SemanticStackVariable | | |
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | const address & | SemanticStackVariable | | |
-| file://:0:0:0:0 | fp_offset | file://:0:0:0:0 | unsigned int | Field | | |
-| file://:0:0:0:0 | gp_offset | file://:0:0:0:0 | unsigned int | Field | | |
-| file://:0:0:0:0 | overflow_arg_area | file://:0:0:0:0 | void * | Field | | |
-| file://:0:0:0:0 | reg_save_area | file://:0:0:0:0 | void * | Field | | |
+| file://:0:0:0:0 | fp_offset | file://:0:0:0:0 | unsigned int | NonLocalCanonicalField | | |
+| file://:0:0:0:0 | gp_offset | file://:0:0:0:0 | unsigned int | NonLocalCanonicalField | | |
+| file://:0:0:0:0 | overflow_arg_area | file://:0:0:0:0 | void * | NonLocalCanonicalField | | |
+| file://:0:0:0:0 | reg_save_area | file://:0:0:0:0 | void * | NonLocalCanonicalField | | |
| variables.cpp:1:12:1:12 | i | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
| variables.cpp:2:12:2:12 | i | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
| variables.cpp:3:12:3:12 | i | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
@@ -33,10 +33,10 @@
| variables.cpp:37:6:37:8 | ap3 | file://:0:0:0:0 | int * | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
| variables.cpp:41:7:41:11 | local | file://:0:0:0:0 | char[] | LocalVariable, SemanticStackVariable | | |
| variables.cpp:43:14:43:18 | local | file://:0:0:0:0 | int | GlobalLikeVariable, StaticLocalVariable | | static |
-| variables.cpp:48:9:48:12 | name | file://:0:0:0:0 | char * | Field | | |
-| variables.cpp:49:12:49:17 | number | file://:0:0:0:0 | long | Field | | |
-| variables.cpp:50:9:50:14 | street | file://:0:0:0:0 | char * | Field | | |
-| variables.cpp:51:9:51:12 | town | file://:0:0:0:0 | char * | Field | | |
+| variables.cpp:48:9:48:12 | name | file://:0:0:0:0 | char * | NonLocalCanonicalField | | |
+| variables.cpp:49:12:49:17 | number | file://:0:0:0:0 | long | NonLocalCanonicalField | | |
+| variables.cpp:50:9:50:14 | street | file://:0:0:0:0 | char * | NonLocalCanonicalField | | |
+| variables.cpp:51:9:51:12 | town | file://:0:0:0:0 | char * | NonLocalCanonicalField | | |
| variables.cpp:52:16:52:22 | country | file://:0:0:0:0 | char * | MemberVariable, StaticStorageDurationVariable | | static |
| variables.cpp:56:14:56:29 | externInFunction | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
| variables.cpp:60:10:60:17 | __func__ | file://:0:0:0:0 | const char[9] | GlobalLikeVariable, StaticInitializedStaticLocalVariable | | static |
From 2e533707161f3e6b63ad0e41060b173990b93827 Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Mon, 24 Nov 2025 15:01:00 +0000
Subject: [PATCH 67/70] Update
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 872b8c97314..d703bf9b54d 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
@@ -2081,7 +2081,7 @@ predicate localExprFlow(Expr e1, Expr e2) {
/**
* A canonical representation of a field.
*
- * For performance reasons we we want a unique `Content` that represents
+ * For performance reasons we want a unique `Content` that represents
* a given field across any template instantiation of a class.
*
* This is possible in _almost_ all cases, but there are cases where it is
From eb6b08591df1a3aa743de690c434f5880faff243 Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Mon, 24 Nov 2025 15:01:09 +0000
Subject: [PATCH 68/70] Update
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 d703bf9b54d..4f7a0fd61dc 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
@@ -2289,7 +2289,7 @@ class FieldContent extends Content, TFieldContent {
* Gets the field associated with this `Content`, if a unique one exists.
*
* For fields from template instantiations this predicate may still return
- * more than field, but all the fields will be constructed from the same
+ * more than one field, but all the fields will be constructed from the same
* template.
*/
Field getField() { none() } // overridden in subclasses
From 47ab307410d01f9f683a9744e6216482aa94f1cd Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Tue, 25 Nov 2025 12:06:58 +0000
Subject: [PATCH 69/70] C++: Respond to review comments.
---
.../code/cpp/ir/dataflow/internal/DataFlowUtil.qll | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
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 4f7a0fd61dc..1185b6a0c9c 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
@@ -2086,12 +2086,13 @@ predicate localExprFlow(Expr e1, Expr e2) {
*
* This is possible in _almost_ all cases, but there are cases where it is
* not possible to map between a field in the uninstantiated template to a
- * field in the instantiated template. This problem appears to be only in the
- * case of a local class definition. So this abstract class has two
- * implementations: a non-local case (where we can represent a canonical field
- * as the field declaration from an uninstantiated class template or a non-
- * templated class), and a local case (where we simply use the field from the
- * instantiated class).
+ * field in the instantiated template. This happens in the case of local class
+ * definitions (because the local class is not the template that constructs
+ * the instantiation - it is the enclosing function). So this abstract class
+ * has two implementations: a non-local case (where we can represent a
+ * canonical field as the field declaration from an uninstantiated class
+ * template or a non-templated class), and a local case (where we simply use
+ * the field from the instantiated class).
*/
abstract private class CanonicalField extends Field {
/** Gets a field represented by this canonical field. */
From 2024f32e814d0e1e38403825672a28a298b9ed74 Mon Sep 17 00:00:00 2001
From: Mathias Vorreiter Pedersen
Date: Tue, 25 Nov 2025 12:36:29 +0000
Subject: [PATCH 70/70] C++: Add an example with missing flow.
---
.../fields/dataflow-consistency.expected | 1 +
.../fields/partial-definition-diff.expected | 2 ++
.../fields/partial-definition-ir.expected | 2 ++
.../fields/partial-definition.expected | 2 ++
.../library-tests/dataflow/fields/simple.cpp | 32 +++++++++++++++++++
5 files changed, 39 insertions(+)
diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected
index 4021dbc492a..1b0b906af52 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected
+++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected
@@ -142,6 +142,7 @@ postWithInFlow
| simple.cpp:92:7:92:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:118:7:118:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
| simple.cpp:124:5:124:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
+| simple.cpp:167:9:167:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge
uniqueParameterNodeAtPosition
uniqueParameterNodePosition
diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected
index 8137e350d85..6cce6ac4f89 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected
+++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected
@@ -308,3 +308,5 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (par
| simple.cpp:124:5:124:6 | * ... | AST only |
| simple.cpp:131:14:131:14 | a | IR only |
| simple.cpp:136:10:136:10 | a | IR only |
+| simple.cpp:167:9:167:9 | x | AST only |
+| simple.cpp:168:8:168:12 | u_int | IR only |
diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected
index 8df575d8e16..b09f949271d 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected
+++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected
@@ -670,6 +670,8 @@
| simple.cpp:131:14:131:14 | a |
| simple.cpp:135:20:135:20 | q |
| simple.cpp:136:10:136:10 | a |
+| simple.cpp:167:3:167:7 | u_int |
+| simple.cpp:168:8:168:12 | u_int |
| struct_init.c:15:8:15:9 | ab |
| struct_init.c:15:12:15:12 | a |
| struct_init.c:16:8:16:9 | ab |
diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected b/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected
index 397e069c166..127cbadd971 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected
+++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected
@@ -597,6 +597,8 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (par
| simple.cpp:118:7:118:7 | i |
| simple.cpp:124:5:124:6 | * ... |
| simple.cpp:135:20:135:20 | q |
+| simple.cpp:167:3:167:7 | u_int |
+| simple.cpp:167:9:167:9 | x |
| struct_init.c:15:8:15:9 | ab |
| struct_init.c:15:12:15:12 | a |
| struct_init.c:16:8:16:9 | ab |
diff --git a/cpp/ql/test/library-tests/dataflow/fields/simple.cpp b/cpp/ql/test/library-tests/dataflow/fields/simple.cpp
index 3b8d882bc2b..d220b416e1a 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/simple.cpp
+++ b/cpp/ql/test/library-tests/dataflow/fields/simple.cpp
@@ -136,4 +136,36 @@ void alias_with_fields(bool b) {
sink(a.i); // $ MISSING: ast,ir
}
+template
+union U_with_two_instantiations_of_different_size {
+ int x;
+ T y;
+};
+
+struct LargeStruct {
+ int data[64];
+};
+
+void test_union_with_two_instantiations_of_different_sizes() {
+ // A union's fields is partitioned into "chunks" for field-flow in order to
+ // improve performance (so that a write to a field of a union does not flow
+ // to too many reads that don't happen at runtime). The partitioning is based
+ // the size of the types in the union. So a write to a field of size k only
+ // flows to a read of size k.
+ // Since field-flow is based on uninstantiated types a field can have
+ // multiple sizes if the union is instantiated with types of
+ // different sizes. So to compute the partition we pick the maximum size.
+ // Because of this there are `Content`s corresponding to the union
+ // `U_with_two_instantiations_of_different_size`: The one for size
+ // `sizeof(int)`, and the one for size `sizeof(LargeStruct)` (because
+ // `LargeStruct` is larger than `int`). So the write to `x` writes to the
+ // `Content` for size `sizeof(int)`, and the read of `y` reads from the
+ // `Content` for size `sizeof(LargeStruct)`.
+ U_with_two_instantiations_of_different_size u_int;
+ U_with_two_instantiations_of_different_size u_very_large;
+
+ u_int.x = user_input();
+ sink(u_int.y); // $ MISSING: ir
+}
+
} // namespace Simple
\ No newline at end of file