Merge branch 'main' into shared-basic-block-library

This commit is contained in:
Simon Friis Vindum
2025-01-24 09:54:26 +01:00
1726 changed files with 158793 additions and 66018 deletions

View File

@@ -1,9 +0,0 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.236.0/containers/cpp/.devcontainer/base.Dockerfile
# [Choice] Debian / Ubuntu version (use Debian 11, Ubuntu 18.04/22.04 on local arm64/Apple Silicon): debian-11, debian-10, ubuntu-22.04, ubuntu-20.04, ubuntu-18.04
FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-ubuntu-22.04
USER root
ADD root.sh /tmp/root.sh
ADD update-codeql.sh /usr/local/bin/update-codeql
RUN bash /tmp/root.sh && rm /tmp/root.sh

View File

@@ -1,25 +0,0 @@
{
"extensions": [
"github.vscode-codeql",
"hbenl.vscode-test-explorer",
"ms-vscode.test-adapter-converter",
"slevesque.vscode-zipexplorer",
"ms-vscode.cpptools"
],
"settings": {
"files.watcherExclude": {
"**/target/**": true
},
"codeQL.runningQueries.memory": 2048
},
"build": {
"dockerfile": "Dockerfile",
},
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined"
],
"remoteUser": "vscode",
"onCreateCommand": ".devcontainer/swift/user.sh"
}

View File

@@ -1,34 +0,0 @@
set -xe
BAZELISK_VERSION=v1.12.0
BAZELISK_DOWNLOAD_SHA=6b0bcb2ea15bca16fffabe6fda75803440375354c085480fe361d2cbf32501db
# install git lfs apt source
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash
# install gh apt source
(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) \
&& sudo mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
apt-get update
export DEBIAN_FRONTEND=noninteractive
apt-get -y install --no-install-recommends \
zlib1g-dev \
uuid-dev \
python3-distutils \
python3-pip \
bash-completion \
git-lfs \
gh
# Install Bazel
curl -fSsL -o /usr/local/bin/bazelisk https://github.com/bazelbuild/bazelisk/releases/download/${BAZELISK_VERSION}/bazelisk-linux-amd64
echo "${BAZELISK_DOWNLOAD_SHA} */usr/local/bin/bazelisk" | sha256sum --check -
chmod 0755 /usr/local/bin/bazelisk
ln -s bazelisk /usr/local/bin/bazel
# install latest codeql
update-codeql

View File

