Compare commits

..

35 Commits

Author SHA1 Message Date
Jean Helie
178f2953c3 use red_cartoon dev ATM model 2022-07-20 13:34:43 +02:00
Stephan Brandauer
9613f73116 enable new features for experimentation 2022-06-13 14:04:47 +02:00
Stephan Brandauer
fd4f509615 add stringConcatenatedWith feature to help the model learn that string concatenation leaves are usually not sinks 2022-06-13 14:04:47 +02:00
Stephan Brandauer
4ba7243b1f add assignedToPropName feature to let the model improve number of false positives for XSS query 2022-06-13 14:04:46 +02:00
Stephan Brandauer
5346ade995 fix bug in InputArgumentIndex feature 2022-06-13 14:04:46 +02:00
Stephan Brandauer
ebedeaf543 performance fixes 2022-06-13 14:04:45 +02:00
Stephan Brandauer
ea1e44b035 use ? for unknown parameternames 2022-06-13 14:04:45 +02:00
Stephan Brandauer
250ed0831c add documentations and rename a feature 2022-06-13 14:04:44 +02:00
Stephan Brandauer
314333f7ed add functionInterfacesInFile and surroundingFunctionParameters features 2022-06-13 14:04:44 +02:00
Stephan Brandauer
3f6d663105 documentation for calleeImports ATM feature 2022-06-13 14:04:43 +02:00
Stephan Brandauer
962ed4a51b documentation for new feature 2022-06-13 14:04:43 +02:00
Stephan Brandauer
2f1882bd3a ATM: new feature to list all imports in an endpoint's file 2022-06-13 14:04:42 +02:00
Esben Sparre Andreasen
6505ad1724 use proper import instead of inlining 2022-06-13 14:00:37 +02:00
Esben Sparre Andreasen
e53ba21387 remove Input_ArgumentIndexAndAccessPathFromCallee 2022-06-13 14:00:36 +02:00
Esben Sparre Andreasen
ec1dc985ef add docstring examples 2022-06-13 14:00:36 +02:00
Esben Sparre Andreasen
008024b3bb address review comments 2022-06-13 14:00:35 +02:00
Esben Sparre Andreasen
5c4043dacb Apply suggestions from code review
Co-authored-by: Henry Mercer <henrymercer@github.com>
2022-06-13 14:00:35 +02:00
Esben Sparre Andreasen
874da9d81c fix semantic merge conflict 2022-06-13 14:00:34 +02:00
Esben Sparre Andreasen
8e0781d78a rename new features 2022-06-13 14:00:34 +02:00
Esben Sparre Andreasen
937d6b1f3e add more features 2022-06-13 14:00:33 +02:00
Esben Sparre Andreasen
7d4125010c improve feature documentation 2022-06-13 14:00:33 +02:00
Esben Sparre Andreasen
a8dd55fe0f improve feature tests with more cases 2022-06-13 14:00:32 +02:00
Esben Sparre Andreasen
57c88d5fd6 improve access path strings 2022-06-13 14:00:32 +02:00
Esben Sparre Andreasen
026dfaec97 support import in getSimpleAccessPath 2022-06-13 14:00:31 +02:00
Esben Sparre Andreasen
c523c4f96e support await in getSimpleAccessPath 2022-06-13 14:00:31 +02:00
Esben Sparre Andreasen
ef5148bb80 avoid using new feautes by default 2022-06-13 14:00:30 +02:00
Esben Sparre Andreasen
13264e1119 add CompareFeatures.ql 2022-06-13 14:00:30 +02:00
Esben Sparre Andreasen
1e299e9bb8 add generic tests for features 2022-06-13 14:00:29 +02:00
Esben Sparre Andreasen
f322aaf344 Document EndpointFeatures.qll 2022-06-13 14:00:29 +02:00
Esben Sparre Andreasen
3c9e70341b add ParameterAccessPathSimpleFromArgumentTraversal 2022-06-13 14:00:28 +02:00
Esben Sparre Andreasen
cfe20810bf improve getSimpleAccessPath 2022-06-13 14:00:28 +02:00
Esben Sparre Andreasen
065002ad18 refactor calleeAccessPath feature to class 2022-06-13 14:00:27 +02:00
Stephan Brandauer
7778aa59ea refactor getACallBasedTokenFeature to class-use 2022-06-13 14:00:27 +02:00
Esben Sparre Andreasen
8ef6f59737 Add CalleeAccessPathSimpleFromArgumentTraversal 2022-06-13 14:00:26 +02:00
Esben Sparre Andreasen
b4339e8ac5 refactor EndpointFeatures.ql to use classes 2022-06-13 14:00:26 +02:00
2734 changed files with 149365 additions and 188019 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,22 +0,0 @@
set -xe
BAZELISK_VERSION=v1.12.0
BAZELISK_DOWNLOAD_SHA=6b0bcb2ea15bca16fffabe6fda75803440375354c085480fe361d2cbf32501db
apt-get update
export DEBIAN_FRONTEND=noninteractive
apt-get -y install --no-install-recommends \
zlib1g-dev \
uuid-dev \
python3-distutils \
python3-pip \
bash-completion
# 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,13 +0,0 @@
set -xe
# 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

@@ -3,12 +3,22 @@ description: Fetches the latest version of CodeQL
runs: runs:
using: composite using: composite
steps: steps:
- name: Select platform - Linux
if: runner.os == 'Linux'
shell: bash
run: echo "GA_CODEQL_CLI_PLATFORM=linux64" >> $GITHUB_ENV
- name: Select platform - MacOS
if: runner.os == 'MacOS'
shell: bash
run: echo "GA_CODEQL_CLI_PLATFORM=osx64" >> $GITHUB_ENV
- name: Fetch CodeQL - name: Fetch CodeQL
shell: bash shell: bash
run: | run: |
gh extension install github/gh-codeql LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1)
gh codeql set-channel nightly gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-$GA_CODEQL_CLI_PLATFORM.zip "$LATEST"
gh codeql version unzip -q -d "${RUNNER_TEMP}" codeql-$GA_CODEQL_CLI_PLATFORM.zip
gh codeql version --format=json | jq -r .unpackedLocation >> "${GITHUB_PATH}" echo "${RUNNER_TEMP}/codeql" >> "${GITHUB_PATH}"
env: env:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}

View File

@@ -10,7 +10,6 @@ on:
- "*/ql/lib/**/*.qll" - "*/ql/lib/**/*.qll"
- "!**/experimental/**" - "!**/experimental/**"
- "!ql/**" - "!ql/**"
- "!swift/**"
- ".github/workflows/check-change-note.yml" - ".github/workflows/check-change-note.yml"
jobs: jobs:

View File

@@ -5,7 +5,6 @@ on:
paths: paths:
- "*/ql/lib/**" - "*/ql/lib/**"
- .github/workflows/check-qldoc.yml - .github/workflows/check-qldoc.yml
- .github/actions/fetch-codeql/action.yml
branches: branches:
- main - main
- "rc/*" - "rc/*"
@@ -15,13 +14,18 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Install CodeQL
run: |
gh extension install github/gh-codeql
gh codeql set-channel nightly
gh codeql version
env:
GITHUB_TOKEN: ${{ github.token }}
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 2 fetch-depth: 2
- name: Install CodeQL
uses: ./.github/actions/fetch-codeql
- name: Check QLdoc coverage - name: Check QLdoc coverage
shell: bash shell: bash
run: | run: |
@@ -30,7 +34,7 @@ jobs:
changed_lib_packs="$(git diff --name-only --diff-filter=ACMRT HEAD^ HEAD | { grep -Po '^(?!swift)[a-z]*/ql/lib' || true; } | sort -u)" changed_lib_packs="$(git diff --name-only --diff-filter=ACMRT HEAD^ HEAD | { grep -Po '^(?!swift)[a-z]*/ql/lib' || true; } | sort -u)"
for pack_dir in ${changed_lib_packs}; do for pack_dir in ${changed_lib_packs}; do
lang="${pack_dir%/ql/lib}" lang="${pack_dir%/ql/lib}"
codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-current.txt" --dir="${pack_dir}" gh codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-current.txt" --dir="${pack_dir}"
done done
git checkout HEAD^ git checkout HEAD^
for pack_dir in ${changed_lib_packs}; do for pack_dir in ${changed_lib_packs}; do
@@ -38,7 +42,7 @@ jobs:
# In this case the right thing to do is to skip the check. # In this case the right thing to do is to skip the check.
[[ ! -d "${pack_dir}" ]] && continue [[ ! -d "${pack_dir}" ]] && continue
lang="${pack_dir%/ql/lib}" lang="${pack_dir%/ql/lib}"
codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-baseline.txt" --dir="${pack_dir}" gh codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-baseline.txt" --dir="${pack_dir}"
awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-current.txt" | sort -u > "${RUNNER_TEMP}/current-undocumented.txt" awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-current.txt" | sort -u > "${RUNNER_TEMP}/current-undocumented.txt"
awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-baseline.txt" | sort -u > "${RUNNER_TEMP}/baseline-undocumented.txt" awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-baseline.txt" | sort -u > "${RUNNER_TEMP}/baseline-undocumented.txt"
UNDOCUMENTED="$(grep -f <(comm -13 "${RUNNER_TEMP}/baseline-undocumented.txt" "${RUNNER_TEMP}/current-undocumented.txt") "${RUNNER_TEMP}/${lang}-current.txt" || true)" UNDOCUMENTED="$(grep -f <(comm -13 "${RUNNER_TEMP}/baseline-undocumented.txt" "${RUNNER_TEMP}/current-undocumented.txt") "${RUNNER_TEMP}/${lang}-current.txt" || true)"

View File

@@ -12,7 +12,6 @@ on:
- main - main
paths: paths:
- ".github/workflows/csv-coverage-metrics.yml" - ".github/workflows/csv-coverage-metrics.yml"
- ".github/actions/fetch-codeql/action.yml"
jobs: jobs:
publish-java: publish-java:

View File

@@ -3,20 +3,18 @@ name: Check framework coverage changes
on: on:
pull_request: pull_request:
paths: paths:
- ".github/workflows/csv-coverage-pr-comment.yml" - '.github/workflows/csv-coverage-pr-comment.yml'
- ".github/workflows/csv-coverage-pr-artifacts.yml" - '*/ql/src/**/*.ql'
- ".github/actions/fetch-codeql/action.yml" - '*/ql/src/**/*.qll'
- "*/ql/src/**/*.ql" - '*/ql/lib/**/*.ql'
- "*/ql/src/**/*.qll" - '*/ql/lib/**/*.qll'
- "*/ql/lib/**/*.ql" - 'misc/scripts/library-coverage/*.py'
- "*/ql/lib/**/*.qll"
- "misc/scripts/library-coverage/*.py"
# input data files # input data files
- "*/documentation/library-coverage/cwe-sink.csv" - '*/documentation/library-coverage/cwe-sink.csv'
- "*/documentation/library-coverage/frameworks.csv" - '*/documentation/library-coverage/frameworks.csv'
branches: branches:
- main - main
- "rc/*" - 'rc/*'
jobs: jobs:
generate: generate:
@@ -25,72 +23,77 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
GITHUB_CONTEXT: ${{ toJSON(github.event) }} GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - MERGE - name: Clone self (github/codeql) - MERGE
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
path: merge path: merge
- name: Clone self (github/codeql) - BASE - name: Clone self (github/codeql) - BASE
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
fetch-depth: 2 fetch-depth: 2
path: base path: base
- run: | - run: |
git checkout HEAD^1 git checkout HEAD^1
git log -1 --format='%H' git log -1 --format='%H'
working-directory: base working-directory: base
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v4 uses: actions/setup-python@v3
with: with:
python-version: 3.8 python-version: 3.8
- name: Download CodeQL CLI - name: Download CodeQL CLI
uses: ./merge/.github/actions/fetch-codeql env:
- name: Generate CSV files on merge commit of the PR GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
echo "Running generator on merge" gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
python merge/misc/scripts/library-coverage/generate-report.py ci merge merge - name: Unzip CodeQL CLI
mkdir out_merge run: unzip -d codeql-cli codeql-linux64.zip
cp framework-coverage-*.csv out_merge/ - name: Generate CSV files on merge commit of the PR
cp framework-coverage-*.rst out_merge/ run: |
- name: Generate CSV files on base commit of the PR echo "Running generator on merge"
run: | PATH="$PATH:codeql-cli/codeql" python merge/misc/scripts/library-coverage/generate-report.py ci merge merge
echo "Running generator on base" mkdir out_merge
python base/misc/scripts/library-coverage/generate-report.py ci base base cp framework-coverage-*.csv out_merge/
mkdir out_base cp framework-coverage-*.rst out_merge/
cp framework-coverage-*.csv out_base/ - name: Generate CSV files on base commit of the PR
cp framework-coverage-*.rst out_base/ run: |
- name: Generate diff of coverage reports echo "Running generator on base"
run: | PATH="$PATH:codeql-cli/codeql" python base/misc/scripts/library-coverage/generate-report.py ci base base
python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md mkdir out_base
- name: Upload CSV package list cp framework-coverage-*.csv out_base/
uses: actions/upload-artifact@v3 cp framework-coverage-*.rst out_base/
with: - name: Generate diff of coverage reports
name: csv-framework-coverage-merge run: |
path: | python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md
out_merge/framework-coverage-*.csv - name: Upload CSV package list
out_merge/framework-coverage-*.rst uses: actions/upload-artifact@v3
- name: Upload CSV package list with:
uses: actions/upload-artifact@v3 name: csv-framework-coverage-merge
with: path: |
name: csv-framework-coverage-base out_merge/framework-coverage-*.csv
path: | out_merge/framework-coverage-*.rst
out_base/framework-coverage-*.csv - name: Upload CSV package list
out_base/framework-coverage-*.rst uses: actions/upload-artifact@v3
- name: Upload comparison results with:
uses: actions/upload-artifact@v3 name: csv-framework-coverage-base
with: path: |
name: comparison out_base/framework-coverage-*.csv
path: | out_base/framework-coverage-*.rst
comparison.md - name: Upload comparison results
- name: Save PR number uses: actions/upload-artifact@v3
run: | with:
mkdir -p pr name: comparison
echo ${{ github.event.pull_request.number }} > pr/NR path: |
- name: Upload PR number comparison.md
uses: actions/upload-artifact@v3 - name: Save PR number
with: run: |
name: pr mkdir -p pr
path: pr/ echo ${{ github.event.pull_request.number }} > pr/NR
- name: Upload PR number
uses: actions/upload-artifact@v3
with:
name: pr
path: pr/

