mirror of
https://github.com/github/codeql.git
synced 2026-05-18 13:17:08 +02:00
Compare commits
2 Commits
codeql-cli
...
jhelie/val
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74a7f83631 | ||
|
|
0e15bb8b9e |
18
.github/actions/fetch-codeql/action.yml
vendored
18
.github/actions/fetch-codeql/action.yml
vendored
@@ -3,12 +3,22 @@ description: Fetches the latest version of CodeQL
|
||||
runs:
|
||||
using: composite
|
||||
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
|
||||
shell: bash
|
||||
run: |
|
||||
gh extension install github/gh-codeql
|
||||
gh codeql set-channel nightly
|
||||
gh codeql version
|
||||
gh codeql version --format=json | jq -r .unpackedLocation >> "${GITHUB_PATH}"
|
||||
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-$GA_CODEQL_CLI_PLATFORM.zip "$LATEST"
|
||||
unzip -q -d "${RUNNER_TEMP}" codeql-$GA_CODEQL_CLI_PLATFORM.zip
|
||||
echo "${RUNNER_TEMP}/codeql" >> "${GITHUB_PATH}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
1
.github/labeler.yml
vendored
1
.github/labeler.yml
vendored
@@ -42,4 +42,3 @@ documentation:
|
||||
|
||||
"QL-for-QL":
|
||||
- ql/**/*
|
||||
- .github/workflows/ql-for-ql*
|
||||
|
||||
16
.github/workflows/check-qldoc.yml
vendored
16
.github/workflows/check-qldoc.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
paths:
|
||||
- "*/ql/lib/**"
|
||||
- .github/workflows/check-qldoc.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
@@ -15,13 +14,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
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
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Install CodeQL
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
|
||||
- name: Check QLdoc coverage
|
||||
shell: bash
|
||||
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)"
|
||||
for pack_dir in ${changed_lib_packs}; do
|
||||
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
|
||||
git checkout HEAD^
|
||||
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.
|
||||
[[ ! -d "${pack_dir}" ]] && continue
|
||||
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}-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)"
|
||||
|
||||
1
.github/workflows/csv-coverage-metrics.yml
vendored
1
.github/workflows/csv-coverage-metrics.yml
vendored
@@ -12,7 +12,6 @@ on:
|
||||
- main
|
||||
paths:
|
||||
- ".github/workflows/csv-coverage-metrics.yml"
|
||||
- ".github/actions/fetch-codeql/action.yml"
|
||||
|
||||
jobs:
|
||||
publish-java:
|
||||
|
||||
163
.github/workflows/csv-coverage-pr-artifacts.yml
vendored
163
.github/workflows/csv-coverage-pr-artifacts.yml
vendored
@@ -3,20 +3,18 @@ name: Check framework coverage changes
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/csv-coverage-pr-comment.yml"
|
||||
- ".github/workflows/csv-coverage-pr-artifacts.yml"
|
||||
- ".github/actions/fetch-codeql/action.yml"
|
||||
- "*/ql/src/**/*.ql"
|
||||
- "*/ql/src/**/*.qll"
|
||||
- "*/ql/lib/**/*.ql"
|
||||
- "*/ql/lib/**/*.qll"
|
||||
- "misc/scripts/library-coverage/*.py"
|
||||
- '.github/workflows/csv-coverage-pr-comment.yml'
|
||||
- '*/ql/src/**/*.ql'
|
||||
- '*/ql/src/**/*.qll'
|
||||
- '*/ql/lib/**/*.ql'
|
||||
- '*/ql/lib/**/*.qll'
|
||||
- 'misc/scripts/library-coverage/*.py'
|
||||
# input data files
|
||||
- "*/documentation/library-coverage/cwe-sink.csv"
|
||||
- "*/documentation/library-coverage/frameworks.csv"
|
||||
- '*/documentation/library-coverage/cwe-sink.csv'
|
||||
- '*/documentation/library-coverage/frameworks.csv'
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
- 'rc/*'
|
||||
|
||||
jobs:
|
||||
generate:
|
||||
@@ -25,72 +23,77 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- name: Clone self (github/codeql) - MERGE
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: merge
|
||||
- name: Clone self (github/codeql) - BASE
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
path: base
|
||||
- run: |
|
||||
git checkout HEAD^1
|
||||
git log -1 --format='%H'
|
||||
working-directory: base
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Download CodeQL CLI
|
||||
uses: ./merge/.github/actions/fetch-codeql
|
||||
- name: Generate CSV files on merge commit of the PR
|
||||
run: |
|
||||
echo "Running generator on merge"
|
||||
python merge/misc/scripts/library-coverage/generate-report.py ci merge merge
|
||||
mkdir out_merge
|
||||
cp framework-coverage-*.csv out_merge/
|
||||
cp framework-coverage-*.rst out_merge/
|
||||
- name: Generate CSV files on base commit of the PR
|
||||
run: |
|
||||
echo "Running generator on base"
|
||||
python base/misc/scripts/library-coverage/generate-report.py ci base base
|
||||
mkdir out_base
|
||||
cp framework-coverage-*.csv out_base/
|
||||
cp framework-coverage-*.rst out_base/
|
||||
- name: Generate diff of coverage reports
|
||||
run: |
|
||||
python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md
|
||||
- name: Upload CSV package list
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: csv-framework-coverage-merge
|
||||
path: |
|
||||
out_merge/framework-coverage-*.csv
|
||||
out_merge/framework-coverage-*.rst
|
||||
- name: Upload CSV package list
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: csv-framework-coverage-base
|
||||
path: |
|
||||
out_base/framework-coverage-*.csv
|
||||
out_base/framework-coverage-*.rst
|
||||
- name: Upload comparison results
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: comparison
|
||||
path: |
|
||||
comparison.md
|
||||
- name: Save PR number
|
||||
run: |
|
||||
mkdir -p pr
|
||||
echo ${{ github.event.pull_request.number }} > pr/NR
|
||||
- name: Upload PR number
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: pr
|
||||
path: pr/
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- name: Clone self (github/codeql) - MERGE
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: merge
|
||||
- name: Clone self (github/codeql) - BASE
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
path: base
|
||||
- run: |
|
||||
git checkout HEAD^1
|
||||
git log -1 --format='%H'
|
||||
working-directory: base
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Download CodeQL CLI
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
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: Generate CSV files on merge commit of the PR
|
||||
run: |
|
||||
echo "Running generator on merge"
|
||||
PATH="$PATH:codeql-cli/codeql" python merge/misc/scripts/library-coverage/generate-report.py ci merge merge
|
||||
mkdir out_merge
|
||||
cp framework-coverage-*.csv out_merge/
|
||||
cp framework-coverage-*.rst out_merge/
|
||||
- name: Generate CSV files on base commit of the PR
|
||||
run: |
|
||||
echo "Running generator on base"
|
||||
PATH="$PATH:codeql-cli/codeql" python base/misc/scripts/library-coverage/generate-report.py ci base base
|
||||
mkdir out_base
|
||||
cp framework-coverage-*.csv out_base/
|
||||
cp framework-coverage-*.rst out_base/
|
||||
- name: Generate diff of coverage reports
|
||||
run: |
|
||||
python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md
|
||||
- name: Upload CSV package list
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: csv-framework-coverage-merge
|
||||
path: |
|
||||
out_merge/framework-coverage-*.csv
|
||||
out_merge/framework-coverage-*.rst
|
||||
- name: Upload CSV package list
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: csv-framework-coverage-base
|
||||
path: |
|
||||
out_base/framework-coverage-*.csv
|
||||
out_base/framework-coverage-*.rst
|
||||
- name: Upload comparison results
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: comparison
|
||||
path: |
|
||||
comparison.md
|
||||
- name: Save PR number
|
||||
run: |
|
||||
mkdir -p pr
|
||||
echo ${{ github.event.pull_request.number }} > pr/NR
|
||||
- name: Upload PR number
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: pr
|
||||
path: pr/
|
||||
|
||||
55
.github/workflows/csv-coverage-timeseries.yml
vendored
55
.github/workflows/csv-coverage-timeseries.yml
vendored
@@ -5,29 +5,38 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone self (github/codeql)
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: script
|
||||
- name: Clone self (github/codeql) for analysis
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: codeqlModels
|
||||
fetch-depth: 0
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Download CodeQL CLI
|
||||
uses: ./script/.github/actions/fetch-codeql
|
||||
- name: Build modeled package list
|
||||
run: |
|
||||
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
|
||||
- name: Clone self (github/codeql)
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: script
|
||||
- name: Clone self (github/codeql) for analysis
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: codeqlModels
|
||||
fetch-depth: 0
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Download CodeQL CLI
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
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: Build modeled package list
|
||||
run: |
|
||||
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
|
||||
|
||||
|
||||
52
.github/workflows/csv-coverage-update.yml
vendored
52
.github/workflows/csv-coverage-update.yml
vendored
@@ -12,27 +12,33 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- name: Clone self (github/codeql)
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: ql
|
||||
fetch-depth: 0
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Download CodeQL CLI
|
||||
uses: ./ql/.github/actions/fetch-codeql
|
||||
- name: Generate coverage files
|
||||
run: |
|
||||
python ql/misc/scripts/library-coverage/generate-report.py ci ql ql
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJSON(github.event) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- name: Clone self (github/codeql)
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: ql
|
||||
fetch-depth: 0
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Download CodeQL CLI
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
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
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY"
|
||||
- name: Generate coverage files
|
||||
run: |
|
||||
PATH="$PATH:codeql-cli/codeql" python ql/misc/scripts/library-coverage/generate-report.py ci ql ql
|
||||
|
||||
- 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"
|
||||
|
||||
65
.github/workflows/csv-coverage.yml
vendored
65
.github/workflows/csv-coverage.yml
vendored
@@ -4,39 +4,46 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
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
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clone self (github/codeql)
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: script
|
||||
- name: Clone self (github/codeql) for analysis
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: codeqlModels
|
||||
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Download CodeQL CLI
|
||||
uses: ./script/.github/actions/fetch-codeql
|
||||
- name: Build modeled package list
|
||||
run: |
|
||||
python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script
|
||||
- name: Upload CSV package list
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: framework-coverage-csv
|
||||
path: framework-coverage-*.csv
|
||||
- name: Upload RST package list
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: framework-coverage-rst
|
||||
path: framework-coverage-*.rst
|
||||
- name: Clone self (github/codeql)
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: script
|
||||
- name: Clone self (github/codeql) for analysis
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: codeqlModels
|
||||
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Download CodeQL CLI
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
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: Build modeled package list
|
||||
run: |
|
||||
PATH="$PATH:codeql-cli/codeql" python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script
|
||||
- name: Upload CSV package list
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: framework-coverage-csv
|
||||
path: framework-coverage-*.csv
|
||||
- name: Upload RST package list
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: framework-coverage-rst
|
||||
path: framework-coverage-*.rst
|
||||
|
||||
|
||||
198
.github/workflows/go-tests.yml
vendored
198
.github/workflows/go-tests.yml
vendored
@@ -4,111 +4,159 @@ on:
|
||||
paths:
|
||||
- "go/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
jobs:
|
||||
|
||||
test-linux:
|
||||
name: Test Linux (Ubuntu)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.19
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
id: go
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Go 1.18.1
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.18.1
|
||||
id: go
|
||||
|
||||
- name: Set up CodeQL CLI
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
- name: Set up CodeQL CLI
|
||||
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
|
||||
shell: bash
|
||||
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd go
|
||||
make
|
||||
- name: Enable problem matchers in repository
|
||||
shell: bash
|
||||
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
|
||||
|
||||
- name: Check that all QL and Go code is autoformatted
|
||||
run: |
|
||||
cd go
|
||||
make check-formatting
|
||||
- name: Build
|
||||
run: |
|
||||
cd go
|
||||
env PATH=$PATH:$HOME/codeql make
|
||||
|
||||
- name: Compile qhelp files to markdown
|
||||
run: |
|
||||
cd go
|
||||
env QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown
|
||||
- name: Check that all QL and Go code is autoformatted
|
||||
run: |
|
||||
cd go
|
||||
env PATH=$PATH:$HOME/codeql make check-formatting
|
||||
|
||||
- name: Upload qhelp markdown
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: qhelp-markdown
|
||||
path: go/qhelp-out/**/*.md
|
||||
- name: Compile qhelp files to markdown
|
||||
run: |
|
||||
cd go
|
||||
env PATH=$PATH:$HOME/codeql QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd go
|
||||
make test
|
||||
- name: Upload qhelp markdown
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: qhelp-markdown
|
||||
path: go/qhelp-out/**/*.md
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd go
|
||||
env PATH=$PATH:$HOME/codeql make test
|
||||
|
||||
test-mac:
|
||||
name: Test MacOS
|
||||
runs-on: macos-latest
|
||||
runs-on: macOS-latest
|
||||
steps:
|
||||
- name: Set up Go 1.19
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
id: go
|
||||
- name: Set up Go 1.18.1
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.18.1
|
||||
id: go
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up CodeQL CLI
|
||||
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
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Enable problem matchers in repository
|
||||
shell: bash
|
||||
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
|
||||
- name: Enable problem matchers in repository
|
||||
shell: bash
|
||||
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd go
|
||||
make
|
||||
- name: Build
|
||||
run: |
|
||||
cd go
|
||||
env PATH=$PATH:$HOME/codeql make
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd go
|
||||
make test
|
||||
- name: Test
|
||||
run: |
|
||||
cd go
|
||||
env PATH=$PATH:$HOME/codeql make test
|
||||
|
||||
test-win:
|
||||
name: Test Windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- name: Set up Go 1.19
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
id: go
|
||||
- name: Set up Go 1.18.1
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.18.1
|
||||
id: go
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up CodeQL CLI
|
||||
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
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Enable problem matchers in repository
|
||||
shell: bash
|
||||
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
|
||||
- name: Enable problem matchers in repository
|
||||
shell: bash
|
||||
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd go
|
||||
make
|
||||
- name: Build
|
||||
run: |
|
||||
$Env:Path += ";$HOME\codeql"
|
||||
cd go
|
||||
make
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd go
|
||||
make test
|
||||
- name: Test
|
||||
run: |
|
||||
$Env:Path += ";$HOME\codeql"
|
||||
cd go
|
||||
make test
|
||||
|
||||
2
.github/workflows/js-ml-tests.yml
vendored
2
.github/workflows/js-ml-tests.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
paths:
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/**"
|
||||
- .github/workflows/js-ml-tests.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
@@ -14,7 +13,6 @@ on:
|
||||
paths:
|
||||
- "javascript/ql/experimental/adaptivethreatmodeling/**"
|
||||
- .github/workflows/js-ml-tests.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
1
.github/workflows/mad_regenerate-models.yml
vendored
1
.github/workflows/mad_regenerate-models.yml
vendored
@@ -9,7 +9,6 @@ on:
|
||||
- main
|
||||
paths:
|
||||
- ".github/workflows/mad_regenerate-models.yml"
|
||||
- ".github/actions/fetch-codeql/action.yml"
|
||||
|
||||
jobs:
|
||||
regenerate-models:
|
||||
|
||||
119
.github/workflows/ql-for-ql-build.yml
vendored
119
.github/workflows/ql-for-ql-build.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Find codeql
|
||||
id: find-codeql
|
||||
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
- name: Get CodeQL version
|
||||
@@ -27,37 +27,30 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
- name: Cache entire pack
|
||||
id: cache-pack
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ runner.temp }}/pack
|
||||
key: ${{ runner.os }}-pack-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('ql/**/*.rs') }}-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/**/qlpack.yml') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}--${{ hashFiles('.github/workflows/ql-for-ql-build.yml') }}
|
||||
- name: Cache queries
|
||||
if: steps.cache-pack.outputs.cache-hit != 'true'
|
||||
id: cache-queries
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ runner.temp }}/queries
|
||||
key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/**/qlpack.yml') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}--${{ hashFiles('.github/workflows/ql-for-ql-build.yml') }}
|
||||
path: ${{ runner.temp }}/query-pack.zip
|
||||
key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/**/qlpack.yml') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}
|
||||
- name: Build query pack
|
||||
if: steps.cache-queries.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-queries.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd ql/ql/src
|
||||
"${CODEQL}" pack create -j 16
|
||||
mv .codeql/pack/codeql/ql/0.0.0 ${{ runner.temp }}/queries
|
||||
"${CODEQL}" pack create
|
||||
cd .codeql/pack/codeql/ql/0.0.0
|
||||
zip "${PACKZIP}" -r .
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
- name: Move cache queries to pack
|
||||
if: steps.cache-pack.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cp -r ${{ runner.temp }}/queries ${{ runner.temp }}/pack
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
|
||||
PACKZIP: ${{ runner.temp }}/query-pack.zip
|
||||
- name: Upload query pack
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: query-pack-zip
|
||||
path: ${{ runner.temp }}/query-pack.zip
|
||||
|
||||
### Build the extractor ###
|
||||
- name: Cache entire extractor
|
||||
if: steps.cache-pack.outputs.cache-hit != 'true'
|
||||
id: cache-extractor
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
@@ -68,7 +61,7 @@ jobs:
|
||||
ql/target/release/ql-extractor.exe
|
||||
key: ${{ runner.os }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('ql/**/*.rs') }}
|
||||
- name: Cache cargo
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
@@ -77,35 +70,72 @@ jobs:
|
||||
ql/target
|
||||
key: ${{ runner.os }}-rust-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
|
||||
- name: Check formatting
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd ql; cargo fmt --all -- --check
|
||||
- name: Build
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd ql; cargo build --verbose
|
||||
- name: Run tests
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd ql; cargo test --verbose
|
||||
- name: Release build
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: cd ql; cargo build --release
|
||||
- name: Generate dbscheme
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true' && steps.cache-pack.outputs.cache-hit != 'true'
|
||||
if: steps.cache-extractor.outputs.cache-hit != 'true'
|
||||
run: ql/target/release/ql-generator --dbscheme ql/ql/src/ql.dbscheme --library ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: extractor-ubuntu-latest
|
||||
path: |
|
||||
ql/target/release/ql-autobuilder
|
||||
ql/target/release/ql-autobuilder.exe
|
||||
ql/target/release/ql-extractor
|
||||
ql/target/release/ql-extractor.exe
|
||||
retention-days: 1
|
||||
|
||||
### Package the queries and extractor ###
|
||||
- name: Package pack
|
||||
if: steps.cache-pack.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cp -r ql/codeql-extractor.yml ql/tools ql/ql/src/ql.dbscheme.stats ${PACK}/
|
||||
mkdir -p ${PACK}/tools/linux64
|
||||
cp ql/target/release/ql-autobuilder ${PACK}/tools/linux64/autobuilder
|
||||
cp ql/target/release/ql-extractor ${PACK}/tools/linux64/extractor
|
||||
chmod +x ${PACK}/tools/linux64/autobuilder
|
||||
chmod +x ${PACK}/tools/linux64/extractor
|
||||
env:
|
||||
PACK: ${{ runner.temp }}/pack
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: query-pack-zip
|
||||
path: query-pack-zip
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: extractor-ubuntu-latest
|
||||
path: linux64
|
||||
- run: |
|
||||
unzip query-pack-zip/*.zip -d pack
|
||||
cp -r ql/codeql-extractor.yml ql/tools ql/ql/src/ql.dbscheme.stats pack/
|
||||
mkdir -p pack/tools/linux64
|
||||
if [[ -f linux64/ql-autobuilder ]]; then
|
||||
cp linux64/ql-autobuilder pack/tools/linux64/autobuilder
|
||||
chmod +x pack/tools/linux64/autobuilder
|
||||
fi
|
||||
if [[ -f linux64/ql-extractor ]]; then
|
||||
cp linux64/ql-extractor pack/tools/linux64/extractor
|
||||
chmod +x pack/tools/linux64/extractor
|
||||
fi
|
||||
cd pack
|
||||
zip -rq ../codeql-ql.zip .
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: codeql-ql-pack
|
||||
path: codeql-ql.zip
|
||||
retention-days: 1
|
||||
|
||||
### Run the analysis ###
|
||||
- name: Download pack
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: codeql-ql-pack
|
||||
path: ${{ runner.temp }}/codeql-ql-pack-artifact
|
||||
|
||||
- name: Prepare pack
|
||||
run: |
|
||||
unzip "${PACK_ARTIFACT}/*.zip" -d "${PACK}"
|
||||
env:
|
||||
PACK_ARTIFACT: ${{ runner.temp }}/codeql-ql-pack-artifact
|
||||
PACK: ${{ runner.temp }}/pack
|
||||
- name: Hack codeql-action options
|
||||
run: |
|
||||
JSON=$(jq -nc --arg pack "${PACK}" '.database."run-queries"=["--search-path", $pack] | .resolve.queries=["--search-path", $pack] | .resolve.extractor=["--search-path", $pack] | .database.init=["--search-path", $pack]')
|
||||
@@ -119,26 +149,21 @@ jobs:
|
||||
echo " - ql/ql/test" >> ${CONF}
|
||||
echo " - \"*/ql/lib/upgrades/\"" >> ${CONF}
|
||||
echo "disable-default-queries: true" >> ${CONF}
|
||||
echo "queries:" >> ${CONF}
|
||||
echo " - uses: ./ql/ql/src/codeql-suites/ql-code-scanning.qls" >> ${CONF}
|
||||
echo "packs:" >> ${CONF}
|
||||
echo " - codeql/ql" >> ${CONF}
|
||||
echo "Config file: "
|
||||
cat ${CONF}
|
||||
env:
|
||||
CONF: ./ql-for-ql-config.yml
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: ql
|
||||
db-location: ${{ runner.temp }}/db
|
||||
config-file: ./ql-for-ql-config.yml
|
||||
- name: Move pack cache
|
||||
run: |
|
||||
cp -r ${PACK}/.cache ql/ql/src/.cache
|
||||
env:
|
||||
PACK: ${{ runner.temp }}/pack
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
category: "ql-for-ql"
|
||||
- name: Copy sarif file to CWD
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
- name: Find codeql
|
||||
id: find-codeql
|
||||
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
- uses: actions/cache@v3
|
||||
|
||||
4
.github/workflows/ql-for-ql-tests.yml
vendored
4
.github/workflows/ql-for-ql-tests.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Find codeql
|
||||
id: find-codeql
|
||||
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
- uses: actions/cache@v3
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
- name: Check QL formatting
|
||||
run: |
|
||||
find ql/ql/src "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 "${CODEQL}" query format --check-only
|
||||
find ql/ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 "${CODEQL}" query format --check-only
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
- name: Check QL compilation
|
||||
|
||||
3
.github/workflows/query-list.yml
vendored
3
.github/workflows/query-list.yml
vendored
@@ -10,7 +10,6 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/query-list.yml'
|
||||
- '.github/actions/fetch-codeql/action.yml'
|
||||
- 'misc/scripts/generate-code-scanning-query-list.py'
|
||||
|
||||
jobs:
|
||||
@@ -30,6 +29,8 @@ jobs:
|
||||
- name: Download CodeQL CLI
|
||||
# Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo
|
||||
uses: ./codeql/.github/actions/fetch-codeql
|
||||
- name: Unzip CodeQL CLI
|
||||
run: unzip -d codeql-cli codeql-linux64.zip
|
||||
- name: Build code scanning query list
|
||||
run: |
|
||||
python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv
|
||||
|
||||
37
.github/workflows/ruby-build.yml
vendored
37
.github/workflows/ruby-build.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
paths:
|
||||
- "ruby/**"
|
||||
- .github/workflows/ruby-build.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
@@ -14,7 +13,6 @@ on:
|
||||
paths:
|
||||
- "ruby/**"
|
||||
- .github/workflows/ruby-build.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
@@ -92,14 +90,19 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- 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
|
||||
run: |
|
||||
codeql pack create ql/lib --output target/packs
|
||||
codeql pack install ql/src
|
||||
codeql pack create ql/src --output target/packs
|
||||
codeql/codeql pack create ql/lib --output target/packs
|
||||
codeql/codeql pack install ql/src
|
||||
codeql/codeql pack create ql/src --output target/packs
|
||||
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}/{}" \;)
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@@ -176,15 +179,19 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [package]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Fetch CodeQL
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Shopify/example-ruby-app
|
||||
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
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
@@ -208,12 +215,12 @@ jobs:
|
||||
- name: Run QL test
|
||||
shell: bash
|
||||
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
|
||||
shell: bash
|
||||
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
|
||||
shell: bash
|
||||
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
|
||||
|
||||
2
.github/workflows/ruby-qltest.yml
vendored
2
.github/workflows/ruby-qltest.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
paths:
|
||||
- "ruby/**"
|
||||
- .github/workflows/ruby-qltest.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
@@ -14,7 +13,6 @@ on:
|
||||
paths:
|
||||
- "ruby/**"
|
||||
- .github/workflows/ruby-qltest.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
|
||||
1
.github/workflows/swift-codegen.yml
vendored
1
.github/workflows/swift-codegen.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
paths:
|
||||
- "swift/**"
|
||||
- .github/workflows/swift-codegen.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
branches:
|
||||
- main
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ on:
|
||||
paths:
|
||||
- "swift/**"
|
||||
- .github/workflows/swift-integration-tests.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
|
||||
1
.github/workflows/swift-qltest.yml
vendored
1
.github/workflows/swift-qltest.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
paths:
|
||||
- "swift/**"
|
||||
- .github/workflows/swift-qltest.yml
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
|
||||
2
.github/workflows/validate-change-notes.yml
vendored
2
.github/workflows/validate-change-notes.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
paths:
|
||||
- "*/ql/*/change-notes/**/*"
|
||||
- ".github/workflows/validate-change-notes.yml"
|
||||
- ".github/actions/fetch-codeql/action.yml"
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
@@ -13,7 +12,6 @@ on:
|
||||
paths:
|
||||
- "*/ql/*/change-notes/**/*"
|
||||
- ".github/workflows/validate-change-notes.yml"
|
||||
- ".github/actions/fetch-codeql/action.yml"
|
||||
|
||||
jobs:
|
||||
check-change-note:
|
||||
|
||||
@@ -392,8 +392,7 @@
|
||||
"python/ql/test/TestUtilities/InlineExpectationsTest.qll",
|
||||
"ruby/ql/test/TestUtilities/InlineExpectationsTest.qll",
|
||||
"ql/ql/test/TestUtilities/InlineExpectationsTest.qll",
|
||||
"go/ql/test/TestUtilities/InlineExpectationsTest.qll",
|
||||
"swift/ql/test/TestUtilities/InlineExpectationsTest.qll"
|
||||
"go/ql/test/TestUtilities/InlineExpectationsTest.qll"
|
||||
],
|
||||
"C++ ExternalAPIs": [
|
||||
"cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll",
|
||||
@@ -485,39 +484,28 @@
|
||||
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll"
|
||||
],
|
||||
"ReDoS Util Python/JS/Ruby/Java": [
|
||||
"javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll",
|
||||
"python/ql/lib/semmle/python/security/regexp/NfaUtils.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll",
|
||||
"java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll"
|
||||
"javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll",
|
||||
"python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll",
|
||||
"java/ql/lib/semmle/code/java/security/performance/ReDoSUtil.qll"
|
||||
],
|
||||
"ReDoS Exponential Python/JS/Ruby/Java": [
|
||||
"javascript/ql/lib/semmle/javascript/security/regexp/ExponentialBackTracking.qll",
|
||||
"python/ql/lib/semmle/python/security/regexp/ExponentialBackTracking.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/regexp/ExponentialBackTracking.qll",
|
||||
"java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll"
|
||||
"javascript/ql/lib/semmle/javascript/security/performance/ExponentialBackTracking.qll",
|
||||
"python/ql/lib/semmle/python/security/performance/ExponentialBackTracking.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/performance/ExponentialBackTracking.qll",
|
||||
"java/ql/lib/semmle/code/java/security/performance/ExponentialBackTracking.qll"
|
||||
],
|
||||
"ReDoS Polynomial Python/JS/Ruby/Java": [
|
||||
"javascript/ql/lib/semmle/javascript/security/regexp/SuperlinearBackTracking.qll",
|
||||
"python/ql/lib/semmle/python/security/regexp/SuperlinearBackTracking.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/regexp/SuperlinearBackTracking.qll",
|
||||
"java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll"
|
||||
],
|
||||
"RegexpMatching Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll",
|
||||
"python/ql/lib/semmle/python/security/regexp/RegexpMatching.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/regexp/RegexpMatching.qll"
|
||||
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
|
||||
"python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/performance/SuperlinearBackTracking.qll",
|
||||
"java/ql/lib/semmle/code/java/security/performance/SuperlinearBackTracking.qll"
|
||||
],
|
||||
"BadTagFilterQuery Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll",
|
||||
"python/ql/lib/semmle/python/security/BadTagFilterQuery.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/BadTagFilterQuery.qll"
|
||||
],
|
||||
"OverlyLargeRange Python/JS/Ruby/Java": [
|
||||
"javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll",
|
||||
"python/ql/lib/semmle/python/security/OverlyLargeRangeQuery.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/OverlyLargeRangeQuery.qll",
|
||||
"java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll"
|
||||
],
|
||||
"CFG": [
|
||||
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
|
||||
"ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll",
|
||||
@@ -597,9 +585,5 @@
|
||||
"Swift patterns test file": [
|
||||
"swift/ql/test/extractor-tests/patterns/patterns.swift",
|
||||
"swift/ql/test/library-tests/parent/patterns.swift"
|
||||
],
|
||||
"IncompleteMultiCharacterSanitization JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/IncompleteMultiCharacterSanitizationQuery.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/IncompleteMultiCharacterSanitizationQuery.qll"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
description: Add new builtin operations
|
||||
compatibility: partial
|
||||
exprs.rel: run exprs.qlo
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
description: Support all constant attribute arguments
|
||||
compatibility: backwards
|
||||
attribute_arg_constant.rel: delete
|
||||
attribute_args.rel: run attribute_args.qlo
|
||||
@@ -1,13 +0,0 @@
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Expr expr, int kind, int kind_new, Location location
|
||||
where
|
||||
exprs(expr, kind, location) and
|
||||
if expr instanceof @blockassignexpr then kind_new = 0 else kind_new = kind
|
||||
select expr, kind_new, location
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
description: Support block assignment
|
||||
compatibility: partial
|
||||
exprs.rel: run exprs.qlo
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
description: Add relation for orphaned local variables
|
||||
compatibility: full
|
||||
orphaned_variables.rel: delete
|
||||
@@ -1,39 +1,3 @@
|
||||
## 0.3.5
|
||||
|
||||
## 0.3.4
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added support for getting the link targets of global and namespace variables.
|
||||
* Added a `BlockAssignExpr` class, which models a `memcpy`-like operation used in compiler generated copy/move constructors and assignment operations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
## 0.3.2
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* 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`.
|
||||
@@ -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.
|
||||
@@ -1,15 +0,0 @@
|
||||
## 0.3.4
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added support for getting the link targets of global and namespace variables.
|
||||
* Added a `BlockAssignExpr` class, which models a `memcpy`-like operation used in compiler generated copy/move constructors and assignment operations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
@@ -1 +0,0 @@
|
||||
## 0.3.5
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.5
|
||||
lastReleaseVersion: 0.3.1
|
||||
|
||||
@@ -119,67 +119,27 @@ module SemanticExprConfig {
|
||||
result = block.getDisplayIndex()
|
||||
}
|
||||
|
||||
newtype TSsaVariable =
|
||||
TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or
|
||||
TSsaOperand(IR::Operand op) { op.isDefinitionInexact() }
|
||||
class SsaVariable instanceof IR::Instruction {
|
||||
SsaVariable() { super.hasMemoryResult() }
|
||||
|
||||
class SsaVariable extends TSsaVariable {
|
||||
string toString() { none() }
|
||||
final string toString() { result = super.toString() }
|
||||
|
||||
Location getLocation() { none() }
|
||||
|
||||
IR::Instruction asInstruction() { none() }
|
||||
|
||||
IR::Operand asOperand() { none() }
|
||||
final Location getLocation() { result = super.getLocation() }
|
||||
}
|
||||
|
||||
class SsaInstructionVariable extends SsaVariable, TSsaInstruction {
|
||||
IR::Instruction instr;
|
||||
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v = sourceExpr }
|
||||
|
||||
SsaInstructionVariable() { this = TSsaInstruction(instr) }
|
||||
predicate phi(SsaVariable v) { v instanceof IR::PhiInstruction }
|
||||
|
||||
final override string toString() { result = instr.toString() }
|
||||
SsaVariable getAPhiInput(SsaVariable v) { result = v.(IR::PhiInstruction).getAnInput() }
|
||||
|
||||
final override Location getLocation() { result = instr.getLocation() }
|
||||
|
||||
final override IR::Instruction asInstruction() { result = instr }
|
||||
}
|
||||
|
||||
class SsaOperand extends SsaVariable, TSsaOperand {
|
||||
IR::Operand op;
|
||||
|
||||
SsaOperand() { this = TSsaOperand(op) }
|
||||
|
||||
final override string toString() { result = op.toString() }
|
||||
|
||||
final override Location getLocation() { result = op.getLocation() }
|
||||
|
||||
final override IR::Operand asOperand() { result = op }
|
||||
}
|
||||
|
||||
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v.asInstruction() = sourceExpr }
|
||||
|
||||
predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction }
|
||||
|
||||
SsaVariable getAPhiInput(SsaVariable v) {
|
||||
exists(IR::PhiInstruction instr |
|
||||
result.asInstruction() = instr.getAnInput()
|
||||
or
|
||||
result.asOperand() = instr.getAnInputOperand()
|
||||
)
|
||||
}
|
||||
|
||||
Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v.asInstruction() }
|
||||
Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v }
|
||||
|
||||
SemType getSsaVariableType(SsaVariable v) {
|
||||
result = getSemanticType(v.asInstruction().getResultIRType())
|
||||
result = getSemanticType(v.(IR::Instruction).getResultIRType())
|
||||
}
|
||||
|
||||
BasicBlock getSsaVariableBasicBlock(SsaVariable v) {
|
||||
result = v.asInstruction().getBlock()
|
||||
or
|
||||
result = v.asOperand().getUse().getBlock()
|
||||
}
|
||||
BasicBlock getSsaVariableBasicBlock(SsaVariable v) { result = v.(IR::Instruction).getBlock() }
|
||||
|
||||
private newtype TReadPosition =
|
||||
TReadPositionBlock(IR::IRBlock block) or
|
||||
@@ -209,9 +169,7 @@ module SemanticExprConfig {
|
||||
|
||||
final override predicate hasRead(SsaVariable v) {
|
||||
exists(IR::Operand operand |
|
||||
operand.getDef() = v.asInstruction() and
|
||||
not operand instanceof IR::PhiInputOperand and
|
||||
operand.getUse().getBlock() = block
|
||||
operand.getDef() = v and not operand instanceof IR::PhiInputOperand
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -228,7 +186,7 @@ module SemanticExprConfig {
|
||||
|
||||
final override predicate hasRead(SsaVariable v) {
|
||||
exists(IR::PhiInputOperand operand |
|
||||
operand.getDef() = v.asInstruction() and
|
||||
operand.getDef() = v and
|
||||
operand.getPredecessorBlock() = pred and
|
||||
operand.getUse().getBlock() = succ
|
||||
)
|
||||
@@ -247,16 +205,17 @@ module SemanticExprConfig {
|
||||
exists(IR::PhiInputOperand operand |
|
||||
pos = TReadPositionPhiInputEdge(operand.getPredecessorBlock(), operand.getUse().getBlock())
|
||||
|
|
||||
phi.asInstruction() = operand.getUse() and
|
||||
(
|
||||
input.asInstruction() = operand.getDef()
|
||||
or
|
||||
input.asOperand() = operand
|
||||
)
|
||||
phi = operand.getUse() and input = operand.getDef()
|
||||
)
|
||||
}
|
||||
|
||||
class Bound instanceof IRBound::Bound {
|
||||
Bound() {
|
||||
this instanceof IRBound::ZeroBound
|
||||
or
|
||||
this.(IRBound::ValueNumberBound).getValueNumber().getAnInstruction() instanceof SsaVariable
|
||||
}
|
||||
|
||||
string toString() { result = super.toString() }
|
||||
|
||||
final Location getLocation() { result = super.getLocation() }
|
||||
@@ -269,13 +228,13 @@ module SemanticExprConfig {
|
||||
|
||||
override string toString() {
|
||||
result =
|
||||
min(SsaVariable v |
|
||||
v.asInstruction() = bound.getValueNumber().getAnInstruction()
|
||||
min(SsaVariable instr |
|
||||
instr = bound.getValueNumber().getAnInstruction()
|
||||
|
|
||||
v
|
||||
instr
|
||||
order by
|
||||
v.asInstruction().getBlock().getDisplayIndex(),
|
||||
v.asInstruction().getDisplayIndexInBlock()
|
||||
instr.(IR::Instruction).getBlock().getDisplayIndex(),
|
||||
instr.(IR::Instruction).getDisplayIndexInBlock()
|
||||
).toString()
|
||||
}
|
||||
}
|
||||
@@ -283,7 +242,7 @@ module SemanticExprConfig {
|
||||
predicate zeroBound(Bound bound) { bound instanceof IRBound::ZeroBound }
|
||||
|
||||
predicate ssaBound(Bound bound, SsaVariable v) {
|
||||
v.asInstruction() = bound.(IRBound::ValueNumberBound).getValueNumber().getAnInstruction()
|
||||
v = bound.(IRBound::ValueNumberBound).getValueNumber().getAnInstruction()
|
||||
}
|
||||
|
||||
Expr getBoundExpr(Bound bound, int delta) {
|
||||
@@ -292,20 +251,22 @@ module SemanticExprConfig {
|
||||
|
||||
class Guard = IRGuards::IRGuardCondition;
|
||||
|
||||
predicate guard(Guard guard, BasicBlock block) { block = guard.getBlock() }
|
||||
predicate guard(Guard guard, BasicBlock block) {
|
||||
block = guard.(IRGuards::IRGuardCondition).getBlock()
|
||||
}
|
||||
|
||||
Expr getGuardAsExpr(Guard guard) { result = guard }
|
||||
|
||||
predicate equalityGuard(Guard guard, Expr e1, Expr e2, boolean polarity) {
|
||||
guard.comparesEq(e1.getAUse(), e2.getAUse(), 0, true, polarity)
|
||||
guard.(IRGuards::IRGuardCondition).comparesEq(e1.getAUse(), e2.getAUse(), 0, true, polarity)
|
||||
}
|
||||
|
||||
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock controlled, boolean branch) {
|
||||
guard.controls(controlled, branch)
|
||||
guard.(IRGuards::IRGuardCondition).controls(controlled, branch)
|
||||
}
|
||||
|
||||
predicate guardHasBranchEdge(Guard guard, BasicBlock bb1, BasicBlock bb2, boolean branch) {
|
||||
guard.controlsEdge(bb1, bb2, branch)
|
||||
guard.(IRGuards::IRGuardCondition).controlsEdge(bb1, bb2, branch)
|
||||
}
|
||||
|
||||
Guard comparisonGuard(Expr e) { result = e }
|
||||
@@ -323,13 +284,9 @@ SemBasicBlock getSemanticBasicBlock(IR::IRBlock block) { result = block }
|
||||
|
||||
IR::IRBlock getCppBasicBlock(SemBasicBlock block) { block = result }
|
||||
|
||||
SemSsaVariable getSemanticSsaVariable(IR::Instruction instr) {
|
||||
result.(SemanticExprConfig::SsaVariable).asInstruction() = instr
|
||||
}
|
||||
SemSsaVariable getSemanticSsaVariable(IR::Instruction instr) { result = instr }
|
||||
|
||||
IR::Instruction getCppSsaVariableInstruction(SemSsaVariable var) {
|
||||
var.(SemanticExprConfig::SsaVariable).asInstruction() = result
|
||||
}
|
||||
IR::Instruction getCppSsaVariableInstruction(SemSsaVariable v) { v = result }
|
||||
|
||||
SemBound getSemanticBound(IRBound::Bound bound) { result = bound }
|
||||
|
||||
|
||||
@@ -160,7 +160,6 @@ private predicate phiModulusInit(SemSsaPhiNode phi, SemBound b, int val, int mod
|
||||
/**
|
||||
* Holds if all inputs to `phi` numbered `1` to `rix` are equal to `b + val` modulo `mod`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int mod, int rix) {
|
||||
rix = 0 and
|
||||
phiModulusInit(phi, b, val, mod)
|
||||
@@ -170,7 +169,7 @@ private predicate phiModulusRankStep(SemSsaPhiNode phi, SemBound b, int val, int
|
||||
val = remainder(v1, mod)
|
||||
|
|
||||
exists(int v2, int m2 |
|
||||
rankedPhiInput(pragma[only_bind_out](phi), inp, edge, rix) and
|
||||
rankedPhiInput(phi, inp, edge, rix) and
|
||||
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
|
||||
ssaModulus(inp, edge, b, v2, m2) and
|
||||
mod = m1.gcd(m2).gcd(v1 - v2)
|
||||
|
||||
@@ -342,10 +342,7 @@ private class ConvertOrBoxExpr extends SemUnaryExpr {
|
||||
* A cast that can be ignored for the purpose of range analysis.
|
||||
*/
|
||||
private class SafeCastExpr extends ConvertOrBoxExpr {
|
||||
SafeCastExpr() {
|
||||
conversionCannotOverflow(getTrackedType(pragma[only_bind_into](getOperand())),
|
||||
getTrackedType(this))
|
||||
}
|
||||
SafeCastExpr() { conversionCannotOverflow(getTrackedType(getOperand()), getTrackedType(this)) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -189,12 +189,9 @@ private class BinarySignExpr extends FlowSignExpr {
|
||||
BinarySignExpr() { binary = this }
|
||||
|
||||
override Sign getSignRestriction() {
|
||||
exists(SemExpr left, SemExpr right |
|
||||
binaryExprOperands(binary, left, right) and
|
||||
result =
|
||||
semExprSign(pragma[only_bind_out](left))
|
||||
.applyBinaryOp(semExprSign(pragma[only_bind_out](right)), binary.getOpcode())
|
||||
)
|
||||
result =
|
||||
semExprSign(binary.getLeftOperand())
|
||||
.applyBinaryOp(semExprSign(binary.getRightOperand()), binary.getOpcode())
|
||||
or
|
||||
exists(SemDivExpr div | div = binary |
|
||||
result = semExprSign(div.getLeftOperand()) and
|
||||
@@ -204,10 +201,6 @@ private class BinarySignExpr extends FlowSignExpr {
|
||||
}
|
||||
}
|
||||
|
||||
private predicate binaryExprOperands(SemBinaryExpr binary, SemExpr left, SemExpr right) {
|
||||
binary.getLeftOperand() = left and binary.getRightOperand() = right
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Convert`, `Box`, or `Unbox` expression.
|
||||
*/
|
||||
@@ -228,7 +221,7 @@ private class UnarySignExpr extends FlowSignExpr {
|
||||
UnarySignExpr() { unary = this and not this instanceof SemCastExpr }
|
||||
|
||||
override Sign getSignRestriction() {
|
||||
result = semExprSign(pragma[only_bind_out](unary.getOperand())).applyUnaryOp(unary.getOpcode())
|
||||
result = semExprSign(unary.getOperand()).applyUnaryOp(unary.getOpcode())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.3.5
|
||||
version: 0.3.2-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -218,6 +218,8 @@ class Folder extends Container, @folder {
|
||||
class File extends Container, @file {
|
||||
override string getAbsolutePath() { files(underlyingElement(this), result) }
|
||||
|
||||
override string toString() { result = Container.super.toString() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "File" }
|
||||
|
||||
override Location getLocation() {
|
||||
|
||||
@@ -41,15 +41,6 @@ class LinkTarget extends @link_target {
|
||||
* translation units which contributed to this link target.
|
||||
*/
|
||||
Class getAClass() { link_parent(unresolveElement(result), this) }
|
||||
|
||||
/**
|
||||
* Gets a global or namespace variable which was compiled into this
|
||||
* link target, or had its declaration included by one of the translation
|
||||
* units which contributed to this link target.
|
||||
*/
|
||||
GlobalOrNamespaceVariable getAGlobalOrNamespaceVariable() {
|
||||
link_parent(unresolveElement(result), this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,7 @@ private import semmle.code.cpp.internal.ResolveClass
|
||||
class Specifier extends Element, @specifier {
|
||||
/** Gets a dummy location for the specifier. */
|
||||
override Location getLocation() {
|
||||
exists(this) and
|
||||
suppressUnusedThis(this) and
|
||||
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
|
||||
* a constant or a token.
|
||||
* a string or a number.
|
||||
*/
|
||||
string getValueText() {
|
||||
if underlyingElement(this) instanceof @attribute_arg_constant_expr
|
||||
then result = this.getValueConstant().getValue()
|
||||
else attribute_arg_value(underlyingElement(this), result)
|
||||
}
|
||||
string getValueText() { attribute_arg_value(underlyingElement(this), result) }
|
||||
|
||||
/**
|
||||
* 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)) }
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@@ -305,12 +294,11 @@ class AttributeArgument extends Element, @attribute_arg {
|
||||
(
|
||||
if underlyingElement(this) instanceof @attribute_arg_type
|
||||
then tail = this.getValueType().getName()
|
||||
else
|
||||
if underlyingElement(this) instanceof @attribute_arg_constant_expr
|
||||
then tail = this.getValueConstant().toString()
|
||||
else tail = this.getValueText()
|
||||
else tail = this.getValueText()
|
||||
) and
|
||||
result = prefix + tail
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate suppressUnusedThis(Specifier s) { any() }
|
||||
|
||||
@@ -398,8 +398,6 @@ class LocalVariable extends LocalScopeVariable, @localvariable {
|
||||
exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result)
|
||||
or
|
||||
exists(ConditionDeclExpr e | e.getVariable() = this and e.getEnclosingFunction() = result)
|
||||
or
|
||||
orphaned_variables(underlyingElement(this), unresolveElement(result))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,9 +471,6 @@ class GlobalOrNamespaceVariable extends Variable, @globalvariable {
|
||||
override Type getType() { globalvariables(underlyingElement(this), unresolveElement(result), _) }
|
||||
|
||||
override Element getEnclosingElement() { none() }
|
||||
|
||||
/** Gets a link target which compiled or referenced this global or namespace variable. */
|
||||
LinkTarget getALinkTarget() { this = result.getAGlobalOrNamespaceVariable() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
107
cpp/ql/lib/semmle/code/cpp/XML.qll
Normal file → Executable file
107
cpp/ql/lib/semmle/code/cpp/XML.qll
Normal file → Executable file
@@ -8,7 +8,7 @@ private class TXmlLocatable =
|
||||
@xmldtd or @xmlelement or @xmlattribute or @xmlnamespace or @xmlcomment or @xmlcharacters;
|
||||
|
||||
/** An XML element that has a location. */
|
||||
class XmlLocatable extends @xmllocatable, TXmlLocatable {
|
||||
class XMLLocatable extends @xmllocatable, TXmlLocatable {
|
||||
/** Gets the source location for this element. */
|
||||
Location getLocation() { xmllocations(this, result) }
|
||||
|
||||
@@ -32,16 +32,13 @@ class XmlLocatable extends @xmllocatable, TXmlLocatable {
|
||||
string toString() { none() } // overridden in subclasses
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlLocatable */
|
||||
deprecated class XMLLocatable = XmlLocatable;
|
||||
|
||||
/**
|
||||
* An `XmlParent` is either an `XmlElement` or an `XmlFile`,
|
||||
* An `XMLParent` is either an `XMLElement` or an `XMLFile`,
|
||||
* both of which can contain other elements.
|
||||
*/
|
||||
class XmlParent extends @xmlparent {
|
||||
XmlParent() {
|
||||
// explicitly restrict `this` to be either an `XmlElement` or an `XmlFile`;
|
||||
class XMLParent extends @xmlparent {
|
||||
XMLParent() {
|
||||
// explicitly restrict `this` to be either an `XMLElement` or an `XMLFile`;
|
||||
// the type `@xmlparent` currently also includes non-XML files
|
||||
this instanceof @xmlelement or xmlEncoding(this, _)
|
||||
}
|
||||
@@ -53,28 +50,28 @@ class XmlParent extends @xmlparent {
|
||||
string getName() { none() } // overridden in subclasses
|
||||
|
||||
/** Gets the file to which this XML parent belongs. */
|
||||
XmlFile getFile() { result = this or xmlElements(this, _, _, _, result) }
|
||||
XMLFile getFile() { result = this or xmlElements(this, _, _, _, result) }
|
||||
|
||||
/** Gets the child element at a specified index of this XML parent. */
|
||||
XmlElement getChild(int index) { xmlElements(result, _, this, index, _) }
|
||||
XMLElement getChild(int index) { xmlElements(result, _, this, index, _) }
|
||||
|
||||
/** Gets a child element of this XML parent. */
|
||||
XmlElement getAChild() { xmlElements(result, _, this, _, _) }
|
||||
XMLElement getAChild() { xmlElements(result, _, this, _, _) }
|
||||
|
||||
/** Gets a child element of this XML parent with the given `name`. */
|
||||
XmlElement getAChild(string name) { xmlElements(result, _, this, _, _) and result.hasName(name) }
|
||||
XMLElement getAChild(string name) { xmlElements(result, _, this, _, _) and result.hasName(name) }
|
||||
|
||||
/** Gets a comment that is a child of this XML parent. */
|
||||
XmlComment getAComment() { xmlComments(result, _, this, _) }
|
||||
XMLComment getAComment() { xmlComments(result, _, this, _) }
|
||||
|
||||
/** Gets a character sequence that is a child of this XML parent. */
|
||||
XmlCharacters getACharactersSet() { xmlChars(result, _, this, _, _, _) }
|
||||
XMLCharacters getACharactersSet() { xmlChars(result, _, this, _, _, _) }
|
||||
|
||||
/** Gets the depth in the tree. (Overridden in XmlElement.) */
|
||||
/** Gets the depth in the tree. (Overridden in XMLElement.) */
|
||||
int getDepth() { result = 0 }
|
||||
|
||||
/** Gets the number of child XML elements of this XML parent. */
|
||||
int getNumberOfChildren() { result = count(XmlElement e | xmlElements(e, _, this, _, _)) }
|
||||
int getNumberOfChildren() { result = count(XMLElement e | xmlElements(e, _, this, _, _)) }
|
||||
|
||||
/** Gets the number of places in the body of this XML parent where text occurs. */
|
||||
int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) }
|
||||
@@ -95,12 +92,9 @@ class XmlParent extends @xmlparent {
|
||||
string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlParent */
|
||||
deprecated class XMLParent = XmlParent;
|
||||
|
||||
/** An XML file. */
|
||||
class XmlFile extends XmlParent, File {
|
||||
XmlFile() { xmlEncoding(this, _) }
|
||||
class XMLFile extends XMLParent, File {
|
||||
XMLFile() { xmlEncoding(this, _) }
|
||||
|
||||
/** Gets a printable representation of this XML file. */
|
||||
override string toString() { result = this.getName() }
|
||||
@@ -126,21 +120,15 @@ class XmlFile extends XmlParent, File {
|
||||
string getEncoding() { xmlEncoding(this, result) }
|
||||
|
||||
/** Gets the XML file itself. */
|
||||
override XmlFile getFile() { result = this }
|
||||
override XMLFile getFile() { result = this }
|
||||
|
||||
/** Gets a top-most element in an XML file. */
|
||||
XmlElement getARootElement() { result = this.getAChild() }
|
||||
XMLElement getARootElement() { result = this.getAChild() }
|
||||
|
||||
/** Gets a DTD associated with this XML file. */
|
||||
XmlDtd getADtd() { xmlDTDs(result, _, _, _, this) }
|
||||
|
||||
/** DEPRECATED: Alias for getADtd */
|
||||
deprecated XmlDtd getADTD() { result = this.getADtd() }
|
||||
XMLDTD getADTD() { xmlDTDs(result, _, _, _, this) }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlFile */
|
||||
deprecated class XMLFile = XmlFile;
|
||||
|
||||
/**
|
||||
* An XML document type definition (DTD).
|
||||
*
|
||||
@@ -152,7 +140,7 @@ deprecated class XMLFile = XmlFile;
|
||||
* <!ELEMENT lastName (#PCDATA)>
|
||||
* ```
|
||||
*/
|
||||
class XmlDtd extends XmlLocatable, @xmldtd {
|
||||
class XMLDTD extends XMLLocatable, @xmldtd {
|
||||
/** Gets the name of the root element of this DTD. */
|
||||
string getRoot() { xmlDTDs(this, result, _, _, _) }
|
||||
|
||||
@@ -166,7 +154,7 @@ class XmlDtd extends XmlLocatable, @xmldtd {
|
||||
predicate isPublic() { not xmlDTDs(this, _, "", _, _) }
|
||||
|
||||
/** Gets the parent of this DTD. */
|
||||
XmlParent getParent() { xmlDTDs(this, _, _, _, result) }
|
||||
XMLParent getParent() { xmlDTDs(this, _, _, _, result) }
|
||||
|
||||
override string toString() {
|
||||
this.isPublic() and
|
||||
@@ -177,9 +165,6 @@ class XmlDtd extends XmlLocatable, @xmldtd {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlDtd */
|
||||
deprecated class XMLDTD = XmlDtd;
|
||||
|
||||
/**
|
||||
* An XML element in an XML file.
|
||||
*
|
||||
@@ -191,7 +176,7 @@ deprecated class XMLDTD = XmlDtd;
|
||||
* </manifest>
|
||||
* ```
|
||||
*/
|
||||
class XmlElement extends @xmlelement, XmlParent, XmlLocatable {
|
||||
class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
|
||||
/** Holds if this XML element has the given `name`. */
|
||||
predicate hasName(string name) { name = this.getName() }
|
||||
|
||||
@@ -199,10 +184,10 @@ class XmlElement extends @xmlelement, XmlParent, XmlLocatable {
|
||||
override string getName() { xmlElements(this, result, _, _, _) }
|
||||
|
||||
/** Gets the XML file in which this XML element occurs. */
|
||||
override XmlFile getFile() { xmlElements(this, _, _, _, result) }
|
||||
override XMLFile getFile() { xmlElements(this, _, _, _, result) }
|
||||
|
||||
/** Gets the parent of this XML element. */
|
||||
XmlParent getParent() { xmlElements(this, _, result, _, _) }
|
||||
XMLParent getParent() { xmlElements(this, _, result, _, _) }
|
||||
|
||||
/** Gets the index of this XML element among its parent's children. */
|
||||
int getIndex() { xmlElements(this, _, _, result, _) }
|
||||
@@ -211,7 +196,7 @@ class XmlElement extends @xmlelement, XmlParent, XmlLocatable {
|
||||
predicate hasNamespace() { xmlHasNs(this, _, _) }
|
||||
|
||||
/** Gets the namespace of this XML element, if any. */
|
||||
XmlNamespace getNamespace() { xmlHasNs(this, result, _) }
|
||||
XMLNamespace getNamespace() { xmlHasNs(this, result, _) }
|
||||
|
||||
/** Gets the index of this XML element among its parent's children. */
|
||||
int getElementPositionIndex() { xmlElements(this, _, _, result, _) }
|
||||
@@ -220,10 +205,10 @@ class XmlElement extends @xmlelement, XmlParent, XmlLocatable {
|
||||
override int getDepth() { result = this.getParent().getDepth() + 1 }
|
||||
|
||||
/** Gets an XML attribute of this XML element. */
|
||||
XmlAttribute getAnAttribute() { result.getElement() = this }
|
||||
XMLAttribute getAnAttribute() { result.getElement() = this }
|
||||
|
||||
/** Gets the attribute with the specified `name`, if any. */
|
||||
XmlAttribute getAttribute(string name) { result.getElement() = this and result.getName() = name }
|
||||
XMLAttribute getAttribute(string name) { result.getElement() = this and result.getName() = name }
|
||||
|
||||
/** Holds if this XML element has an attribute with the specified `name`. */
|
||||
predicate hasAttribute(string name) { exists(this.getAttribute(name)) }
|
||||
@@ -235,9 +220,6 @@ class XmlElement extends @xmlelement, XmlParent, XmlLocatable {
|
||||
override string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlElement */
|
||||
deprecated class XMLElement = XmlElement;
|
||||
|
||||
/**
|
||||
* An attribute that occurs inside an XML element.
|
||||
*
|
||||
@@ -248,18 +230,18 @@ deprecated class XMLElement = XmlElement;
|
||||
* android:versionCode="1"
|
||||
* ```
|
||||
*/
|
||||
class XmlAttribute extends @xmlattribute, XmlLocatable {
|
||||
class XMLAttribute extends @xmlattribute, XMLLocatable {
|
||||
/** Gets the name of this attribute. */
|
||||
string getName() { xmlAttrs(this, _, result, _, _, _) }
|
||||
|
||||
/** Gets the XML element to which this attribute belongs. */
|
||||
XmlElement getElement() { xmlAttrs(this, result, _, _, _, _) }
|
||||
XMLElement getElement() { xmlAttrs(this, result, _, _, _, _) }
|
||||
|
||||
/** Holds if this attribute has a namespace. */
|
||||
predicate hasNamespace() { xmlHasNs(this, _, _) }
|
||||
|
||||
/** Gets the namespace of this attribute, if any. */
|
||||
XmlNamespace getNamespace() { xmlHasNs(this, result, _) }
|
||||
XMLNamespace getNamespace() { xmlHasNs(this, result, _) }
|
||||
|
||||
/** Gets the value of this attribute. */
|
||||
string getValue() { xmlAttrs(this, _, _, result, _, _) }
|
||||
@@ -268,9 +250,6 @@ class XmlAttribute extends @xmlattribute, XmlLocatable {
|
||||
override string toString() { result = this.getName() + "=" + this.getValue() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlAttribute */
|
||||
deprecated class XMLAttribute = XmlAttribute;
|
||||
|
||||
/**
|
||||
* A namespace used in an XML file.
|
||||
*
|
||||
@@ -280,29 +259,23 @@ deprecated class XMLAttribute = XmlAttribute;
|
||||
* xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
* ```
|
||||
*/
|
||||
class XmlNamespace extends XmlLocatable, @xmlnamespace {
|
||||
class XMLNamespace extends XMLLocatable, @xmlnamespace {
|
||||
/** Gets the prefix of this namespace. */
|
||||
string getPrefix() { xmlNs(this, result, _, _) }
|
||||
|
||||
/** Gets the URI of this namespace. */
|
||||
string getUri() { xmlNs(this, _, result, _) }
|
||||
|
||||
/** DEPRECATED: Alias for getUri */
|
||||
deprecated string getURI() { result = this.getUri() }
|
||||
string getURI() { xmlNs(this, _, result, _) }
|
||||
|
||||
/** Holds if this namespace has no prefix. */
|
||||
predicate isDefault() { this.getPrefix() = "" }
|
||||
|
||||
override string toString() {
|
||||
this.isDefault() and result = this.getUri()
|
||||
this.isDefault() and result = this.getURI()
|
||||
or
|
||||
not this.isDefault() and result = this.getPrefix() + ":" + this.getUri()
|
||||
not this.isDefault() and result = this.getPrefix() + ":" + this.getURI()
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlNamespace */
|
||||
deprecated class XMLNamespace = XmlNamespace;
|
||||
|
||||
/**
|
||||
* A comment in an XML file.
|
||||
*
|
||||
@@ -312,20 +285,17 @@ deprecated class XMLNamespace = XmlNamespace;
|
||||
* <!-- This is a comment. -->
|
||||
* ```
|
||||
*/
|
||||
class XmlComment extends @xmlcomment, XmlLocatable {
|
||||
class XMLComment extends @xmlcomment, XMLLocatable {
|
||||
/** Gets the text content of this XML comment. */
|
||||
string getText() { xmlComments(this, result, _, _) }
|
||||
|
||||
/** Gets the parent of this XML comment. */
|
||||
XmlParent getParent() { xmlComments(this, _, result, _) }
|
||||
XMLParent getParent() { xmlComments(this, _, result, _) }
|
||||
|
||||
/** Gets a printable representation of this XML comment. */
|
||||
override string toString() { result = this.getText() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlComment */
|
||||
deprecated class XMLComment = XmlComment;
|
||||
|
||||
/**
|
||||
* A sequence of characters that occurs between opening and
|
||||
* closing tags of an XML element, excluding other elements.
|
||||
@@ -336,12 +306,12 @@ deprecated class XMLComment = XmlComment;
|
||||
* <content>This is a sequence of characters.</content>
|
||||
* ```
|
||||
*/
|
||||
class XmlCharacters extends @xmlcharacters, XmlLocatable {
|
||||
class XMLCharacters extends @xmlcharacters, XMLLocatable {
|
||||
/** Gets the content of this character sequence. */
|
||||
string getCharacters() { xmlChars(this, result, _, _, _, _) }
|
||||
|
||||
/** Gets the parent of this character sequence. */
|
||||
XmlParent getParent() { xmlChars(this, _, result, _, _, _) }
|
||||
XMLParent getParent() { xmlChars(this, _, result, _, _, _) }
|
||||
|
||||
/** Holds if this character sequence is CDATA. */
|
||||
predicate isCDATA() { xmlChars(this, _, _, _, 1, _) }
|
||||
@@ -349,6 +319,3 @@ class XmlCharacters extends @xmlcharacters, XmlLocatable {
|
||||
/** Gets a printable representation of this XML character sequence. */
|
||||
override string toString() { result = this.getCharacters() }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for XmlCharacters */
|
||||
deprecated class XMLCharacters = XmlCharacters;
|
||||
|
||||
@@ -231,7 +231,7 @@ class BasicBlock extends ControlFlowNodeBase {
|
||||
exists(Function f | f.getBlock() = this)
|
||||
or
|
||||
exists(TryStmt t, BasicBlock tryblock |
|
||||
// a `Handler` precedes the `CatchBlock`, and is always the beginning
|
||||
// a `Handler` preceeds the `CatchBlock`, and is always the beginning
|
||||
// of a new `BasicBlock` (see `primitive_basic_block_entry_node`).
|
||||
this.(Handler).getTryStmt() = t and
|
||||
tryblock.isReachable() and
|
||||
|
||||
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
File diff suppressed because it is too large
Load Diff
@@ -699,7 +699,7 @@ private predicate exprToExprStep_nocfg(Expr fromExpr, Expr toExpr) {
|
||||
call.getTarget() = f and
|
||||
// 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
|
||||
// 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
|
||||
then outModel.isReturnValueDeref()
|
||||
else outModel.isReturnValue()
|
||||
|
||||
@@ -47,20 +47,6 @@ class AssignExpr extends Assignment, @assignexpr {
|
||||
override string toString() { result = "... = ..." }
|
||||
}
|
||||
|
||||
/**
|
||||
* A compiler generated assignment operation that may occur in a compiler generated
|
||||
* copy/move constructor or assignment operator, and which functions like `memcpy`
|
||||
* where the size argument is based on the type of the rvalue of the assignment.
|
||||
*/
|
||||
class BlockAssignExpr extends Assignment, @blockassignexpr {
|
||||
override string getOperator() { result = "=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BlockAssignExpr" }
|
||||
|
||||
/** Gets a textual representation of this assignment. */
|
||||
override string toString() { result = "... = ..." }
|
||||
}
|
||||
|
||||
/**
|
||||
* A non-overloaded binary assignment operation other than `=`.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -120,8 +120,8 @@ class BuiltInNoOp extends BuiltInOperation, @noopexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ `__builtin_offsetof` built-in operation (used by some implementations
|
||||
* of `offsetof`). The operation retains its semantics even in the presence
|
||||
* of an overloaded `operator &`). This is a gcc/clang extension.
|
||||
* of `offsetof`). The operation retains its semantics even in the presence
|
||||
* of an overloaded `operator &`). This is a GNU/Clang extension.
|
||||
* ```
|
||||
* struct S {
|
||||
* int a, b;
|
||||
@@ -137,8 +137,8 @@ class BuiltInOperationBuiltInOffsetOf extends BuiltInOperation, @offsetofexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ `__INTADDR__` built-in operation (used by some implementations
|
||||
* of `offsetof`). The operation retains its semantics even in the presence
|
||||
* of an overloaded `operator &`). This is an EDG extension.
|
||||
* of `offsetof`). The operation retains its semantics even in the presence
|
||||
* of an overloaded `operator &`). This is an EDG extension.
|
||||
* ```
|
||||
* struct S {
|
||||
* int a, b;
|
||||
@@ -173,7 +173,7 @@ class BuiltInOperationHasAssign extends BuiltInOperation, @hasassignexpr {
|
||||
*
|
||||
* 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 {
|
||||
@@ -189,7 +189,7 @@ class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr {
|
||||
* Returns `true` if a copy assignment operator has an empty exception
|
||||
* specification.
|
||||
* ```
|
||||
* std::integral_constant<bool, __has_nothrow_assign(_Tp)> hnta;
|
||||
* std::integral_constant< bool, __has_nothrow_assign(_Tp)> hnta;
|
||||
* ```
|
||||
*/
|
||||
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.
|
||||
* ```
|
||||
* std::integral_constant<bool, __has_nothrow_copy(MyType) >;
|
||||
* std::integral_constant< bool, __has_nothrow_copy(MyType) >;
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasNoThrowCopy extends BuiltInOperation, @hasnothrowcopy {
|
||||
@@ -266,7 +266,7 @@ class BuiltInOperationHasTrivialConstructor extends BuiltInOperation, @hastrivia
|
||||
*
|
||||
* 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 {
|
||||
@@ -468,7 +468,7 @@ class BuiltInOperationIsUnion extends BuiltInOperation, @isunionexpr {
|
||||
* ```
|
||||
* template<typename _Tp1, typename _Tp2>
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* for more information.
|
||||
* ```
|
||||
@@ -493,29 +494,11 @@ class BuiltInOperationBuiltInShuffleVector extends BuiltInOperation, @builtinshu
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
* for more information.
|
||||
* ```
|
||||
@@ -564,7 +547,7 @@ class BuiltInOperationBuiltInAddressOf extends UnaryOperation, BuiltInOperation,
|
||||
* ```
|
||||
* template<typename T, typename... Args>
|
||||
* 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
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the assignment operator `C::operator =(const D& d)` is
|
||||
* trivial (i.e., it will not call any operation that is non-trivial).
|
||||
* Returns `true` if the assignment operator `C::operator =(const C& c)` is
|
||||
* 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 {
|
||||
@@ -645,10 +631,10 @@ class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istrivial
|
||||
* The `__is_nothrow_assignable` built-in operation (used by some
|
||||
* 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).
|
||||
* ```
|
||||
* bool v = __is_nothrow_assignable(MyType1, MyType2);
|
||||
* bool v = __is_nothrow_assignable(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowassignableexpr {
|
||||
@@ -657,30 +643,15 @@ class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowas
|
||||
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
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* 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
|
||||
* variable, or (3) multiple occurrences of base `class` objects, among other
|
||||
* restrictions. See https://en.cppreference.com/w/cpp/named_req/StandardLayoutType
|
||||
* `union` WITHOUT (1) virtual functions or base classes, (2) reference member
|
||||
* variable or (3) multiple occurrences of base `class` objects, among other
|
||||
* restrictions. Please see
|
||||
* https://en.cppreference.com/w/cpp/named_req/StandardLayoutType
|
||||
* for more information.
|
||||
* ```
|
||||
* bool v = __is_standard_layout(MyType);
|
||||
@@ -697,7 +668,7 @@ class BuiltInOperationIsStandardLayout extends BuiltInOperation, @isstandardlayo
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istriviallycopyableexpr {
|
||||
@@ -711,13 +682,13 @@ class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istrivially
|
||||
* the `<type_traits>` header).
|
||||
*
|
||||
* 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
|
||||
* for more information.
|
||||
*
|
||||
* ```
|
||||
* 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 {
|
||||
@@ -734,7 +705,7 @@ class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr
|
||||
* compiler, with semantics of the `memcpy` operation.
|
||||
* ```
|
||||
* 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,
|
||||
@@ -752,7 +723,7 @@ class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation,
|
||||
* ```
|
||||
* template<typename T>
|
||||
* 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>
|
||||
* 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
|
||||
* 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
|
||||
* message forwarding. See
|
||||
* message forwarding. Please see
|
||||
* https://docs.microsoft.com/en-us/cpp/extensions/delegate-cpp-component-extensions
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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`,
|
||||
* 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.
|
||||
* ```
|
||||
* 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
|
||||
* 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
|
||||
* For more information.
|
||||
* ```
|
||||
@@ -951,7 +922,7 @@ class BuiltInOperationIsValueClass extends BuiltInOperation, @isvalueclassexpr {
|
||||
* ```
|
||||
* template<typename T>
|
||||
* 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
|
||||
* 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. */
|
||||
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" }
|
||||
}
|
||||
|
||||
@@ -596,12 +596,9 @@ class ParenthesisExpr extends Conversion, @parexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ expression that could not be resolved, or that can no longer be
|
||||
* represented due to a database upgrade or downgrade.
|
||||
* A C/C++ expression that has not been resolved.
|
||||
*
|
||||
* If the expression could not be resolved, it has type `ErroneousType`. In the
|
||||
* case of a database upgrade or downgrade, the original type from before the
|
||||
* upgrade or downgrade is kept if that type can be represented.
|
||||
* It is assigned `ErroneousType` as its type.
|
||||
*/
|
||||
class ErrorExpr extends Expr, @errorexpr {
|
||||
override string toString() { result = "<error expr>" }
|
||||
|
||||
@@ -38,9 +38,6 @@ abstract class MustFlowConfiguration extends string {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@@ -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`. */
|
||||
private predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, MustFlowConfiguration config) {
|
||||
exists(config) and
|
||||
Cached::step(pragma[only_bind_into](nodeFrom), pragma[only_bind_into](nodeTo)) and
|
||||
(
|
||||
config.allowInterproceduralFlow()
|
||||
or
|
||||
getEnclosingCallable(nodeFrom) = getEnclosingCallable(nodeTo)
|
||||
)
|
||||
Cached::step(nodeFrom, nodeTo)
|
||||
or
|
||||
config.isAdditionalFlowStep(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
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
@@ -244,25 +244,7 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
|
||||
* calling context. For example, this would happen with flow through a
|
||||
* global or static variable.
|
||||
*/
|
||||
predicate jumpStep(Node n1, Node n2) {
|
||||
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()
|
||||
)
|
||||
}
|
||||
predicate jumpStep(Node n1, Node n2) { none() }
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` via an assignment to `f`.
|
||||
|
||||
@@ -39,7 +39,7 @@ private module Liveness {
|
||||
/**
|
||||
* Holds if the `i`th node of basic block `bb` is a reference to `v` of kind `k`.
|
||||
*/
|
||||
predicate ref(BasicBlock bb, int i, SourceVariable v, RefKind k) {
|
||||
private predicate ref(BasicBlock bb, int i, SourceVariable v, RefKind k) {
|
||||
exists(boolean certain | variableRead(bb, i, v, certain) | k = Read(certain))
|
||||
or
|
||||
exists(boolean certain | variableWrite(bb, i, v, certain) | k = Write(certain))
|
||||
@@ -76,10 +76,6 @@ private module Liveness {
|
||||
not result + 1 = refRank(bb, _, v, _)
|
||||
}
|
||||
|
||||
predicate lastRefIsRead(BasicBlock bb, SourceVariable v) {
|
||||
maxRefRank(bb, v) = refRank(bb, _, v, Read(_))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the (1-based) rank of the first reference to `v` inside basic block `bb`
|
||||
* that is either a read or a certain write.
|
||||
@@ -189,29 +185,23 @@ newtype TDefinition =
|
||||
|
||||
private module SsaDefReaches {
|
||||
newtype TSsaRefKind =
|
||||
SsaActualRead() or
|
||||
SsaPhiRead() or
|
||||
SsaRead() or
|
||||
SsaDef()
|
||||
|
||||
class SsaRead = SsaActualRead or SsaPhiRead;
|
||||
|
||||
/**
|
||||
* A classification of SSA variable references into reads and definitions.
|
||||
*/
|
||||
class SsaRefKind extends TSsaRefKind {
|
||||
string toString() {
|
||||
this = SsaActualRead() and
|
||||
result = "SsaActualRead"
|
||||
or
|
||||
this = SsaPhiRead() and
|
||||
result = "SsaPhiRead"
|
||||
this = SsaRead() and
|
||||
result = "SsaRead"
|
||||
or
|
||||
this = SsaDef() and
|
||||
result = "SsaDef"
|
||||
}
|
||||
|
||||
int getOrder() {
|
||||
this instanceof SsaRead and
|
||||
this = SsaRead() and
|
||||
result = 0
|
||||
or
|
||||
this = SsaDef() and
|
||||
@@ -219,80 +209,6 @@ private module SsaDefReaches {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `bb` is in the dominance frontier of a block containing a
|
||||
* read of `v`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate inReadDominanceFrontier(BasicBlock bb, SourceVariable v) {
|
||||
exists(BasicBlock readbb | inDominanceFrontier(readbb, bb) |
|
||||
lastRefIsRead(readbb, v)
|
||||
or
|
||||
phiRead(readbb, v)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if a phi-read node should be inserted for variable `v` at the beginning
|
||||
* of basic block `bb`.
|
||||
*
|
||||
* Phi-read nodes are like normal phi nodes, but they are inserted based on reads
|
||||
* instead of writes, and only if the dominance-frontier block does not already
|
||||
* contain a reference (read or write) to `v`. Unlike normal phi nodes, this is
|
||||
* an internal implementation detail that is not exposed.
|
||||
*
|
||||
* The motivation for adding phi-reads is to improve performance of the use-use
|
||||
* calculation in cases where there is a large number of reads that can reach the
|
||||
* same join-point, and from there reach a large number of basic blocks. Example:
|
||||
*
|
||||
* ```cs
|
||||
* if (a)
|
||||
* use(x);
|
||||
* else if (b)
|
||||
* use(x);
|
||||
* else if (c)
|
||||
* use(x);
|
||||
* else if (d)
|
||||
* use(x);
|
||||
* // many more ifs ...
|
||||
*
|
||||
* // phi-read for `x` inserted here
|
||||
*
|
||||
* // program not mentioning `x`, with large basic block graph
|
||||
*
|
||||
* use(x);
|
||||
* ```
|
||||
*
|
||||
* Without phi-reads, the analysis has to replicate reachability for each of
|
||||
* the guarded uses of `x`. However, with phi-reads, the analysis will limit
|
||||
* each conditional use of `x` to reach the basic block containing the phi-read
|
||||
* node for `x`, and only that basic block will have to compute reachability
|
||||
* through the remainder of the large program.
|
||||
*
|
||||
* Like normal reads, each phi-read node `phi-read` can be reached from exactly
|
||||
* one SSA definition (without passing through another definition): Assume, for
|
||||
* the sake of contradiction, that there are two reaching definitions `def1` and
|
||||
* `def2`. Now, if both `def1` and `def2` dominate `phi-read`, then the nearest
|
||||
* dominating definition will prevent the other from reaching `phi-read`. So, at
|
||||
* least one of `def1` and `def2` cannot dominate `phi-read`; assume it is `def1`.
|
||||
* Then `def1` must go through one of its dominance-frontier blocks in order to
|
||||
* reach `phi-read`. However, such a block will always start with a (normal) phi
|
||||
* node, which contradicts reachability.
|
||||
*
|
||||
* Also, like normal reads, the unique SSA definition `def` that reaches `phi-read`,
|
||||
* will dominate `phi-read`. Assuming it doesn't means that the path from `def`
|
||||
* to `phi-read` goes through a dominance-frontier block, and hence a phi node,
|
||||
* which contradicts reachability.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate phiRead(BasicBlock bb, SourceVariable v) {
|
||||
inReadDominanceFrontier(bb, v) and
|
||||
liveAtEntry(bb, v) and
|
||||
// only if there are no other references to `v` inside `bb`
|
||||
not ref(bb, _, v, _) and
|
||||
not exists(Definition def | def.definesAt(v, bb, _))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`th node of basic block `bb` is a reference to `v`,
|
||||
* either a read (when `k` is `SsaRead()`) or an SSA definition (when `k`
|
||||
@@ -300,16 +216,11 @@ private module SsaDefReaches {
|
||||
*
|
||||
* Unlike `Liveness::ref`, this includes `phi` nodes.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) {
|
||||
variableRead(bb, i, v, _) and
|
||||
k = SsaActualRead()
|
||||
k = SsaRead()
|
||||
or
|
||||
phiRead(bb, v) and
|
||||
i = -1 and
|
||||
k = SsaPhiRead()
|
||||
or
|
||||
any(Definition def).definesAt(v, bb, i) and
|
||||
exists(Definition def | def.definesAt(v, bb, i)) and
|
||||
k = SsaDef()
|
||||
}
|
||||
|
||||
@@ -362,7 +273,7 @@ private module SsaDefReaches {
|
||||
)
|
||||
or
|
||||
ssaDefReachesRank(bb, def, rnk - 1, v) and
|
||||
rnk = ssaRefRank(bb, _, v, any(SsaRead k))
|
||||
rnk = ssaRefRank(bb, _, v, SsaRead())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -372,7 +283,7 @@ private module SsaDefReaches {
|
||||
predicate ssaDefReachesReadWithinBlock(SourceVariable v, Definition def, BasicBlock bb, int i) {
|
||||
exists(int rnk |
|
||||
ssaDefReachesRank(bb, def, rnk, v) and
|
||||
rnk = ssaRefRank(bb, i, v, any(SsaRead k))
|
||||
rnk = ssaRefRank(bb, i, v, SsaRead())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -398,94 +309,45 @@ private module SsaDefReaches {
|
||||
ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v)
|
||||
}
|
||||
|
||||
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v, SsaRefKind k) {
|
||||
exists(ssaDefRank(def, v, bb, _, k))
|
||||
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
||||
exists(ssaDefRank(def, v, bb, _, _))
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) {
|
||||
ssaDefReachesEndOfBlock(bb, def, _) and
|
||||
not defOccursInBlock(_, bb, def.getSourceVariable(), _)
|
||||
not defOccursInBlock(_, bb, def.getSourceVariable())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `def` is accessed in basic block `bb1` (either a read or a write),
|
||||
* `bb2` is a transitive successor of `bb1`, `def` is live at the end of _some_
|
||||
* predecessor of `bb2`, and the underlying variable for `def` is neither read
|
||||
* nor written in any block on the path between `bb1` and `bb2`.
|
||||
*
|
||||
* Phi reads are considered as normal reads for this predicate.
|
||||
* `bb2` is a transitive successor of `bb1`, `def` is live at the end of `bb1`,
|
||||
* and the underlying variable for `def` is neither read nor written in any block
|
||||
* on the path between `bb1` and `bb2`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate varBlockReachesInclPhiRead(Definition def, BasicBlock bb1, BasicBlock bb2) {
|
||||
defOccursInBlock(def, bb1, _, _) and
|
||||
predicate varBlockReaches(Definition def, BasicBlock bb1, BasicBlock bb2) {
|
||||
defOccursInBlock(def, bb1, _) and
|
||||
bb2 = getABasicBlockSuccessor(bb1)
|
||||
or
|
||||
exists(BasicBlock mid |
|
||||
varBlockReachesInclPhiRead(def, bb1, mid) and
|
||||
varBlockReaches(def, bb1, mid) and
|
||||
ssaDefReachesThroughBlock(def, mid) and
|
||||
bb2 = getABasicBlockSuccessor(mid)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate phiReadStep(Definition def, SourceVariable v, BasicBlock bb1, BasicBlock bb2) {
|
||||
varBlockReachesInclPhiRead(def, bb1, bb2) and
|
||||
defOccursInBlock(def, bb2, v, SsaPhiRead())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate varBlockReachesExclPhiRead(Definition def, BasicBlock bb1, BasicBlock bb2) {
|
||||
varBlockReachesInclPhiRead(pragma[only_bind_into](def), bb1, pragma[only_bind_into](bb2)) and
|
||||
ssaRef(bb2, _, def.getSourceVariable(), [SsaActualRead().(TSsaRefKind), SsaDef()])
|
||||
or
|
||||
exists(BasicBlock mid |
|
||||
varBlockReachesExclPhiRead(def, mid, bb2) and
|
||||
phiReadStep(def, _, bb1, mid)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `def` is accessed in basic block `bb1` (either a read or a write),
|
||||
* the underlying variable `v` of `def` is accessed in basic block `bb2`
|
||||
* (either a read or a write), `bb2` is a transitive successor of `bb1`, and
|
||||
* `v` is neither read nor written in any block on the path between `bb1`
|
||||
* and `bb2`.
|
||||
* `def` is read at index `i2` in basic block `bb2`, `bb2` is in a transitive
|
||||
* successor block of `bb1`, and `def` is neither read nor written in any block
|
||||
* on a path between `bb1` and `bb2`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate varBlockReaches(Definition def, BasicBlock bb1, BasicBlock bb2) {
|
||||
varBlockReachesExclPhiRead(def, bb1, bb2) and
|
||||
not defOccursInBlock(def, bb1, _, SsaPhiRead())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
||||
varBlockReaches(def, bb1, bb2) and
|
||||
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaActualRead()) = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `def` is accessed in basic block `bb` (either a read or a write),
|
||||
* `bb1` can reach a transitive successor `bb2` where `def` is no longer live,
|
||||
* and `v` is neither read nor written in any block on the path between `bb`
|
||||
* and `bb2`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate varBlockReachesExit(Definition def, BasicBlock bb) {
|
||||
exists(BasicBlock bb2 | varBlockReachesInclPhiRead(def, bb, bb2) |
|
||||
not defOccursInBlock(def, bb2, _, _) and
|
||||
not ssaDefReachesEndOfBlock(bb2, def, _)
|
||||
)
|
||||
or
|
||||
exists(BasicBlock mid |
|
||||
varBlockReachesExit(def, mid) and
|
||||
phiReadStep(def, _, bb, mid)
|
||||
)
|
||||
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1
|
||||
}
|
||||
}
|
||||
|
||||
predicate phiReadExposedForTesting = phiRead/2;
|
||||
|
||||
private import SsaDefReaches
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -503,8 +365,7 @@ predicate liveThrough(BasicBlock bb, SourceVariable v) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable v) {
|
||||
exists(int last |
|
||||
last = maxSsaRefRank(pragma[only_bind_into](bb), pragma[only_bind_into](v)) and
|
||||
exists(int last | last = maxSsaRefRank(bb, v) |
|
||||
ssaDefReachesRank(bb, def, last, v) and
|
||||
liveAtExit(bb, v)
|
||||
)
|
||||
@@ -544,7 +405,7 @@ pragma[nomagic]
|
||||
predicate ssaDefReachesRead(SourceVariable v, Definition def, BasicBlock bb, int i) {
|
||||
ssaDefReachesReadWithinBlock(v, def, bb, i)
|
||||
or
|
||||
ssaRef(bb, i, v, any(SsaRead k)) and
|
||||
variableRead(bb, i, v, _) and
|
||||
ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and
|
||||
not ssaDefReachesReadWithinBlock(v, _, bb, i)
|
||||
}
|
||||
@@ -560,7 +421,7 @@ pragma[nomagic]
|
||||
predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) {
|
||||
exists(int rnk |
|
||||
rnk = ssaDefRank(def, _, bb1, i1, _) and
|
||||
rnk + 1 = ssaDefRank(def, _, bb1, i2, SsaActualRead()) and
|
||||
rnk + 1 = ssaDefRank(def, _, bb1, i2, SsaRead()) and
|
||||
variableRead(bb1, i2, _, _) and
|
||||
bb2 = bb1
|
||||
)
|
||||
@@ -677,15 +538,18 @@ predicate lastRefRedefNoUncertainReads(Definition def, BasicBlock bb, int i, Def
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
||||
// Can reach another definition
|
||||
lastRefRedef(def, bb, i, _)
|
||||
or
|
||||
exists(SourceVariable v | lastSsaRef(def, v, bb, i) |
|
||||
lastSsaRef(def, _, bb, i) and
|
||||
(
|
||||
// Can reach exit directly
|
||||
bb instanceof ExitBasicBlock
|
||||
or
|
||||
// Can reach a block using one or more steps, where `def` is no longer live
|
||||
varBlockReachesExit(def, bb)
|
||||
exists(BasicBlock bb2 | varBlockReaches(def, bb, bb2) |
|
||||
not defOccursInBlock(def, bb2, _) and
|
||||
not ssaDefReachesEndOfBlock(bb2, def, _)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ module InstructionConsistency {
|
||||
abstract Language::Location getLocation();
|
||||
}
|
||||
|
||||
class PresentIRFunction extends OptionalIRFunction, TPresentIRFunction {
|
||||
private class PresentIRFunction extends OptionalIRFunction, TPresentIRFunction {
|
||||
private IRFunction irFunc;
|
||||
|
||||
PresentIRFunction() { this = TPresentIRFunction(irFunc) }
|
||||
@@ -37,8 +37,6 @@ module InstructionConsistency {
|
||||
result =
|
||||
min(Language::Location loc | loc = irFunc.getLocation() | loc order by loc.toString())
|
||||
}
|
||||
|
||||
IRFunction getIRFunction() { result = irFunc }
|
||||
}
|
||||
|
||||
private class MissingIRFunction extends OptionalIRFunction, TMissingIRFunction {
|
||||
|
||||
@@ -3,7 +3,7 @@ import semmle.code.cpp.ir.internal.Overlap
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
private import semmle.code.cpp.Print
|
||||
private import semmle.code.cpp.ir.implementation.unaliased_ssa.IR
|
||||
private import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as OldSsa
|
||||
private import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as OldSSA
|
||||
private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
|
||||
private import semmle.code.cpp.ir.internal.IntegerInterval as Interval
|
||||
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||
@@ -572,7 +572,7 @@ private Overlap getVariableMemoryLocationOverlap(
|
||||
* Holds if the def/use information for the result of `instr` can be reused from the previous
|
||||
* iteration of the IR.
|
||||
*/
|
||||
predicate canReuseSsaForOldResult(Instruction instr) { OldSsa::canReuseSsaForMemoryResult(instr) }
|
||||
predicate canReuseSsaForOldResult(Instruction instr) { OldSSA::canReuseSsaForMemoryResult(instr) }
|
||||
|
||||
/** DEPRECATED: Alias for canReuseSsaForOldResult */
|
||||
deprecated predicate canReuseSSAForOldResult = canReuseSsaForOldResult/1;
|
||||
|
||||
@@ -5,8 +5,8 @@ private import Imports::OperandTag
|
||||
private import Imports::Overlap
|
||||
private import Imports::TInstruction
|
||||
private import Imports::RawIR as RawIR
|
||||
private import SsaInstructions
|
||||
private import SsaOperands
|
||||
private import SSAInstructions
|
||||
private import SSAOperands
|
||||
private import NewIR
|
||||
|
||||
private class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
@@ -2,14 +2,7 @@ import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as OldIR
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.reachability.ReachableBlock as Reachability
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.reachability.Dominance as Dominance
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IR as NewIR
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::AliasedSsaInstructions as SsaInstructions
|
||||
|
||||
/** DEPRECATED: Alias for SsaInstructions */
|
||||
deprecated module SSAInstructions = SsaInstructions;
|
||||
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::AliasedSsaInstructions as SSAInstructions
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import AliasedSSA as Alias
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::AliasedSsaOperands as SsaOperands
|
||||
|
||||
/** DEPRECATED: Alias for SsaOperands */
|
||||
deprecated module SSAOperands = SsaOperands;
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::AliasedSsaOperands as SSAOperands
|
||||
|
||||
@@ -29,15 +29,15 @@ newtype TInstruction =
|
||||
UnaliasedSsa::SSA::hasUnreachedInstruction(irFunc)
|
||||
} or
|
||||
TAliasedSsaPhiInstruction(
|
||||
TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation
|
||||
TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation
|
||||
) {
|
||||
AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
||||
AliasedSSA::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
||||
} or
|
||||
TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) {
|
||||
AliasedSsa::SSA::hasChiInstruction(primaryInstruction)
|
||||
AliasedSSA::SSA::hasChiInstruction(primaryInstruction)
|
||||
} or
|
||||
TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
||||
AliasedSsa::SSA::hasUnreachedInstruction(irFunc)
|
||||
AliasedSSA::SSA::hasUnreachedInstruction(irFunc)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ module AliasedSsaInstructions {
|
||||
class TPhiInstruction = TAliasedSsaPhiInstruction or TUnaliasedSsaPhiInstruction;
|
||||
|
||||
TPhiInstruction phiInstruction(
|
||||
TRawInstruction blockStartInstr, AliasedSsa::SSA::MemoryLocation memoryLocation
|
||||
TRawInstruction blockStartInstr, AliasedSSA::SSA::MemoryLocation memoryLocation
|
||||
) {
|
||||
result = TAliasedSsaPhiInstruction(blockStartInstr, memoryLocation)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as IRConstruction
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConstruction as UnaliasedSsa
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConstruction as AliasedSsa
|
||||
|
||||
/** DEPRECATED: Alias for AliasedSsa */
|
||||
deprecated module AliasedSSA = AliasedSsa;
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConstruction as AliasedSSA
|
||||
|
||||
@@ -22,7 +22,7 @@ module InstructionConsistency {
|
||||
abstract Language::Location getLocation();
|
||||
}
|
||||
|
||||
class PresentIRFunction extends OptionalIRFunction, TPresentIRFunction {
|
||||
private class PresentIRFunction extends OptionalIRFunction, TPresentIRFunction {
|
||||
private IRFunction irFunc;
|
||||
|
||||
PresentIRFunction() { this = TPresentIRFunction(irFunc) }
|
||||
@@ -37,8 +37,6 @@ module InstructionConsistency {
|
||||
result =
|
||||
min(Language::Location loc | loc = irFunc.getLocation() | loc order by loc.toString())
|
||||
}
|
||||
|
||||
IRFunction getIRFunction() { result = irFunc }
|
||||
}
|
||||
|
||||
private class MissingIRFunction extends OptionalIRFunction, TMissingIRFunction {
|
||||
|
||||
@@ -947,7 +947,7 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* The IR translation of a root element, either a function or a global variable.
|
||||
* Represents the IR translation of a root element, either a function or a global variable.
|
||||
*/
|
||||
abstract class TranslatedRootElement extends TranslatedElement {
|
||||
TranslatedRootElement() {
|
||||
|
||||
@@ -1450,6 +1450,8 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
|
||||
result = this.getLeftOperand().getResult()
|
||||
}
|
||||
|
||||
abstract Instruction getStoredValue();
|
||||
|
||||
final TranslatedExpr getLeftOperand() {
|
||||
result = getTranslatedExpr(expr.getLValue().getFullyConverted())
|
||||
}
|
||||
@@ -1491,75 +1493,6 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedBlockAssignExpr extends TranslatedNonConstantExpr {
|
||||
override BlockAssignExpr expr;
|
||||
|
||||
final override TranslatedElement getChild(int id) {
|
||||
id = 0 and result = this.getLeftOperand()
|
||||
or
|
||||
id = 1 and result = this.getRightOperand()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
// The operand evaluation order should not matter since block assignments behave like memcpy.
|
||||
result = this.getLeftOperand().getFirstInstruction()
|
||||
}
|
||||
|
||||
final override Instruction getResult() { result = this.getInstruction(AssignmentStoreTag()) }
|
||||
|
||||
final TranslatedExpr getLeftOperand() {
|
||||
result = getTranslatedExpr(expr.getLValue().getFullyConverted())
|
||||
}
|
||||
|
||||
final TranslatedExpr getRightOperand() {
|
||||
result = getTranslatedExpr(expr.getRValue().getFullyConverted())
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = LoadTag() and
|
||||
result = this.getInstruction(AssignmentStoreTag()) and
|
||||
kind instanceof GotoEdge
|
||||
or
|
||||
tag = AssignmentStoreTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getLeftOperand() and
|
||||
result = this.getRightOperand().getFirstInstruction()
|
||||
or
|
||||
child = this.getRightOperand() and
|
||||
result = this.getInstruction(LoadTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = LoadTag() and
|
||||
opcode instanceof Opcode::Load and
|
||||
resultType = getTypeForPRValue(expr.getRValue().getType())
|
||||
or
|
||||
tag = AssignmentStoreTag() and
|
||||
opcode instanceof Opcode::Store and
|
||||
// The frontend specifies that the relevant type is the one of the source.
|
||||
resultType = getTypeForPRValue(expr.getRValue().getType())
|
||||
}
|
||||
|
||||
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
tag = LoadTag() and
|
||||
operandTag instanceof AddressOperandTag and
|
||||
result = this.getRightOperand().getResult()
|
||||
or
|
||||
tag = AssignmentStoreTag() and
|
||||
(
|
||||
operandTag instanceof AddressOperandTag and
|
||||
result = this.getLeftOperand().getResult()
|
||||
or
|
||||
operandTag instanceof StoreValueOperandTag and
|
||||
result = this.getInstruction(LoadTag())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedAssignOperation extends TranslatedNonConstantExpr {
|
||||
override AssignOperation expr;
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
|
||||
result = this.getInstruction(InitializerVariableAddressTag())
|
||||
or
|
||||
tag = InitializerVariableAddressTag() and
|
||||
result = this.getChild(1).getFirstInstruction()
|
||||
result = getChild(1).getFirstInstruction()
|
||||
or
|
||||
tag = ReturnTag() and
|
||||
result = this.getInstruction(AliasedUseTag())
|
||||
|
||||
@@ -22,7 +22,7 @@ module InstructionConsistency {
|
||||
abstract Language::Location getLocation();
|
||||
}
|
||||
|
||||
class PresentIRFunction extends OptionalIRFunction, TPresentIRFunction {
|
||||
private class PresentIRFunction extends OptionalIRFunction, TPresentIRFunction {
|
||||
private IRFunction irFunc;
|
||||
|
||||
PresentIRFunction() { this = TPresentIRFunction(irFunc) }
|
||||
@@ -37,8 +37,6 @@ module InstructionConsistency {
|
||||
result =
|
||||
min(Language::Location loc | loc = irFunc.getLocation() | loc order by loc.toString())
|
||||
}
|
||||
|
||||
IRFunction getIRFunction() { result = irFunc }
|
||||
}
|
||||
|
||||
private class MissingIRFunction extends OptionalIRFunction, TMissingIRFunction {
|
||||
|
||||
@@ -5,8 +5,8 @@ private import Imports::OperandTag
|
||||
private import Imports::Overlap
|
||||
private import Imports::TInstruction
|
||||
private import Imports::RawIR as RawIR
|
||||
private import SsaInstructions
|
||||
private import SsaOperands
|
||||
private import SSAInstructions
|
||||
private import SSAOperands
|
||||
private import NewIR
|
||||
|
||||
private class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
@@ -3,14 +3,7 @@ import semmle.code.cpp.ir.implementation.raw.internal.reachability.ReachableBloc
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.reachability.Dominance as Dominance
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as NewIR
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.IRConstruction as RawStage
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::UnaliasedSsaInstructions as SsaInstructions
|
||||
|
||||
/** DEPRECATED: Alias for SsaInstructions */
|
||||
deprecated module SSAInstructions = SsaInstructions;
|
||||
|
||||
import semmle.code.cpp.ir.implementation.internal.TInstruction::UnaliasedSsaInstructions as SSAInstructions
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import SimpleSSA as Alias
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::UnaliasedSsaOperands as SsaOperands
|
||||
|
||||
/** DEPRECATED: Alias for SsaOperands */
|
||||
deprecated module SSAOperands = SsaOperands;
|
||||
import semmle.code.cpp.ir.implementation.internal.TOperand::UnaliasedSsaOperands as SSAOperands
|
||||
|
||||
@@ -218,7 +218,7 @@ private class CallAllocationExpr extends AllocationExpr, FunctionCall {
|
||||
exists(target.getReallocPtrArg()) and
|
||||
this.getArgument(target.getSizeArg()).getValue().toInt() = 0
|
||||
) and
|
||||
// these are modeled directly (and more accurately), avoid duplication
|
||||
// these are modelled directly (and more accurately), avoid duplication
|
||||
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,12 @@ private class StdPair extends ClassTemplateInstantiation {
|
||||
StdPair() { this.hasQualifiedName(["std", "bsl"], "pair") }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: This is now called `StdPair` and is a private part of the
|
||||
* library implementation.
|
||||
*/
|
||||
deprecated class StdPairClass = StdPair;
|
||||
|
||||
/**
|
||||
* Any of the single-parameter constructors of `std::pair` that takes a reference to an
|
||||
* instantiation of `std::pair`. These constructors allow conversion between pair types when the
|
||||
|
||||
@@ -27,6 +27,13 @@ abstract class RemoteFlowSourceFunction extends Function {
|
||||
predicate hasSocketInput(FunctionInput input) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `RemoteFlowSourceFunction` instead.
|
||||
*
|
||||
* A library function that returns data that may be read from a network connection.
|
||||
*/
|
||||
deprecated class RemoteFlowFunction = RemoteFlowSourceFunction;
|
||||
|
||||
/**
|
||||
* A library function that returns data that is directly controlled by a user.
|
||||
*/
|
||||
@@ -37,6 +44,13 @@ abstract class LocalFlowSourceFunction extends Function {
|
||||
abstract predicate hasLocalFlowSource(FunctionOutput output, string description);
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `LocalFlowSourceFunction` instead.
|
||||
*
|
||||
* A library function that returns data that is directly controlled by a user.
|
||||
*/
|
||||
deprecated class LocalFlowFunction = LocalFlowSourceFunction;
|
||||
|
||||
/** A library function that sends data over a network connection. */
|
||||
abstract class RemoteFlowSinkFunction extends Function {
|
||||
/**
|
||||
|
||||
@@ -1573,7 +1573,7 @@ private module SimpleRangeAnalysisCached {
|
||||
result = min([max(getTruncatedUpperBounds(expr)), getGuardedUpperBound(expr)])
|
||||
}
|
||||
|
||||
/** Holds if the upper bound of `expr` may have been widened. This means the upper bound is in practice likely to be overly wide. */
|
||||
/** Holds if the upper bound of `expr` may have been widened. This means the the upper bound is in practice likely to be overly wide. */
|
||||
cached
|
||||
predicate upperBoundMayBeWidened(Expr e) {
|
||||
isRecursiveExpr(e) and
|
||||
|
||||
@@ -50,7 +50,7 @@ VariableAccess varUse(LocalScopeVariable v) { result = v.getAnAccess() }
|
||||
* Holds if `e` potentially overflows and `use` is an operand of `e` that is not guarded.
|
||||
*/
|
||||
predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
|
||||
// Since `e` is guaranteed to be a `BinaryArithmeticOperation`, a `UnaryArithmeticOperation` or
|
||||
// Since `e` is guarenteed to be a `BinaryArithmeticOperation`, a `UnaryArithmeticOperation` or
|
||||
// an `AssignArithmeticOperation` by the other constraints in this predicate, we know that
|
||||
// `convertedExprMightOverflowPositively` will have a result even when `e` is not analyzable
|
||||
// by `SimpleRangeAnalysis`.
|
||||
@@ -80,7 +80,7 @@ predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
|
||||
* Holds if `e` potentially underflows and `use` is an operand of `e` that is not guarded.
|
||||
*/
|
||||
predicate missingGuardAgainstUnderflow(Operation e, VariableAccess use) {
|
||||
// Since `e` is guaranteed to be a `BinaryArithmeticOperation`, a `UnaryArithmeticOperation` or
|
||||
// Since `e` is guarenteed to be a `BinaryArithmeticOperation`, a `UnaryArithmeticOperation` or
|
||||
// an `AssignArithmeticOperation` by the other constraints in this predicate, we know that
|
||||
// `convertedExprMightOverflowNegatively` will have a result even when `e` is not analyzable
|
||||
// by `SimpleRangeAnalysis`.
|
||||
|
||||
@@ -523,11 +523,6 @@ autoderivation(
|
||||
int derivation_type: @type ref
|
||||
);
|
||||
|
||||
orphaned_variables(
|
||||
int var: @localvariable ref,
|
||||
int function: @function ref
|
||||
)
|
||||
|
||||
enumconstants(
|
||||
unique int id: @enumconstant,
|
||||
int parent: @usertype ref,
|
||||
@@ -904,7 +899,6 @@ case @attribute_arg.kind of
|
||||
| 1 = @attribute_arg_token
|
||||
| 2 = @attribute_arg_constant
|
||||
| 3 = @attribute_arg_type
|
||||
| 4 = @attribute_arg_constant_expr
|
||||
;
|
||||
|
||||
attribute_arg_value(
|
||||
@@ -915,10 +909,6 @@ attribute_arg_type(
|
||||
unique int arg: @attribute_arg ref,
|
||||
int type_id: @type ref
|
||||
);
|
||||
attribute_arg_constant(
|
||||
unique int arg: @attribute_arg ref,
|
||||
int constant: @expr ref
|
||||
)
|
||||
attribute_arg_name(
|
||||
unique int arg: @attribute_arg ref,
|
||||
string name: string ref
|
||||
@@ -1307,7 +1297,7 @@ funbind(
|
||||
|
||||
@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr
|
||||
|
||||
@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
|
||||
@assign_expr = @assignexpr | @assign_op_expr
|
||||
|
||||
/*
|
||||
case @allocator.form of
|
||||
@@ -1660,12 +1650,6 @@ case @expr.kind of
|
||||
| 327 = @co_await
|
||||
| 328 = @co_yield
|
||||
| 329 = @temp_init
|
||||
| 330 = @isassignable
|
||||
| 331 = @isaggregate
|
||||
| 332 = @hasuniqueobjectrepresentations
|
||||
| 333 = @builtinbitcast
|
||||
| 334 = @builtinshuffle
|
||||
| 335 = @blockassignexpr
|
||||
;
|
||||
|
||||
@var_args_expr = @vastartexpr
|
||||
@@ -1727,11 +1711,6 @@ case @expr.kind of
|
||||
| @isfinalexpr
|
||||
| @builtinchooseexpr
|
||||
| @builtincomplex
|
||||
| @isassignable
|
||||
| @isaggregate
|
||||
| @hasuniqueobjectrepresentations
|
||||
| @builtinbitcast
|
||||
| @builtinshuffle
|
||||
;
|
||||
|
||||
new_allocated_type(
|
||||
|
||||
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
@@ -1,2 +0,0 @@
|
||||
description: Add new builtin operations
|
||||
compatibility: backwards
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
description: Support all constant attribute arguments
|
||||
compatibility: partial
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
description: Support block assignment
|
||||
compatibility: backwards
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user