@@ -1,20 +0,0 @@
#!/bin/bash -e
URL=https://github.com/github/codeql-cli-binaries/releases
LATEST_VERSION=$(curl -L -s -H 'Accept: application/json' $URL/latest | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
CURRENT_VERSION=v$(codeql version 2>/dev/null | sed -ne 's/.*release \([0-9.]*\)\./\1/p')
if [[ $CURRENT_VERSION != $LATEST_VERSION ]]; then
if [[ $UID != 0 ]]; then
echo "update required, please run this script with sudo:"
echo " sudo $0"
exit 1
fi
ZIP=$(mktemp codeql.XXXX.zip)
curl -fSqL -o $ZIP $URL/download/$LATEST_VERSION/codeql-linux64.zip
unzip -q $ZIP -d /opt
rm $ZIP
ln -sf /opt/codeql/codeql /usr/local/bin/codeql
echo installed version $LATEST_VERSION
else
echo current version $CURRENT_VERSION is up-to-date
fi

View File

@@ -1,15 +0,0 @@
set -xe
git lfs install
# add the workspace to the codeql search path
mkdir -p /home/vscode/.config/codeql
echo "--search-path /workspaces/codeql" > /home/vscode/.config/codeql/config
# create a swift extractor pack with the current state
cd /workspaces/codeql
bazel run swift/create-extractor-pack
#install and set up pre-commit
python3 -m pip install pre-commit --no-warn-script-location
$HOME/.local/bin/pre-commit install

View File

@@ -9,5 +9,4 @@ paths-ignore:
- '/python/'
- '/javascript/ql/test'
- '/javascript/extractor/tests'
- '/rust/ql/test'
- '/rust/ql/integration-tests'
- '/rust/ql'

View File

@@ -19,7 +19,7 @@ on:
jobs:
CodeQL-Build:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
permissions:
contents: read
@@ -38,12 +38,10 @@ jobs:
languages: cpp
config-file: ./.github/codeql/codeql-config.yml
- name: "[Ubuntu] Remove GCC 13 from runner image"
shell: bash
- name: Install dependencies
run: |
sudo rm -f /etc/apt/sources.list.d/ubuntu-toolchain-r-ubuntu-test-jammy.list
sudo apt-get update
sudo apt-get install -y --allow-downgrades libc6=2.35-* libc6-dev=2.35-* libstdc++6=12.3.0-* libgcc-s1=12.3.0-*
sudo apt-get install -y uuid-dev
- name: "Build Swift extractor using Bazel"
run: |

View File

@@ -48,12 +48,6 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: ./swift/actions/build-and-test
build-and-test-linux:
if: github.repository_owner == 'github'
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: ./swift/actions/build-and-test
qltests-macos:
if: ${{ github.repository_owner == 'github' && github.event_name == 'pull_request' }}
needs: build-and-test-macos

View File

@@ -1,4 +0,0 @@
---
category: majorAnalysis
---
* Added support for TypeScript 5.7.

335
Cargo.lock generated
View File

@@ -92,9 +92,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.94"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
[[package]]
name = "argfile"
@@ -116,11 +116,14 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
name = "ast-generator"
version = "0.1.0"
dependencies = [
"anyhow",
"either",
"itertools 0.12.1",
"itertools 0.14.0",
"mustache",
"proc-macro2",
"quote",
"ra_ap_stdx",
"serde",
"ungrammar",
]
@@ -153,9 +156,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be"
[[package]]
name = "borsh"
@@ -168,9 +171,9 @@ dependencies = [
[[package]]
name = "bstr"
version = "1.11.1"
version = "1.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8"
checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0"
dependencies = [
"memchr",
"serde",
@@ -184,9 +187,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
version = "1.20.0"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
[[package]]
name = "byteorder"
@@ -228,9 +231,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.5"
version = "1.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7"
dependencies = [
"shlex",
]
@@ -265,7 +268,7 @@ version = "0.98.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f2eb1cd6054da221bd1ac0197fb2fe5e2caf3dcb93619398fc1433f8f09093"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.7.0",
"chalk-derive",
]
@@ -315,9 +318,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.23"
version = "4.5.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
dependencies = [
"clap_builder",
"clap_derive",
@@ -325,9 +328,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.23"
version = "4.5.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
dependencies = [
"anstream",
"anstyle",
@@ -337,9 +340,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.18"
version = "4.5.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
dependencies = [
"heck 0.5.0",
"proc-macro2",
@@ -411,8 +414,8 @@ dependencies = [
"dunce",
"figment",
"glob",
"itertools 0.13.0",
"log",
"itertools 0.14.0",
"log 0.4.22",
"num-traits",
"ra_ap_base_db",
"ra_ap_cfg",
@@ -433,6 +436,7 @@ dependencies = [
"serde_json",
"serde_with",
"stderrlog",
"toml",
"triomphe",
]
@@ -585,7 +589,7 @@ version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5"
dependencies = [
"log",
"log 0.4.22",
]
[[package]]
@@ -743,9 +747,9 @@ dependencies = [
[[package]]
name = "glob"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "globset"
@@ -755,7 +759,7 @@ checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19"
dependencies = [
"aho-corasick",
"bstr",
"log",
"log 0.4.22",
"regex-automata 0.4.9",
"regex-syntax 0.8.5",
]
@@ -922,9 +926,9 @@ dependencies = [
[[package]]
name = "itertools"
version = "0.13.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
@@ -995,7 +999,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.7.0",
"libc",
"redox_syscall",
]
@@ -1020,6 +1024,15 @@ dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
dependencies = [
"log 0.4.22",
]
[[package]]
name = "log"
version = "0.4.22"
@@ -1072,7 +1085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
"log 0.4.22",
"wasi",
"windows-sys 0.48.0",
]
@@ -1086,6 +1099,16 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "mustache"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51956ef1c5d20a1384524d91e616fb44dfc7d8f249bf696d49c97dd3289ecab5"
dependencies = [
"log 0.3.9",
"serde",
]
[[package]]
name = "nohash-hasher"
version = "0.2.0"
@@ -1098,14 +1121,14 @@ version = "6.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.7.0",
"crossbeam-channel",
"filetime",
"fsevent-sys",
"inotify",
"kqueue",
"libc",
"log",
"log 0.4.22",
"mio",
"walkdir",
"windows-sys 0.48.0",
@@ -1250,9 +1273,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "powerfmt"
@@ -1271,9 +1294,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.92"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
@@ -1293,40 +1316,39 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ra-ap-rustc_abi"
version = "0.80.0"
version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613760a3071b25a67a8d7bc97b37c7fd4722562e9479137b83ae9cf8f8c1601a"
checksum = "28b782af0a7a8df16ddf43cd70da9f17bc3b1ce712c9e4992b6edb16f5f53632"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.7.0",
"ra-ap-rustc_index",
"tracing",
]
[[package]]
name = "ra-ap-rustc_index"
version = "0.80.0"
version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b2bc6b4ecede8ff28295041e22c2e66853f8e0125990c05135bad3c30bad12c"
checksum = "ce5742f134960482f543b35ecebec3cacc6d79a9a685713518b4d8d70c5f9aa8"
dependencies = [
"arrayvec",
"ra-ap-rustc_index_macros",
"smallvec",
]
[[package]]
name = "ra-ap-rustc_index_macros"
version = "0.80.0"
version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2374a39fb2d92d0509178c2b442eadca3cc10e403ef9729a040c1855b08ff261"
checksum = "d7ea011fcf68309a8835ad01d91c032cb18444617b00e2cab21d45b208164441"
dependencies = [
"proc-macro2",
"quote",
@@ -1335,9 +1357,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_lexer"
version = "0.80.0"
version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a2cf8e48b69af3ecc29ed3449892e8a999111d2f75212a78aa242e117cf1711"
checksum = "eb76f0a4d4c20859e41f0a23bff0f37ab9ca9171c214a6c7dd72ea69434865dc"
dependencies = [
"unicode-properties",
"unicode-xid",
@@ -1345,9 +1367,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_parse_format"
version = "0.80.0"
version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d6f59a22b559263c5c42747ae362cf5d4fb272293fa119a4623f8ec288f9656"
checksum = "06080bd35078305421a62da77f3c128482d8d44441b6da8ce9d146d1cd9cdb5b"
dependencies = [
"ra-ap-rustc_index",
"ra-ap-rustc_lexer",
@@ -1355,9 +1377,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_pattern_analysis"
version = "0.80.0"
version = "0.87.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7d0575b54ffe09bc5d2f158454bc05f0c30c01d9992310965f854be50ae22b8"
checksum = "68a3154fe4c20c177d7b3c678a2d3a97aba0cca156ddef88959915041889daf0"
dependencies = [
"ra-ap-rustc_index",
"rustc-hash 2.1.0",
@@ -1368,9 +1390,9 @@ dependencies = [
[[package]]
name = "ra_ap_base_db"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "321b770750ff90b03af539ac6d47ca46208f6f747be97c0a4aaca3a428447c8f"
checksum = "548b95b278a8f6f888a0bb6cb7bf4201fe920d3800cd99770054e5eb72f3cd6a"
dependencies = [
"la-arena",
"lz4_flex",
@@ -1389,9 +1411,9 @@ dependencies = [
[[package]]
name = "ra_ap_cfg"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5023f50ebcf3656d85b96565dac56d50cc3e3d959c41592f457d2230d7be706a"
checksum = "921e2b0232d1e8352eb9f476bb55c1d8bcbed0531adc17c74aa711fef015c851"
dependencies = [
"ra_ap_intern",
"ra_ap_tt",
@@ -1400,10 +1422,16 @@ dependencies = [
]
[[package]]
name = "ra_ap_hir"
version = "0.0.248"
name = "ra_ap_edition"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a9a085cf581d5f503aa467d32bbd1e5e7f94a3e86f881ca9c19b379570c62"
checksum = "a7cc6633305d878cafb4a4482e7e7002d1a5d7b15fa837728b6613ff5336f8a4"
[[package]]
name = "ra_ap_hir"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3f6b31381a297e5bb4fa76108a2cf7bf8d35067a130f932aa6fdfb733ba3a1"
dependencies = [
"arrayvec",
"either",
@@ -1426,12 +1454,12 @@ dependencies = [
[[package]]
name = "ra_ap_hir_def"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "825c47fec7aab22c38ad9eba1d76102a95a6eb089e85b4e58308089d056c3cdc"
checksum = "84144bdda7af170e660d312982889622f4a5361c1bb74df2afa2a6ce17d48644"
dependencies = [
"arrayvec",
"bitflags 2.6.0",
"bitflags 2.7.0",
"cov-mark",
"dashmap",
"drop_bomb",
@@ -1463,9 +1491,9 @@ dependencies = [
[[package]]
name = "ra_ap_hir_expand"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1084b708f90de31888deb6e7f9cda5ebb8e6a59484143a3df0a4007dcf496b17"
checksum = "441661b394acfa4f3ac4cb54386f8ee8b451504ec167b0bf0e4200da1bbca50d"
dependencies = [
"cov-mark",
"either",
@@ -1491,12 +1519,12 @@ dependencies = [
[[package]]
name = "ra_ap_hir_ty"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "400a42e442b6d8f64adea48a8c9e39f76a1b9ed9964fd40222bd2d7cfe0a5a79"
checksum = "6feea30dff289f33a8ed76172ff4cb299db22d224f88735aa2c7f49ba1e5e77f"
dependencies = [
"arrayvec",
"bitflags 2.6.0",
"bitflags 2.7.0",
"chalk-derive",
"chalk-ir",
"chalk-recursive",
@@ -1531,12 +1559,12 @@ dependencies = [
[[package]]
name = "ra_ap_ide_db"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4ced45b107a8f4c1a4cee68b270d08832327b34ad0bf7794879342ac280bc8b"
checksum = "7e33bd5a0139b6c74d34ed963494115abe3f9c95cf5936871ab3d9b548ccbbdf"
dependencies = [
"arrayvec",
"bitflags 2.6.0",
"bitflags 2.7.0",
"cov-mark",
"crossbeam-channel",
"either",
@@ -1562,9 +1590,9 @@ dependencies = [
[[package]]
name = "ra_ap_intern"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5432d6cf7382c06dab31b6c1772446c8576dd19fcbc007bc8a6fd8bca3d424d"
checksum = "faa7ee24ae9bf4d2536ef7fb6de35f30856edbf7b3d6ac02e5a2532118896569"
dependencies = [
"dashmap",
"hashbrown 0.14.5",
@@ -1575,15 +1603,15 @@ dependencies = [
[[package]]
name = "ra_ap_limit"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "822501c9f88830865ebedf944130dbe0603fa8d30a5da90f3224c1dcca2660de"
checksum = "90d8a2aecbd488cf79b430bd5abe6650da44ae58b31cd6052c909dbd3f5d5926"
[[package]]
name = "ra_ap_load-cargo"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d5b002bcda197a4e9442c827dc86305d8fc1820fbbcb9814ff9bbc2c50f4e9c"
checksum = "6e2372aadd32e85460de595891c8b3562126166bc94fdc24508d6784c9d93357"
dependencies = [
"anyhow",
"crossbeam-channel",
@@ -1603,9 +1631,9 @@ dependencies = [
[[package]]
name = "ra_ap_mbe"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4fce40b490b6bbca3d033f4cbf32ef07069423aa3edc1e00ec26ddabf503866"
checksum = "bf69ba82adb6e436617ecd09c0ff58006f376060dff437eb9fd383c2983f6d01"
dependencies = [
"arrayvec",
"cov-mark",
@@ -1624,34 +1652,33 @@ dependencies = [
[[package]]
name = "ra_ap_parser"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "573c14046174e3ef03a9d73841dbc52fd1d6224fffd1a0713aef95b45e024f75"
checksum = "8f499b6c33a588d60ed9722d057954a21ec01913b97a5693ff40ba4828ffa7b9"
dependencies = [
"drop_bomb",
"ra-ap-rustc_lexer",
"ra_ap_edition",
"ra_ap_limit",
"tracing",
]
[[package]]
name = "ra_ap_paths"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57aa6e3d7c45806434cdee09aa74b561723552732e8b089213fe821ae84404ec"
checksum = "b5a16df131fa641a4af4d9488152b7b332a6a30e93bc655fdbe88f555ba28825"
dependencies = [
"camino",
"serde",
]
[[package]]
name = "ra_ap_proc_macro_api"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79d9595e05b422f3258c51f9a529129c9a59f99037deac652ff2cdd0c97e0bda"
checksum = "3480e0d07197ebcc2db5836b0c39625e07b0d77c6471a2a748e5bdf54ce556e3"
dependencies = [
"indexmap 2.7.0",
"ra_ap_base_db",
"ra_ap_intern",
"ra_ap_paths",
"ra_ap_span",
@@ -1659,15 +1686,16 @@ dependencies = [
"ra_ap_tt",
"rustc-hash 2.1.0",
"serde",
"serde_derive",
"serde_json",
"tracing",
]
[[package]]
name = "ra_ap_profile"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "459551d7e5a6dda9204c3741215c1f6a97cf6f4553e3c29294f7f8ac0ec91f57"
checksum = "95b707dd9c92139030587d81b3333428f48af8f4728330ed12101ab0bb431d72"
dependencies = [
"cfg-if",
"libc",
@@ -1677,9 +1705,9 @@ dependencies = [
[[package]]
name = "ra_ap_project_model"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "171aacd6d1642f9d821f27fc318a503cfe10c5c6294193c401e991266e38a583"
checksum = "551a0de5a16f0538fbaf401a319d81d1a034f7aa014e46ac87c5bd74229a211b"
dependencies = [
"anyhow",
"cargo_metadata",
@@ -1695,6 +1723,7 @@ dependencies = [
"rustc-hash 2.1.0",
"semver",
"serde",
"serde_derive",
"serde_json",
"tracing",
"triomphe",
@@ -1702,9 +1731,9 @@ dependencies = [
[[package]]
name = "ra_ap_salsa"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "504314128b0998f54d8e253a328a53e2a697f579f8d1f194b52f77cd8a540e36"
checksum = "6ec0c82d9e5affbf7d582750b301d279589787a5ac729f95756f5a0b0bf2b4a4"
dependencies = [
"indexmap 2.7.0",
"itertools 0.12.1",
@@ -1720,9 +1749,9 @@ dependencies = [
[[package]]
name = "ra_ap_salsa-macros"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d957f6ec9a6f11cf9c8ce0f27711f4f9813bdd690b3efa6a280cb06a75b5a0fc"
checksum = "8440192eb549dda1cdefc95eaa1fc42ad13cfbd303add757517d77c81e7dc2e1"
dependencies = [
"heck 0.4.1",
"proc-macro2",
@@ -1732,9 +1761,9 @@ dependencies = [
[[package]]
name = "ra_ap_span"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c82fd3ff10c25958db0c254f8f4378cb75069017b675f4fe4c5e7d5f2827e71"
checksum = "18690685d10da2577d7821d46c0de5a884bf1755e59635cbb1a795451e2a4acc"
dependencies = [
"hashbrown 0.14.5",
"la-arena",
@@ -1748,9 +1777,9 @@ dependencies = [
[[package]]
name = "ra_ap_stdx"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0be113ed187f4bf5403ebd8256d3d4aead8d265f670d534c646edea68516ef86"
checksum = "4016934faae8413b4ad3f1bf063c7ffccdcfdf3f67ff32f4a79a197a3c1cb0da"
dependencies = [
"always-assert",
"crossbeam-channel",
@@ -1763,9 +1792,9 @@ dependencies = [
[[package]]
name = "ra_ap_syntax"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5af8d681a9fd408be1b17f3b150eb98907fb72b9b44000ada9c3e9b6c059188"
checksum = "e8e381d21d166d12b11906171f82382473d60abfead0c4acc6d7d07150f87f73"
dependencies = [
"cov-mark",
"either",
@@ -1783,9 +1812,9 @@ dependencies = [
[[package]]
name = "ra_ap_syntax-bridge"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f957885289e9789dffcd81ebfa4c2d49be3fad41f7718ffeacb3599f6d88678"
checksum = "65f1960218acd2ed8e486e7bd24f80a7eb89591906c6b0831296b2a75c556b2f"
dependencies = [
"ra_ap_intern",
"ra_ap_parser",
@@ -1799,9 +1828,9 @@ dependencies = [
[[package]]
name = "ra_ap_toolchain"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e067bd4107ec52a241b68398539632df0a850013907070002d4d403c3691e51c"
checksum = "c9195f69ff02f076f5a726c7fbafa2b4639d00235906cb44e52ca75cd8b33c30"
dependencies = [
"camino",
"home",
@@ -1809,9 +1838,9 @@ dependencies = [
[[package]]
name = "ra_ap_tt"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c38deb50d7a26663c28deb01e5611b3b92b5a87298940e0638589f03c3faf62"
checksum = "8ac261d79d3ec475a1f3b2a758d3e466f2b9d7d883fb72239b06979bf6880018"
dependencies = [
"arrayvec",
"ra-ap-rustc_lexer",
@@ -1822,9 +1851,9 @@ dependencies = [
[[package]]
name = "ra_ap_vfs"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168a9378dd3f185ae94dda9c35e4d468a8ff105c8f4bb57e17f6e2312d84d1a8"
checksum = "ee35a171beccbb01b4ede1d9ad91dee487a3742d7cc39efd7aed6961027cbe78"
dependencies = [
"crossbeam-channel",
"fst",
@@ -1838,9 +1867,9 @@ dependencies = [
[[package]]
name = "ra_ap_vfs-notify"
version = "0.0.248"
version = "0.0.258"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a5e13d88bf8bbd8dd02c96dd8d89e6cebc2757a0edf13b3b85007024fcf216c"
checksum = "b234b7651eb5d61f18d4f4643590bb8b1fd59ef766a1059741c09c540ec8cd86"
dependencies = [
"crossbeam-channel",
"notify",
@@ -1909,7 +1938,7 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.7.0",
]
[[package]]
@@ -2036,18 +2065,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
@@ -2056,9 +2085,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.133"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
dependencies = [
"itoa",
"memchr",
@@ -2067,10 +2096,19 @@ dependencies = [
]
[[package]]
name = "serde_with"
version = "3.11.0"
name = "serde_spanned"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817"
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
dependencies = [
"serde",
]
[[package]]
name = "serde_with"
version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa"
dependencies = [
"base64",
"chrono",
@@ -2086,9 +2124,9 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "3.11.0"
version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d"
checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e"
dependencies = [
"darling",
"proc-macro2",
@@ -2160,7 +2198,7 @@ checksum = "61c910772f992ab17d32d6760e167d2353f4130ed50e796752689556af07dc6b"
dependencies = [
"chrono",
"is-terminal",
"log",
"log 0.4.22",
"termcolor",
"thread_local",
]
@@ -2179,9 +2217,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.90"
version = "2.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
dependencies = [
"proc-macro2",
"quote",
@@ -2275,6 +2313,40 @@ dependencies = [
"time-core",
]
[[package]]
name = "toml"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
"indexmap 2.7.0",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "tracing"
version = "0.1.41"
@@ -2313,7 +2385,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"log 0.4.22",
"once_cell",
"tracing-core",
]
@@ -2338,9 +2410,9 @@ dependencies = [
[[package]]
name = "tree-sitter"
version = "0.24.5"
version = "0.24.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ac95b18f0f727aaaa012bd5179a1916706ee3ed071920fdbda738750b0c0bf5"
checksum = "5f2434c86ba59ed15af56039cc5bf1acf8ba76ce301e32ef08827388ef285ec5"
dependencies = [
"cc",
"regex",
@@ -2502,7 +2574,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
dependencies = [
"bumpalo",
"log",
"log 0.4.22",
"proc-macro2",
"quote",
"syn",
@@ -2726,6 +2798,15 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.6.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a"
dependencies = [
"memchr",
]
[[package]]
name = "yansi"
version = "1.0.1"

View File

@@ -65,26 +65,93 @@ rust_host_tools.host_tools(
# deps for python extractor
# keep in sync by running `misc/bazel/3rdparty/update_cargo_deps.sh`
py_deps = use_extension("//misc/bazel/3rdparty:py_deps_extension.bzl", "p")
use_repo(py_deps, "vendor__anyhow-1.0.44", "vendor__cc-1.0.70", "vendor__clap-2.33.3", "vendor__regex-1.5.5", "vendor__smallvec-1.6.1", "vendor__string-interner-0.12.2", "vendor__thiserror-1.0.29", "vendor__tree-sitter-0.20.4", "vendor__tree-sitter-graph-0.7.0")
use_repo(
py_deps,
"vendor__anyhow-1.0.44",
"vendor__cc-1.0.70",
"vendor__clap-2.33.3",
"vendor__regex-1.5.5",
"vendor__smallvec-1.6.1",
"vendor__string-interner-0.12.2",
"vendor__thiserror-1.0.29",
"vendor__tree-sitter-0.20.4",
"vendor__tree-sitter-graph-0.7.0",
)
# deps for ruby+rust
# keep in sync by running `misc/bazel/3rdparty/update_cargo_deps.sh`
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
use_repo(tree_sitter_extractors_deps, "vendor__anyhow-1.0.94", "vendor__argfile-0.2.1", "vendor__chrono-0.4.39", "vendor__clap-4.5.23", "vendor__dunce-1.0.5", "vendor__either-1.13.0", "vendor__encoding-0.2.33", "vendor__figment-0.10.19", "vendor__flate2-1.0.35", "vendor__glob-0.3.1", "vendor__globset-0.4.15", "vendor__itertools-0.12.1", "vendor__itertools-0.13.0", "vendor__lazy_static-1.5.0", "vendor__log-0.4.22", "vendor__num-traits-0.2.19", "vendor__num_cpus-1.16.0", "vendor__proc-macro2-1.0.92", "vendor__quote-1.0.37", "vendor__ra_ap_base_db-0.0.248", "vendor__ra_ap_cfg-0.0.248", "vendor__ra_ap_hir-0.0.248", "vendor__ra_ap_hir_def-0.0.248", "vendor__ra_ap_hir_expand-0.0.248", "vendor__ra_ap_ide_db-0.0.248", "vendor__ra_ap_intern-0.0.248", "vendor__ra_ap_load-cargo-0.0.248", "vendor__ra_ap_parser-0.0.248", "vendor__ra_ap_paths-0.0.248", "vendor__ra_ap_project_model-0.0.248", "vendor__ra_ap_span-0.0.248", "vendor__ra_ap_stdx-0.0.248", "vendor__ra_ap_syntax-0.0.248", "vendor__ra_ap_vfs-0.0.248", "vendor__rand-0.8.5", "vendor__rayon-1.10.0", "vendor__regex-1.11.1", "vendor__serde-1.0.216", "vendor__serde_json-1.0.133", "vendor__serde_with-3.11.0", "vendor__stderrlog-0.6.0", "vendor__syn-2.0.90", "vendor__tracing-0.1.41", "vendor__tracing-subscriber-0.3.19", "vendor__tree-sitter-0.24.5", "vendor__tree-sitter-embedded-template-0.23.2", "vendor__tree-sitter-json-0.24.8", "vendor__tree-sitter-ql-0.23.1", "vendor__tree-sitter-ruby-0.23.1", "vendor__triomphe-0.1.14", "vendor__ungrammar-1.16.1")
use_repo(
tree_sitter_extractors_deps,
"vendor__anyhow-1.0.95",
"vendor__argfile-0.2.1",
"vendor__chrono-0.4.39",
"vendor__clap-4.5.26",
"vendor__dunce-1.0.5",
"vendor__either-1.13.0",
"vendor__encoding-0.2.33",
"vendor__figment-0.10.19",
"vendor__flate2-1.0.35",
"vendor__glob-0.3.2",
"vendor__globset-0.4.15",
"vendor__itertools-0.14.0",
"vendor__lazy_static-1.5.0",
"vendor__log-0.4.22",
"vendor__mustache-0.9.0",
"vendor__num-traits-0.2.19",
"vendor__num_cpus-1.16.0",
"vendor__proc-macro2-1.0.93",
"vendor__quote-1.0.38",
"vendor__ra_ap_base_db-0.0.258",
"vendor__ra_ap_cfg-0.0.258",
"vendor__ra_ap_hir-0.0.258",
"vendor__ra_ap_hir_def-0.0.258",
"vendor__ra_ap_hir_expand-0.0.258",
"vendor__ra_ap_ide_db-0.0.258",
"vendor__ra_ap_intern-0.0.258",
"vendor__ra_ap_load-cargo-0.0.258",
"vendor__ra_ap_parser-0.0.258",
"vendor__ra_ap_paths-0.0.258",
"vendor__ra_ap_project_model-0.0.258",
"vendor__ra_ap_span-0.0.258",
"vendor__ra_ap_stdx-0.0.258",
"vendor__ra_ap_syntax-0.0.258",
"vendor__ra_ap_vfs-0.0.258",
"vendor__rand-0.8.5",
"vendor__rayon-1.10.0",
"vendor__regex-1.11.1",
"vendor__serde-1.0.217",
"vendor__serde_json-1.0.135",
"vendor__serde_with-3.12.0",
"vendor__stderrlog-0.6.0",
"vendor__syn-2.0.96",
"vendor__toml-0.8.19",
"vendor__tracing-0.1.41",
"vendor__tracing-subscriber-0.3.19",
"vendor__tree-sitter-0.24.6",
"vendor__tree-sitter-embedded-template-0.23.2",
"vendor__tree-sitter-json-0.24.8",
"vendor__tree-sitter-ql-0.23.1",
"vendor__tree-sitter-ruby-0.23.1",
"vendor__triomphe-0.1.14",
"vendor__ungrammar-1.16.1",
)
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# rust-analyzer sources needed by the rust ast-generator (see `rust/ast-generator/README.md`)
RUST_ANALYZER_SRC_TAG = "2025-01-07"
http_archive(
name = "rust-analyzer-src",
build_file = "//rust/ast-generator:BUILD.rust-analyzer-src.bazel",
integrity = "sha256-jl4KJmZku+ilMLnuX2NU+qa1v10IauSiDiz23sZo360=",
integrity = "sha256-eo8mIaUafZL8LOM65bDIIIXw1rNQ/P/x5RK/XUtgo5g=",
patch_args = ["-p1"],
patches = [
"//rust/ast-generator:patches/rust-analyzer.patch",
],
strip_prefix = "rust-analyzer-2024-12-16",
url = "https://github.com/rust-lang/rust-analyzer/archive/refs/tags/2024-12-16.tar.gz",
strip_prefix = "rust-analyzer-%s" % RUST_ANALYZER_SRC_TAG,
url = "https://github.com/rust-lang/rust-analyzer/archive/refs/tags/%s.tar.gz" % RUST_ANALYZER_SRC_TAG,
)
dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet")
@@ -151,6 +218,7 @@ use_repo(
"kotlin-compiler-2.0.0-RC1",
"kotlin-compiler-2.0.20-Beta2",
"kotlin-compiler-2.1.0-Beta1",
"kotlin-compiler-2.1.20-Beta1",
"kotlin-compiler-embeddable-1.5.0",
"kotlin-compiler-embeddable-1.5.10",
"kotlin-compiler-embeddable-1.5.20",
@@ -165,6 +233,7 @@ use_repo(
"kotlin-compiler-embeddable-2.0.0-RC1",
"kotlin-compiler-embeddable-2.0.20-Beta2",
"kotlin-compiler-embeddable-2.1.0-Beta1",
"kotlin-compiler-embeddable-2.1.20-Beta1",
"kotlin-stdlib-1.5.0",
"kotlin-stdlib-1.5.10",
"kotlin-stdlib-1.5.20",
@@ -179,6 +248,7 @@ use_repo(
"kotlin-stdlib-2.0.0-RC1",
"kotlin-stdlib-2.0.20-Beta2",
"kotlin-stdlib-2.1.0-Beta1",
"kotlin-stdlib-2.1.20-Beta1",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

View File

@@ -2,10 +2,16 @@ if (($null -ne $env:LGTM_INDEX_INCLUDE) -or ($null -ne $env:LGTM_INDEX_EXCLUDE)
Write-Output 'Path filters set. Passing them through to the JavaScript extractor.'
} else {
Write-Output 'No path filters set. Using the default filters.'
# Note: We're adding the `reusable_workflows` subdirectories to proactively
# record workflows that were called cross-repo, check them out locally,
# and enable an interprocedural analysis across the workflow files.
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
$DefaultPathFilters = @(
'exclude:**/*',
'include:.github/workflows/**/*.yml',
'include:.github/workflows/**/*.yaml',
'include:.github/workflows/*.yml',
'include:.github/workflows/*.yaml',
'include:.github/reusable_workflows/**/*.yml',
'include:.github/reusable_workflows/**/*.yaml',
'include:**/action.yml',
'include:**/action.yaml'
)

View File

@@ -2,10 +2,16 @@
set -eu
# Note: We're adding the `reusable_workflows` subdirectories to proactively
# record workflows that were called cross-repo, check them out locally,
# and enable an interprocedural analysis across the workflow files.
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
DEFAULT_PATH_FILTERS=$(cat << END
exclude:**/*
include:.github/workflows/**/*.yml
include:.github/workflows/**/*.yaml
include:.github/workflows/*.yml
include:.github/workflows/*.yaml
include:.github/reusable_workflows/**/*.yml
include:.github/reusable_workflows/**/*.yaml
include:**/action.yml
include:**/action.yaml
END

View File

@@ -0,0 +1,9 @@
## 0.4.1
No user-facing changes.
## 0.4.0
### New Features
* Initial public preview release

View File

@@ -1,4 +1,5 @@
---
category: newQuery
---
## 0.4.0
### New Features
* Initial public preview release

View File

@@ -0,0 +1,3 @@
## 0.4.1
No user-facing changes.

View File

@@ -0,0 +1,2 @@
---
lastReleaseVersion: 0.4.1

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all
version: 0.4.0-dev
version: 0.4.2-dev
library: true
warnOnImplicitThis: true
dependencies:

View File

@@ -0,0 +1,9 @@
## 0.4.1
No user-facing changes.
## 0.4.0
### New Queries
* Initial public preview release

View File

@@ -1,4 +1,5 @@
---
category: feature
---
## 0.4.0
### New Queries
* Initial public preview release

View File

@@ -0,0 +1,3 @@
## 0.4.1
No user-facing changes.

View File

@@ -0,0 +1,2 @@
---
lastReleaseVersion: 0.4.1

View File

@@ -0,0 +1,2 @@
- description: Extended and experimental security queries for GitHub Actions
- import: codeql-suites/actions-code-scanning.qls

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries
version: 0.4.0-dev
version: 0.4.2-dev
library: false
warnOnImplicitThis: true
groups: [actions, queries]

View File

@@ -6,7 +6,7 @@ on:
jobs:
test1:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
outputs:
job_output: ${{ steps.source.outputs.value }}
steps:

View File

@@ -491,7 +491,7 @@ jobs:
send_results:
name: Send results to webhook
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: always()
needs: [
setup,

View File

@@ -3,7 +3,7 @@ on:
jobs:
test:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
if: >
(github.event.workflow_run.event == 'pull_request' ||
github.event.workflow_run.event == 'pull_request_target') &&

View File

@@ -3,7 +3,7 @@ on:
jobs:
test:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Run Issue form parser
id: parse

View File

@@ -7,7 +7,7 @@ on:
jobs:
test1:
if: github.event.comment.body == '@metabase-bot run visual tests'
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Fetch issue
uses: octokit/request-action@v2.x

View File

@@ -7,7 +7,7 @@ on:
jobs:
test1:
if: github.event.comment.body == '@metabase-bot run visual tests'
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Fetch issue
uses: octokit/request-action@v2.x

View File

@@ -21,9 +21,9 @@ jobs:
matrix:
include:
- language: javascript
os: ubuntu-22.04
os: ubuntu-24.04
- language: ruby
os: ubuntu-22.04-16core
os: ubuntu-24.04-16core
steps:
- name: Checkout repository

View File

@@ -247,7 +247,8 @@
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll",
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll"
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll",
"rust/ql/lib/codeql/rust/security/internal/SensitiveDataHeuristics.qll"
],
"IncompleteUrlSubstringSanitization": [
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
description: Support variable template specializations
compatibility: full
var_specialized.rel: delete

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
class Stmt extends @stmt {
string toString() { none() }
}
class Location extends @location_stmt {
string toString() { none() }
}
predicate isConstevalIf(Stmt stmt) {
exists(int kind | stmts(stmt, kind, _) | kind = 38 or kind = 39)
}
from Stmt stmt, int kind, int kind_new, Location location
where
stmts(stmt, kind, location) and
if isConstevalIf(stmt) then kind_new = 7 else kind_new = kind // Turns consteval if into a block with two block statements in it
select stmt, kind_new, location

View File

@@ -0,0 +1,5 @@
description: Support (not) consteval if
compatibility: full
consteval_if_then.rel: delete
consteval_if_else.rel: delete
stmts.rel: run stmts.qlo

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
description: Support template template parameter arguments and instantiations
compatibility: full
template_template_instantiation.rel: delete
template_template_argument.rel: delete
template_template_argument_value.rel: delete

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
class PreprocessorDirective extends @preprocdirect {
string toString() { none() }
}
class Location extends @location_default {
string toString() { none() }
}
bindingset[kind]
int getKind(int kind) {
if kind = 14
then result = 6 // Represent MSFT #import as #include
else
if kind = 15 or kind = 6
then result = 3 // Represent #elifdef and #elifndef as #elif
else result = kind
}
from PreprocessorDirective ppd, int kind, Location l
where preprocdirects(ppd, kind, l)
select ppd, getKind(kind), l

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
description: Support #elifdef, #elifndef and #import
compatibility: full
preprocdirects.rel: run preprocdirects.qlo

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: Support concept id expressions
compatibility: full
concept_instantiation.rel: delete
is_type_constraint.rel: delete

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
description: Improve user types and proxy classes
compatibility: full
usertypes.rel: run usertypes.qlo

View File

@@ -0,0 +1,10 @@
class UserType extends @usertype {
string toString() { none() }
}
bindingset[kind]
int getKind(int kind) { if kind in [15, 16, 17] then result = 6 else result = kind }
from UserType usertype, string name, int kind
where usertypes(usertype, name, kind)
select usertype, name, getKind(kind)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
description: Support requires clauses and type constraints
compatibility: full
fun_requires.rel: delete
var_requires.rel: delete
type_requires.rel: delete
type_template_type_constraint.rel: delete

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
description: Support concept templates
compatibility: full
concept_templates.rel: delete
concept_template_argument.rel: delete
concept_template_argument_value.rel: delete

View File

@@ -1,3 +1,46 @@
## 3.2.0
### New Features
* Add a new predicate `getAnIndirectBarrier` to the parameterized module `InstructionBarrierGuard` in `semmle.code.cpp.dataflow.new.DataFlow` for computing indirect dataflow nodes that are guarded by a given instruction. This predicate is similar to the `getAnIndirectBarrier` predicate on the parameterized module `BarrierGuard`.
* A new predicate `getDecltype` was added to the `ProxyClass` class, which yields the decltype for the proxy class.
* Template classes that are of `struct` type are now also instances of the `Struct` class.
* Template classes that are of `union` type are now also instances of the `Union` class.
* A new abstract class `ConfigurationTestFile` (`semmle.code.cpp.ConfigurationTestFile.ConfigurationTestFile`) was introduced, which represents files created to test the build configuration. A subclass `CmakeTryCompileFile` of `ConfigurationTestFile` was also introduced, which represents files created by CMake to test the build configuration.
* New predicates `getARequiresClause`, `getTemplateRequiresClause` and `getFunctionRequiresClause` were added to the `FunctionDeclarationEntry` class, which yield the requires clauses when the entry represents a function template declaration with requires clauses.
* A new predicate `getRequiresClause` was added to the `TypeDeclarationEntry` class, which yields the requires clause when the entry represents a class template declaration with a requires clause.
* A new predicate `getRequiresClause` was added to the `VariableDeclarationEntry` class, which yields the requires clause when the entry represents a variable template declaration with a requires clause.
* A new predicate `getTypeConstraint` was added to the `TypeTemplateParameter` class, which yields the type constraint of the parameter if it exists.
* A new class `VariableTemplateSpecialization` was introduced, which represents explicit specializations of variable templates.
* A new predicate `isSpecialization` was added to the `Variable` class, which holds if the variable is a template specialization.
* A new class `ConceptIdExpr` was introduced, which represents C++20 concept id expressions.
* A new class `Concept` was introduced, which represents C++20 concepts.
* The `getTemplateArgumentType` and `getTemplateArgumentValue` predicates of the `Declaration` class now also yield template arguments of concepts.
* A new class `ConstevalIfStmt` was introduced, which represents the C++23 `if consteval` and `if ! consteval` statements.
### Minor Analysis Improvements
* `DefaultOptions::exits` now holds for C23 functions with the `_Noreturn` or `___Noreturn__` attribute.
## 3.1.0
### Deprecated APIs
* The `TemplateParameter` class, representing C++ type template parameters has been deprecated. Use `TypeTemplateParameter` instead.
### New Features
* New classes `SizeofPackExprOperator` and `SizeofPackTypeOperator` were introduced, which represent the C++ `sizeof...` operator taking expressions and type arguments, respectively.
* A new class `TemplateTemplateParameterInstantiation` was introduced, which represents instantiations of template template parameters.
* A new predicate `getAnInstantiation` was added to the `TemplateTemplateParameter` class, which yields instantiations of template template parameters.
* The `getTemplateArgumentType` and `getTemplateArgumentValue` predicates of the `Declaration` class now also yield template arguments of template template parameters.
* A new class `NonTypeTemplateParameter` was introduced, which represents C++ non-type template parameters.
* A new class `TemplateParameterBase` was introduced, which represents C++ non-type template parameters, type template parameters, and template template parameters.
### Minor Analysis Improvements
* The `Guards` library (`semmle.code.cpp.controlflow.Guards`) has been improved to recognize more guard conditions.
## 3.0.0
### Breaking Changes

View File

@@ -54,11 +54,11 @@ class Options extends string {
*
* By default, this holds for `exit`, `_exit`, `_Exit`, `abort`,
* `__assert_fail`, `longjmp`, `__builtin_unreachable` and any
* function with a `noreturn` or `__noreturn__` attribute or
* `noreturn` specifier.
* function with a `noreturn`, `__noreturn__`, or `_Noreturn`
* attribute or `noreturn` specifier.
*/
predicate exits(Function f) {
f.getAnAttribute().hasName(["noreturn", "__noreturn__"])
f.getAnAttribute().hasName(["noreturn", "__noreturn__", "_Noreturn"])
or
f.getASpecifier().hasName("noreturn")
or

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* New classes `PreprocessorElifdef` and `PreprocessorElifndef` were introduced, which represents the C23/C++23 `#elifdef` and `#elifndef` preprocessor directives.
* A new class `TypeLibraryImport` was introduced, which represents the `#import` preprocessor directive as used by the Microsoft Visual C++ for importing type libraries.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The `Guards` library (`semmle.code.cpp.controlflow.Guards`) has been improved to recognize more guard conditions.

View File

@@ -1,4 +0,0 @@
---
category: feature
---
* A new class `TemplateParameterBase` was introduced, which represents C++ non-type template parameters, type template parameters, and template template parameters.

View File

@@ -1,4 +0,0 @@
---
category: deprecated
---
* The `TemplateParameter` class, representing C++ type template parameters has been deprecated. Use `TypeTemplateParameter` instead.

View File

@@ -1,4 +0,0 @@
---
category: feature
---
* A new class `NonTypeTemplateParameter` was introduced, which represents C++ non-type template parameters.

View File

@@ -1,4 +0,0 @@
---
category: feature
---
* New classes `SizeofPackExprOperator` and `SizeofPackTypeOperator` were introduced, which represent the C++ `sizeof...` operator taking expressions and type arguments, respectively.

View File

@@ -0,0 +1,18 @@
## 3.1.0
### Deprecated APIs
* The `TemplateParameter` class, representing C++ type template parameters has been deprecated. Use `TypeTemplateParameter` instead.
### New Features
* New classes `SizeofPackExprOperator` and `SizeofPackTypeOperator` were introduced, which represent the C++ `sizeof...` operator taking expressions and type arguments, respectively.
* A new class `TemplateTemplateParameterInstantiation` was introduced, which represents instantiations of template template parameters.
* A new predicate `getAnInstantiation` was added to the `TemplateTemplateParameter` class, which yields instantiations of template template parameters.
* The `getTemplateArgumentType` and `getTemplateArgumentValue` predicates of the `Declaration` class now also yield template arguments of template template parameters.
* A new class `NonTypeTemplateParameter` was introduced, which represents C++ non-type template parameters.
* A new class `TemplateParameterBase` was introduced, which represents C++ non-type template parameters, type template parameters, and template template parameters.
### Minor Analysis Improvements
* The `Guards` library (`semmle.code.cpp.controlflow.Guards`) has been improved to recognize more guard conditions.

View File

@@ -0,0 +1,23 @@
## 3.2.0
### New Features
* Add a new predicate `getAnIndirectBarrier` to the parameterized module `InstructionBarrierGuard` in `semmle.code.cpp.dataflow.new.DataFlow` for computing indirect dataflow nodes that are guarded by a given instruction. This predicate is similar to the `getAnIndirectBarrier` predicate on the parameterized module `BarrierGuard`.
* A new predicate `getDecltype` was added to the `ProxyClass` class, which yields the decltype for the proxy class.
* Template classes that are of `struct` type are now also instances of the `Struct` class.
* Template classes that are of `union` type are now also instances of the `Union` class.
* A new abstract class `ConfigurationTestFile` (`semmle.code.cpp.ConfigurationTestFile.ConfigurationTestFile`) was introduced, which represents files created to test the build configuration. A subclass `CmakeTryCompileFile` of `ConfigurationTestFile` was also introduced, which represents files created by CMake to test the build configuration.
* New predicates `getARequiresClause`, `getTemplateRequiresClause` and `getFunctionRequiresClause` were added to the `FunctionDeclarationEntry` class, which yield the requires clauses when the entry represents a function template declaration with requires clauses.
* A new predicate `getRequiresClause` was added to the `TypeDeclarationEntry` class, which yields the requires clause when the entry represents a class template declaration with a requires clause.
* A new predicate `getRequiresClause` was added to the `VariableDeclarationEntry` class, which yields the requires clause when the entry represents a variable template declaration with a requires clause.
* A new predicate `getTypeConstraint` was added to the `TypeTemplateParameter` class, which yields the type constraint of the parameter if it exists.
* A new class `VariableTemplateSpecialization` was introduced, which represents explicit specializations of variable templates.
* A new predicate `isSpecialization` was added to the `Variable` class, which holds if the variable is a template specialization.
* A new class `ConceptIdExpr` was introduced, which represents C++20 concept id expressions.
* A new class `Concept` was introduced, which represents C++20 concepts.
* The `getTemplateArgumentType` and `getTemplateArgumentValue` predicates of the `Declaration` class now also yield template arguments of concepts.
* A new class `ConstevalIfStmt` was introduced, which represents the C++23 `if consteval` and `if ! consteval` statements.
### Minor Analysis Improvements
* `DefaultOptions::exits` now holds for C23 functions with the `_Noreturn` or `___Noreturn__` attribute.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 3.0.0
lastReleaseVersion: 3.2.0

View File

@@ -0,0 +1,8 @@
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
- ["", "", False, "SysAllocString", "", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"]
- ["", "", False, "SysAllocStringByteLen", "", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"]
- ["", "", False, "SysAllocStringLen", "", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"]

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 3.0.1-dev
version: 3.2.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -570,10 +570,13 @@ class Class extends UserType {
/**
* Holds if this class, struct or union is constructed from another class as
* a result of template instantiation. It originates either from a class
* template or from a class nested in a class template.
* template, a class nested in a class template, or a template template
* parameter.
*/
predicate isConstructedFrom(Class c) {
class_instantiation(underlyingElement(this), unresolveElement(c))
predicate isConstructedFrom(UserType t) {
class_instantiation(underlyingElement(this), unresolveElement(t))
or
template_template_instantiation(underlyingElement(this), unresolveElement(t))
}
/**
@@ -866,7 +869,7 @@ class AbstractClass extends Class {
* `FullClassTemplateSpecialization`.
*/
class TemplateClass extends Class {
TemplateClass() { usertypes(underlyingElement(this), _, 6) }
TemplateClass() { usertypes(underlyingElement(this), _, [15, 16, 17]) }
/**
* Gets a class instantiated from this template.
@@ -1073,13 +1076,19 @@ class VirtualBaseClass extends Class {
}
/**
* The proxy class (where needed) associated with a template parameter, as
* in the following code:
* ```
* The proxy class (where needed) associated with a template parameter or a
* decltype, as in the following code:
* ```cpp
* template <typename T>
* struct S : T { // the type of this T is a proxy class
* ...
* };
*
* template <typename T>
* concept C =
* decltype(std::span{std::declval<T&>()})::extent
* != std::dynamic_extent;
* // the type of decltype(std::span{std::declval<T&>()}) is a proxy class
* ```
*/
class ProxyClass extends UserType {
@@ -1090,10 +1099,13 @@ class ProxyClass extends UserType {
/** Gets the location of the proxy class. */
override Location getLocation() { result = this.getTemplateParameter().getDefinitionLocation() }
/** Gets the template parameter for which this is the proxy class. */
/** Gets the template parameter for which this is the proxy class, if any. */
TypeTemplateParameter getTemplateParameter() {
is_proxy_class_for(underlyingElement(this), unresolveElement(result))
}
/** Gets the decltype for which this is the proxy class, if any. */
Decltype getDecltype() { is_proxy_class_for(underlyingElement(this), unresolveElement(result)) }
}
// Unpacks "array of ... of array of t" into t.

View File

@@ -153,9 +153,139 @@ class NestedRequirementExpr extends Expr, @nested_requirement {
/**
* A C++ concept id expression.
*
* For example, if:
* ```cpp
* template<typename T, T X> concept C = ...;
* ...
* requires { C<int, 1>; };
* ```
* then `C<int, 1>` is a concept id expression that refers to
* the concept `C`.
*/
class ConceptIdExpr extends RequirementExpr, @concept_id {
override string toString() { result = "concept<...>" }
override string toString() {
result = this.getConcept().getName() + "<...>"
or
// The following is for backward compatibility with databases created with
// CodeQL 2.19.3, 2.19.4, and 2.20.0. Those databases include concept id
// expressions, but do not include concept template information.
not exists(this.getConcept()) and
result = "concept<...>"
}
override string getAPrimaryQlClass() { result = "ConceptIdExpr" }
/**
* Holds if the concept id is used as a type constraint.
*
* In this case, the first template argument is implicit.
*/
predicate isTypeConstraint() { is_type_constraint(underlyingElement(this)) }
/**
* Gets the concept this concept id refers to.
*/
Concept getConcept() { concept_instantiation(underlyingElement(this), unresolveElement(result)) }
/**
* Gets a template argument passed to the concept.
*/
final Locatable getATemplateArgument() { result = this.getTemplateArgument(_) }
/**
* Gets the kind of a non-type template argument passed to the concept.
*/
final Locatable getATemplateArgumentKind() { result = this.getTemplateArgumentKind(_) }
/**
* Gets the `i`th template argument passed to the concept.
*
* For example, if:
* ```cpp
* template<typename T, T X> concept C = ...;
* ...
* requires { C<int, 1>; };
* ```
* then `getTemplateArgument(0)` yields `int`, and `getTemplateArgument(1)`
* yields `1`.
*
* If the concept id is a type constraint, then `getTemplateArgument(0)`
* will not yield a result.
*/
final Locatable getTemplateArgument(int index) {
if exists(this.getTemplateArgumentValue(index))
then result = this.getTemplateArgumentValue(index)
else result = this.getTemplateArgumentType(index)
}
/**
* Gets the kind of the `i`th template argument value passed to the concept.
*
* For example, if:
* ```cpp
* template<typename T, T X> concept C = ...;
* ...
* requires { C<int, 1>; };
* ```
* then `getTemplateArgumentKind(1)` yields `int`, and there is no result for
* `getTemplateArgumentKind(0)`.
*/
final Locatable getTemplateArgumentKind(int index) {
exists(this.getTemplateArgumentValue(index)) and
result = this.getTemplateArgumentType(index)
}
/**
* Gets the number of template arguments passed to the concept.
*/
final int getNumberOfTemplateArguments() {
result = count(int i | exists(this.getTemplateArgument(i)))
}
private Type getTemplateArgumentType(int index) {
exists(int i | if this.isTypeConstraint() then i = index - 1 else i = index |
concept_template_argument(underlyingElement(this), i, unresolveElement(result))
)
}
private Expr getTemplateArgumentValue(int index) {
exists(int i | if this.isTypeConstraint() then i = index - 1 else i = index |
concept_template_argument_value(underlyingElement(this), i, unresolveElement(result))
)
}
}
/**
* A C++ concept.
*
* For example:
* ```cpp
* template<class T>
* concept C = std::is_same<T, int>::value;
* ```
*/
class Concept extends Declaration, @concept_template {
override string getAPrimaryQlClass() { result = "Concept" }
override Location getLocation() { concept_templates(underlyingElement(this), _, result) }
override string getName() { concept_templates(underlyingElement(this), result, _) }
/**
* Gets the constraint expression of the concept.
*
* For example, in
* ```cpp
* template<class T>
* concept C = std::is_same<T, int>::value;
* ```
* the constraint expression is `std::is_same<T, int>::value`.
*/
Expr getExpr() { result.getParent() = this }
/**
* Gets a concept id expression that refers to this concept
*/
ConceptIdExpr getAReferringConceptIdExpr() { this = result.getConcept() }
}

View File

@@ -0,0 +1,28 @@
/**
* Provides classes for identifying files that created to test the
* build configuration. It is often desirable to exclude these files
* from analysis.
*/
import File
/**
* A file created to test the system configuration.
*/
abstract class ConfigurationTestFile extends File { }
/**
* A file created by CMake to test the system configuration.
*/
class CmakeTryCompileFile extends ConfigurationTestFile {
CmakeTryCompileFile() {
exists(Folder folder, Folder parent |
folder = this.getParentContainer() and
parent = folder.getParentContainer()
|
folder.getBaseName().matches("TryCompile-%") and
parent.getBaseName() = "CMakeScratch" and
parent.getParentContainer().getBaseName() = "CMakeFiles"
)
}
}

View File

@@ -235,7 +235,7 @@ class Declaration extends Locatable, @declaration {
*
* `Foo<int, 1> bar;`
*
* Will have `getTemplateArgument())` return `int`, and
* Will have `getTemplateArgument(0)` return `int`, and
* `getTemplateArgument(1)` return `1`.
*/
final Locatable getTemplateArgument(int index) {
@@ -277,6 +277,10 @@ class Declaration extends Locatable, @declaration {
function_template_argument(underlyingElement(this), index, unresolveElement(result))
or
variable_template_argument(underlyingElement(this), index, unresolveElement(result))
or
template_template_argument(underlyingElement(this), index, unresolveElement(result))
or
concept_template_argument(underlyingElement(this), index, unresolveElement(result))
}
private Expr getTemplateArgumentValue(int index) {
@@ -285,6 +289,10 @@ class Declaration extends Locatable, @declaration {
function_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
variable_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
template_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
concept_template_argument_value(underlyingElement(this), index, unresolveElement(result))
}
}

View File

@@ -253,7 +253,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
*/
override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }
/** Holds if this Function is a Template specialization. */
/** Holds if this function is a template specialization. */
predicate isSpecialization() {
exists(FunctionDeclarationEntry fde |
fun_decls(unresolveElement(fde), underlyingElement(this), _, _, _) and
@@ -665,7 +665,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
/** Holds if this declaration is also a definition of its function. */
override predicate isDefinition() { fun_def(underlyingElement(this)) }
/** Holds if this declaration is a Template specialization. */
/** Holds if this declaration is a template specialization. */
predicate isSpecialization() { fun_specialized(underlyingElement(this)) }
/**
@@ -715,6 +715,27 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* specification.
*/
predicate isNoExcept() { fun_decl_empty_noexcept(underlyingElement(this)) }
/**
* Gets a requires clause if this declaration is a template with such a clause.
*/
Expr getARequiresClause() { fun_requires(underlyingElement(this), _, unresolveElement(result)) }
/**
* Gets the requires clause that appears after the template argument list if this
* declaration is a template with such a clause.
*/
Expr getTemplateRequiresClause() {
fun_requires(underlyingElement(this), 1, unresolveElement(result))
}
/**
* Gets the requires clause that appears after the declarator if this declaration
* is a template with such a clause.
*/
Expr getFunctionRequiresClause() {
fun_requires(underlyingElement(this), 2, unresolveElement(result))
}
}
/**

View File

@@ -57,9 +57,9 @@ class IncludeNext extends Include, @ppd_include_next {
}
/**
* A `#import` preprocessor directive (used heavily in Objective C, and
* supported by GCC as an extension in C). For example the following code
* contains one `Import` directive:
* An Objective C `#import` preprocessor directive (supported by GCC as
* an extension in C). For example the following code contains one `Import`
* directive:
* ```
* #import <header3.h>
* ```
@@ -67,3 +67,14 @@ class IncludeNext extends Include, @ppd_include_next {
class Import extends Include, @ppd_objc_import {
override string toString() { result = "#import " + this.getIncludeText() }
}
/**
* A Microsoft `#import` preprocessor directive for importing a type library.
* For example the following code contains one `TypeLibraryImport` directive:
* ```
* #import "library.tlb"
* ```
*/
class TypeLibraryImport extends Include, @ppd_ms_import {
override string toString() { result = "#import " + this.getIncludeText() }
}

View File

@@ -42,7 +42,7 @@ private class TPreprocessorBranchDirective = @ppd_branch or @ppd_else or @ppd_en
/**
* A C/C++ preprocessor branch related directive: `#if`, `#ifdef`,
* `#ifndef`, `#elif`, `#else` or `#endif`.
* `#ifndef`, `#elif`, `#elifdef`, `#elifndef`, `#else` or `#endif`.
*/
class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBranchDirective {
/**
@@ -74,8 +74,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
}
/**
* Gets the next `#elif`, `#else` or `#endif` matching this branching
* directive.
* Gets the next `#elif`, `#elifdef`, `#elifndef`, `#else` or `#endif` matching
* this branching directive.
*
* For example `somePreprocessorBranchDirective.getIf().getNext()` gets
* the second directive in the same construct as
@@ -88,8 +88,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
}
/**
* Gets the index of this branching directive within the matching #if,
* #ifdef or #ifndef.
* Gets the index of this branching directive within the matching `#if`,
* `#ifdef` or `#ifndef`.
*/
private int getIndexInBranch(PreprocessorBranch branch) {
this =
@@ -102,8 +102,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
}
/**
* A C/C++ preprocessor branching directive: `#if`, `#ifdef`, `#ifndef`, or
* `#elif`.
* A C/C++ preprocessor branching directive: `#if`, `#ifdef`, `#ifndef`,
* `#elif`, `#elifdef`, or `#elifndef`.
*
* A branching directive has a condition and that condition may be evaluated
* at compile-time. As a result, the preprocessor will either take the
@@ -151,8 +151,8 @@ class PreprocessorBranch extends PreprocessorBranchDirective, @ppd_branch {
* #endif
* ```
* For the related notion of a directive which causes branching (which
* includes `#if`, plus also `#ifdef`, `#ifndef`, and `#elif`), see
* `PreprocessorBranch`.
* includes `#if`, plus also `#ifdef`, `#ifndef`, `#elif`, `#elifdef`,
* and `#elifndef`), see `PreprocessorBranch`.
*/
class PreprocessorIf extends PreprocessorBranch, @ppd_if {
override string toString() { result = "#if " + this.getHead() }
@@ -222,6 +222,40 @@ class PreprocessorElif extends PreprocessorBranch, @ppd_elif {
override string toString() { result = "#elif " + this.getHead() }
}
/**
* A C/C++ preprocessor `#elifdef` directive. For example there is a
* `PreprocessorElifdef` on the third line of the following code:
* ```
* #ifdef MYDEFINE1
* // ...
* #elifdef MYDEFINE2
* // ...
* #else
* // ...
* #endif
* ```
*/
class PreprocessorElifdef extends PreprocessorBranch, @ppd_elifdef {
override string toString() { result = "#elifdef " + this.getHead() }
}
/**
* A C/C++ preprocessor `#elifndef` directive. For example there is a
* `PreprocessorElifndef` on the third line of the following code:
* ```
* #ifdef MYDEFINE1
* // ...
* #elifndef MYDEFINE2
* // ...
* #else
* // ...
* #endif
* ```
*/
class PreprocessorElifndef extends PreprocessorBranch, @ppd_elifndef {
override string toString() { result = "#elifndef " + this.getHead() }
}
/**
* A C/C++ preprocessor `#endif` directive. For example there is a
* `PreprocessorEndif` on the third line of the following code:

View File

@@ -88,6 +88,10 @@ private Declaration getAnEnclosingDeclaration(Locatable ast) {
or
result = ast.(Initializer).getDeclaration()
or
exists(ConceptIdExpr concept | ast = concept.getATemplateArgument() |
result = concept.getEnclosingFunction()
)
or
result = ast
}
@@ -107,6 +111,12 @@ private newtype TPrintAstNode =
TRequiresExprParametersNode(RequiresExpr req) {
shouldPrintDeclaration(getAnEnclosingDeclaration(req))
} or
TConceptIdExprArgumentsNode(ConceptIdExpr concept) {
shouldPrintDeclaration(getAnEnclosingDeclaration(concept))
} or
TConceptIdExprTypeArgumentNode(Type type, ConceptIdExpr concept, int childIndex) {
type = concept.getTemplateArgument(childIndex)
} or
TConstructorInitializersNode(Constructor ctor) {
ctor.hasEntryPoint() and
shouldPrintDeclaration(ctor)
@@ -357,6 +367,26 @@ class StringLiteralNode extends ExprNode {
override string getValue() { result = "\"" + escapeString(expr.getValue()) + "\"" }
}
/**
* A node representing a `ConceptIdExpr`.
*/
class ConceptIdExprNode extends ExprNode {
override ConceptIdExpr expr;
override PrintAstNode getChildInternal(int childIndex) {
result = super.getChildInternal(childIndex)
or
childIndex = -1 and
result.(ConceptIdExprArgumentsNode).getConceptIdExpr() = expr
}
override string getChildAccessorPredicateInternal(int childIndex) {
result = super.getChildAccessorPredicateInternal(childIndex)
or
childIndex = -1 and result = "<args>"
}
}
/**
* A node representing a `Conversion`.
*/
@@ -593,6 +623,63 @@ class InitializerNode extends AstNode {
}
}
/**
* A node representing the arguments of a `ConceptIdExpr`.
*/
class ConceptIdExprArgumentsNode extends PrintAstNode, TConceptIdExprArgumentsNode {
ConceptIdExpr concept;
ConceptIdExprArgumentsNode() { this = TConceptIdExprArgumentsNode(concept) }
final override string toString() { result = "" }
final override Location getLocation() { result = getRepresentativeLocation(concept) }
override PrintAstNode getChildInternal(int childIndex) {
exists(Locatable arg | arg = concept.getTemplateArgument(childIndex) |
result.(ConceptIdExprTypeArgumentNode).isArgumentNode(arg, concept, childIndex)
or
result.(ExprNode).getAst() = arg
)
}
override string getChildAccessorPredicateInternal(int childIndex) {
exists(this.getChildInternal(childIndex)) and
result = "getTemplateArgument(" + childIndex + ")"
}
/**
* Gets the `ConceptIdExpr` for which this node represents the parameters.
*/
final ConceptIdExpr getConceptIdExpr() { result = concept }
}
/**
* A node representing a type argument of a `ConceptIdExpr`.
*/
class ConceptIdExprTypeArgumentNode extends PrintAstNode, TConceptIdExprTypeArgumentNode {
Type type;
ConceptIdExpr concept;
int index;
ConceptIdExprTypeArgumentNode() { this = TConceptIdExprTypeArgumentNode(type, concept, index) }
final override string toString() { result = qlClass(type) + type.toString() }
final override Location getLocation() { result = getRepresentativeLocation(type) }
override AstNode getChildInternal(int childIndex) { none() }
override string getChildAccessorPredicateInternal(int childIndex) { none() }
/**
* Holds if `t` is the `i`th template argument of `c`.
*/
predicate isArgumentNode(Type t, ConceptIdExpr c, int i) {
type = t and concept = c and index = i
}
}
/**
* A node representing the parameters of a `Function`.
*/
@@ -611,7 +698,7 @@ class FunctionParametersNode extends PrintAstNode, TFunctionParametersNode {
override string getChildAccessorPredicateInternal(int childIndex) {
exists(this.getChildInternal(childIndex)) and
result = "getParameter(" + childIndex.toString() + ")"
result = "getParameter(" + childIndex + ")"
}
/**
@@ -638,7 +725,7 @@ class RequiresExprParametersNode extends PrintAstNode, TRequiresExprParametersNo
override string getChildAccessorPredicateInternal(int childIndex) {
exists(this.getChildInternal(childIndex)) and
result = "getParameter(" + childIndex.toString() + ")"
result = "getParameter(" + childIndex + ")"
}
/**
@@ -665,7 +752,7 @@ class ConstructorInitializersNode extends PrintAstNode, TConstructorInitializers
final override string getChildAccessorPredicateInternal(int childIndex) {
exists(this.getChildInternal(childIndex)) and
result = "getInitializer(" + childIndex.toString() + ")"
result = "getInitializer(" + childIndex + ")"
}
/**
@@ -692,7 +779,7 @@ class DestructorDestructionsNode extends PrintAstNode, TDestructorDestructionsNo
final override string getChildAccessorPredicateInternal(int childIndex) {
exists(this.getChildInternal(childIndex)) and
result = "getDestruction(" + childIndex.toString() + ")"
result = "getDestruction(" + childIndex + ")"
}
/**
@@ -825,6 +912,10 @@ private predicate namedStmtChildPredicates(Locatable s, Element e, string pred)
or
s.(ConstexprIfStmt).getElse() = e and pred = "getElse()"
or
s.(ConstevalIfStmt).getThen() = e and pred = "getThen()"
or
s.(ConstevalIfStmt).getElse() = e and pred = "getElse()"
or
s.(Handler).getParameter() = e and pred = "getParameter()"
or
s.(IfStmt).getInitialization() = e and pred = "getInitialization()"

View File

@@ -20,7 +20,7 @@ import semmle.code.cpp.Class
* ```
*/
class Struct extends Class {
Struct() { usertypes(underlyingElement(this), _, 1) or usertypes(underlyingElement(this), _, 3) }
Struct() { usertypes(underlyingElement(this), _, [1, 3, 15, 17]) }
override string getAPrimaryQlClass() { result = "Struct" }

View File

@@ -52,13 +52,18 @@ deprecated class TemplateParameter = TypeTemplateParameter;
* ```
*/
class TypeTemplateParameter extends UserType, TemplateParameterImpl {
TypeTemplateParameter() {
usertypes(underlyingElement(this), _, 7) or usertypes(underlyingElement(this), _, 8)
}
TypeTemplateParameter() { usertypes(underlyingElement(this), _, [7, 8]) }
override string getAPrimaryQlClass() { result = "TypeTemplateParameter" }
override predicate involvesTemplateParameter() { any() }
/**
* Get the type constraint of this type template parameter.
*/
Expr getTypeConstraint() {
type_template_type_constraint(underlyingElement(this), unresolveElement(result))
}
}
/**
@@ -75,6 +80,18 @@ class TemplateTemplateParameter extends TypeTemplateParameter {
TemplateTemplateParameter() { usertypes(underlyingElement(this), _, 8) }
override string getAPrimaryQlClass() { result = "TemplateTemplateParameter" }
/**
* Gets a class instantiated from this template template parameter.
*
* For example for `Container<T>` in the following code, the result is
* `Container<Elem>`:
* ```
* template <template <typename T> class Container, class Elem>
* void foo(const Container<Elem> &value) { }
* ```
*/
Class getAnInstantiation() { result.isConstructedFrom(this) }
}
/**
@@ -90,3 +107,32 @@ class AutoType extends TypeTemplateParameter {
override Location getLocation() { result instanceof UnknownDefaultLocation }
}
/**
* A class that is an instantiation of a template template parameter. For example,
* in the following code there is a `Container<Elem>` instantiation:
* ```
* template <template <typename T> class Container, class Elem>
* void foo(const Container<Elem> &value) { }
* ```
* For the `Container` template itself, see `TemplateTemplateParameter`.
*/
class TemplateTemplateParameterInstantiation extends Class {
TemplateTemplateParameter ttp;
TemplateTemplateParameterInstantiation() { ttp.getAnInstantiation() = this }
override string getAPrimaryQlClass() { result = "TemplateTemplateParameterInstantiation" }
/**
* Gets the template template parameter from which this instantiation was instantiated.
*
* For example for `Container<Elem>` in the following code, the result is
* `Container<T>`:
* ```
* template <template <typename T> class Container, class Elem>
* void foo(const Container<Elem> &value) { }
* ```
*/
TemplateTemplateParameter getTemplate() { result = ttp }
}

View File

@@ -406,10 +406,7 @@ class IntegralOrEnumType extends Type {
isIntegralType(underlyingElement(this), _)
or
// Enum type
(
usertypes(underlyingElement(this), _, 4) or
usertypes(underlyingElement(this), _, 13)
)
usertypes(underlyingElement(this), _, [4, 13])
}
}

View File

@@ -13,10 +13,7 @@ private import semmle.code.cpp.internal.ResolveClass
* ```
*/
class TypedefType extends UserType {
TypedefType() {
usertypes(underlyingElement(this), _, 5) or
usertypes(underlyingElement(this), _, 14)
}
TypedefType() { usertypes(underlyingElement(this), _, [5, 14]) }
/**
* Gets the base type of this typedef type.

View File

@@ -15,7 +15,7 @@ import semmle.code.cpp.Struct
* ```
*/
class Union extends Struct {
Union() { usertypes(underlyingElement(this), _, 3) }
Union() { usertypes(underlyingElement(this), _, [3, 17]) }
override string getAPrimaryQlClass() { result = "Union" }

View File

@@ -129,4 +129,9 @@ class TypeDeclarationEntry extends DeclarationEntry, @type_decl {
* class or typedef.
*/
predicate isTopLevel() { type_decl_top(underlyingElement(this)) }
/**
* Gets the requires clause if this declaration is a template with such a clause.
*/
Expr getRequiresClause() { type_requires(underlyingElement(this), unresolveElement(result)) }
}

View File

@@ -187,6 +187,14 @@ class Variable extends Declaration, @variable {
* `for (char c : str) { ... }`
*/
predicate isCompilerGenerated() { compgenerated(underlyingElement(this)) }
/** Holds if this variable is a template specialization. */
predicate isSpecialization() {
exists(VariableDeclarationEntry vde |
var_decls(unresolveElement(vde), underlyingElement(this), _, _, _) and
vde.isSpecialization()
)
}
}
/**
@@ -267,6 +275,14 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
override predicate isDefinition() { var_def(underlyingElement(this)) }
override string getASpecifier() { var_decl_specifiers(underlyingElement(this), result) }
/** Holds if this declaration is a template specialization. */
predicate isSpecialization() { var_specialized(underlyingElement(this)) }
/**
* Gets the requires clause if this declaration is a template with such a clause.
*/
Expr getRequiresClause() { var_requires(underlyingElement(this), unresolveElement(result)) }
}
/**
@@ -594,7 +610,10 @@ class TemplateVariable extends Variable {
/**
* Gets an instantiation of this variable template.
*/
Variable getAnInstantiation() { result.isConstructedFrom(this) }
Variable getAnInstantiation() {
result.isConstructedFrom(this) and
not result.isSpecialization()
}
}
/**
@@ -624,6 +643,21 @@ class VariableTemplateInstantiation extends Variable {
TemplateVariable getTemplate() { result = tv }
}
/**
* An explicit specialization of a C++ variable template.
*/
class VariableTemplateSpecialization extends Variable {
VariableTemplateSpecialization() { this.isSpecialization() }
override string getAPrimaryQlClass() { result = "VariableTemplateSpecialization" }
/**
* Gets the primary template for the specialization (the function template
* this specializes).
*/
TemplateVariable getPrimaryTemplate() { this.isConstructedFrom(result) }
}
/**
* A non-static local variable or parameter that is not part of an
* uninstantiated template. Uninstantiated templates are purely syntax, and

View File

@@ -233,6 +233,114 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl
}
}
/**
* Holds if `ir` controls `block`, meaning that `block` is only
* entered if the value of this condition is `v`. This helper
* predicate does not necessarily hold for binary logical operations like
* `&&` and `||`. See the detailed explanation on predicate `controls`.
*/
private predicate controlsBlock(IRGuardCondition ir, BasicBlock controlled, AbstractValue v) {
exists(IRBlock irb |
ir.valueControls(irb, v) and
nonExcludedIRAndBasicBlock(irb, controlled) and
not isUnreachedBlock(irb)
)
}
private class GuardConditionFromNotExpr extends GuardConditionImpl {
IRGuardCondition ir;
GuardConditionFromNotExpr() {
// Users often expect the `x` in `!x` to also be a guard condition. But
// from the perspective of the IR the `x` is just the left-hand side of a
// comparison against 0 so it's not included as a normal
// `IRGuardCondition`. So to align with user expectations we make that `x`
// a `GuardCondition`.
exists(NotExpr notExpr |
this = notExpr.getOperand() and
ir.getUnconvertedResultExpression() = notExpr
)
}
override predicate valueControls(BasicBlock controlled, AbstractValue v) {
// This condition must determine the flow of control; that is, this
// node must be a top-level condition.
controlsBlock(ir, controlled, v.getDualValue())
}
pragma[inline]
override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) {
exists(Instruction li, Instruction ri |
li.getUnconvertedResultExpression() = left and
ri.getUnconvertedResultExpression() = right and
ir.comparesLt(li.getAUse(), ri.getAUse(), k, isLessThan, testIsTrue.booleanNot())
)
}
pragma[inline]
override predicate comparesLt(Expr e, int k, boolean isLessThan, AbstractValue value) {
exists(Instruction i |
i.getUnconvertedResultExpression() = e and
ir.comparesLt(i.getAUse(), k, isLessThan, value.getDualValue())
)
}
pragma[inline]
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
exists(Instruction li, Instruction ri, boolean testIsTrue |
li.getUnconvertedResultExpression() = left and
ri.getUnconvertedResultExpression() = right and
ir.comparesLt(li.getAUse(), ri.getAUse(), k, isLessThan, testIsTrue.booleanNot()) and
this.controls(block, testIsTrue)
)
}
pragma[inline]
override predicate ensuresLt(Expr e, int k, BasicBlock block, boolean isLessThan) {
exists(Instruction i, AbstractValue value |
i.getUnconvertedResultExpression() = e and
ir.comparesLt(i.getAUse(), k, isLessThan, value.getDualValue()) and
this.valueControls(block, value)
)
}
pragma[inline]
override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
exists(Instruction li, Instruction ri |
li.getUnconvertedResultExpression() = left and
ri.getUnconvertedResultExpression() = right and
ir.comparesEq(li.getAUse(), ri.getAUse(), k, areEqual, testIsTrue.booleanNot())
)
}
pragma[inline]
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
exists(Instruction li, Instruction ri, boolean testIsTrue |
li.getUnconvertedResultExpression() = left and
ri.getUnconvertedResultExpression() = right and
ir.comparesEq(li.getAUse(), ri.getAUse(), k, areEqual, testIsTrue.booleanNot()) and
this.controls(block, testIsTrue)
)
}
pragma[inline]
override predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value) {
exists(Instruction i |
i.getUnconvertedResultExpression() = e and
ir.comparesEq(i.getAUse(), k, areEqual, value.getDualValue())
)
}
pragma[inline]
override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) {
exists(Instruction i, AbstractValue value |
i.getUnconvertedResultExpression() = e and
ir.comparesEq(i.getAUse(), k, areEqual, value.getDualValue()) and
this.valueControls(block, value)
)
}
}
/**
* A Boolean condition in the AST that guards one or more basic blocks and has a corresponding IR
* instruction.
@@ -245,7 +353,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
override predicate valueControls(BasicBlock controlled, AbstractValue v) {
// This condition must determine the flow of control; that is, this
// node must be a top-level condition.
this.controlsBlock(controlled, v)
controlsBlock(ir, controlled, v)
}
pragma[inline]
@@ -319,20 +427,6 @@ private class GuardConditionFromIR extends GuardConditionImpl {
this.valueControls(block, value)
)
}
/**
* Holds if this condition controls `block`, meaning that `block` is only
* entered if the value of this condition is `v`. This helper
* predicate does not necessarily hold for binary logical operations like
* `&&` and `||`. See the detailed explanation on predicate `controls`.
*/
private predicate controlsBlock(BasicBlock controlled, AbstractValue v) {
exists(IRBlock irb |
ir.valueControls(irb, v) and
nonExcludedIRAndBasicBlock(irb, controlled) and
not isUnreachedBlock(irb)
)
}
}
private predicate excludeAsControlledInstruction(Instruction instr) {
@@ -588,7 +682,7 @@ class IRGuardCondition extends Instruction {
/** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `value`. */
pragma[inline]
predicate comparesEq(Operand op, int k, boolean areEqual, AbstractValue value) {
unary_compares_eq(valueNumber(this), op, k, areEqual, false, value)
unary_compares_eq(valueNumber(this), op, k, areEqual, value)
}
/**
@@ -610,7 +704,7 @@ class IRGuardCondition extends Instruction {
pragma[inline]
predicate ensuresEq(Operand op, int k, IRBlock block, boolean areEqual) {
exists(AbstractValue value |
unary_compares_eq(valueNumber(this), op, k, areEqual, false, value) and
unary_compares_eq(valueNumber(this), op, k, areEqual, value) and
this.valueControls(block, value)
)
}
@@ -636,7 +730,7 @@ class IRGuardCondition extends Instruction {
pragma[inline]
predicate ensuresEqEdge(Operand op, int k, IRBlock pred, IRBlock succ, boolean areEqual) {
exists(AbstractValue value |
unary_compares_eq(valueNumber(this), op, k, areEqual, false, value) and
unary_compares_eq(valueNumber(this), op, k, areEqual, value) and
this.valueControlsEdge(pred, succ, value)
)
}
@@ -847,77 +941,72 @@ private module Cached {
compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), left, right, k, areEqual, value)
}
private predicate isConvertedBool(Instruction instr) {
instr.getResultIRType() instanceof IRBooleanType
or
isConvertedBool(instr.(ConvertInstruction).getUnary())
or
isConvertedBool(instr.(BuiltinExpectCallInstruction).getCondition())
}
/**
* Holds if `op == k` is `areEqual` given that `test` is equal to `value`.
*
* Many internal predicates in this file have a `inNonZeroCase` column.
* Ideally, the `k` column would be a type such as `Option<int>::Option`, to
* represent whether we have a concrete value `k` such that `op == k`, or whether
* we only know that `op != 0`.
* However, cannot instantiate `Option` with an infinite type. Thus the boolean
* `inNonZeroCase` is used to distinquish the `Some` (where we have a concrete
* value `k`) and `None` cases (where we only know that `op != 0`).
*
* Thus, if `inNonZeroCase = true` then `op != 0` and the value of `k` is
* meaningless.
*
* To see why `inNonZeroCase` is needed consider the following C program:
* ```c
* char* p = ...;
* if(p) {
* use(p);
* }
* ```
* in C++ there would be an int-to-bool conversion on `p`. However, since C
* does not have booleans there is no conversion. We want to be able to
* conclude that `p` is non-zero in the true branch, so we need to give `k`
* some value. However, simply setting `k = 1` would make the rest of the
* analysis think that `k == 1` holds inside the branch. So we distinquish
* between the above case and
* ```c
* if(p == 1) {
* use(p)
* }
* ```
* by setting `inNonZeroCase` to `true` in the former case, but not in the
* latter.
*/
cached
predicate unary_compares_eq(
ValueNumber test, Operand op, int k, boolean areEqual, boolean inNonZeroCase,
AbstractValue value
ValueNumber test, Operand op, int k, boolean areEqual, AbstractValue value
) {
/* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */
exists(AbstractValue v | unary_simple_comparison_eq(test, op, k, inNonZeroCase, v) |
exists(AbstractValue v | unary_simple_comparison_eq(test, op, k, v) |
areEqual = true and value = v
or
areEqual = false and value = v.getDualValue()
)
or
unary_complex_eq(test, op, k, areEqual, inNonZeroCase, value)
unary_complex_eq(test, op, k, areEqual, value)
or
/* (x is true => (op == k)) => (!x is false => (op == k)) */
exists(AbstractValue dual, boolean inNonZeroCase0 |
exists(AbstractValue dual |
value = dual.getDualValue() and
unary_compares_eq(test.(LogicalNotValueNumber).getUnary(), op, k, inNonZeroCase0, areEqual,
dual)
|
k = 0 and inNonZeroCase = inNonZeroCase0
or
k != 0 and inNonZeroCase = true
unary_compares_eq(test.(LogicalNotValueNumber).getUnary(), op, k, areEqual, dual)
)
or
// ((test is `areEqual` => op == const + k2) and const == `k1`) =>
// test is `areEqual` => op == k1 + k2
inNonZeroCase = false and
exists(int k1, int k2, Instruction const |
compares_eq(test, op, const.getAUse(), k2, areEqual, value) and
int_value(const) = k1 and
k = k1 + k2
)
or
unary_compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, areEqual,
inNonZeroCase, value)
exists(CompareValueNumber cmp, Operand left, Operand right, AbstractValue v |
test = cmp and
pragma[only_bind_into](cmp)
.hasOperands(pragma[only_bind_into](left), pragma[only_bind_into](right)) and
isConvertedBool(left.getDef()) and
int_value(right.getDef()) = 0 and
unary_compares_eq(valueNumberOfOperand(left), op, k, areEqual, v)
|
cmp instanceof CompareNEValueNumber and
v = value
or
cmp instanceof CompareEQValueNumber and
v.getDualValue() = value
)
or
unary_compares_eq(test.(BuiltinExpectCallValueNumber).getCondition(), op, k, areEqual, value)
or
exists(BinaryLogicalOperation logical, Expr operand, boolean b |
test.getAnInstruction().getUnconvertedResultExpression() = logical and
op.getDef().getUnconvertedResultExpression() = operand and
logical.impliesValue(operand, b, value.(BooleanValue).getValue())
|
k = 1 and
areEqual = b
or
k = 0 and
areEqual = b.booleanNot()
)
}
/** Rearrange various simple comparisons into `left == right + k` form. */
@@ -939,74 +1028,64 @@ private module Cached {
* Holds if `op` is an operand that is eventually used in a unary comparison
* with a constant.
*/
private predicate isRelevantUnaryComparisonOperand(Operand op) {
// Base case: `op` is an operand of a `CompareEQInstruction` or `CompareNEInstruction`,
// and the other operand is a constant.
exists(CompareInstruction eq, Instruction instr |
eq.hasOperands(op, instr.getAUse()) and
exists(int_value(instr))
|
eq instanceof CompareEQInstruction
or
eq instanceof CompareNEInstruction
)
or
// C doesn't have int-to-bool conversions, so `if(x)` will just generate:
// r2_1(glval<int>) = VariableAddress[x]
// r2_2(int) = Load[x] : &:r2_1, m1_6
// v2_3(void) = ConditionalBranch : r2_2
exists(ConditionalBranchInstruction branch | branch.getConditionOperand() = op)
private predicate mayBranchOn(Instruction instr) {
exists(ConditionalBranchInstruction branch | branch.getCondition() = instr)
or
// If `!x` is a relevant unary comparison then so is `x`.
exists(LogicalNotInstruction logicalNot |
isRelevantUnaryComparisonOperand(unique( | | logicalNot.getAUse())) and
logicalNot.getUnaryOperand() = op
mayBranchOn(logicalNot) and
logicalNot.getUnary() = instr
)
or
// If `y` is a relevant unary comparison and `y = x` then so is `x`.
not op.isDefinitionInexact() and
exists(CopyInstruction copy |
isRelevantUnaryComparisonOperand(unique( | | copy.getAUse())) and
op = copy.getSourceValueOperand()
mayBranchOn(copy) and
instr = copy.getSourceValue()
)
or
// If phi(x1, x2) is a relevant unary comparison then so are `x1` and `x2`.
not op.isDefinitionInexact() and
exists(PhiInstruction phi |
isRelevantUnaryComparisonOperand(unique( | | phi.getAUse())) and
op = phi.getAnInputOperand()
mayBranchOn(phi) and
instr = phi.getAnInput()
)
or
// If `__builtin_expect(x)` is a relevant unary comparison then so is `x`.
exists(BuiltinExpectCallInstruction call |
isRelevantUnaryComparisonOperand(unique( | | call.getAUse())) and
op = call.getConditionOperand()
mayBranchOn(call) and
instr = call.getCondition()
)
}
/** Rearrange various simple comparisons into `op == k` form. */
private predicate unary_simple_comparison_eq(
ValueNumber test, Operand op, int k, boolean inNonZeroCase, AbstractValue value
ValueNumber test, Operand op, int k, AbstractValue value
) {
exists(CaseEdge case, SwitchConditionValueNumber condition |
condition = test and
op = condition.getExpressionOperand() and
case = value.(MatchValue).getCase() and
exists(condition.getSuccessor(case)) and
case.getValue().toInt() = k and
inNonZeroCase = false
case.getValue().toInt() = k
)
or
isRelevantUnaryComparisonOperand(op) and
op.getDef() = test.getAnInstruction() and
(
k = 1 and
exists(Instruction const | int_value(const) = k |
value.(BooleanValue).getValue() = true and
inNonZeroCase = true
test.(CompareEQValueNumber).hasOperands(op, const.getAUse())
or
k = 0 and
value.(BooleanValue).getValue() = false and
inNonZeroCase = false
test.(CompareNEValueNumber).hasOperands(op, const.getAUse())
)
or
exists(BooleanValue bv |
bv = value and
mayBranchOn(op.getDef()) and
op = test.getAUse()
|
k = 0 and
bv.getValue() = false
or
k = 1 and
bv.getValue() = true
)
}
@@ -1061,13 +1140,12 @@ private module Cached {
* an instruction that compares the value of `__builtin_expect(op == k, _)` to `0`.
*/
private predicate unary_builtin_expect_eq(
CompareValueNumber cmp, Operand op, int k, boolean areEqual, boolean inNonZeroCase,
AbstractValue value
CompareValueNumber cmp, Operand op, int k, boolean areEqual, AbstractValue value
) {
exists(BuiltinExpectCallValueNumber call, Instruction const, AbstractValue innerValue |
int_value(const) = 0 and
cmp.hasOperands(call.getAUse(), const.getAUse()) and
unary_compares_eq(call.getCondition(), op, k, areEqual, inNonZeroCase, innerValue)
unary_compares_eq(call.getCondition(), op, k, areEqual, innerValue)
|
cmp instanceof CompareNEValueNumber and
value = innerValue
@@ -1078,14 +1156,13 @@ private module Cached {
}
private predicate unary_complex_eq(
ValueNumber test, Operand op, int k, boolean areEqual, boolean inNonZeroCase,
AbstractValue value
ValueNumber test, Operand op, int k, boolean areEqual, AbstractValue value
) {
unary_sub_eq(test, op, k, areEqual, inNonZeroCase, value)
unary_sub_eq(test, op, k, areEqual, value)
or
unary_add_eq(test, op, k, areEqual, inNonZeroCase, value)
unary_add_eq(test, op, k, areEqual, value)
or
unary_builtin_expect_eq(test, op, k, areEqual, inNonZeroCase, value)
unary_builtin_expect_eq(test, op, k, areEqual, value)
}
/*
@@ -1347,20 +1424,17 @@ private module Cached {
// op - x == c => op == (c+x)
private predicate unary_sub_eq(
ValueNumber test, Operand op, int k, boolean areEqual, boolean inNonZeroCase,
AbstractValue value
ValueNumber test, Operand op, int k, boolean areEqual, AbstractValue value
) {
inNonZeroCase = false and
exists(SubInstruction sub, int c, int x |
unary_compares_eq(test, sub.getAUse(), c, areEqual, inNonZeroCase, value) and
unary_compares_eq(test, sub.getAUse(), c, areEqual, value) and
op = sub.getLeftOperand() and
x = int_value(sub.getRight()) and
k = c + x
)
or
inNonZeroCase = false and
exists(PointerSubInstruction sub, int c, int x |
unary_compares_eq(test, sub.getAUse(), c, areEqual, inNonZeroCase, value) and
unary_compares_eq(test, sub.getAUse(), c, areEqual, value) and
op = sub.getLeftOperand() and
x = int_value(sub.getRight()) and
k = c + x
@@ -1415,12 +1489,10 @@ private module Cached {
// left + x == right + c => left == right + (c-x)
private predicate unary_add_eq(
ValueNumber test, Operand left, int k, boolean areEqual, boolean inNonZeroCase,
AbstractValue value
ValueNumber test, Operand left, int k, boolean areEqual, AbstractValue value
) {
inNonZeroCase = false and
exists(AddInstruction lhs, int c, int x |
unary_compares_eq(test, lhs.getAUse(), c, areEqual, inNonZeroCase, value) and
unary_compares_eq(test, lhs.getAUse(), c, areEqual, value) and
(
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
or
@@ -1429,9 +1501,8 @@ private module Cached {
k = c - x
)
or
inNonZeroCase = false and
exists(PointerAddInstruction lhs, int c, int x |
unary_compares_eq(test, lhs.getAUse(), c, areEqual, inNonZeroCase, value) and
unary_compares_eq(test, lhs.getAUse(), c, areEqual, value) and
(
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
or
@@ -1453,3 +1524,25 @@ private module Cached {
}
private import Cached
/**
* Holds if `left < right + k` evaluates to `isLt` given that some guard
* evaluates to `value`.
*
* To find the specific guard that performs the comparison
* use `IRGuards.comparesLt`.
*/
predicate comparesLt(Operand left, Operand right, int k, boolean isLt, AbstractValue value) {
compares_lt(_, left, right, k, isLt, value)
}
/**
* Holds if `left = right + k` evaluates to `isLt` given that some guard
* evaluates to `value`.
*
* To find the specific guard that performs the comparison
* use `IRGuards.comparesEq`.
*/
predicate comparesEq(Operand left, Operand right, int k, boolean isLt, AbstractValue value) {
compares_eq(_, left, right, k, isLt, value)
}

View File

@@ -876,6 +876,25 @@ private predicate subEdge(Pos p1, Node n1, Node n2, Pos p2) {
p2.nodeAfter(n2, s)
)
or
// NotConstevalIfStmt -> { then, else } ->
exists(ConstevalIfStmt s |
p1.nodeAt(n1, s) and
p2.nodeBefore(n2, s.getThen())
or
p1.nodeAt(n1, s) and
p2.nodeBefore(n2, s.getElse())
or
p1.nodeAt(n1, s) and
not exists(s.getElse()) and
p2.nodeAfter(n2, s)
or
p1.nodeAfter(n1, s.getThen()) and
p2.nodeAfter(n2, s)
or
p1.nodeAfter(n1, s.getElse()) and
p2.nodeAfter(n2, s)
)
or
// WhileStmt -> condition ; body -> condition ; after dtors -> after
exists(WhileStmt s |
p1.nodeAt(n1, s) and

View File

@@ -479,15 +479,100 @@ private Function getFullyTemplatedFunction(Function f) {
)
}
/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
bindingset[s, t]
private string withConst(string s, Type t) {
if t.isConst() then result = "const " + s else result = s
}
/** Prefixes `volatile` to `s` if `t` is const, or returns `s` otherwise. */
bindingset[s, t]
private string withVolatile(string s, Type t) {
if t.isVolatile() then result = "volatile " + s else result = s
}
/**
* Gets the type name of the `n`'th parameter of `f` without any template
* arguments.
* Returns `s` prefixed with appropriate specifiers from `t`, or `s` if `t` has
* no relevant specifiers.
*/
bindingset[s, t]
private string withSpecifiers(string s, Type t) {
// An `int` that is both const and volatile will be printed as
// `const volatile int` to match the behavior of `Type.getName` which
// is generated by the extractor.
result = withConst(withVolatile(s, t), t)
}
/**
* Gets the string version of `t`, after resolving typedefs. The boolean `needsSpace` is `true`
* if a space should be appended before concatenating any additional symbols
* (such as `*` or `&`) when recursively constructing the type name.
*/
private string getTypeName(Type t, boolean needsSpace) {
// We don't care about template instantiations since we always base models
// on the uninstantiated templates
not t.isFromTemplateInstantiation(_) and
(
exists(DerivedType dt, string s, boolean needsSpace0 |
dt = t and s = withSpecifiers(getTypeName(dt.getBaseType(), needsSpace0), dt)
|
dt instanceof ReferenceType and
not dt instanceof RValueReferenceType and
needsSpace = false and
(if needsSpace0 = true then result = s + " &" else result = s + "&")
or
dt instanceof RValueReferenceType and
needsSpace = false and
(if needsSpace0 = true then result = s + " &&" else result = s + "&&")
or
dt instanceof PointerType and
needsSpace = false and
(if needsSpace0 = true then result = s + " *" else result = s + "*")
or
// We don't need to check for `needsSpace0` here because the type of
// `x` in `int x[1024]` is formatted without a space between the bracket
// and the `int` by `Type.getName`. That is, calling `Type.getName` on
// the type of `x` gives `int[1024]` and not `int [1024]`.
needsSpace = false and
exists(ArrayType array | array = dt |
result = s + "[" + array.getArraySize() + "]"
or
not array.hasArraySize() and
result = s + "[]"
)
or
not dt instanceof ReferenceType and
not dt instanceof PointerType and
not dt instanceof ArrayType and
result = s and
needsSpace = needsSpace0
)
or
not t instanceof DerivedType and
not t instanceof TypedefType and
result = t.getName() and
(if result.matches(["%*", "%&", "%]"]) then needsSpace = false else needsSpace = true)
)
or
result = getTypeName(t.(TypedefType).getBaseType(), needsSpace)
}
/**
* Gets a type name for the `n`'th parameter of `f` without any template
* arguments. The result may be a string representing a type for which the
* typedefs have been resolved.
*/
bindingset[f]
pragma[inline_late]
string getParameterTypeWithoutTemplateArguments(Function f, int n) {
exists(string s, string base, string specifiers |
s = f.getParameter(n).getType().getName() and
exists(string s, string base, string specifiers, Type t |
t = f.getParameter(n).getType() and
// The name of the string can either be the possibly typedefed name
// or an alternative name where typedefs has been resolved.
// `getTypeName(t, _)` is almost equal to `t.resolveTypedefs().getName()`,
// except that `t.resolveTypedefs()` doesn't have a result when the
// resulting type doesn't appear in the database.
s = [t.getName(), getTypeName(t, _)] and
parseAngles(s, base, _, specifiers) and
result = base + specifiers
)
@@ -902,18 +987,19 @@ private Element interpretElement0(
)
}
/** Gets the source/sink/summary element corresponding to the supplied parameters. */
Element interpretElement(
string namespace, string type, boolean subtypes, string name, string signature, string ext
) {
elementSpec(namespace, type, subtypes, name, signature, ext) and
exists(Element e | e = interpretElement0(namespace, type, subtypes, name, signature) |
ext = "" and result = e
)
}
cached
private module Cached {
/** Gets the source/sink/summary element corresponding to the supplied parameters. */
cached
Element interpretElement(
string namespace, string type, boolean subtypes, string name, string signature, string ext
) {
elementSpec(namespace, type, subtypes, name, signature, ext) and
exists(Element e | e = interpretElement0(namespace, type, subtypes, name, signature) |
ext = "" and result = e
)
}
/**
* Holds if `node` is specified as a source with the given kind in a CSV flow
* model.

View File

@@ -12,8 +12,14 @@ private import semmle.code.cpp.dataflow.ExternalFlow
private import semmle.code.cpp.ir.IR
module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
private import codeql.util.Void
class SummarizedCallableBase = Function;
class SourceBase = Void;
class SinkBase = Void;
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
ReturnKind getStandardReturnValueKind() { result.(NormalReturnKind).getIndirectionIndex() = 0 }
@@ -93,6 +99,10 @@ private module StepsInput implements Impl::Private::StepsInputSig {
DataFlowCall getACall(Public::SummarizedCallable sc) {
result.getStaticCallTarget().getUnderlyingCallable() = sc
}
Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() }
Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}
module SourceSinkInterpretationInput implements

View File

@@ -1,8 +1,9 @@
/**
* This library offers a view of preprocessor branches (`#if`, `#ifdef`,
* `#ifndef`, `#elif` and `#else`) as blocks of code between the opening and
* closing directives, with navigable parent-child relationships to other
* blocks. The main class is `PreprocessorBlock`.
* `#ifndef`, `#elif`, `#elifdef`, `#elifndef`, and `#else`) as blocks of
* code between the opening and closing directives, with navigable
* parent-child relationships to other blocks. The main class is
* `PreprocessorBlock`.
*/
import cpp
@@ -32,10 +33,10 @@ private int getPreprocIndex(PreprocessorBranchDirective directive) {
/**
* A chunk of code from one preprocessor branch (`#if`, `#ifdef`,
* `#ifndef`, `#elif` or `#else`) to the directive that closes it
* (`#elif`, `#else` or `#endif`). The `getParent()` method
* allows these blocks to be navigated as a tree, with the root
* being the entire file.
* `#ifndef`, `#elif`, `#elifdef`, `#elifndef`, or `#else`) to the
* directive that closes it (`#elif`, `#elifdef`, `#elifndef`, `#else`,
* or `#endif`). The `getParent()` method allows these blocks to be
* navigated as a tree, with the root being the entire file.
*/
class PreprocessorBlock extends @element {
PreprocessorBlock() {

View File

@@ -227,11 +227,11 @@ class ProxyClass extends UserType {
}
class TypeTemplateParameter extends UserType {
TypeTemplateParameter() { usertypes(this, _, 7) or usertypes(this, _, 8) }
TypeTemplateParameter() { usertypes(this, _, [7, 8]) }
}
class TemplateClass extends UserType {
TemplateClass() { usertypes(this, _, 6) }
TemplateClass() { usertypes(this, _, [15, 16, 17]) }
UserType getAnInstantiation() {
class_instantiation(result, this) and

View File

@@ -114,15 +114,7 @@ private module Cached {
* Holds if `t` is a struct, class, union, or template.
*/
cached
predicate isClass(@usertype t) {
usertypes(t, _, 1) or
usertypes(t, _, 2) or
usertypes(t, _, 3) or
usertypes(t, _, 6) or
usertypes(t, _, 10) or
usertypes(t, _, 11) or
usertypes(t, _, 12)
}
predicate isClass(@usertype t) { usertypes(t, _, [1, 2, 3, 15, 16, 17]) }
cached
predicate isType(@type t) {

View File

@@ -382,7 +382,7 @@ private class SideEffectArgumentNode extends ArgumentNode, SideEffectOperandNode
exists(int indirectionIndex |
pos = TIndirectionPosition(argumentIndex, pragma[only_bind_into](indirectionIndex)) and
this.getCallInstruction() = dfCall.asCallInstruction() and
super.hasAddressOperandAndIndirectionIndex(_, pragma[only_bind_into](indirectionIndex))
super.hasAddressOperandAndIndirectionIndex(arg, pragma[only_bind_into](indirectionIndex))
)
}
}

View File

@@ -757,9 +757,11 @@ class SsaIteratorNode extends Node, TSsaIteratorNode {
class SideEffectOperandNode extends Node instanceof IndirectOperand {
CallInstruction call;
int argumentIndex;
ArgumentOperand arg;
SideEffectOperandNode() {
IndirectOperand.super.hasOperandAndIndirectionIndex(call.getArgumentOperand(argumentIndex), _)
arg = call.getArgumentOperand(argumentIndex) and
IndirectOperand.super.hasOperandAndIndirectionIndex(arg, _)
}
CallInstruction getCallInstruction() { result = call }
@@ -2494,6 +2496,36 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
result = TSsaPhiInputNode(phi, input)
)
}
bindingset[value, n]
pragma[inline_late]
private predicate indirectOperandHasValueNumber(ValueNumber value, int indirectionIndex, Node n) {
exists(Operand use |
use = value.getAnInstruction().getAUse() and
n.asIndirectOperand(indirectionIndex) = use
)
}
/**
* Gets an indirect node with indirection index `indirectionIndex` that is
* safely guarded by the given guard check.
*/
Node getAnIndirectBarrierNode(int indirectionIndex) {
exists(IRGuardCondition g, ValueNumber value, boolean edge |
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge) and
indirectOperandHasValueNumber(value, indirectionIndex, result) and
controls(g, result, edge)
)
or
exists(
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
|
instructionGuardChecks(g, def.getARead().asIndirectOperand(indirectionIndex).getDef(), branch) and
guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input),
pragma[only_bind_into](phi)) and
result = TSsaPhiInputNode(phi, input)
)
}
}
/**

View File

@@ -899,6 +899,24 @@ class MemoryLocation extends FinalMemoryLocation {
MemoryLocation() { not useOverlapWithBusyDef(this) }
}
bindingset[fun]
pragma[inline_late]
private MemoryLocation getUnknownMemoryLocation(IRFunction fun, boolean isMayAccess) {
result = TUnknownMemoryLocation(fun, isMayAccess)
}
bindingset[fun]
pragma[inline_late]
private MemoryLocation getAllAliasedMemory(IRFunction fun, boolean isMayAccess) {
result = TAllAliasedMemory(fun, isMayAccess)
}
bindingset[fun]
pragma[inline_late]
private MemoryLocation getAllNonLocalMemory(IRFunction fun, boolean isMayAccess) {
result = TAllNonLocalMemory(fun, isMayAccess)
}
MemoryLocation getResultMemoryLocation(Instruction instr) {
not canReuseSsaForOldResult(instr) and
exists(MemoryAccessKind kind, boolean isMayAccess |
@@ -926,7 +944,7 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
// And otherwise we assign it a memory location that groups all the relevant memory locations into one.
result = getGroupedMemoryLocation(var, unbindBool(isMayAccess), false)
)
else result = TUnknownMemoryLocation(instr.getEnclosingIRFunction(), isMayAccess)
else result = getUnknownMemoryLocation(instr.getEnclosingIRFunction(), isMayAccess)
)
or
kind instanceof EntireAllocationMemoryAccess and
@@ -935,10 +953,10 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
unbindBool(isMayAccess))
or
kind instanceof EscapedMemoryAccess and
result = TAllAliasedMemory(instr.getEnclosingIRFunction(), isMayAccess)
result = getAllAliasedMemory(instr.getEnclosingIRFunction(), isMayAccess)
or
kind instanceof NonLocalMemoryAccess and
result = TAllNonLocalMemory(instr.getEnclosingIRFunction(), isMayAccess)
result = getAllNonLocalMemory(instr.getEnclosingIRFunction(), isMayAccess)
)
)
}

View File

@@ -171,6 +171,23 @@ module Raw {
// forwarded the result of another translated expression.
instruction = translatedExpr.getInstruction(_)
)
or
// Consider the snippet `if(x) { ... }` where `x` is an integer.
// In C++ there is a `BoolConversion` conversion on `x` which generates a
// `CompareNEInstruction` whose `getInstructionConvertedResultExpression`
// is the `BoolConversion` (by the logic in the disjunct above). Thus,
// calling `getInstructionUnconvertedResultExpression` on the
// `CompareNEInstruction` gives `x` in C++ code.
// However, in C there is no such conversion to return. So instead we have
// to map the result of `getInstructionConvertedResultExpression` on the
// `CompareNEInstruction` to `x` manually. This ensures that calling
// `getInstructionUnconvertedResultExpression` on the `CompareNEInstruction`
// gives `x` in both the C case and C++ case.
exists(TranslatedValueCondition translatedValueCondition |
translatedValueCondition = getTranslatedCondition(result) and
translatedValueCondition.shouldGenerateCompareNE() and
instruction = translatedValueCondition.getInstruction(ValueConditionCompareTag())
)
}
cached

View File

@@ -38,7 +38,11 @@ newtype TInstructionTag =
AllocationSizeTag() or
AllocationElementSizeTag() or
AllocationExtentConvertTag() or
ValueConditionCompareTag() or
ValueConditionConstantTag() or
ValueConditionConditionalBranchTag() or
ValueConditionConditionalConstantTag() or
ValueConditionConditionalCompareTag() or
ConditionValueTrueTempAddressTag() or
ConditionValueTrueConstantTag() or
ConditionValueTrueStoreTag() or
@@ -49,6 +53,8 @@ newtype TInstructionTag =
ConditionValueResultLoadTag() or
BoolConversionConstantTag() or
BoolConversionCompareTag() or
NotExprOperationTag() or
NotExprConstantTag() or
ResultCopyTag() or
LoadTag() or // Implicit load due to lvalue-to-rvalue conversion
CatchTag() or
@@ -167,6 +173,14 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = ValueConditionConditionalBranchTag() and result = "ValCondCondBranch"
or
tag = ValueConditionConditionalConstantTag() and result = "ValueConditionConditionalConstant"
or
tag = ValueConditionConditionalCompareTag() and result = "ValueConditionConditionalCompare"
or
tag = ValueConditionCompareTag() and result = "ValCondCondCompare"
or
tag = ValueConditionConstantTag() and result = "ValCondConstant"
or
tag = ConditionValueTrueTempAddressTag() and result = "CondValTrueTempAddr"
or
tag = ConditionValueTrueConstantTag() and result = "CondValTrueConst"
@@ -187,6 +201,10 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = BoolConversionCompareTag() and result = "BoolConvComp"
or
tag = NotExprOperationTag() and result = "NotExprOperation"
or
tag = NotExprConstantTag() and result = "NotExprWithBoolConversionConstant"
or
tag = ResultCopyTag() and result = "ResultCopy"
or
tag = LoadTag() and result = "Load" // Implicit load due to lvalue-to-rvalue conversion

View File

@@ -47,7 +47,7 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
{
TranslatedFlexibleCondition() { this = TTranslatedFlexibleCondition(expr) }
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisited when we get unnamed destructors
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
@@ -187,7 +187,24 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
private Type getValueExprType() {
result = this.getValueExpr().getExprType().getUnspecifiedType()
}
predicate shouldGenerateCompareNE() { not this.getValueExprType() instanceof BoolType }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
this.shouldGenerateCompareNE() and
(
tag = ValueConditionCompareTag() and
opcode instanceof Opcode::CompareNE and
resultType = getBoolType()
or
tag = ValueConditionConstantTag() and
opcode instanceof Opcode::Constant and
resultType = getTypeForPRValue(this.getValueExprType())
)
or
tag = ValueConditionConditionalBranchTag() and
opcode instanceof Opcode::ConditionalBranch and
resultType = getVoidType()
@@ -195,11 +212,24 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
child = this.getValueExpr() and
result = this.getInstruction(ValueConditionConditionalBranchTag()) and
kind instanceof GotoEdge
kind instanceof GotoEdge and
if this.shouldGenerateCompareNE()
then result = this.getInstruction(ValueConditionConstantTag())
else result = this.getInstruction(ValueConditionConditionalBranchTag())
}
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
this.shouldGenerateCompareNE() and
(
tag = ValueConditionConstantTag() and
kind instanceof GotoEdge and
result = this.getInstruction(ValueConditionCompareTag())
or
tag = ValueConditionCompareTag() and
kind instanceof GotoEdge and
result = this.getInstruction(ValueConditionConditionalBranchTag())
)
or
tag = ValueConditionConditionalBranchTag() and
(
kind instanceof TrueEdge and
@@ -211,9 +241,26 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
this.shouldGenerateCompareNE() and
tag = ValueConditionCompareTag() and
(
operandTag instanceof LeftOperandTag and
result = this.getValueExpr().getResult()
or
operandTag instanceof RightOperandTag and
result = this.getInstruction(ValueConditionConstantTag())
)
or
tag = ValueConditionConditionalBranchTag() and
operandTag instanceof ConditionOperandTag and
result = this.getValueExpr().getResult()
if this.shouldGenerateCompareNE()
then result = this.getInstruction(ValueConditionCompareTag())
else result = this.getValueExpr().getResult()
}
override string getInstructionConstantValue(InstructionTag tag) {
tag = ValueConditionConstantTag() and
result = "0"
}
private TranslatedExpr getValueExpr() { result = getTranslatedExpr(expr) }

Some files were not shown because too many files have changed in this diff Show More