View File

@@ -22,7 +22,7 @@ jobs:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v4 uses: actions/setup-python@v3
with: with:
python-version: 3.8 python-version: 3.8

View File

@@ -5,29 +5,38 @@ on:
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
path: script path: script
- name: Clone self (github/codeql) for analysis - name: Clone self (github/codeql) for analysis
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
path: codeqlModels path: codeqlModels
fetch-depth: 0 fetch-depth: 0
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v4 uses: actions/setup-python@v3
with: with:
python-version: 3.8 python-version: 3.8
- name: Download CodeQL CLI - name: Download CodeQL CLI
uses: ./script/.github/actions/fetch-codeql env:
- name: Build modeled package list GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Upload timeseries CSV - name: Unzip CodeQL CLI
uses: actions/upload-artifact@v3 run: unzip -d codeql-cli codeql-linux64.zip
with: - name: Build modeled package list
name: framework-coverage-timeseries run: |
path: framework-coverage-timeseries-*.csv CLI=$(realpath "codeql-cli/codeql")
echo $CLI
PATH="$PATH:$CLI" python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels
- name: Upload timeseries CSV
uses: actions/upload-artifact@v3
with:
name: framework-coverage-timeseries
path: framework-coverage-timeseries-*.csv

View File

@@ -12,27 +12,33 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Dump GitHub context - name: Dump GitHub context
env: env:
GITHUB_CONTEXT: ${{ toJSON(github.event) }} GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
path: ql path: ql
fetch-depth: 0 fetch-depth: 0
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v4 uses: actions/setup-python@v3
with: with:
python-version: 3.8 python-version: 3.8
- name: Download CodeQL CLI - name: Download CodeQL CLI
uses: ./ql/.github/actions/fetch-codeql env:
- name: Generate coverage files GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
python ql/misc/scripts/library-coverage/generate-report.py ci ql ql gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Create pull request with changes - name: Generate coverage files
env: run: |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PATH="$PATH:codeql-cli/codeql" python ql/misc/scripts/library-coverage/generate-report.py ci ql ql
run: |
python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY" - name: Create pull request with changes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY"

View File

@@ -4,39 +4,46 @@ on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
qlModelShaOverride: qlModelShaOverride:
description: "github/codeql repo SHA used for looking up the CSV models" description: 'github/codeql repo SHA used for looking up the CSV models'
required: false required: false
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
path: script path: script
- name: Clone self (github/codeql) for analysis - name: Clone self (github/codeql) for analysis
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
path: codeqlModels path: codeqlModels
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }} ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v4 uses: actions/setup-python@v3
with: with:
python-version: 3.8 python-version: 3.8
- name: Download CodeQL CLI - name: Download CodeQL CLI
uses: ./script/.github/actions/fetch-codeql env:
- name: Build modeled package list GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip"
- name: Upload CSV package list - name: Unzip CodeQL CLI
uses: actions/upload-artifact@v3 run: unzip -d codeql-cli codeql-linux64.zip
with: - name: Build modeled package list
name: framework-coverage-csv run: |
path: framework-coverage-*.csv PATH="$PATH:codeql-cli/codeql" python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script
- name: Upload RST package list - name: Upload CSV package list
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: framework-coverage-rst name: framework-coverage-csv
path: framework-coverage-*.rst path: framework-coverage-*.csv
- name: Upload RST package list
uses: actions/upload-artifact@v3
with:
name: framework-coverage-rst
path: framework-coverage-*.rst

View File

@@ -4,111 +4,159 @@ on:
paths: paths:
- "go/**" - "go/**"
- .github/workflows/go-tests.yml - .github/workflows/go-tests.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml - codeql-workspace.yml
jobs: jobs:
test-linux: test-linux:
name: Test Linux (Ubuntu) name: Test Linux (Ubuntu)
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Set up Go 1.18.1
uses: actions/setup-go@v3
with:
go-version: 1.18.1
id: go
- name: Check out code - name: Set up Go 1.18.1
uses: actions/checkout@v2 uses: actions/setup-go@v3
with:
go-version: 1.18.1
id: go
- name: Set up CodeQL CLI - name: Set up CodeQL CLI
uses: ./.github/actions/fetch-codeql run: |
echo "Removing old CodeQL Directory..."
rm -rf $HOME/codeql
echo "Done"
cd $HOME
echo "Downloading CodeQL CLI..."
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1)
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST"
echo "Done"
echo "Unpacking CodeQL CLI..."
unzip -q codeql-linux64.zip
rm -f codeql-linux64.zip
echo "Done"
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Enable problem matchers in repository - name: Check out code
shell: bash uses: actions/checkout@v2
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build - name: Enable problem matchers in repository
run: | shell: bash
cd go run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
make
- name: Check that all QL and Go code is autoformatted - name: Build
run: | run: |
cd go cd go
make check-formatting env PATH=$PATH:$HOME/codeql make
- name: Compile qhelp files to markdown - name: Check that all QL and Go code is autoformatted
run: | run: |
cd go cd go
env QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown env PATH=$PATH:$HOME/codeql make check-formatting
- name: Upload qhelp markdown - name: Compile qhelp files to markdown
uses: actions/upload-artifact@v2 run: |
with: cd go
name: qhelp-markdown env PATH=$PATH:$HOME/codeql QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown
path: go/qhelp-out/**/*.md
- name: Test - name: Upload qhelp markdown
run: | uses: actions/upload-artifact@v2
cd go with:
make test name: qhelp-markdown
path: go/qhelp-out/**/*.md
- name: Test
run: |
cd go
env PATH=$PATH:$HOME/codeql make test
test-mac: test-mac:
name: Test MacOS name: Test MacOS
runs-on: macos-latest runs-on: macOS-latest
steps: steps:
- name: Set up Go 1.18.1 - name: Set up Go 1.18.1
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: 1.18.1 go-version: 1.18.1
id: go id: go
- name: Check out code - name: Set up CodeQL CLI
uses: actions/checkout@v2 run: |
echo "Removing old CodeQL Directory..."
rm -rf $HOME/codeql
echo "Done"
cd $HOME
echo "Downloading CodeQL CLI..."
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1)
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-osx64.zip "$LATEST"
echo "Done"
echo "Unpacking CodeQL CLI..."
unzip -q codeql-osx64.zip
rm -f codeql-osx64.zip
echo "Done"
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Set up CodeQL CLI - name: Check out code
uses: ./.github/actions/fetch-codeql uses: actions/checkout@v2
- name: Enable problem matchers in repository - name: Enable problem matchers in repository
shell: bash shell: bash
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build - name: Build
run: | run: |
cd go cd go
make env PATH=$PATH:$HOME/codeql make
- name: Test - name: Test
run: | run: |
cd go cd go
make test env PATH=$PATH:$HOME/codeql make test
test-win: test-win:
name: Test Windows name: Test Windows
runs-on: windows-2019 runs-on: windows-2019
steps: steps:
- name: Set up Go 1.18.1 - name: Set up Go 1.18.1
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: 1.18.1 go-version: 1.18.1
id: go id: go
- name: Check out code - name: Set up CodeQL CLI
uses: actions/checkout@v2 run: |
echo "Removing old CodeQL Directory..."
rm -rf $HOME/codeql
echo "Done"
cd "$HOME"
echo "Downloading CodeQL CLI..."
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1)
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-win64.zip "$LATEST"
echo "Done"
echo "Unpacking CodeQL CLI..."
unzip -q -o codeql-win64.zip
unzip -q -o codeql-win64.zip codeql/codeql.exe
rm -f codeql-win64.zip
echo "Done"
env:
GITHUB_TOKEN: ${{ github.token }}
shell:
bash
- name: Set up CodeQL CLI - name: Check out code
uses: ./.github/actions/fetch-codeql uses: actions/checkout@v2
- name: Enable problem matchers in repository - name: Enable problem matchers in repository
shell: bash shell: bash
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build - name: Build
run: | run: |
cd go $Env:Path += ";$HOME\codeql"
make cd go
make
- name: Test - name: Test
run: | run: |
cd go $Env:Path += ";$HOME\codeql"
make test cd go
make test

View File

@@ -5,7 +5,6 @@ on:
paths: paths:
- "javascript/ql/experimental/adaptivethreatmodeling/**" - "javascript/ql/experimental/adaptivethreatmodeling/**"
- .github/workflows/js-ml-tests.yml - .github/workflows/js-ml-tests.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml - codeql-workspace.yml
branches: branches:
- main - main
@@ -14,7 +13,6 @@ on:
paths: paths:
- "javascript/ql/experimental/adaptivethreatmodeling/**" - "javascript/ql/experimental/adaptivethreatmodeling/**"
- .github/workflows/js-ml-tests.yml - .github/workflows/js-ml-tests.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml - codeql-workspace.yml
workflow_dispatch: workflow_dispatch:

View File

@@ -9,7 +9,6 @@ on:
- main - main
paths: paths:
- ".github/workflows/mad_regenerate-models.yml" - ".github/workflows/mad_regenerate-models.yml"
- ".github/actions/fetch-codeql/action.yml"
jobs: jobs:
regenerate-models: regenerate-models:

View File

@@ -10,16 +10,16 @@ env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
jobs: jobs:
analyze: queries:
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest
steps: steps:
### Build the queries ###
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Find codeql - name: Find codeql
id: find-codeql id: find-codeql
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
with: with:
languages: javascript # does not matter languages: javascript # does not matter
tools: latest
- name: Get CodeQL version - name: Get CodeQL version
id: get-codeql-version id: get-codeql-version
run: | run: |
@@ -49,7 +49,14 @@ jobs:
name: query-pack-zip name: query-pack-zip
path: ${{ runner.temp }}/query-pack.zip path: ${{ runner.temp }}/query-pack.zip
### Build the extractor ### extractors:
strategy:
fail-fast: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache entire extractor - name: Cache entire extractor
id: cache-extractor id: cache-extractor
uses: actions/cache@v3 uses: actions/cache@v3
@@ -93,8 +100,15 @@ jobs:
ql/target/release/ql-extractor ql/target/release/ql-extractor
ql/target/release/ql-extractor.exe ql/target/release/ql-extractor.exe
retention-days: 1 retention-days: 1
package:
runs-on: ubuntu-latest
### Package the queries and extractor ### needs:
- extractors
- queries
steps:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v3
with: with:
name: query-pack-zip name: query-pack-zip
@@ -122,8 +136,16 @@ jobs:
name: codeql-ql-pack name: codeql-ql-pack
path: codeql-ql.zip path: codeql-ql.zip
retention-days: 1 retention-days: 1
analyze:
runs-on: ubuntu-latest
strategy:
matrix:
folder: [cpp, csharp, java, javascript, python, ql, ruby, swift, go]
### Run the analysis ### needs:
- package
steps:
- name: Download pack - name: Download pack
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
with: with:
@@ -143,11 +165,14 @@ jobs:
env: env:
PACK: ${{ runner.temp }}/pack PACK: ${{ runner.temp }}/pack
- name: Checkout repository
uses: actions/checkout@v3
- name: Create CodeQL config file - name: Create CodeQL config file
run: | run: |
echo "paths:" > ${CONF}
echo " - ${FOLDER}" >> ${CONF}
echo "paths-ignore:" >> ${CONF} echo "paths-ignore:" >> ${CONF}
echo " - ql/ql/test" >> ${CONF} echo " - ql/ql/test" >> ${CONF}
echo " - \"*/ql/lib/upgrades/\"" >> ${CONF}
echo "disable-default-queries: true" >> ${CONF} echo "disable-default-queries: true" >> ${CONF}
echo "packs:" >> ${CONF} echo "packs:" >> ${CONF}
echo " - codeql/ql" >> ${CONF} echo " - codeql/ql" >> ${CONF}
@@ -155,34 +180,24 @@ jobs:
cat ${CONF} cat ${CONF}
env: env:
CONF: ./ql-for-ql-config.yml CONF: ./ql-for-ql-config.yml
FOLDER: ${{ matrix.folder }}
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
with: with:
languages: ql languages: ql
db-location: ${{ runner.temp }}/db db-location: ${{ runner.temp }}/db
config-file: ./ql-for-ql-config.yml config-file: ./ql-for-ql-config.yml
tools: latest
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980 uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980
with: with:
category: "ql-for-ql" category: "ql-for-ql-${{ matrix.folder }}"
- name: Copy sarif file to CWD - name: Copy sarif file to CWD
run: cp ../results/ql.sarif ./ql-for-ql.sarif run: cp ../results/ql.sarif ./${{ matrix.folder }}.sarif
- name: Fixup the $scema in sarif # Until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part in a stable release
run: |
sed -i 's/\$schema.*/\$schema": "https:\/\/raw.githubusercontent.com\/oasis-tcs\/sarif-spec\/master\/Schemata\/sarif-schema-2.1.0",/' ql-for-ql.sarif
- name: Sarif as artifact - name: Sarif as artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: ql-for-ql.sarif name: ${{ matrix.folder }}.sarif
path: ql-for-ql.sarif path: ${{ matrix.folder }}.sarif
- name: Split out the sarif file into langs
run: |
mkdir split-sarif
node ./ql/scripts/split-sarif.js ql-for-ql.sarif split-sarif
- name: Upload langs as artifacts
uses: actions/upload-artifact@v3
with:
name: ql-for-ql-langs
path: split-sarif
retention-days: 1

View File

@@ -36,7 +36,7 @@ jobs:
ql/target ql/target
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }} key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
- name: Build Extractor - name: Build Extractor
run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./scripts/create-extractor-pack.sh run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./create-extractor-pack.sh
env: env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }} CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Checkout ${{ matrix.repo }} - name: Checkout ${{ matrix.repo }}

View File

@@ -36,7 +36,7 @@ jobs:
run: | run: |
cd ql; cd ql;
codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }}); codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }});
env "PATH=$PATH:$codeqlpath" ./scripts/create-extractor-pack.sh env "PATH=$PATH:$codeqlpath" ./create-extractor-pack.sh
- name: Run QL tests - name: Run QL tests
run: | run: |
"${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test "${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test

View File

@@ -10,7 +10,6 @@ on:
pull_request: pull_request:
paths: paths:
- '.github/workflows/query-list.yml' - '.github/workflows/query-list.yml'
- '.github/actions/fetch-codeql/action.yml'
- 'misc/scripts/generate-code-scanning-query-list.py' - 'misc/scripts/generate-code-scanning-query-list.py'
jobs: jobs:
@@ -24,12 +23,14 @@ jobs:
with: with:
path: codeql path: codeql
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v4 uses: actions/setup-python@v3
with: with:
python-version: 3.8 python-version: 3.8
- name: Download CodeQL CLI - name: Download CodeQL CLI
# Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo # Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo
uses: ./codeql/.github/actions/fetch-codeql uses: ./codeql/.github/actions/fetch-codeql
- name: Unzip CodeQL CLI
run: unzip -d codeql-cli codeql-linux64.zip
- name: Build code scanning query list - name: Build code scanning query list
run: | run: |
python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv

View File

@@ -5,7 +5,6 @@ on:
paths: paths:
- "ruby/**" - "ruby/**"
- .github/workflows/ruby-build.yml - .github/workflows/ruby-build.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml - codeql-workspace.yml
branches: branches:
- main - main
@@ -14,7 +13,6 @@ on:
paths: paths:
- "ruby/**" - "ruby/**"
- .github/workflows/ruby-build.yml - .github/workflows/ruby-build.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml - codeql-workspace.yml
branches: branches:
- main - main
@@ -92,14 +90,19 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Fetch CodeQL - name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql run: |
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1)
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST"
unzip -q codeql-linux64.zip
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Build Query Pack - name: Build Query Pack
run: | run: |
codeql pack create ql/lib --output target/packs codeql/codeql pack create ql/lib --output target/packs
codeql pack install ql/src codeql/codeql pack install ql/src
codeql pack create ql/src --output target/packs codeql/codeql pack create ql/src --output target/packs
PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*) PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src codeql/codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
(cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;) (cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;)
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v3
with: with:
@@ -176,15 +179,19 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
needs: [package] needs: [package]
steps: steps:
- uses: actions/checkout@v3
- name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
repository: Shopify/example-ruby-app repository: Shopify/example-ruby-app
ref: 67a0decc5eb550f3a9228eda53925c3afd40dfe9 ref: 67a0decc5eb550f3a9228eda53925c3afd40dfe9
- name: Fetch CodeQL
shell: bash
run: |
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1)
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql.zip "$LATEST"
unzip -q codeql.zip
env:
GITHUB_TOKEN: ${{ github.token }}
working-directory: ${{ runner.temp }}
- name: Download Ruby bundle - name: Download Ruby bundle
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
with: with:
@@ -208,12 +215,12 @@ jobs:
- name: Run QL test - name: Run QL test
shell: bash shell: bash
run: | run: |
codeql test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" . "${{ runner.temp }}/codeql/codeql" test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" .
- name: Create database - name: Create database
shell: bash shell: bash
run: | run: |
codeql database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root . ../database "${{ runner.temp }}/codeql/codeql" database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root . ../database
- name: Analyze database - name: Analyze database
shell: bash shell: bash
run: | run: |
codeql database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls "${{ runner.temp }}/codeql/codeql" database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls

View File

@@ -5,7 +5,6 @@ on:
paths: paths:
- "ruby/**" - "ruby/**"
- .github/workflows/ruby-qltest.yml - .github/workflows/ruby-qltest.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml - codeql-workspace.yml
branches: branches:
- main - main
@@ -14,7 +13,6 @@ on:
paths: paths:
- "ruby/**" - "ruby/**"
- .github/workflows/ruby-qltest.yml - .github/workflows/ruby-qltest.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml - codeql-workspace.yml
branches: branches:
- main - main

View File

@@ -5,7 +5,6 @@ on:
paths: paths:
- "swift/**" - "swift/**"
- .github/workflows/swift-codegen.yml - .github/workflows/swift-codegen.yml
- .github/actions/fetch-codeql/action.yml
branches: branches:
- main - main
@@ -16,22 +15,18 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- uses: bazelbuild/setup-bazelisk@v2 - uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v3
- uses: pre-commit/action@v3.0.0
name: Check that python code is properly formatted
with:
extra_args: autopep8 --all-files
- name: Run unit tests - name: Run unit tests
run: | run: |
bazel test //swift/codegen/test --test_output=errors bazel test //swift/codegen/test --test_output=errors
- uses: pre-commit/action@v3.0.0 - name: Check that QL generated code was checked in
name: Check that QL generated code was checked in run: |
with: bazel run //swift/codegen
extra_args: swift-codegen --all-files git add swift
git diff --exit-code --stat HEAD
- name: Generate C++ files - name: Generate C++ files
run: | run: |
bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/swift-generated-cpp-files bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/swift-generated-headers
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v3
with: with:
name: swift-generated-cpp-files name: swift-generated-headers
path: swift-generated-cpp-files/** path: swift-generated-headers/*.h

View File

@@ -1,35 +0,0 @@
name: "Swift: Run Integration Tests"
on:
pull_request:
paths:
- "swift/**"
- .github/workflows/swift-integration-tests.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
branches:
- main
defaults:
run:
working-directory: swift
jobs:
integration-tests:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-20.04
# - macos-latest TODO
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v3
- name: Build Swift extractor
run: |
bazel run //swift:create-extractor-pack
- name: Run integration tests
run: |
python integration-tests/runner.py

View File

@@ -5,7 +5,6 @@ on:
paths: paths:
- "swift/**" - "swift/**"
- .github/workflows/swift-qltest.yml - .github/workflows/swift-qltest.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml - codeql-workspace.yml
branches: branches:
- main - main

View File

@@ -5,7 +5,6 @@ on:
paths: paths:
- "*/ql/*/change-notes/**/*" - "*/ql/*/change-notes/**/*"
- ".github/workflows/validate-change-notes.yml" - ".github/workflows/validate-change-notes.yml"
- ".github/actions/fetch-codeql/action.yml"
branches: branches:
- main - main
- "rc/*" - "rc/*"
@@ -13,7 +12,6 @@ on:
paths: paths:
- "*/ql/*/change-notes/**/*" - "*/ql/*/change-notes/**/*"
- ".github/workflows/validate-change-notes.yml" - ".github/workflows/validate-change-notes.yml"
- ".github/actions/fetch-codeql/action.yml"
jobs: jobs:
check-change-note: check-change-note:

3
.gitignore vendored
View File

@@ -58,6 +58,3 @@ go/main
# node_modules folders except in the JS test suite # node_modules folders except in the JS test suite
node_modules/ node_modules/
!/javascript/ql/test/**/node_modules/ !/javascript/ql/test/**/node_modules/
# Temporary folders for working with generated models
.model-temp

View File

@@ -15,12 +15,6 @@ repos:
- id: clang-format - id: clang-format
files: ^swift/.*\.(h|c|cpp)$ files: ^swift/.*\.(h|c|cpp)$
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v1.6.0
hooks:
- id: autopep8
files: ^swift/codegen/.*\.py
- repo: local - repo: local
hooks: hooks:
- id: codeql-format - id: codeql-format
@@ -46,7 +40,7 @@ repos:
name: Run Swift checked in code generation name: Run Swift checked in code generation
files: ^swift/(codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)) files: ^swift/(codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements))
language: system language: system
entry: bazel run //swift/codegen -- --quiet entry: bazel run //swift/codegen
pass_filenames: false pass_filenames: false
- id: swift-codegen-unit-tests - id: swift-codegen-unit-tests

View File

@@ -42,4 +42,3 @@ WORKSPACE.bazel @github/codeql-ci-reviewers
/.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers /.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers /.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
/.github/workflows/ruby-* @github/codeql-ruby /.github/workflows/ruby-* @github/codeql-ruby
/.github/workflows/swift-* @github/codeql-c

View File

@@ -75,8 +75,7 @@
"DataFlow Java/C# Flow Summaries": [ "DataFlow Java/C# Flow Summaries": [
"java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll", "java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll", "ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll"
"swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll"
], ],
"SsaReadPosition Java/C#": [ "SsaReadPosition Java/C#": [
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll", "java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
@@ -392,8 +391,7 @@
"python/ql/test/TestUtilities/InlineExpectationsTest.qll", "python/ql/test/TestUtilities/InlineExpectationsTest.qll",
"ruby/ql/test/TestUtilities/InlineExpectationsTest.qll", "ruby/ql/test/TestUtilities/InlineExpectationsTest.qll",
"ql/ql/test/TestUtilities/InlineExpectationsTest.qll", "ql/ql/test/TestUtilities/InlineExpectationsTest.qll",
"go/ql/test/TestUtilities/InlineExpectationsTest.qll", "go/ql/test/TestUtilities/InlineExpectationsTest.qll"
"swift/ql/test/TestUtilities/InlineExpectationsTest.qll"
], ],
"C++ ExternalAPIs": [ "C++ ExternalAPIs": [
"cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll", "cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll",
@@ -454,11 +452,11 @@
"python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp" "python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp"
], ],
"IDE Contextual Queries": [ "IDE Contextual Queries": [
"cpp/ql/lib/IDEContextual.qll", "cpp/ql/src/IDEContextual.qll",
"csharp/ql/lib/IDEContextual.qll", "csharp/ql/src/IDEContextual.qll",
"java/ql/lib/IDEContextual.qll", "java/ql/src/IDEContextual.qll",
"javascript/ql/lib/IDEContextual.qll", "javascript/ql/src/IDEContextual.qll",
"python/ql/lib/analysis/IDEContextual.qll" "python/ql/src/analysis/IDEContextual.qll"
], ],
"SSA C#": [ "SSA C#": [
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
@@ -529,8 +527,7 @@
"java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll", "java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll",
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll", "javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll", "ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll",
"python/ql/lib/semmle/python/frameworks/data/internal/AccessPathSyntax.qll", "python/ql/lib/semmle/python/frameworks/data/internal/AccessPathSyntax.qll"
"swift/ql/lib/codeql/swift/dataflow/internal/AccessPathSyntax.qll"
], ],
"IncompleteUrlSubstringSanitization": [ "IncompleteUrlSubstringSanitization": [
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll", "javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",

View File

@@ -1,17 +0,0 @@
class Expr extends @expr {
string toString() { none() }
}
class Location extends @location_expr {
string toString() { none() }
}
predicate isExprWithNewBuiltin(Expr expr) {
exists(int kind | exprs(expr, kind, _) | 330 <= kind and kind <= 334)
}
from Expr expr, int kind, int kind_new, Location location
where
exprs(expr, kind, location) and
if isExprWithNewBuiltin(expr) then kind_new = 0 else kind_new = kind
select expr, kind_new, location

View File

@@ -1,3 +0,0 @@
description: Add new builtin operations
compatibility: partial
exprs.rel: run exprs.qlo

View File

@@ -1,17 +0,0 @@
class AttributeArgument extends @attribute_arg {
string toString() { none() }
}
class Attribute extends @attribute {
string toString() { none() }
}
class LocationDefault extends @location_default {
string toString() { none() }
}
from AttributeArgument arg, int kind, Attribute attr, int index, LocationDefault location
where
attribute_args(arg, kind, attr, index, location) and
not arg instanceof @attribute_arg_constant_expr
select arg, kind, attr, index, location

View File

@@ -1,4 +0,0 @@
description: Support all constant attribute arguments
compatibility: backwards
attribute_arg_constant.rel: delete
attribute_args.rel: run attribute_args.qlo

View File

@@ -1,43 +1,3 @@
## 0.3.3
### New Features
* Added a predicate `getValueConstant` to `AttributeArgument` that yields the argument value as an `Expr` when the value is a constant expression.
* A new class predicate `MustFlowConfiguration::allowInterproceduralFlow` has been added to the `semmle.code.cpp.ir.dataflow.MustFlow` library. The new predicate can be overridden to disable interprocedural flow.
* Added subclasses of `BuiltInOperations` for `__builtin_bit_cast`, `__builtin_shuffle`, `__has_unique_object_representations`, `__is_aggregate`, and `__is_assignable`.
### Major Analysis Improvements
* The IR dataflow library now includes flow through global variables. This enables new findings in many scenarios.
## 0.3.2
### Bug Fixes
* Under certain circumstances a variable declaration that is not also a definition could be associated with a `Variable` that did not have the definition as a `VariableDeclarationEntry`. This is now fixed, and a unique `Variable` will exist that has both the declaration and the definition as a `VariableDeclarationEntry`.
## 0.3.1
### Minor Analysis Improvements
* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions.
## 0.3.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
### Bug Fixes
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.
## 0.2.3
### New Features
* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization.
## 0.2.2 ## 0.2.2
### Deprecated APIs ### Deprecated APIs

View File

@@ -1,5 +1,4 @@
## 0.2.3 ---
category: feature
### New Features ---
* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization. * An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization.

View File

@@ -1,9 +0,0 @@
## 0.3.0
### Deprecated APIs
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
### Bug Fixes
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.

View File

@@ -1,5 +0,0 @@
## 0.3.1
### Minor Analysis Improvements
* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions.

View File

@@ -1,5 +0,0 @@
## 0.3.2
### Bug Fixes
* Under certain circumstances a variable declaration that is not also a definition could be associated with a `Variable` that did not have the definition as a `VariableDeclarationEntry`. This is now fixed, and a unique `Variable` will exist that has both the declaration and the definition as a `VariableDeclarationEntry`.

View File

@@ -1,11 +0,0 @@
## 0.3.3
### New Features
* Added a predicate `getValueConstant` to `AttributeArgument` that yields the argument value as an `Expr` when the value is a constant expression.
* A new class predicate `MustFlowConfiguration::allowInterproceduralFlow` has been added to the `semmle.code.cpp.ir.dataflow.MustFlow` library. The new predicate can be overridden to disable interprocedural flow.
* Added subclasses of `BuiltInOperations` for `__builtin_bit_cast`, `__builtin_shuffle`, `__has_unique_object_representations`, `__is_aggregate`, and `__is_assignable`.
### Major Analysis Improvements
* The IR dataflow library now includes flow through global variables. This enables new findings in many scenarios.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.3.3 lastReleaseVersion: 0.2.2

View File

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

View File

@@ -6,7 +6,6 @@
import semmle.code.cpp.Location import semmle.code.cpp.Location
private import semmle.code.cpp.Enclosing private import semmle.code.cpp.Enclosing
private import semmle.code.cpp.internal.ResolveClass private import semmle.code.cpp.internal.ResolveClass
private import semmle.code.cpp.internal.ResolveGlobalVariable
/** /**
* Get the `Element` that represents this `@element`. * Get the `Element` that represents this `@element`.
@@ -29,12 +28,9 @@ Element mkElement(@element e) { unresolveElement(result) = e }
pragma[inline] pragma[inline]
@element unresolveElement(Element e) { @element unresolveElement(Element e) {
not result instanceof @usertype and not result instanceof @usertype and
not result instanceof @variable and
result = e result = e
or or
e = resolveClass(result) e = resolveClass(result)
or
e = resolveGlobalVariable(result)
} }
/** /**

View File

@@ -12,7 +12,7 @@ private import semmle.code.cpp.internal.ResolveClass
class Specifier extends Element, @specifier { class Specifier extends Element, @specifier {
/** Gets a dummy location for the specifier. */ /** Gets a dummy location for the specifier. */
override Location getLocation() { override Location getLocation() {
exists(this) and suppressUnusedThis(this) and
result instanceof UnknownDefaultLocation result instanceof UnknownDefaultLocation
} }
@@ -256,13 +256,9 @@ class AttributeArgument extends Element, @attribute_arg {
/** /**
* Gets the text for the value of this argument, if its value is * Gets the text for the value of this argument, if its value is
* a constant or token. * a string or a number.
*/ */
string getValueText() { string getValueText() { attribute_arg_value(underlyingElement(this), result) }
if underlyingElement(this) instanceof @attribute_arg_constant_expr
then result = this.getValueConstant().getValue()
else attribute_arg_value(underlyingElement(this), result)
}
/** /**
* Gets the value of this argument, if its value is integral. * Gets the value of this argument, if its value is integral.
@@ -274,13 +270,6 @@ class AttributeArgument extends Element, @attribute_arg {
*/ */
Type getValueType() { attribute_arg_type(underlyingElement(this), unresolveElement(result)) } Type getValueType() { attribute_arg_type(underlyingElement(this), unresolveElement(result)) }
/**
* Gets the value of this argument, if its value is a constant.
*/
Expr getValueConstant() {
attribute_arg_constant(underlyingElement(this), unresolveElement(result))
}
/** /**
* Gets the attribute to which this is an argument. * Gets the attribute to which this is an argument.
*/ */
@@ -305,12 +294,11 @@ class AttributeArgument extends Element, @attribute_arg {
( (
if underlyingElement(this) instanceof @attribute_arg_type if underlyingElement(this) instanceof @attribute_arg_type
then tail = this.getValueType().getName() then tail = this.getValueType().getName()
else else tail = this.getValueText()
if underlyingElement(this) instanceof @attribute_arg_constant_expr
then tail = this.getValueConstant().toString()
else tail = this.getValueText()
) and ) and
result = prefix + tail result = prefix + tail
) )
} }
} }
private predicate suppressUnusedThis(Specifier s) { any() }

View File

@@ -48,8 +48,8 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
} }
override TypeDeclarationEntry getADeclarationEntry() { override TypeDeclarationEntry getADeclarationEntry() {
if type_decls(_, unresolveElement(this), _) if type_decls(_, underlyingElement(this), _)
then type_decls(underlyingElement(result), unresolveElement(this), _) then type_decls(unresolveElement(result), underlyingElement(this), _)
else exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry()) else exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry())
} }

View File

@@ -6,7 +6,6 @@ import semmle.code.cpp.Element
import semmle.code.cpp.exprs.Access import semmle.code.cpp.exprs.Access
import semmle.code.cpp.Initializer import semmle.code.cpp.Initializer
private import semmle.code.cpp.internal.ResolveClass private import semmle.code.cpp.internal.ResolveClass
private import semmle.code.cpp.internal.ResolveGlobalVariable
/** /**
* A C/C++ variable. For example, in the following code there are four * A C/C++ variable. For example, in the following code there are four
@@ -33,8 +32,6 @@ private import semmle.code.cpp.internal.ResolveGlobalVariable
* can have multiple declarations. * can have multiple declarations.
*/ */
class Variable extends Declaration, @variable { class Variable extends Declaration, @variable {
Variable() { isVariable(underlyingElement(this)) }
override string getAPrimaryQlClass() { result = "Variable" } override string getAPrimaryQlClass() { result = "Variable" }
/** Gets the initializer of this variable, if any. */ /** Gets the initializer of this variable, if any. */

View File

@@ -168,7 +168,7 @@ private predicate callsVariadicFormatter(
) { ) {
// calls a variadic formatter with `formatParamIndex`, `outputParamIndex` linked // calls a variadic formatter with `formatParamIndex`, `outputParamIndex` linked
exists(FunctionCall fc, int format, int output | exists(FunctionCall fc, int format, int output |
variadicFormatter(pragma[only_bind_into](fc.getTarget()), type, format, output) and variadicFormatter(fc.getTarget(), type, format, output) and
fc.getEnclosingFunction() = f and fc.getEnclosingFunction() = f and
fc.getArgument(format) = f.getParameter(formatParamIndex).getAnAccess() and fc.getArgument(format) = f.getParameter(formatParamIndex).getAnAccess() and
fc.getArgument(output) = f.getParameter(outputParamIndex).getAnAccess() fc.getArgument(output) = f.getParameter(outputParamIndex).getAnAccess()
@@ -176,7 +176,7 @@ private predicate callsVariadicFormatter(
or or
// calls a variadic formatter with only `formatParamIndex` linked // calls a variadic formatter with only `formatParamIndex` linked
exists(FunctionCall fc, string calledType, int format, int output | exists(FunctionCall fc, string calledType, int format, int output |
variadicFormatter(pragma[only_bind_into](fc.getTarget()), calledType, format, output) and variadicFormatter(fc.getTarget(), calledType, format, output) and
fc.getEnclosingFunction() = f and fc.getEnclosingFunction() = f and
fc.getArgument(format) = f.getParameter(formatParamIndex).getAnAccess() and fc.getArgument(format) = f.getParameter(formatParamIndex).getAnAccess() and
not fc.getArgument(output) = f.getParameter(_).getAnAccess() and not fc.getArgument(output) = f.getParameter(_).getAnAccess() and

View File

@@ -46,7 +46,7 @@ predicate nullCheckExpr(Expr checkExpr, Variable var) {
or or
exists(LogicalAndExpr op, AnalysedExpr child | exists(LogicalAndExpr op, AnalysedExpr child |
expr = op and expr = op and
op.getAnOperand() = child and op.getRightOperand() = child and
nullCheckExpr(child, v) nullCheckExpr(child, v)
) )
or or
@@ -99,7 +99,7 @@ predicate validCheckExpr(Expr checkExpr, Variable var) {
or or
exists(LogicalAndExpr op, AnalysedExpr child | exists(LogicalAndExpr op, AnalysedExpr child |
expr = op and expr = op and
op.getAnOperand() = child and op.getRightOperand() = child and
validCheckExpr(child, v) validCheckExpr(child, v)
) )
or or
@@ -169,10 +169,7 @@ class AnalysedExpr extends Expr {
*/ */
predicate isDef(LocalScopeVariable v) { predicate isDef(LocalScopeVariable v) {
this.inCondition() and this.inCondition() and
( this.(Assignment).getLValue() = v.getAnAccess()
this.(Assignment).getLValue() = v.getAnAccess() or
this.(ConditionDeclExpr).getVariableAccess() = v.getAnAccess()
)
} }
/** /**

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -699,7 +699,7 @@ private predicate exprToExprStep_nocfg(Expr fromExpr, Expr toExpr) {
call.getTarget() = f and call.getTarget() = f and
// AST dataflow treats a reference as if it were the referred-to object, while the dataflow // AST dataflow treats a reference as if it were the referred-to object, while the dataflow
// models treat references as pointers. If the return type of the call is a reference, then // models treat references as pointers. If the return type of the call is a reference, then
// look for data flow to the referred-to object, rather than the reference itself. // look for data flow the the referred-to object, rather than the reference itself.
if call.getType().getUnspecifiedType() instanceof ReferenceType if call.getType().getUnspecifiedType() instanceof ReferenceType
then outModel.isReturnValueDeref() then outModel.isReturnValueDeref()
else outModel.isReturnValue() else outModel.isReturnValue()
@@ -850,34 +850,6 @@ class ContentSet instanceof Content {
} }
/** /**
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
*
* The expression `e` is expected to be a syntactic part of the guard `g`.
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
* the argument `x`.
*/
signature predicate guardChecksSig(GuardCondition g, Expr e, boolean branch);
/**
* Provides a set of barrier nodes for a guard that validates an expression.
*
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
* in data flow and taint tracking.
*/
module BarrierGuard<guardChecksSig/3 guardChecks> {
/** Gets a node that is safely guarded by the given guard check. */
ExprNode getABarrierNode() {
exists(GuardCondition g, SsaDefinition def, Variable v, boolean branch |
result.getExpr() = def.getAUse(v) and
guardChecks(g, def.getAUse(v), branch) and
g.controls(result.getExpr().getBasicBlock(), branch)
)
}
}
/**
* DEPRECATED: Use `BarrierGuard` module instead.
*
* A guard that validates some expression. * A guard that validates some expression.
* *
* To use this in a configuration, extend the class and provide a * To use this in a configuration, extend the class and provide a
@@ -886,7 +858,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
* *
* It is important that all extending classes in scope are disjoint. * It is important that all extending classes in scope are disjoint.
*/ */
deprecated class BarrierGuard extends GuardCondition { class BarrierGuard extends GuardCondition {
/** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */ /** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */
abstract predicate checks(Expr e, boolean b); abstract predicate checks(Expr e, boolean b);

View File

@@ -47,6 +47,12 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { n
*/ */
predicate defaultTaintSanitizer(DataFlow::Node node) { none() } predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
/**
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
* but not in local taint.
*/
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
/** /**
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding * Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent * local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent

View File

@@ -116,30 +116,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead. predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard) this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
} }
/** /**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited * Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`. * when the flow state is `state`.
*/ */
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
none()
}
deprecated final override predicate isBarrierGuard( final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state) this.isSanitizerGuard(guard, state)
} }

View File

@@ -116,30 +116,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead. predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard) this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
} }
/** /**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited * Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`. * when the flow state is `state`.
*/ */
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
none()
}
deprecated final override predicate isBarrierGuard( final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state) this.isSanitizerGuard(guard, state)
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Provides classes for modeling built-in operations. Built-in operations are * Provides classes for modeling built-in operations. Built-in operations are
* typically compiler specific and are used by libraries and generated code. * typically compiler specific and are used by libraries and generated code.
*/ */
@@ -120,8 +120,8 @@ class BuiltInNoOp extends BuiltInOperation, @noopexpr {
/** /**
* A C/C++ `__builtin_offsetof` built-in operation (used by some implementations * A C/C++ `__builtin_offsetof` built-in operation (used by some implementations
* of `offsetof`). The operation retains its semantics even in the presence * of `offsetof`). The operation retains its semantics even in the presence
* of an overloaded `operator &`). This is a gcc/clang extension. * of an overloaded `operator &`). This is a GNU/Clang extension.
* ``` * ```
* struct S { * struct S {
* int a, b; * int a, b;
@@ -137,8 +137,8 @@ class BuiltInOperationBuiltInOffsetOf extends BuiltInOperation, @offsetofexpr {
/** /**
* A C/C++ `__INTADDR__` built-in operation (used by some implementations * A C/C++ `__INTADDR__` built-in operation (used by some implementations
* of `offsetof`). The operation retains its semantics even in the presence * of `offsetof`). The operation retains its semantics even in the presence
* of an overloaded `operator &`). This is an EDG extension. * of an overloaded `operator &`). This is an EDG extension.
* ``` * ```
* struct S { * struct S {
* int a, b; * int a, b;
@@ -173,7 +173,7 @@ class BuiltInOperationHasAssign extends BuiltInOperation, @hasassignexpr {
* *
* Returns `true` if the type has a copy constructor. * Returns `true` if the type has a copy constructor.
* ``` * ```
* std::integral_constant<bool, __has_copy(_Tp)> hc; * std::integral_constant< bool, __has_copy(_Tp)> hc;
* ``` * ```
*/ */
class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr { class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr {
@@ -189,7 +189,7 @@ class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr {
* Returns `true` if a copy assignment operator has an empty exception * Returns `true` if a copy assignment operator has an empty exception
* specification. * specification.
* ``` * ```
* std::integral_constant<bool, __has_nothrow_assign(_Tp)> hnta; * std::integral_constant< bool, __has_nothrow_assign(_Tp)> hnta;
* ``` * ```
*/ */
class BuiltInOperationHasNoThrowAssign extends BuiltInOperation, @hasnothrowassign { class BuiltInOperationHasNoThrowAssign extends BuiltInOperation, @hasnothrowassign {
@@ -220,7 +220,7 @@ class BuiltInOperationHasNoThrowConstructor extends BuiltInOperation, @hasnothro
* *
* Returns `true` if the copy constructor has an empty exception specification. * Returns `true` if the copy constructor has an empty exception specification.
* ``` * ```
* std::integral_constant<bool, __has_nothrow_copy(MyType) >; * std::integral_constant< bool, __has_nothrow_copy(MyType) >;
* ``` * ```
*/ */
class BuiltInOperationHasNoThrowCopy extends BuiltInOperation, @hasnothrowcopy { class BuiltInOperationHasNoThrowCopy extends BuiltInOperation, @hasnothrowcopy {
@@ -266,7 +266,7 @@ class BuiltInOperationHasTrivialConstructor extends BuiltInOperation, @hastrivia
* *
* Returns true if the type has a trivial copy constructor. * Returns true if the type has a trivial copy constructor.
* ``` * ```
* std::integral_constant<bool, __has_trivial_copy(MyType)> htc; * std::integral_constant< bool, __has_trivial_copy(MyType) > htc;
* ``` * ```
*/ */
class BuiltInOperationHasTrivialCopy extends BuiltInOperation, @hastrivialcopy { class BuiltInOperationHasTrivialCopy extends BuiltInOperation, @hastrivialcopy {
@@ -468,7 +468,7 @@ class BuiltInOperationIsUnion extends BuiltInOperation, @isunionexpr {
* ``` * ```
* template<typename _Tp1, typename _Tp2> * template<typename _Tp1, typename _Tp2>
* struct types_compatible * struct types_compatible
* : public integral_constant<bool, __builtin_types_compatible_p(_Tp1, _Tp2)> * : public integral_constant<bool, __builtin_types_compatible_p(_Tp1, _Tp2) >
* { }; * { };
* ``` * ```
*/ */
@@ -479,7 +479,8 @@ class BuiltInOperationBuiltInTypesCompatibleP extends BuiltInOperation, @typesco
/** /**
* A clang `__builtin_shufflevector` expression. * A clang `__builtin_shufflevector` expression.
* *
* It outputs a permutation of elements from one or two input vectors. See * It outputs a permutation of elements from one or two input vectors.
* Please see
* https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#langext-builtin-shufflevector * https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#langext-builtin-shufflevector
* for more information. * for more information.
* ``` * ```
@@ -493,29 +494,11 @@ class BuiltInOperationBuiltInShuffleVector extends BuiltInOperation, @builtinshu
override string getAPrimaryQlClass() { result = "BuiltInOperationBuiltInShuffleVector" } override string getAPrimaryQlClass() { result = "BuiltInOperationBuiltInShuffleVector" }
} }
/**
* A gcc `__builtin_shuffle` expression.
*
* It outputs a permutation of elements from one or two input vectors.
* See https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
* for more information.
* ```
* // Concatenate every other element of 4-element vectors V1 and V2.
* M = {0, 2, 4, 6};
* V3 = __builtin_shuffle(V1, V2, M);
* ```
*/
class BuiltInOperationBuiltInShuffle extends BuiltInOperation, @builtinshuffle {
override string toString() { result = "__builtin_shuffle" }
override string getAPrimaryQlClass() { result = "BuiltInOperationBuiltInShuffle" }
}
/** /**
* A clang `__builtin_convertvector` expression. * A clang `__builtin_convertvector` expression.
* *
* Allows for conversion of vectors of equal element count and compatible * Allows for conversion of vectors of equal element count and compatible
* element types. See * element types. Please see
* https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#builtin-convertvector * https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#builtin-convertvector
* for more information. * for more information.
* ``` * ```
@@ -564,7 +547,7 @@ class BuiltInOperationBuiltInAddressOf extends UnaryOperation, BuiltInOperation,
* ``` * ```
* template<typename T, typename... Args> * template<typename T, typename... Args>
* struct is_trivially_constructible * struct is_trivially_constructible
* : public integral_constant<bool, __is_trivially_constructible(T, Args...)> * : public integral_constant<bool, __is_trivially_constructible(T, Args...) >
* { }; * { };
* ``` * ```
*/ */
@@ -629,10 +612,13 @@ class BuiltInOperationIsTriviallyDestructible extends BuiltInOperation, @istrivi
* The `__is_trivially_assignable` built-in operation (used by some * The `__is_trivially_assignable` built-in operation (used by some
* implementations of the `<type_traits>` header). * implementations of the `<type_traits>` header).
* *
* Returns `true` if the assignment operator `C::operator =(const D& d)` is * Returns `true` if the assignment operator `C::operator =(const C& c)` is
* trivial (i.e., it will not call any operation that is non-trivial). * trivial.
* ``` * ```
* bool v = __is_trivially_assignable(MyType1, MyType2); * template<typename T>
* struct is_trivially_assignable
* : public integral_constant<bool, __is_trivially_assignable(T) >
* { };
* ``` * ```
*/ */
class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istriviallyassignableexpr { class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istriviallyassignableexpr {
@@ -645,10 +631,10 @@ class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istrivial
* The `__is_nothrow_assignable` built-in operation (used by some * The `__is_nothrow_assignable` built-in operation (used by some
* implementations of the `<type_traits>` header). * implementations of the `<type_traits>` header).
* *
* Returns true if there exists a `C::operator =(const D& d) nothrow` * Returns true if there exists a `C::operator =(const C& c) nothrow`
* assignment operator (i.e, with an empty exception specification). * assignment operator (i.e, with an empty exception specification).
* ``` * ```
* bool v = __is_nothrow_assignable(MyType1, MyType2); * bool v = __is_nothrow_assignable(MyType);
* ``` * ```
*/ */
class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowassignableexpr { class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowassignableexpr {
@@ -657,30 +643,15 @@ class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowas
override string getAPrimaryQlClass() { result = "BuiltInOperationIsNothrowAssignable" } override string getAPrimaryQlClass() { result = "BuiltInOperationIsNothrowAssignable" }
} }
/**
* The `__is_assignable` built-in operation (used by some implementations
* of the `<type_traits>` header).
*
* Returns true if there exists a `C::operator =(const D& d)` assignment
* operator.
* ```
* bool v = __is_assignable(MyType1, MyType2);
* ```
*/
class BuiltInOperationIsAssignable extends BuiltInOperation, @isassignable {
override string toString() { result = "__is_assignable" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsAssignable" }
}
/** /**
* The `__is_standard_layout` built-in operation (used by some implementations * The `__is_standard_layout` built-in operation (used by some implementations
* of the `<type_traits>` header). * of the `<type_traits>` header).
* *
* Returns `true` if the type is a primitive type, or a `class`, `struct` or * Returns `true` if the type is a primitive type, or a `class`, `struct` or
* `union` without (1) virtual functions or base classes, (2) reference member * `union` WITHOUT (1) virtual functions or base classes, (2) reference member
* variable, or (3) multiple occurrences of base `class` objects, among other * variable or (3) multiple occurrences of base `class` objects, among other
* restrictions. See https://en.cppreference.com/w/cpp/named_req/StandardLayoutType * restrictions. Please see
* https://en.cppreference.com/w/cpp/named_req/StandardLayoutType
* for more information. * for more information.
* ``` * ```
* bool v = __is_standard_layout(MyType); * bool v = __is_standard_layout(MyType);
@@ -697,7 +668,7 @@ class BuiltInOperationIsStandardLayout extends BuiltInOperation, @isstandardlayo
* implementations of the `<type_traits>` header). * implementations of the `<type_traits>` header).
* *
* Returns `true` if instances of this type can be copied by trivial * Returns `true` if instances of this type can be copied by trivial
* means. The copying is done in a manner similar to the `memcpy` * means. The copying is done in a manner similar to the `memcpy`
* function. * function.
*/ */
class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istriviallycopyableexpr { class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istriviallycopyableexpr {
@@ -711,13 +682,13 @@ class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istrivially
* the `<type_traits>` header). * the `<type_traits>` header).
* *
* Returns `true` if the type is a scalar type, a reference type or an array of * Returns `true` if the type is a scalar type, a reference type or an array of
* literal types, among others. See * literal types, among others. Please see
* https://en.cppreference.com/w/cpp/named_req/LiteralType * https://en.cppreference.com/w/cpp/named_req/LiteralType
* for more information. * for more information.
* *
* ``` * ```
* template <typename _Tp> * template <typename _Tp>
* std::integral_constant<bool, __is_literal_type(_Tp)> ilt; * std::integral_constant< bool, __is_literal_type(_Tp)> ilt;
* ``` * ```
*/ */
class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr { class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr {
@@ -734,7 +705,7 @@ class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr
* compiler, with semantics of the `memcpy` operation. * compiler, with semantics of the `memcpy` operation.
* ``` * ```
* template <typename _Tp> * template <typename _Tp>
* std::integral_constant<bool, __has_trivial_move_constructor(_Tp)> htmc; * std::integral_constant< bool, __has_trivial_move_constructor(_Tp)> htmc;
* ``` * ```
*/ */
class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation, class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation,
@@ -752,7 +723,7 @@ class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation,
* ``` * ```
* template<typename T> * template<typename T>
* struct has_trivial_move_assign * struct has_trivial_move_assign
* : public integral_constant<bool, __has_trivial_move_assign(T)> * : public integral_constant<bool, __has_trivial_move_assign(T) >
* { }; * { };
* ``` * ```
*/ */
@@ -787,7 +758,7 @@ class BuiltInOperationHasNothrowMoveAssign extends BuiltInOperation, @hasnothrow
* ``` * ```
* template<typename T, typename... Args> * template<typename T, typename... Args>
* struct is_constructible * struct is_constructible
* : public integral_constant<bool, __is_constructible(T, Args...)> * : public integral_constant<bool, __is_constructible(T, Args...) >
* { }; * { };
* ``` * ```
*/ */
@@ -814,7 +785,7 @@ class BuiltInOperationIsNothrowConstructible extends BuiltInOperation, @isnothro
} }
/** /**
* The `__has_finalizer` built-in operation. This is a Microsoft extension. * The `__has_finalizer` built-in operation. This is a Microsoft extension.
* *
* Returns `true` if the type defines a _finalizer_ `C::!C(void)`, to be called * Returns `true` if the type defines a _finalizer_ `C::!C(void)`, to be called
* from either the regular destructor or the garbage collector. * from either the regular destructor or the garbage collector.
@@ -829,10 +800,10 @@ class BuiltInOperationHasFinalizer extends BuiltInOperation, @hasfinalizerexpr {
} }
/** /**
* The `__is_delegate` built-in operation. This is a Microsoft extension. * The `__is_delegate` built-in operation. This is a Microsoft extension.
* *
* Returns `true` if the function has been declared as a `delegate`, used in * Returns `true` if the function has been declared as a `delegate`, used in
* message forwarding. See * message forwarding. Please see
* https://docs.microsoft.com/en-us/cpp/extensions/delegate-cpp-component-extensions * https://docs.microsoft.com/en-us/cpp/extensions/delegate-cpp-component-extensions
* for more information. * for more information.
*/ */
@@ -843,9 +814,9 @@ class BuiltInOperationIsDelegate extends BuiltInOperation, @isdelegateexpr {
} }
/** /**
* The `__is_interface_class` built-in operation. This is a Microsoft extension. * The `__is_interface_class` built-in operation. This is a Microsoft extension.
* *
* Returns `true` if the type has been declared as an `interface`. See * Returns `true` if the type has been declared as an `interface`. Please see
* https://docs.microsoft.com/en-us/cpp/extensions/interface-class-cpp-component-extensions * https://docs.microsoft.com/en-us/cpp/extensions/interface-class-cpp-component-extensions
* for more information. * for more information.
*/ */
@@ -856,9 +827,9 @@ class BuiltInOperationIsInterfaceClass extends BuiltInOperation, @isinterfacecla
} }
/** /**
* The `__is_ref_array` built-in operation. This is a Microsoft extension. * The `__is_ref_array` built-in operation. This is a Microsoft extension.
* *
* Returns `true` if the object passed in is a _platform array_. See * Returns `true` if the object passed in is a _platform array_. Please see
* https://docs.microsoft.com/en-us/cpp/extensions/arrays-cpp-component-extensions * https://docs.microsoft.com/en-us/cpp/extensions/arrays-cpp-component-extensions
* for more information. * for more information.
* ``` * ```
@@ -873,9 +844,9 @@ class BuiltInOperationIsRefArray extends BuiltInOperation, @isrefarrayexpr {
} }
/** /**
* The `__is_ref_class` built-in operation. This is a Microsoft extension. * The `__is_ref_class` built-in operation. This is a Microsoft extension.
* *
* Returns `true` if the type is a _reference class_. See * Returns `true` if the type is a _reference class_. Please see
* https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions * https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions
* for more information. * for more information.
* ``` * ```
@@ -890,10 +861,10 @@ class BuiltInOperationIsRefClass extends BuiltInOperation, @isrefclassexpr {
} }
/** /**
* The `__is_sealed` built-in operation. This is a Microsoft extension. * The `__is_sealed` built-in operation. This is a Microsoft extension.
* *
* Returns `true` if a given class or virtual function is marked as `sealed`, * Returns `true` if a given class or virtual function is marked as `sealed`,
* meaning that it cannot be extended or overridden. The `sealed` keyword * meaning that it cannot be extended or overridden. The `sealed` keyword
* is similar to the C++11 `final` keyword. * is similar to the C++11 `final` keyword.
* ``` * ```
* ref class X sealed { * ref class X sealed {
@@ -908,7 +879,7 @@ class BuiltInOperationIsSealed extends BuiltInOperation, @issealedexpr {
} }
/** /**
* The `__is_simple_value_class` built-in operation. This is a Microsoft extension. * The `__is_simple_value_class` built-in operation. This is a Microsoft extension.
* *
* Returns `true` if passed a value type that contains no references to the * Returns `true` if passed a value type that contains no references to the
* garbage-collected heap. * garbage-collected heap.
@@ -927,9 +898,9 @@ class BuiltInOperationIsSimpleValueClass extends BuiltInOperation, @issimplevalu
} }
/** /**
* The `__is_value_class` built-in operation. This is a Microsoft extension. * The `__is_value_class` built-in operation. This is a Microsoft extension.
* *
* Returns `true` if passed a value type. See * Returns `true` if passed a value type. Please see
* https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions * https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions
* For more information. * For more information.
* ``` * ```
@@ -951,7 +922,7 @@ class BuiltInOperationIsValueClass extends BuiltInOperation, @isvalueclassexpr {
* ``` * ```
* template<typename T> * template<typename T>
* struct is_final * struct is_final
* : public integral_constant<bool, __is_final(T)> * : public integral_constant<bool, __is_final(T) >
* { }; * { };
* ``` * ```
*/ */
@@ -962,7 +933,7 @@ class BuiltInOperationIsFinal extends BuiltInOperation, @isfinalexpr {
} }
/** /**
* The `__builtin_choose_expr` expression. This is a gcc/clang extension. * The `__builtin_choose_expr` expression. This is a GNU/Clang extension.
* *
* The expression functions similarly to the ternary `?:` operator, except * The expression functions similarly to the ternary `?:` operator, except
* that it is evaluated at compile-time. * that it is evaluated at compile-time.
@@ -1007,50 +978,3 @@ class BuiltInComplexOperation extends BuiltInOperation, @builtincomplex {
/** Gets the operand corresponding to the imaginary part of the complex number. */ /** Gets the operand corresponding to the imaginary part of the complex number. */
Expr getImaginaryOperand() { this.hasChild(result, 1) } Expr getImaginaryOperand() { this.hasChild(result, 1) }
} }
/**
* A C++ `__is_aggregate` built-in operation (used by some implementations of the
* `<type_traits>` header).
*
* Returns `true` if the type has is an aggregate type.
* ```
* std::integral_constant<bool, __is_aggregate(_Tp)> ia;
* ```
*/
class BuiltInOperationIsAggregate extends BuiltInOperation, @isaggregate {
override string toString() { result = "__is_aggregate" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsAggregate" }
}
/**
* A C++ `__has_unique_object_representations` built-in operation (used by some
* implementations of the `<type_traits>` header).
*
* Returns `true` if the type is trivially copyable and if the object representation
* is unique for two objects with the same value.
* ```
* bool v = __has_unique_object_representations(MyType);
* ```
*/
class BuiltInOperationHasUniqueObjectRepresentations extends BuiltInOperation,
@hasuniqueobjectrepresentations {
override string toString() { result = "__has_unique_object_representations" }
override string getAPrimaryQlClass() { result = "BuiltInOperationHasUniqueObjectRepresentations" }
}
/**
* A C/C++ `__builtin_bit_cast` built-in operation (used by some implementations
* of `std::bit_cast`).
*
* Performs a bit cast from a value to a type.
* ```
* __builtin_bit_cast(Type, value);
* ```
*/
class BuiltInBitCast extends BuiltInOperation, @builtinbitcast {
override string toString() { result = "__builtin_bit_cast" }
override string getAPrimaryQlClass() { result = "BuiltInBitCast" }
}

View File

@@ -255,10 +255,8 @@ class FunctionCall extends Call, @funbindexpr {
/** /**
* Gets the function called by this call. * Gets the function called by this call.
* *
* In the case of virtual function calls, the result is the most-specific function in the override tree * In the case of virtual function calls, the result is the most-specific function in the override tree (as
* such that the target at runtime will be one of `result.getAnOverridingFunction*()`. The most-specific * determined by the compiler) such that the target at runtime will be one of `result.getAnOverridingFunction*()`.
* function is determined by the compiler based on the compile time type of the object the function is a
* member of.
*/ */
override Function getTarget() { funbind(underlyingElement(this), unresolveElement(result)) } override Function getTarget() { funbind(underlyingElement(this), unresolveElement(result)) }

View File

@@ -49,9 +49,6 @@ class Expr extends StmtParent, @expr {
/** Gets the enclosing variable of this expression, if any. */ /** Gets the enclosing variable of this expression, if any. */
Variable getEnclosingVariable() { result = exprEnclosingElement(this) } Variable getEnclosingVariable() { result = exprEnclosingElement(this) }
/** Gets the enclosing variable or function of this expression. */
Declaration getEnclosingDeclaration() { result = exprEnclosingElement(this) }
/** Gets a child of this expression. */ /** Gets a child of this expression. */
Expr getAChild() { exists(int n | result = this.getChild(n)) } Expr getAChild() { exists(int n | result = this.getChild(n)) }
@@ -596,12 +593,9 @@ class ParenthesisExpr extends Conversion, @parexpr {
} }
/** /**
* A C/C++ expression that could not be resolved, or that can no longer be * A C/C++ expression that has not been resolved.
* represented due to a database upgrade or downgrade.
* *
* If the expression could not be resolved, it has type `ErroneousType`. In the * It is assigned `ErroneousType` as its type.
* case of a database upgrade or downgrade, the original type from before the
* upgrade or downgrade is kept if that type can be represented.
*/ */
class ErrorExpr extends Expr, @errorexpr { class ErrorExpr extends Expr, @errorexpr {
override string toString() { result = "<error expr>" } override string toString() { result = "<error expr>" }

View File

@@ -4,7 +4,11 @@
* qualified. * qualified.
* *
* This file contains classes that mirror the standard AST classes for C++, but * This file contains classes that mirror the standard AST classes for C++, but
* these classes are only concerned with naming. * these classes are only concerned with naming. The other difference is that
* these classes don't use the `ResolveClass.qll` mechanisms like
* `unresolveElement` because these classes should eventually be part of the
* implementation of `ResolveClass.qll`, allowing it to match up classes when
* their qualified names and parameters match.
*/ */
private import semmle.code.cpp.Declaration as D private import semmle.code.cpp.Declaration as D

View File

@@ -115,13 +115,15 @@ private module Cached {
*/ */
cached cached
predicate isClass(@usertype t) { predicate isClass(@usertype t) {
usertypes(t, _, 1) or (
usertypes(t, _, 2) or usertypes(t, _, 1) or
usertypes(t, _, 3) or usertypes(t, _, 2) or
usertypes(t, _, 6) or usertypes(t, _, 3) or
usertypes(t, _, 10) or usertypes(t, _, 6) or
usertypes(t, _, 11) or usertypes(t, _, 10) or
usertypes(t, _, 12) usertypes(t, _, 11) or
usertypes(t, _, 12)
)
} }
cached cached

View File

@@ -1,57 +0,0 @@
private predicate hasDefinition(@globalvariable g) {
exists(@var_decl vd | var_decls(vd, g, _, _, _) | var_def(vd))
}
private predicate onlyOneCompleteGlobalVariableExistsWithMangledName(@mangledname name) {
strictcount(@globalvariable g | hasDefinition(g) and mangled_name(g, name)) = 1
}
/** Holds if `g` is a unique global variable with a definition named `name`. */
private predicate isGlobalWithMangledNameAndWithDefinition(@mangledname name, @globalvariable g) {
hasDefinition(g) and
mangled_name(g, name) and
onlyOneCompleteGlobalVariableExistsWithMangledName(name)
}
/** Holds if `g` is a global variable without a definition named `name`. */
private predicate isGlobalWithMangledNameAndWithoutDefinition(@mangledname name, @globalvariable g) {
not hasDefinition(g) and
mangled_name(g, name)
}
/**
* Holds if `incomplete` is a global variable without a definition, and there exists
* a unique global variable `complete` with the same name that does have a definition.
*/
private predicate hasTwinWithDefinition(@globalvariable incomplete, @globalvariable complete) {
exists(@mangledname name |
not variable_instantiation(incomplete, complete) and
isGlobalWithMangledNameAndWithoutDefinition(name, incomplete) and
isGlobalWithMangledNameAndWithDefinition(name, complete)
)
}
import Cached
cached
private module Cached {
/**
* If `v` is a global variable without a definition, and there exists a unique
* global variable with the same name that does have a definition, then the
* result is that unique global variable. Otherwise, the result is `v`.
*/
cached
@variable resolveGlobalVariable(@variable v) {
hasTwinWithDefinition(v, result)
or
not hasTwinWithDefinition(v, _) and
result = v
}
cached
predicate isVariable(@variable v) {
not v instanceof @globalvariable
or
v = resolveGlobalVariable(_)
}
}

View File

@@ -38,9 +38,6 @@ abstract class MustFlowConfiguration extends string {
*/ */
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
/** Holds if this configuration allows flow from arguments to parameters. */
predicate allowInterproceduralFlow() { any() }
/** /**
* Holds if data must flow from `source` to `sink` for this configuration. * Holds if data must flow from `source` to `sink` for this configuration.
* *
@@ -207,25 +204,10 @@ private module Cached {
} }
} }
/**
* Gets the enclosing callable of `n`. Unlike `n.getEnclosingCallable()`, this
* predicate ensures that joins go from `n` to the result instead of the other
* way around.
*/
pragma[inline]
private Declaration getEnclosingCallable(DataFlow::Node n) {
pragma[only_bind_into](result) = pragma[only_bind_out](n).getEnclosingCallable()
}
/** Holds if `nodeFrom` flows to `nodeTo`. */ /** Holds if `nodeFrom` flows to `nodeTo`. */
private predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, MustFlowConfiguration config) { private predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, MustFlowConfiguration config) {
exists(config) and exists(config) and
Cached::step(pragma[only_bind_into](nodeFrom), pragma[only_bind_into](nodeTo)) and Cached::step(nodeFrom, nodeTo)
(
config.allowInterproceduralFlow()
or
getEnclosingCallable(nodeFrom) = getEnclosingCallable(nodeTo)
)
or or
config.isAdditionalFlowStep(nodeFrom, nodeTo) config.isAdditionalFlowStep(nodeFrom, nodeTo)
} }

View File

@@ -244,25 +244,7 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
* calling context. For example, this would happen with flow through a * calling context. For example, this would happen with flow through a
* global or static variable. * global or static variable.
*/ */
predicate jumpStep(Node n1, Node n2) { predicate jumpStep(Node n1, Node n2) { none() }
exists(GlobalOrNamespaceVariable v |
v =
n1.asInstruction()
.(StoreInstruction)
.getResultAddress()
.(VariableAddressInstruction)
.getAstVariable() and
v = n2.asVariable()
or
v =
n2.asInstruction()
.(LoadInstruction)
.getSourceAddress()
.(VariableAddressInstruction)
.getAstVariable() and
v = n1.asVariable()
)
}
/** /**
* Holds if data can flow from `node1` to `node2` via an assignment to `f`. * Holds if data can flow from `node1` to `node2` via an assignment to `f`.

View File

@@ -100,7 +100,7 @@ class Node extends TIRDataFlowNode {
Declaration getEnclosingCallable() { none() } // overridden in subclasses Declaration getEnclosingCallable() { none() } // overridden in subclasses
/** Gets the function to which this node belongs, if any. */ /** Gets the function to which this node belongs, if any. */
Declaration getFunction() { none() } // overridden in subclasses Function getFunction() { none() } // overridden in subclasses
/** Gets the type of this node. */ /** Gets the type of this node. */
IRType getType() { none() } // overridden in subclasses IRType getType() { none() } // overridden in subclasses
@@ -196,7 +196,7 @@ class InstructionNode extends Node, TInstructionNode {
override Declaration getEnclosingCallable() { result = this.getFunction() } override Declaration getEnclosingCallable() { result = this.getFunction() }
override Declaration getFunction() { result = instr.getEnclosingFunction() } override Function getFunction() { result = instr.getEnclosingFunction() }
override IRType getType() { result = instr.getResultIRType() } override IRType getType() { result = instr.getResultIRType() }
@@ -222,7 +222,7 @@ class OperandNode extends Node, TOperandNode {
override Declaration getEnclosingCallable() { result = this.getFunction() } override Declaration getEnclosingCallable() { result = this.getFunction() }
override Declaration getFunction() { result = op.getUse().getEnclosingFunction() } override Function getFunction() { result = op.getUse().getEnclosingFunction() }
override IRType getType() { result = op.getIRType() } override IRType getType() { result = op.getIRType() }
@@ -274,7 +274,7 @@ class StoreNodeInstr extends StoreNode, TStoreNodeInstr {
/** Gets the underlying instruction. */ /** Gets the underlying instruction. */
Instruction getInstruction() { result = instr } Instruction getInstruction() { result = instr }
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() } override Function getFunction() { result = this.getInstruction().getEnclosingFunction() }
override IRType getType() { result = this.getInstruction().getResultIRType() } override IRType getType() { result = this.getInstruction().getResultIRType() }
@@ -328,7 +328,7 @@ class StoreNodeOperand extends StoreNode, TStoreNodeOperand {
/** Gets the underlying operand. */ /** Gets the underlying operand. */
Operand getOperand() { result = operand } Operand getOperand() { result = operand }
override Declaration getFunction() { result = operand.getDef().getEnclosingFunction() } override Function getFunction() { result = operand.getDef().getEnclosingFunction() }
override IRType getType() { result = operand.getIRType() } override IRType getType() { result = operand.getIRType() }
@@ -384,7 +384,7 @@ class ReadNode extends Node, TReadNode {
override Declaration getEnclosingCallable() { result = this.getFunction() } override Declaration getEnclosingCallable() { result = this.getFunction() }
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() } override Function getFunction() { result = this.getInstruction().getEnclosingFunction() }
override IRType getType() { result = this.getInstruction().getResultIRType() } override IRType getType() { result = this.getInstruction().getResultIRType() }
@@ -436,7 +436,7 @@ class SsaPhiNode extends Node, TSsaPhiNode {
override Declaration getEnclosingCallable() { result = this.getFunction() } override Declaration getEnclosingCallable() { result = this.getFunction() }
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() } override Function getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
override IRType getType() { result instanceof IRVoidType } override IRType getType() { result instanceof IRVoidType }
@@ -673,7 +673,7 @@ class VariableNode extends Node, TVariableNode {
/** Gets the variable corresponding to this node. */ /** Gets the variable corresponding to this node. */
Variable getVariable() { result = v } Variable getVariable() { result = v }
override Declaration getFunction() { none() } override Function getFunction() { none() }
override Declaration getEnclosingCallable() { override Declaration getEnclosingCallable() {
// When flow crosses from one _enclosing callable_ to another, the // When flow crosses from one _enclosing callable_ to another, the
@@ -1092,56 +1092,6 @@ class ContentSet instanceof Content {
} }
/** /**
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
*
* The expression `e` is expected to be a syntactic part of the guard `g`.
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
* the argument `x`.
*/
signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
/**
* Provides a set of barrier nodes for a guard that validates an expression.
*
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
* in data flow and taint tracking.
*/
module BarrierGuard<guardChecksSig/3 guardChecks> {
/** Gets a node that is safely guarded by the given guard check. */
ExprNode getABarrierNode() {
exists(IRGuardCondition g, ValueNumber value, boolean edge |
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
result.asInstruction() = value.getAnInstruction() and
g.controls(result.asInstruction().getBlock(), edge)
)
}
}
/**
* Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
*/
signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction instr, boolean branch);
/**
* Provides a set of barrier nodes for a guard that validates an instruction.
*
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
* in data flow and taint tracking.
*/
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
/** Gets a node that is safely guarded by the given guard check. */
ExprNode getABarrierNode() {
exists(IRGuardCondition g, ValueNumber value, boolean edge |
instructionGuardChecks(g, value.getAnInstruction(), edge) and
result.asInstruction() = value.getAnInstruction() and
g.controls(result.asInstruction().getBlock(), edge)
)
}
}
/**
* DEPRECATED: Use `BarrierGuard` module instead.
*
* A guard that validates some instruction. * A guard that validates some instruction.
* *
* To use this in a configuration, extend the class and provide a * To use this in a configuration, extend the class and provide a
@@ -1150,7 +1100,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
* *
* It is important that all extending classes in scope are disjoint. * It is important that all extending classes in scope are disjoint.
*/ */
deprecated class BarrierGuard extends IRGuardCondition { class BarrierGuard extends IRGuardCondition {
/** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */ /** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */
predicate checksInstr(Instruction instr, boolean b) { none() } predicate checksInstr(Instruction instr, boolean b) { none() }

View File

@@ -94,6 +94,12 @@ private string getNodeProperty(DataFlow::Node node, string key) {
any(DataFlow::Configuration cfg).isBarrierIn(node) and kind = "in" any(DataFlow::Configuration cfg).isBarrierIn(node) and kind = "in"
or or
any(DataFlow::Configuration cfg).isBarrierOut(node) and kind = "out" any(DataFlow::Configuration cfg).isBarrierOut(node) and kind = "out"
or
exists(DataFlow::BarrierGuard guard |
any(DataFlow::Configuration cfg).isBarrierGuard(guard) and
node = guard.getAGuardedNode() and
kind = "guard(" + guard.getResultId() + ")"
)
| |
kind, ", " kind, ", "
) )

View File

@@ -163,6 +163,12 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { n
*/ */
predicate defaultTaintSanitizer(DataFlow::Node node) { none() } predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
/**
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
* but not in local taint.
*/
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
/** /**
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a * Holds if taint can flow from `instrIn` to `instrOut` through a call to a
* modeled function. * modeled function.

View File

@@ -116,30 +116,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead. predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard) this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
} }
/** /**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited * Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`. * when the flow state is `state`.
*/ */
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
none()
}
deprecated final override predicate isBarrierGuard( final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state) this.isSanitizerGuard(guard, state)
} }

View File

@@ -116,30 +116,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead. predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard) this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
} }
/** /**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited * Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`. * when the flow state is `state`.
*/ */
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
none()
}
deprecated final override predicate isBarrierGuard( final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state) this.isSanitizerGuard(guard, state)
} }

View File

@@ -116,30 +116,20 @@ abstract class Configuration extends DataFlow::Configuration {
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) } final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
/** /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead. predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
*/
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
this.isSanitizerGuard(guard) this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
} }
/** /**
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
*
* Holds if taint propagation through nodes guarded by `guard` is prohibited * Holds if taint propagation through nodes guarded by `guard` is prohibited
* when the flow state is `state`. * when the flow state is `state`.
*/ */
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
none()
}
deprecated final override predicate isBarrierGuard( final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
DataFlow::BarrierGuard guard, DataFlow::FlowState state
) {
this.isSanitizerGuard(guard, state) this.isSanitizerGuard(guard, state)
} }

View File

@@ -16,7 +16,7 @@ class IRConfiguration extends TIRConfiguration {
/** /**
* Holds if IR should be created for function `func`. By default, holds for all functions. * Holds if IR should be created for function `func`. By default, holds for all functions.
*/ */
predicate shouldCreateIRForFunction(Language::Declaration func) { any() } predicate shouldCreateIRForFunction(Language::Function func) { any() }
/** /**
* Holds if the strings used as part of an IR dump should be generated for function `func`. * Holds if the strings used as part of an IR dump should be generated for function `func`.
@@ -25,7 +25,7 @@ class IRConfiguration extends TIRConfiguration {
* of debug strings for IR that will not be dumped. We still generate the actual IR for these * of debug strings for IR that will not be dumped. We still generate the actual IR for these
* functions, however, to preserve the results of any interprocedural analysis. * functions, however, to preserve the results of any interprocedural analysis.
*/ */
predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) { any() } predicate shouldEvaluateDebugStringsForFunction(Language::Function func) { any() }
} }
private newtype TIREscapeAnalysisConfiguration = MkIREscapeAnalysisConfiguration() private newtype TIREscapeAnalysisConfiguration = MkIREscapeAnalysisConfiguration()

View File

@@ -97,7 +97,7 @@ class IRBlockBase extends TIRBlock {
/** /**
* Gets the `Function` that contains this block. * Gets the `Function` that contains this block.
*/ */
final Language::Declaration getEnclosingFunction() { final Language::Function getEnclosingFunction() {
result = getFirstInstruction(this).getEnclosingFunction() result = getFirstInstruction(this).getEnclosingFunction()
} }
} }

View File

@@ -524,23 +524,4 @@ module InstructionConsistency {
"' has a `this` argument operand that is not an address, in function '$@'." and "' has a `this` argument operand that is not an address, in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText) irFunc = getInstructionIRFunction(instr, irFuncText)
} }
query predicate nonUniqueIRVariable(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
exists(VariableInstruction vi, IRVariable v1, IRVariable v2 |
instr = vi and vi.getIRVariable() = v1 and vi.getIRVariable() = v2 and v1 != v2
) and
message =
"Variable instruction '" + instr.toString() +
"' has multiple associated variables, in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
or
instr.getOpcode() instanceof Opcode::VariableAddress and
not instr instanceof VariableInstruction and
message =
"Variable address instruction '" + instr.toString() +
"' has no associated variable, in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
} }

View File

@@ -18,7 +18,7 @@ private import Imports::IRType
* by the AST-to-IR translation (`IRTempVariable`). * by the AST-to-IR translation (`IRTempVariable`).
*/ */
class IRVariable extends TIRVariable { class IRVariable extends TIRVariable {
Language::Declaration func; Language::Function func;
IRVariable() { IRVariable() {
this = TIRUserVariable(_, _, func) or this = TIRUserVariable(_, _, func) or
@@ -79,7 +79,7 @@ class IRVariable extends TIRVariable {
/** /**
* Gets the function that references this variable. * Gets the function that references this variable.
*/ */
final Language::Declaration getEnclosingFunction() { result = func } final Language::Function getEnclosingFunction() { result = func }
} }
/** /**
@@ -246,7 +246,7 @@ class IREllipsisVariable extends IRTempVariable, IRParameter {
final override string toString() { result = "#ellipsis" } final override string toString() { result = "#ellipsis" }
final override int getIndex() { result = func.(Language::Function).getNumberOfParameters() } final override int getIndex() { result = func.getNumberOfParameters() }
} }
/** /**

View File

@@ -194,7 +194,7 @@ class Instruction extends Construction::TStageInstruction {
/** /**
* Gets the function that contains this instruction. * Gets the function that contains this instruction.
*/ */
final Language::Declaration getEnclosingFunction() { final Language::Function getEnclosingFunction() {
result = this.getEnclosingIRFunction().getFunction() result = this.getEnclosingIRFunction().getFunction()
} }

View File

@@ -26,20 +26,20 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
* Holds if the IR for `func` should be printed. By default, holds for all * Holds if the IR for `func` should be printed. By default, holds for all
* functions. * functions.
*/ */
predicate shouldPrintFunction(Language::Declaration decl) { any() } predicate shouldPrintFunction(Language::Function func) { any() }
} }
/** /**
* Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped. * Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
*/ */
private class FilteredIRConfiguration extends IRConfiguration { private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) { override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
shouldPrintFunction(func) shouldPrintFunction(func)
} }
} }
private predicate shouldPrintFunction(Language::Declaration decl) { private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl)) exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
} }
private string getAdditionalInstructionProperty(Instruction instr, string key) { private string getAdditionalInstructionProperty(Instruction instr, string key) {

View File

@@ -5,28 +5,23 @@
private import IRFunctionBaseInternal private import IRFunctionBaseInternal
private newtype TIRFunction = private newtype TIRFunction =
TFunctionIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) } or MkIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) }
TVarInitIRFunction(Language::GlobalVariable var) { IRConstruction::Raw::varHasIRFunc(var) }
/** /**
* The IR for a function. This base class contains only the predicates that are the same between all * The IR for a function. This base class contains only the predicates that are the same between all
* phases of the IR. Each instantiation of `IRFunction` extends this class. * phases of the IR. Each instantiation of `IRFunction` extends this class.
*/ */
class IRFunctionBase extends TIRFunction { class IRFunctionBase extends TIRFunction {
Language::Declaration decl; Language::Function func;
IRFunctionBase() { IRFunctionBase() { this = MkIRFunction(func) }
this = TFunctionIRFunction(decl)
or
this = TVarInitIRFunction(decl)
}
/** Gets a textual representation of this element. */ /** Gets a textual representation of this element. */
final string toString() { result = "IR: " + decl.toString() } final string toString() { result = "IR: " + func.toString() }
/** Gets the function whose IR is represented. */ /** Gets the function whose IR is represented. */
final Language::Declaration getFunction() { result = decl } final Language::Function getFunction() { result = func }
/** Gets the location of the function. */ /** Gets the location of the function. */
final Language::Location getLocation() { result = decl.getLocation() } final Language::Location getLocation() { result = func.getLocation() }
} }

View File

@@ -2,21 +2,21 @@ private import TIRVariableInternal
private import Imports::TempVariableTag private import Imports::TempVariableTag
newtype TIRVariable = newtype TIRVariable =
TIRUserVariable(Language::Variable var, Language::LanguageType type, Language::Declaration func) { TIRUserVariable(Language::Variable var, Language::LanguageType type, Language::Function func) {
Construction::hasUserVariable(func, var, type) Construction::hasUserVariable(func, var, type)
} or } or
TIRTempVariable( TIRTempVariable(
Language::Declaration func, Language::AST ast, TempVariableTag tag, Language::LanguageType type Language::Function func, Language::AST ast, TempVariableTag tag, Language::LanguageType type
) { ) {
Construction::hasTempVariable(func, ast, tag, type) Construction::hasTempVariable(func, ast, tag, type)
} or } or
TIRDynamicInitializationFlag( TIRDynamicInitializationFlag(
Language::Declaration func, Language::Variable var, Language::LanguageType type Language::Function func, Language::Variable var, Language::LanguageType type
) { ) {
Construction::hasDynamicInitializationFlag(func, var, type) Construction::hasDynamicInitializationFlag(func, var, type)
} or } or
TIRStringLiteral( TIRStringLiteral(
Language::Declaration func, Language::AST ast, Language::LanguageType type, Language::Function func, Language::AST ast, Language::LanguageType type,
Language::StringLiteral literal Language::StringLiteral literal
) { ) {
Construction::hasStringLiteral(func, ast, type, literal) Construction::hasStringLiteral(func, ast, type, literal)

View File

@@ -97,7 +97,7 @@ class IRBlockBase extends TIRBlock {
/** /**
* Gets the `Function` that contains this block. * Gets the `Function` that contains this block.
*/ */
final Language::Declaration getEnclosingFunction() { final Language::Function getEnclosingFunction() {
result = getFirstInstruction(this).getEnclosingFunction() result = getFirstInstruction(this).getEnclosingFunction()
} }
} }

View File

@@ -524,23 +524,4 @@ module InstructionConsistency {
"' has a `this` argument operand that is not an address, in function '$@'." and "' has a `this` argument operand that is not an address, in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText) irFunc = getInstructionIRFunction(instr, irFuncText)
} }
query predicate nonUniqueIRVariable(
Instruction instr, string message, OptionalIRFunction irFunc, string irFuncText
) {
exists(VariableInstruction vi, IRVariable v1, IRVariable v2 |
instr = vi and vi.getIRVariable() = v1 and vi.getIRVariable() = v2 and v1 != v2
) and
message =
"Variable instruction '" + instr.toString() +
"' has multiple associated variables, in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
or
instr.getOpcode() instanceof Opcode::VariableAddress and
not instr instanceof VariableInstruction and
message =
"Variable address instruction '" + instr.toString() +
"' has no associated variable, in function '$@'." and
irFunc = getInstructionIRFunction(instr, irFuncText)
}
} }

View File

@@ -18,7 +18,7 @@ private import Imports::IRType
* by the AST-to-IR translation (`IRTempVariable`). * by the AST-to-IR translation (`IRTempVariable`).
*/ */
class IRVariable extends TIRVariable { class IRVariable extends TIRVariable {
Language::Declaration func; Language::Function func;
IRVariable() { IRVariable() {
this = TIRUserVariable(_, _, func) or this = TIRUserVariable(_, _, func) or
@@ -79,7 +79,7 @@ class IRVariable extends TIRVariable {
/** /**
* Gets the function that references this variable. * Gets the function that references this variable.
*/ */
final Language::Declaration getEnclosingFunction() { result = func } final Language::Function getEnclosingFunction() { result = func }
} }
/** /**
@@ -246,7 +246,7 @@ class IREllipsisVariable extends IRTempVariable, IRParameter {
final override string toString() { result = "#ellipsis" } final override string toString() { result = "#ellipsis" }
final override int getIndex() { result = func.(Language::Function).getNumberOfParameters() } final override int getIndex() { result = func.getNumberOfParameters() }
} }
/** /**

View File

@@ -194,7 +194,7 @@ class Instruction extends Construction::TStageInstruction {
/** /**
* Gets the function that contains this instruction. * Gets the function that contains this instruction.
*/ */
final Language::Declaration getEnclosingFunction() { final Language::Function getEnclosingFunction() {
result = this.getEnclosingIRFunction().getFunction() result = this.getEnclosingIRFunction().getFunction()
} }

View File

@@ -26,20 +26,20 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
* Holds if the IR for `func` should be printed. By default, holds for all * Holds if the IR for `func` should be printed. By default, holds for all
* functions. * functions.
*/ */
predicate shouldPrintFunction(Language::Declaration decl) { any() } predicate shouldPrintFunction(Language::Function func) { any() }
} }
/** /**
* Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped. * Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
*/ */
private class FilteredIRConfiguration extends IRConfiguration { private class FilteredIRConfiguration extends IRConfiguration {
override predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) { override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
shouldPrintFunction(func) shouldPrintFunction(func)
} }
} }
private predicate shouldPrintFunction(Language::Declaration decl) { private predicate shouldPrintFunction(Language::Function func) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl)) exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
} }
private string getAdditionalInstructionProperty(Instruction instr, string key) { private string getAdditionalInstructionProperty(Instruction instr, string key) {

View File

@@ -13,7 +13,6 @@ private import TranslatedElement
private import TranslatedExpr private import TranslatedExpr
private import TranslatedStmt private import TranslatedStmt
private import TranslatedFunction private import TranslatedFunction
private import TranslatedGlobalVar
TranslatedElement getInstructionTranslatedElement(Instruction instruction) { TranslatedElement getInstructionTranslatedElement(Instruction instruction) {
instruction = TRawInstruction(result, _) instruction = TRawInstruction(result, _)
@@ -36,41 +35,29 @@ module Raw {
cached cached
predicate functionHasIR(Function func) { exists(getTranslatedFunction(func)) } predicate functionHasIR(Function func) { exists(getTranslatedFunction(func)) }
cached
predicate varHasIRFunc(GlobalOrNamespaceVariable var) {
var.hasInitializer() and
(
not var.getType().isDeeplyConst()
or
var.getInitializer().getExpr() instanceof StringLiteral
)
}
cached cached
predicate hasInstruction(TranslatedElement element, InstructionTag tag) { predicate hasInstruction(TranslatedElement element, InstructionTag tag) {
element.hasInstruction(_, tag, _) element.hasInstruction(_, tag, _)
} }
cached cached
predicate hasUserVariable(Declaration decl, Variable var, CppType type) { predicate hasUserVariable(Function func, Variable var, CppType type) {
getTranslatedFunction(decl).hasUserVariable(var, type) getTranslatedFunction(func).hasUserVariable(var, type)
or
getTranslatedVarInit(decl).hasUserVariable(var, type)
} }
cached cached
predicate hasTempVariable(Declaration decl, Locatable ast, TempVariableTag tag, CppType type) { predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag, CppType type) {
exists(TranslatedElement element | exists(TranslatedElement element |
element.getAst() = ast and element.getAst() = ast and
decl = element.getFunction() and func = element.getFunction() and
element.hasTempVariable(tag, type) element.hasTempVariable(tag, type)
) )
} }
cached cached
predicate hasStringLiteral(Declaration decl, Locatable ast, CppType type, StringLiteral literal) { predicate hasStringLiteral(Function func, Locatable ast, CppType type, StringLiteral literal) {
literal = ast and literal = ast and
literal.getEnclosingDeclaration() = decl and literal.getEnclosingFunction() = func and
getTypeForPRValue(literal.getType()) = type getTypeForPRValue(literal.getType()) = type
} }

View File

@@ -180,7 +180,7 @@ abstract class TranslatedSideEffects extends TranslatedElement {
/** DEPRECATED: Alias for getAst */ /** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() } deprecated override Locatable getAST() { result = getAst() }
final override Declaration getFunction() { result = getExpr().getEnclosingDeclaration() } final override Function getFunction() { result = getExpr().getEnclosingFunction() }
final override TranslatedElement getChild(int i) { final override TranslatedElement getChild(int i) {
result = result =
@@ -375,7 +375,7 @@ abstract class TranslatedSideEffect extends TranslatedElement {
kind instanceof GotoEdge kind instanceof GotoEdge
} }
final override Declaration getFunction() { result = getParent().getFunction() } final override Function getFunction() { result = getParent().getFunction() }
final override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) { final override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
@@ -436,6 +436,13 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
result = index result = index
} }
/**
* Gets the `TranslatedFunction` containing this expression.
*/
final TranslatedFunction getEnclosingFunction() {
result = getTranslatedFunction(call.getEnclosingFunction())
}
final override predicate sideEffectInstruction(Opcode opcode, CppType type) { final override predicate sideEffectInstruction(Opcode opcode, CppType type) {
opcode = sideEffectOpcode and opcode = sideEffectOpcode and
( (

View File

@@ -25,9 +25,9 @@ private Element getRealParent(Expr expr) {
result.(Destructor).getADestruction() = expr result.(Destructor).getADestruction() = expr
} }
IRUserVariable getIRUserVariable(Declaration decl, Variable var) { IRUserVariable getIRUserVariable(Function func, Variable var) {
result.getVariable() = var and result.getVariable() = var and
result.getEnclosingFunction() = decl result.getEnclosingFunction() = func
} }
IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) { IRTempVariable getIRTempVariable(Locatable ast, TempVariableTag tag) {
@@ -67,8 +67,7 @@ private predicate ignoreExprAndDescendants(Expr expr) {
exists(Initializer init, StaticStorageDurationVariable var | exists(Initializer init, StaticStorageDurationVariable var |
init = var.getInitializer() and init = var.getInitializer() and
not var.hasDynamicInitialization() and not var.hasDynamicInitialization() and
expr = init.getExpr().getFullyConverted() and expr = init.getExpr().getFullyConverted()
not var instanceof GlobalOrNamespaceVariable
) )
or or
// Ignore descendants of `__assume` expressions, since we translated these to `NoOp`. // Ignore descendants of `__assume` expressions, since we translated these to `NoOp`.
@@ -118,8 +117,7 @@ private predicate ignoreExprOnly(Expr expr) {
// should not be translated. // should not be translated.
exists(NewOrNewArrayExpr new | expr = new.getAllocatorCall().getArgument(0)) exists(NewOrNewArrayExpr new | expr = new.getAllocatorCall().getArgument(0))
or or
not translateFunction(expr.getEnclosingFunction()) and not translateFunction(expr.getEnclosingFunction())
not Raw::varHasIRFunc(expr.getEnclosingVariable())
or or
// We do not yet translate destructors properly, so for now we ignore the // We do not yet translate destructors properly, so for now we ignore the
// destructor call. We do, however, translate the expression being // destructor call. We do, however, translate the expression being
@@ -664,8 +662,7 @@ newtype TTranslatedElement =
opcode = getASideEffectOpcode(call, -1) opcode = getASideEffectOpcode(call, -1)
} or } or
// The side effect that initializes newly-allocated memory. // The side effect that initializes newly-allocated memory.
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) }
TTranslatedGlobalOrNamespaceVarInit(GlobalOrNamespaceVariable var) { Raw::varHasIRFunc(var) }
/** /**
* Gets the index of the first explicitly initialized element in `initList` * Gets the index of the first explicitly initialized element in `initList`
@@ -795,7 +792,7 @@ abstract class TranslatedElement extends TTranslatedElement {
/** /**
* Gets the `Function` that contains this element. * Gets the `Function` that contains this element.
*/ */
abstract Declaration getFunction(); abstract Function getFunction();
/** /**
* Gets the successor instruction of the instruction that was generated by * Gets the successor instruction of the instruction that was generated by
@@ -945,14 +942,3 @@ abstract class TranslatedElement extends TTranslatedElement {
*/ */
final TranslatedElement getParent() { result.getAChild() = this } final TranslatedElement getParent() { result.getAChild() = this }
} }
/**
* The IR translation of a root element, either a function or a global variable.
*/
abstract class TranslatedRootElement extends TranslatedElement {
TranslatedRootElement() {
this instanceof TTranslatedFunction
or
this instanceof TTranslatedGlobalOrNamespaceVarInit
}
}

View File

@@ -12,7 +12,6 @@ private import TranslatedElement
private import TranslatedFunction private import TranslatedFunction
private import TranslatedInitialization private import TranslatedInitialization
private import TranslatedStmt private import TranslatedStmt
private import TranslatedGlobalVar
import TranslatedCall import TranslatedCall
/** /**
@@ -79,7 +78,7 @@ abstract class TranslatedExpr extends TranslatedElement {
/** DEPRECATED: Alias for getAst */ /** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() } deprecated override Locatable getAST() { result = this.getAst() }
final override Declaration getFunction() { result = expr.getEnclosingDeclaration() } final override Function getFunction() { result = expr.getEnclosingFunction() }
/** /**
* Gets the expression from which this `TranslatedExpr` is generated. * Gets the expression from which this `TranslatedExpr` is generated.
@@ -89,10 +88,8 @@ abstract class TranslatedExpr extends TranslatedElement {
/** /**
* Gets the `TranslatedFunction` containing this expression. * Gets the `TranslatedFunction` containing this expression.
*/ */
final TranslatedRootElement getEnclosingFunction() { final TranslatedFunction getEnclosingFunction() {
result = getTranslatedFunction(expr.getEnclosingFunction()) result = getTranslatedFunction(expr.getEnclosingFunction())
or
result = getTranslatedVarInit(expr.getEnclosingVariable())
} }
} }
@@ -790,7 +787,7 @@ class TranslatedThisExpr extends TranslatedNonConstantExpr {
override IRVariable getInstructionVariable(InstructionTag tag) { override IRVariable getInstructionVariable(InstructionTag tag) {
tag = ThisAddressTag() and tag = ThisAddressTag() and
result = this.getEnclosingFunction().(TranslatedFunction).getThisVariable() result = this.getEnclosingFunction().getThisVariable()
} }
} }
@@ -841,7 +838,7 @@ class TranslatedNonFieldVariableAccess extends TranslatedVariableAccess {
override IRVariable getInstructionVariable(InstructionTag tag) { override IRVariable getInstructionVariable(InstructionTag tag) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
result = getIRUserVariable(expr.getEnclosingDeclaration(), expr.getTarget()) result = getIRUserVariable(expr.getEnclosingFunction(), expr.getTarget())
} }
} }
@@ -2525,7 +2522,7 @@ class TranslatedVarArgsStart extends TranslatedNonConstantExpr {
final override IRVariable getInstructionVariable(InstructionTag tag) { final override IRVariable getInstructionVariable(InstructionTag tag) {
tag = VarArgsStartEllipsisAddressTag() and tag = VarArgsStartEllipsisAddressTag() and
result = this.getEnclosingFunction().(TranslatedFunction).getEllipsisVariable() result = this.getEnclosingFunction().getEllipsisVariable()
} }
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {

View File

@@ -58,7 +58,7 @@ predicate hasReturnValue(Function func) { not func.getUnspecifiedType() instance
* Represents the IR translation of a function. This is the root elements for * Represents the IR translation of a function. This is the root elements for
* all other elements associated with this function. * all other elements associated with this function.
*/ */
class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction { class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
Function func; Function func;
TranslatedFunction() { this = TTranslatedFunction(func) } TranslatedFunction() { this = TTranslatedFunction(func) }

View File

@@ -1,132 +0,0 @@
import semmle.code.cpp.ir.implementation.raw.internal.TranslatedElement
private import cpp
private import semmle.code.cpp.ir.implementation.IRType
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.CppType
private import TranslatedInitialization
private import InstructionTag
private import semmle.code.cpp.ir.internal.IRUtilities
class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
TTranslatedGlobalOrNamespaceVarInit, InitializationContext {
GlobalOrNamespaceVariable var;
TranslatedGlobalOrNamespaceVarInit() { this = TTranslatedGlobalOrNamespaceVarInit(var) }
override string toString() { result = var.toString() }
final override GlobalOrNamespaceVariable getAst() { result = var }
final override Declaration getFunction() { result = var }
final Location getLocation() { result = var.getLocation() }
override Instruction getFirstInstruction() { result = this.getInstruction(EnterFunctionTag()) }
override TranslatedElement getChild(int n) {
n = 1 and
result = getTranslatedInitialization(var.getInitializer().getExpr().getFullyConverted())
}
override predicate hasInstruction(Opcode op, InstructionTag tag, CppType type) {
op instanceof Opcode::EnterFunction and
tag = EnterFunctionTag() and
type = getVoidType()
or
op instanceof Opcode::AliasedDefinition and
tag = AliasedDefinitionTag() and
type = getUnknownType()
or
op instanceof Opcode::VariableAddress and
tag = InitializerVariableAddressTag() and
type = getTypeForGLValue(var.getType())
or
op instanceof Opcode::ReturnVoid and
tag = ReturnTag() and
type = getVoidType()
or
op instanceof Opcode::AliasedUse and
tag = AliasedUseTag() and
type = getVoidType()
or
op instanceof Opcode::ExitFunction and
tag = ExitFunctionTag() and
type = getVoidType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
tag = EnterFunctionTag() and
result = this.getInstruction(AliasedDefinitionTag())
or
tag = AliasedDefinitionTag() and
result = this.getInstruction(InitializerVariableAddressTag())
or
tag = InitializerVariableAddressTag() and
result = this.getChild(1).getFirstInstruction()
or
tag = ReturnTag() and
result = this.getInstruction(AliasedUseTag())
or
tag = AliasedUseTag() and
result = this.getInstruction(ExitFunctionTag())
)
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getChild(1) and
result = this.getInstruction(ReturnTag())
}
final override CppType getInstructionMemoryOperandType(
InstructionTag tag, TypedOperandTag operandTag
) {
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
result = getUnknownType()
}
override IRUserVariable getInstructionVariable(InstructionTag tag) {
tag = InitializerVariableAddressTag() and
result.getVariable() = var and
result.getEnclosingFunction() = var
}
override Instruction getTargetAddress() {
result = this.getInstruction(InitializerVariableAddressTag())
}
override Type getTargetType() { result = var.getUnspecifiedType() }
/**
* Holds if this variable defines or accesses variable `var` with type `type`. This includes all
* parameters and local variables, plus any global variables or static data members that are
* directly accessed by the function.
*/
final predicate hasUserVariable(Variable varUsed, CppType type) {
(
(
varUsed instanceof GlobalOrNamespaceVariable
or
varUsed instanceof MemberVariable and not varUsed instanceof Field
) and
exists(VariableAccess access |
access.getTarget() = varUsed and
access.getEnclosingVariable() = var
)
or
var = varUsed
or
varUsed.(LocalScopeVariable).getEnclosingElement*() = var
or
varUsed.(Parameter).getCatchBlock().getEnclosingElement*() = var
) and
type = getTypeForPRValue(getVariableType(varUsed))
}
}
TranslatedGlobalOrNamespaceVarInit getTranslatedVarInit(GlobalOrNamespaceVariable var) {
result.getAst() = var
}

View File

@@ -137,10 +137,7 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
final override string toString() { result = "init: " + expr.toString() } final override string toString() { result = "init: " + expr.toString() }
final override Declaration getFunction() { final override Function getFunction() { result = expr.getEnclosingFunction() }
result = expr.getEnclosingFunction() or
result = expr.getEnclosingVariable().(GlobalOrNamespaceVariable)
}
final override Locatable getAst() { result = expr } final override Locatable getAst() { result = expr }
@@ -489,10 +486,7 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
/** DEPRECATED: Alias for getAst */ /** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() } deprecated override Locatable getAST() { result = getAst() }
final override Declaration getFunction() { final override Function getFunction() { result = ast.getEnclosingFunction() }
result = ast.getEnclosingFunction() or
result = ast.getEnclosingVariable().(GlobalOrNamespaceVariable)
}
final override Instruction getFirstInstruction() { result = getInstruction(getFieldAddressTag()) } final override Instruction getFirstInstruction() { result = getInstruction(getFieldAddressTag()) }
@@ -639,11 +633,7 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
/** DEPRECATED: Alias for getAst */ /** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() } deprecated override Locatable getAST() { result = getAst() }
final override Declaration getFunction() { final override Function getFunction() { result = initList.getEnclosingFunction() }
result = initList.getEnclosingFunction()
or
result = initList.getEnclosingVariable().(GlobalOrNamespaceVariable)
}
final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) } final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) }

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